[{"data":1,"prerenderedAt":2020},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation":3,"surround:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation":1985,"ancestors:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation":1994,"children:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation":1999,"related:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation":2000},{"id":4,"title":5,"body":6,"dateModified":1950,"datePublished":1950,"description":1951,"extension":1952,"faq":1953,"keyword":1962,"kind":1963,"meta":1964,"navigation":97,"path":1974,"seo":1975,"slug":1978,"stem":1979,"topics":1980,"type":1983,"__hash__":1984},"docs\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation\u002Findex.md","Build an Intercompany Reconciliation",{"type":7,"value":8,"toc":1938},"minimark",[9,19,24,53,65,69,394,397,401,739,750,948,952,1189,1196,1265,1403,1407,1809,1820,1824,1827,1831,1866,1870,1873,1877,1883,1889,1895,1901,1905,1934],[10,11,12,13,18],"p",{},"When companies in the same group trade with each other, each records its side: the UK company books a receivable from its German sister, and the German company books a payable to the UK. On consolidation the two must cancel exactly — the group cannot owe money to itself — and at every month end they rarely do. One side booked an invoice the other has not received yet; the German side recorded a recharge in euros at a different rate; someone posted a payment to the wrong intercompany account; one entry has no counterpart at all. The intercompany reconciliation finds each difference and sorts it into a category the two finance teams can act on. This page builds it with pandas from the two companies' intercompany ledgers: matching entries by reference, converting to the group currency, separating timing, exchange and genuine differences, checking that the balances eliminate, and writing a shared workbook. It belongs to ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002F","Building Finance and Operations Reports",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47,50],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," pandas",[35,51,52],{"class":45}," openpyxl\n",[10,54,55,56,60,61,64],{},"The workbook holds the September 2026 intercompany ledger lines from both sides: the UK company's account ",[57,58,59],"em",{},"due from Germany"," (receivable, positive amounts increase it) and the German company's account ",[57,62,63],{},"due to UK"," (payable, negative amounts increase it), each in the currency of the transaction. A rates file gives the group's month-end rate for euros.",[20,66,68],{"id":67},"step-1-put-both-sides-on-the-same-basis","Step 1 — Put both sides on the same basis",[25,70,74],{"className":71,"code":72,"language":73,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\nuk = pd.read_excel(\"intercompany.xlsx\", sheet_name=\"UK - due from DE\").assign(Side=\"UK\")\nde = pd.read_excel(\"intercompany.xlsx\", sheet_name=\"DE - due to UK\").assign(Side=\"DE\")\nrates = pd.read_excel(\"rates.xlsx\").set_index(\"Currency\")[\"Rate to GBP\"]\n\ndef to_group(df, flip):\n    out = df.copy()\n    out[\"GBP\"] = (out[\"Amount\"] * out[\"Currency\"].map(rates) * (-1 if flip else 1)).round(2)\n    return out\n\nuk_g, de_g = to_group(uk, flip=False), to_group(de, flip=True)\nprint(f\"UK balance due from DE: {uk_g['GBP'].sum():,.2f} GBP | DE balance due to UK: {de_g['GBP'].sum():,.2f} GBP\")\n","python",[32,75,76,92,99,140,172,200,205,218,229,294,303,308,339],{"__ignoreMap":30},[35,77,78,82,86,89],{"class":37,"line":38},[35,79,81],{"class":80},"s-kum","import",[35,83,85],{"class":84},"skGVy"," pandas ",[35,87,88],{"class":80},"as",[35,90,91],{"class":84}," pd\n",[35,93,95],{"class":37,"line":94},2,[35,96,98],{"emptyLinePlaceholder":97},true,"\n",[35,100,102,105,108,111,114,117,121,123,126,129,132,134,137],{"class":37,"line":101},3,[35,103,104],{"class":84},"uk ",[35,106,107],{"class":80},"=",[35,109,110],{"class":84}," pd.read_excel(",[35,112,113],{"class":45},"\"intercompany.xlsx\"",[35,115,116],{"class":84},", ",[35,118,120],{"class":119},"sa561","sheet_name",[35,122,107],{"class":80},[35,124,125],{"class":45},"\"UK - due from DE\"",[35,127,128],{"class":84},").assign(",[35,130,131],{"class":119},"Side",[35,133,107],{"class":80},[35,135,136],{"class":45},"\"UK\"",[35,138,139],{"class":84},")\n",[35,141,143,146,148,150,152,154,156,158,161,163,165,167,170],{"class":37,"line":142},4,[35,144,145],{"class":84},"de ",[35,147,107],{"class":80},[35,149,110],{"class":84},[35,151,113],{"class":45},[35,153,116],{"class":84},[35,155,120],{"class":119},[35,157,107],{"class":80},[35,159,160],{"class":45},"\"DE - due to UK\"",[35,162,128],{"class":84},[35,164,131],{"class":119},[35,166,107],{"class":80},[35,168,169],{"class":45},"\"DE\"",[35,171,139],{"class":84},[35,173,175,178,180,182,185,188,191,194,197],{"class":37,"line":174},5,[35,176,177],{"class":84},"rates ",[35,179,107],{"class":80},[35,181,110],{"class":84},[35,183,184],{"class":45},"\"rates.xlsx\"",[35,186,187],{"class":84},").set_index(",[35,189,190],{"class":45},"\"Currency\"",[35,192,193],{"class":84},")[",[35,195,196],{"class":45},"\"Rate to GBP\"",[35,198,199],{"class":84},"]\n",[35,201,203],{"class":37,"line":202},6,[35,204,98],{"emptyLinePlaceholder":97},[35,206,208,211,215],{"class":37,"line":207},7,[35,209,210],{"class":80},"def",[35,212,214],{"class":213},"s_Opv"," to_group",[35,216,217],{"class":84},"(df, flip):\n",[35,219,221,224,226],{"class":37,"line":220},8,[35,222,223],{"class":84},"    out ",[35,225,107],{"class":80},[35,227,228],{"class":84}," df.copy()\n",[35,230,232,235,238,241,243,246,249,251,254,257,259,262,264,267,270,274,277,280,283,286,289,292],{"class":37,"line":231},9,[35,233,234],{"class":84},"    out[",[35,236,237],{"class":45},"\"GBP\"",[35,239,240],{"class":84},"] ",[35,242,107],{"class":80},[35,244,245],{"class":84}," (out[",[35,247,248],{"class":45},"\"Amount\"",[35,250,240],{"class":84},[35,252,253],{"class":80},"*",[35,255,256],{"class":84}," out[",[35,258,190],{"class":45},[35,260,261],{"class":84},"].map(rates) ",[35,263,253],{"class":80},[35,265,266],{"class":84}," (",[35,268,269],{"class":80},"-",[35,271,273],{"class":272},"sP0c6","1",[35,275,276],{"class":80}," if",[35,278,279],{"class":84}," flip ",[35,281,282],{"class":80},"else",[35,284,285],{"class":272}," 1",[35,287,288],{"class":84},")).round(",[35,290,291],{"class":272},"2",[35,293,139],{"class":84},[35,295,297,300],{"class":37,"line":296},10,[35,298,299],{"class":80},"    return",[35,301,302],{"class":84}," out\n",[35,304,306],{"class":37,"line":305},11,[35,307,98],{"emptyLinePlaceholder":97},[35,309,311,314,316,319,322,324,327,330,332,334,337],{"class":37,"line":310},12,[35,312,313],{"class":84},"uk_g, de_g ",[35,315,107],{"class":80},[35,317,318],{"class":84}," to_group(uk, ",[35,320,321],{"class":119},"flip",[35,323,107],{"class":80},[35,325,326],{"class":272},"False",[35,328,329],{"class":84},"), to_group(de, ",[35,331,321],{"class":119},[35,333,107],{"class":80},[35,335,336],{"class":272},"True",[35,338,139],{"class":84},[35,340,342,345,348,351,354,358,361,364,367,370,373,376,378,381,383,385,387,389,392],{"class":37,"line":341},13,[35,343,344],{"class":272},"print",[35,346,347],{"class":84},"(",[35,349,350],{"class":80},"f",[35,352,353],{"class":45},"\"UK balance due from DE: ",[35,355,357],{"class":356},"sSjpA","{",[35,359,360],{"class":84},"uk_g[",[35,362,363],{"class":45},"'GBP'",[35,365,366],{"class":84},"].sum()",[35,368,369],{"class":80},":,.2f",[35,371,372],{"class":356},"}",[35,374,375],{"class":45}," GBP | DE balance due to UK: ",[35,377,357],{"class":356},[35,379,380],{"class":84},"de_g[",[35,382,363],{"class":45},[35,384,366],{"class":84},[35,386,369],{"class":80},[35,388,372],{"class":356},[35,390,391],{"class":45}," GBP\"",[35,393,139],{"class":84},[10,395,396],{},"Two adjustments make the sides comparable. The German ledger shows its payable as negative numbers, so its signs are flipped: after flipping, both sides show \"amount owed by Germany to the UK\" as positive. And every amount is converted to sterling at the group's month-end rate, so euro transactions on either side can be compared with sterling ones. On this basis the UK says Germany owes it 60,606.40; Germany says it owes 51,942.26. The 8,664.14 gap is what the reconciliation has to explain.",[20,398,400],{"id":399},"step-2-match-entries-by-reference","Step 2 — Match entries by reference",[25,402,404],{"className":71,"code":403,"language":73,"meta":30,"style":30},"m = uk_g.merge(de_g, on=\"Reference\", how=\"outer\", suffixes=(\"_UK\", \"_DE\"), indicator=True)\nm[[\"GBP_UK\", \"GBP_DE\"]] = m[[\"GBP_UK\", \"GBP_DE\"]].fillna(0)\nm[\"Difference\"] = (m[\"GBP_UK\"] - m[\"GBP_DE\"]).round(2)\n\ndef classify(r):\n    if r[\"_merge\"] == \"left_only\":\n        return \"Only in UK (in transit or missing in DE)\"\n    if r[\"_merge\"] == \"right_only\":\n        return \"Only in DE (not booked in UK)\"\n    if abs(r[\"Difference\"]) \u003C 0.01:\n        return \"Matched\"\n    if r[\"Currency_UK\"] != r[\"Currency_DE\"]:\n        return \"Exchange difference\"\n    return \"Amount differs\"\n\nm[\"Category\"] = m.apply(classify, axis=1)\nprint(m[[\"Reference\", \"Description_UK\", \"GBP_UK\", \"GBP_DE\", \"Difference\", \"Category\"]].to_string(index=False))\n",[32,405,406,463,498,531,535,545,567,575,592,599,622,629,651,658,666,671,695],{"__ignoreMap":30},[35,407,408,411,413,416,419,421,424,426,429,431,434,436,439,441,443,446,448,451,454,457,459,461],{"class":37,"line":38},[35,409,410],{"class":84},"m ",[35,412,107],{"class":80},[35,414,415],{"class":84}," uk_g.merge(de_g, ",[35,417,418],{"class":119},"on",[35,420,107],{"class":80},[35,422,423],{"class":45},"\"Reference\"",[35,425,116],{"class":84},[35,427,428],{"class":119},"how",[35,430,107],{"class":80},[35,432,433],{"class":45},"\"outer\"",[35,435,116],{"class":84},[35,437,438],{"class":119},"suffixes",[35,440,107],{"class":80},[35,442,347],{"class":84},[35,444,445],{"class":45},"\"_UK\"",[35,447,116],{"class":84},[35,449,450],{"class":45},"\"_DE\"",[35,452,453],{"class":84},"), ",[35,455,456],{"class":119},"indicator",[35,458,107],{"class":80},[35,460,336],{"class":272},[35,462,139],{"class":84},[35,464,465,468,471,473,476,479,481,484,486,488,490,493,496],{"class":37,"line":94},[35,466,467],{"class":84},"m[[",[35,469,470],{"class":45},"\"GBP_UK\"",[35,472,116],{"class":84},[35,474,475],{"class":45},"\"GBP_DE\"",[35,477,478],{"class":84},"]] ",[35,480,107],{"class":80},[35,482,483],{"class":84}," m[[",[35,485,470],{"class":45},[35,487,116],{"class":84},[35,489,475],{"class":45},[35,491,492],{"class":84},"]].fillna(",[35,494,495],{"class":272},"0",[35,497,139],{"class":84},[35,499,500,503,506,508,510,513,515,517,519,522,524,527,529],{"class":37,"line":101},[35,501,502],{"class":84},"m[",[35,504,505],{"class":45},"\"Difference\"",[35,507,240],{"class":84},[35,509,107],{"class":80},[35,511,512],{"class":84}," (m[",[35,514,470],{"class":45},[35,516,240],{"class":84},[35,518,269],{"class":80},[35,520,521],{"class":84}," m[",[35,523,475],{"class":45},[35,525,526],{"class":84},"]).round(",[35,528,291],{"class":272},[35,530,139],{"class":84},[35,532,533],{"class":37,"line":142},[35,534,98],{"emptyLinePlaceholder":97},[35,536,537,539,542],{"class":37,"line":174},[35,538,210],{"class":80},[35,540,541],{"class":213}," classify",[35,543,544],{"class":84},"(r):\n",[35,546,547,550,553,556,558,561,564],{"class":37,"line":202},[35,548,549],{"class":80},"    if",[35,551,552],{"class":84}," r[",[35,554,555],{"class":45},"\"_merge\"",[35,557,240],{"class":84},[35,559,560],{"class":80},"==",[35,562,563],{"class":45}," \"left_only\"",[35,565,566],{"class":84},":\n",[35,568,569,572],{"class":37,"line":207},[35,570,571],{"class":80},"        return",[35,573,574],{"class":45}," \"Only in UK (in transit or missing in DE)\"\n",[35,576,577,579,581,583,585,587,590],{"class":37,"line":220},[35,578,549],{"class":80},[35,580,552],{"class":84},[35,582,555],{"class":45},[35,584,240],{"class":84},[35,586,560],{"class":80},[35,588,589],{"class":45}," \"right_only\"",[35,591,566],{"class":84},[35,593,594,596],{"class":37,"line":231},[35,595,571],{"class":80},[35,597,598],{"class":45}," \"Only in DE (not booked in UK)\"\n",[35,600,601,603,606,609,611,614,617,620],{"class":37,"line":296},[35,602,549],{"class":80},[35,604,605],{"class":272}," abs",[35,607,608],{"class":84},"(r[",[35,610,505],{"class":45},[35,612,613],{"class":84},"]) ",[35,615,616],{"class":80},"\u003C",[35,618,619],{"class":272}," 0.01",[35,621,566],{"class":84},[35,623,624,626],{"class":37,"line":305},[35,625,571],{"class":80},[35,627,628],{"class":45}," \"Matched\"\n",[35,630,631,633,635,638,640,643,645,648],{"class":37,"line":310},[35,632,549],{"class":80},[35,634,552],{"class":84},[35,636,637],{"class":45},"\"Currency_UK\"",[35,639,240],{"class":84},[35,641,642],{"class":80},"!=",[35,644,552],{"class":84},[35,646,647],{"class":45},"\"Currency_DE\"",[35,649,650],{"class":84},"]:\n",[35,652,653,655],{"class":37,"line":341},[35,654,571],{"class":80},[35,656,657],{"class":45}," \"Exchange difference\"\n",[35,659,661,663],{"class":37,"line":660},14,[35,662,299],{"class":80},[35,664,665],{"class":45}," \"Amount differs\"\n",[35,667,669],{"class":37,"line":668},15,[35,670,98],{"emptyLinePlaceholder":97},[35,672,674,676,679,681,683,686,689,691,693],{"class":37,"line":673},16,[35,675,502],{"class":84},[35,677,678],{"class":45},"\"Category\"",[35,680,240],{"class":84},[35,682,107],{"class":80},[35,684,685],{"class":84}," m.apply(classify, ",[35,687,688],{"class":119},"axis",[35,690,107],{"class":80},[35,692,273],{"class":272},[35,694,139],{"class":84},[35,696,698,700,703,705,707,710,712,714,716,718,720,722,724,726,729,732,734,736],{"class":37,"line":697},17,[35,699,344],{"class":272},[35,701,702],{"class":84},"(m[[",[35,704,423],{"class":45},[35,706,116],{"class":84},[35,708,709],{"class":45},"\"Description_UK\"",[35,711,116],{"class":84},[35,713,470],{"class":45},[35,715,116],{"class":84},[35,717,475],{"class":45},[35,719,116],{"class":84},[35,721,505],{"class":45},[35,723,116],{"class":84},[35,725,678],{"class":45},[35,727,728],{"class":84},"]].to_string(",[35,730,731],{"class":119},"index",[35,733,107],{"class":80},[35,735,326],{"class":272},[35,737,738],{"class":84},"))\n",[10,740,741,742,745,746,749],{},"An outer merge on the transaction reference lines up each entry with its counterpart and keeps entries that exist on only one side, which ",[32,743,744],{},"indicator=True"," labels. The classification then follows the questions a group accountant asks. An entry only in the UK books is usually ",[57,747,748],{},"in transit"," — invoiced on the 29th and not yet received in Germany — or was never recorded there. An entry only in the German books is something the UK has not booked, such as a recharge raised by Germany. Where both sides have the entry but the sterling amounts differ, the cause is usually exchange: one side booked the invoice in sterling, the other converted it to euros at the rate of the day, and the month-end rates no longer agree. A difference between entries in the same currency is a genuine amount error.",[751,752,760,761,760,765,760,769,760,776,760,786,760,797,760,803,760,807,760,811,760,814,760,819,760,828,760,833,760,841,760,848,760,853,760,858,760,861,760,864,760,868,760,871,760,876,760,883,760,887,760,890,760,893,760,896,760,900,760,903,760,906,760,912,760,915,760,918,760,920,760,923,760,927,760,930,760,934,760,941,760,945],"svg",{"viewBox":753,"role":754,"ariaLabelledBy":755,"xmlns":758,"style":759},"4 0 752 272","img",[756,757],"ic-classify-t","ic-classify-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[762,763,764],"title",{"id":756},"How each intercompany line is classified",[766,767,768],"desc",{"id":757},"Lines in both ledgers with the same group-currency amount are matched. Lines in both with a different amount are exchange differences if the two sides booked different currencies, otherwise amount errors. Lines only in the selling company's ledger are usually in transit; lines only in the buying company's ledger have not been booked by the seller.",[770,771],"rect",{"x":772,"y":495,"width":773,"height":774,"fill":775},"4","752","272","#ffffff",[770,777],{"x":778,"y":779,"width":780,"height":781,"rx":782,"fill":783,"stroke":784,"style":785},"240.0","16.0","280.0","75.5","12","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[787,788,790],"g",{"transform":789},"translate(368.0,29.0) scale(1.000)",[791,792],"path",{"d":793,"fill":794,"stroke":795,"style":796},"M6 4v5a5 5 0 0 0 5 5h7 M6 20v-5 M15 11l3 3-3 3","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[798,799,802],"text",{"x":800,"y":781,"style":801},"380.0","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Match on reference",[37,804],{"x1":800,"y1":805,"x2":800,"y2":806,"stroke":784,"style":785},"91.5","111.5",[37,808],{"x1":809,"y1":806,"x2":810,"y2":806,"stroke":784,"style":785},"104.0","656.0",[37,812],{"x1":809,"y1":806,"x2":809,"y2":813,"stroke":784,"style":785},"157.5",[815,816],"polygon",{"points":817,"fill":818},"104.0,161.5 99.0,152.5 109.0,152.5","#5b5cf0",[770,820],{"x":821,"y":822,"width":823,"height":824,"rx":825,"fill":775,"stroke":826,"style":827},"38.2","121.5","131.6","21.0","10","var(--line,#cdd5e6)","stroke-width:1.2px",[798,829,832],{"x":809,"y":830,"style":831},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","both, same amount",[770,834],{"x":835,"y":836,"width":837,"height":838,"rx":782,"fill":839,"stroke":840,"style":785},"20.0","163.5","168.0","93.0","#d9f4f1","var(--teal,#0f9488)",[787,842,844],{"transform":843},"translate(92.0,176.5) scale(1.000)",[791,845],{"d":846,"fill":794,"stroke":847,"style":796},"M5 12.5l4.5 4.5L19 7","var(--teal-ink,#0b6157)",[798,849,852],{"x":809,"y":850,"style":851},"223.0","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Matched",[798,854,857],{"x":809,"y":855,"style":856},"242.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","no action",[37,859],{"x1":860,"y1":806,"x2":860,"y2":813,"stroke":784,"style":785},"288.0",[815,862],{"points":863,"fill":818},"288.0,161.5 283.0,152.5 293.0,152.5",[770,865],{"x":866,"y":822,"width":867,"height":824,"rx":825,"fill":775,"stroke":826,"style":827},"208.0","160.0",[798,869,870],{"x":860,"y":830,"style":831},"both, different currency",[770,872],{"x":873,"y":836,"width":837,"height":838,"rx":782,"fill":874,"stroke":875,"style":785},"204.0","#fdefd8","var(--gold,#b4740a)",[787,877,879],{"transform":878},"translate(276.0,176.5) scale(1.000)",[791,880],{"d":881,"fill":794,"stroke":882,"style":796},"M20 11a8 8 0 1 0-2.3 5.7 M20 4v7h-7","var(--gold-ink,#7a4e06)",[798,884,886],{"x":860,"y":850,"style":885},"font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Exchange difference",[798,888,889],{"x":860,"y":855,"style":856},"group FX policy",[37,891],{"x1":892,"y1":806,"x2":892,"y2":813,"stroke":784,"style":785},"472.0",[815,894],{"points":895,"fill":818},"472.0,161.5 467.0,152.5 477.0,152.5",[770,897],{"x":898,"y":822,"width":899,"height":824,"rx":825,"fill":775,"stroke":826,"style":827},"401.9","140.2",[798,901,902],{"x":892,"y":830,"style":831},"both, same currency",[770,904],{"x":905,"y":836,"width":837,"height":838,"rx":782,"fill":783,"stroke":784,"style":785},"388.0",[787,907,909],{"transform":908},"translate(460.0,176.5) scale(1.000)",[791,910],{"d":911,"fill":794,"stroke":795,"style":796},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[798,913,914],{"x":892,"y":850,"style":801},"Amount differs",[798,916,917],{"x":892,"y":855,"style":856},"correct one side",[37,919],{"x1":810,"y1":806,"x2":810,"y2":813,"stroke":784,"style":785},[815,921],{"points":922,"fill":818},"656.0,161.5 651.0,152.5 661.0,152.5",[770,924],{"x":925,"y":822,"width":926,"height":824,"rx":825,"fill":775,"stroke":826,"style":827},"607.9","96.1",[798,928,929],{"x":810,"y":830,"style":831},"one side only",[770,931],{"x":932,"y":836,"width":837,"height":838,"rx":782,"fill":933,"stroke":826,"style":785},"572.0","#e7ebef",[787,935,937],{"transform":936},"translate(644.0,176.5) scale(1.000)",[791,938],{"d":939,"fill":794,"stroke":940,"style":796},"M12 3a9 9 0 1 0 .01 0z M12 7v5l3.5 2","var(--text,#172033)",[798,942,944],{"x":810,"y":850,"style":943},"font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","In transit or missing",[798,946,947],{"x":810,"y":855,"style":856},"book or confirm",[20,949,951],{"id":950},"step-3-summarise-and-check-the-elimination","Step 3 — Summarise and check the elimination",[25,953,955],{"className":71,"code":954,"language":73,"meta":30,"style":30},"summary = m.groupby(\"Category\")[\"Difference\"].agg([\"count\", \"sum\"]).rename(columns={\"count\": \"Lines\", \"sum\": \"GBP\"}).round(2)\nprint(summary.to_string())\ngap = round(uk_g[\"GBP\"].sum() - de_g[\"GBP\"].sum(), 2)\nexplained = round(summary[\"GBP\"].sum(), 2)\nprint(f\"gap {gap:,.2f} | explained by categories {explained:,.2f} | unexplained {gap - explained:,.2f}\")\nafter = round(gap - summary.loc[summary.index.str.startswith((\"Only in UK\", \"Exchange\")), \"GBP\"].sum(), 2)\nprint(f\"difference left after in-transit and FX items: {after:,.2f}\")\n",[32,956,957,1017,1024,1056,1076,1129,1165],{"__ignoreMap":30},[35,958,959,962,964,967,969,971,973,976,979,981,984,987,990,992,994,996,999,1002,1004,1006,1008,1010,1013,1015],{"class":37,"line":38},[35,960,961],{"class":84},"summary ",[35,963,107],{"class":80},[35,965,966],{"class":84}," m.groupby(",[35,968,678],{"class":45},[35,970,193],{"class":84},[35,972,505],{"class":45},[35,974,975],{"class":84},"].agg([",[35,977,978],{"class":45},"\"count\"",[35,980,116],{"class":84},[35,982,983],{"class":45},"\"sum\"",[35,985,986],{"class":84},"]).rename(",[35,988,989],{"class":119},"columns",[35,991,107],{"class":80},[35,993,357],{"class":84},[35,995,978],{"class":45},[35,997,998],{"class":84},": ",[35,1000,1001],{"class":45},"\"Lines\"",[35,1003,116],{"class":84},[35,1005,983],{"class":45},[35,1007,998],{"class":84},[35,1009,237],{"class":45},[35,1011,1012],{"class":84},"}).round(",[35,1014,291],{"class":272},[35,1016,139],{"class":84},[35,1018,1019,1021],{"class":37,"line":94},[35,1020,344],{"class":272},[35,1022,1023],{"class":84},"(summary.to_string())\n",[35,1025,1026,1029,1031,1034,1037,1039,1042,1044,1047,1049,1052,1054],{"class":37,"line":101},[35,1027,1028],{"class":84},"gap ",[35,1030,107],{"class":80},[35,1032,1033],{"class":272}," round",[35,1035,1036],{"class":84},"(uk_g[",[35,1038,237],{"class":45},[35,1040,1041],{"class":84},"].sum() ",[35,1043,269],{"class":80},[35,1045,1046],{"class":84}," de_g[",[35,1048,237],{"class":45},[35,1050,1051],{"class":84},"].sum(), ",[35,1053,291],{"class":272},[35,1055,139],{"class":84},[35,1057,1058,1061,1063,1065,1068,1070,1072,1074],{"class":37,"line":142},[35,1059,1060],{"class":84},"explained ",[35,1062,107],{"class":80},[35,1064,1033],{"class":272},[35,1066,1067],{"class":84},"(summary[",[35,1069,237],{"class":45},[35,1071,1051],{"class":84},[35,1073,291],{"class":272},[35,1075,139],{"class":84},[35,1077,1078,1080,1082,1084,1087,1089,1092,1094,1096,1099,1101,1104,1106,1108,1111,1113,1115,1117,1120,1122,1124,1127],{"class":37,"line":174},[35,1079,344],{"class":272},[35,1081,347],{"class":84},[35,1083,350],{"class":80},[35,1085,1086],{"class":45},"\"gap ",[35,1088,357],{"class":356},[35,1090,1091],{"class":84},"gap",[35,1093,369],{"class":80},[35,1095,372],{"class":356},[35,1097,1098],{"class":45}," | explained by categories ",[35,1100,357],{"class":356},[35,1102,1103],{"class":84},"explained",[35,1105,369],{"class":80},[35,1107,372],{"class":356},[35,1109,1110],{"class":45}," | unexplained ",[35,1112,357],{"class":356},[35,1114,1028],{"class":84},[35,1116,269],{"class":80},[35,1118,1119],{"class":84}," explained",[35,1121,369],{"class":80},[35,1123,372],{"class":356},[35,1125,1126],{"class":45},"\"",[35,1128,139],{"class":84},[35,1130,1131,1134,1136,1138,1141,1143,1146,1149,1151,1154,1157,1159,1161,1163],{"class":37,"line":202},[35,1132,1133],{"class":84},"after ",[35,1135,107],{"class":80},[35,1137,1033],{"class":272},[35,1139,1140],{"class":84},"(gap ",[35,1142,269],{"class":80},[35,1144,1145],{"class":84}," summary.loc[summary.index.str.startswith((",[35,1147,1148],{"class":45},"\"Only in UK\"",[35,1150,116],{"class":84},[35,1152,1153],{"class":45},"\"Exchange\"",[35,1155,1156],{"class":84},")), ",[35,1158,237],{"class":45},[35,1160,1051],{"class":84},[35,1162,291],{"class":272},[35,1164,139],{"class":84},[35,1166,1167,1169,1171,1173,1176,1178,1181,1183,1185,1187],{"class":37,"line":207},[35,1168,344],{"class":272},[35,1170,347],{"class":84},[35,1172,350],{"class":80},[35,1174,1175],{"class":45},"\"difference left after in-transit and FX items: ",[35,1177,357],{"class":356},[35,1179,1180],{"class":84},"after",[35,1182,369],{"class":80},[35,1184,372],{"class":356},[35,1186,1126],{"class":45},[35,1188,139],{"class":84},[10,1190,1191,1192,18],{},"The categories add up exactly to the gap between the two balances, which is the check that the reconciliation is complete. Then comes the question that matters for consolidation: once items in transit are booked by the receiving company and exchange differences are handled under the group's policy, what genuine difference remains? The 8,664.14 gap breaks down into 9,600.00 of goods shipped on 29 September and not yet received in Germany, 64.14 of exchange differences — 64.11 of it on the royalty, which Germany converted at a different rate from the group's, the rest pennies of rounding — and −1,000.00 for a freight recharge Germany booked that the UK never raised. After the in-transit and exchange items, that −1,000.00 is the genuine disagreement one of the two finance teams has to resolve before the balances will eliminate. Comparing two sets of records line by line is the same technique as in ",[14,1193,1195],{"href":1194},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bank-reconciliation-report\u002F","Build a Bank Reconciliation Report",[751,1197,760,1203,760,1206,760,1209,760,1213,760,1219,760,1225,760,1230,760,1235,760,1238,760,1242,760,1245,760,1250,760,1253,760,1257,760,1260],{"viewBox":1198,"role":754,"ariaLabelledBy":1199,"xmlns":758,"style":1202},"4 0 739 140",[1200,1201],"ic-gap-t","ic-gap-d","width:100%;max-width:739px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[762,1204,1205],{"id":1200},"What explains the gap between the two balances",[766,1207,1208],{"id":1201},"The UK shows 60,606.40 due from Germany and Germany shows 51,942.26 due to the UK. The goods shipped on 29 September and not yet received in Germany account for 9,600.00 of the 8,664.14 gap, exchange differences for 64.14, and the freight recharge booked only in Germany for minus 1,000.00.",[770,1210],{"x":772,"y":495,"width":1211,"height":1212,"fill":775},"739","140",[770,1214],{"x":835,"y":779,"width":1215,"height":1216,"rx":1217,"fill":933,"stroke":826,"style":1218},"183.4","28.0","7","stroke-width:1px",[798,1220,1224],{"x":1221,"y":1222,"style":1223},"111.7","34.5","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","In transit (IC-2026-034)",[770,1226],{"x":1227,"y":779,"width":1228,"height":1216,"rx":1217,"fill":933,"stroke":826,"style":1229},"213.4","446.7","stroke-width:1.5px",[798,1231,1234],{"x":1232,"y":1222,"style":1233},"668.1","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:start","9,600.00",[770,1236],{"x":835,"y":1237,"width":1215,"height":1216,"rx":1217,"fill":933,"stroke":826,"style":1218},"56.0",[798,1239,1241],{"x":1221,"y":1240,"style":1223},"74.5","Exchange differences",[770,1243],{"x":1227,"y":1237,"width":1244,"height":1216,"rx":1217,"fill":874,"stroke":875,"style":1229},"6.0",[798,1246,1249],{"x":1247,"y":1240,"style":1248},"227.4","font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:start","64.14",[770,1251],{"x":835,"y":1252,"width":1215,"height":1216,"rx":1217,"fill":933,"stroke":826,"style":1218},"96.0",[798,1254,1256],{"x":1221,"y":1255,"style":1223},"114.5","Only in DE (freight)",[770,1258],{"x":1227,"y":1252,"width":1259,"height":1216,"rx":1217,"fill":783,"stroke":784,"style":1229},"46.5",[798,1261,1264],{"x":1262,"y":1255,"style":1263},"268.0","font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:start","−1,000.00",[751,1266,760,1271,760,1274,760,1277,760,1280,760,1284,760,1290,760,1295,760,1299,760,1303,760,1307,760,1310,760,1313,760,1318,760,1322,760,1325,760,1328,760,1332,760,1335,760,1338,760,1343,760,1346,760,1350,760,1354,760,1357,760,1360,760,1366,760,1370,760,1373,760,1376,760,1380,760,1383,760,1386,760,1391,760,1395,760,1397,760,1400],{"viewBox":1267,"role":754,"ariaLabelledBy":1268,"xmlns":758,"style":759},"4 0 752 160",[1269,1270],"ic-flow-t","ic-flow-d",[762,1272,1273],{"id":1269},"Reconciling one pair of group companies",[766,1275,1276],{"id":1270},"Load both intercompany ledgers, flip the payable side's signs, convert both to the group currency, outer-merge on the shared reference, classify each line, check that the categories sum to the gap and write a summary and line-by-line workbook.",[770,1278],{"x":772,"y":495,"width":773,"height":1279,"fill":775},"160",[770,1281],{"x":835,"y":779,"width":1282,"height":1283,"rx":782,"fill":933,"stroke":826,"style":785},"115.2","128.0",[787,1285,1287],{"transform":1286},"translate(65.6,37.8) scale(1.000)",[791,1288],{"d":1289,"fill":794,"stroke":940,"style":796},"M5 6c0-1.7 3.1-3 7-3s7 1.3 7 3-3.1 3-7 3-7-1.3-7-3z M5 6v12c0 1.7 3.1 3 7 3s7-1.3 7-3V6 M5 12c0 1.7 3.1 3 7 3s7-1.3 7-3",[798,1291,1294],{"x":1292,"y":1293,"style":943},"77.6","84.2","Two ledgers",[798,1296,1298],{"x":1292,"y":1297,"style":856},"103.8","receivable and",[798,1300,1302],{"x":1292,"y":1301,"style":856},"121.2","payable",[37,1304],{"x1":899,"y1":1305,"x2":1306,"y2":1305,"stroke":784,"style":785},"80.0","162.2",[815,1308],{"points":1309,"fill":818},"166.2,80.0 157.2,85.0 157.2,75.0",[770,1311],{"x":1312,"y":779,"width":1282,"height":1283,"rx":782,"fill":783,"stroke":784,"style":785},"171.2",[787,1314,1316],{"transform":1315},"translate(216.8,37.8) scale(1.000)",[791,1317],{"d":881,"fill":794,"stroke":795,"style":796},[798,1319,1321],{"x":1320,"y":1293,"style":801},"228.8","Same basis",[798,1323,1324],{"x":1320,"y":1297,"style":856},"flip signs,",[798,1326,1327],{"x":1320,"y":1301,"style":856},"convert to GBP",[37,1329],{"x1":1330,"y1":1305,"x2":1331,"y2":1305,"stroke":784,"style":785},"291.4","313.4",[815,1333],{"points":1334,"fill":818},"317.4,80.0 308.4,85.0 308.4,75.0",[770,1336],{"x":1337,"y":779,"width":1282,"height":1283,"rx":782,"fill":874,"stroke":875,"style":785},"322.4",[787,1339,1341],{"transform":1340},"translate(368.0,46.5) scale(1.000)",[791,1342],{"d":793,"fill":794,"stroke":882,"style":796},[798,1344,1345],{"x":800,"y":838,"style":885},"Outer merge",[798,1347,1349],{"x":800,"y":1348,"style":856},"112.5","on reference",[37,1351],{"x1":1352,"y1":1305,"x2":1353,"y2":1305,"stroke":784,"style":785},"442.6","464.6",[815,1355],{"points":1356,"fill":818},"468.6,80.0 459.6,85.0 459.6,75.0",[770,1358],{"x":1359,"y":779,"width":1282,"height":1283,"rx":782,"fill":839,"stroke":840,"style":785},"473.6",[787,1361,1363],{"transform":1362},"translate(519.2,37.8) scale(1.000)",[791,1364],{"d":1365,"fill":794,"stroke":847,"style":796},"M3 5h18l-7 8v6l-4 2v-8z",[798,1367,1369],{"x":1368,"y":1293,"style":851},"531.2","Classify lines",[798,1371,1372],{"x":1368,"y":1297,"style":856},"transit, FX,",[798,1374,1375],{"x":1368,"y":1301,"style":856},"one-sided",[37,1377],{"x1":1378,"y1":1305,"x2":1379,"y2":1305,"stroke":784,"style":785},"593.8","615.8",[815,1381],{"points":1382,"fill":818},"619.8,80.0 610.8,85.0 610.8,75.0",[770,1384],{"x":1385,"y":779,"width":1282,"height":1283,"rx":782,"fill":933,"stroke":826,"style":785},"624.8",[787,1387,1389],{"transform":1388},"translate(670.4,29.0) scale(1.000)",[791,1390],{"d":846,"fill":794,"stroke":940,"style":796},[798,1392,1394],{"x":1393,"y":781,"style":943},"682.4","Prove the",[798,1396,1091],{"x":1393,"y":838,"style":943},[798,1398,1399],{"x":1393,"y":1348,"style":856},"categories =",[798,1401,1091],{"x":1393,"y":1402,"style":856},"130.0",[20,1404,1406],{"id":1405},"step-4-a-workbook-both-teams-can-use","Step 4 — A workbook both teams can use",[25,1408,1410],{"className":71,"code":1409,"language":73,"meta":30,"style":30},"from openpyxl import load_workbook\nfrom openpyxl.styles import Font\n\npath = \"ic_recon_UK_DE_2026-09.xlsx\"\ncols = [\"Reference\", \"Date_UK\", \"Date_DE\", \"Description_UK\", \"Description_DE\", \"Currency_UK\", \"Amount_UK\",\n        \"Currency_DE\", \"Amount_DE\", \"GBP_UK\", \"GBP_DE\", \"Difference\", \"Category\"]\nwith pd.ExcelWriter(path, engine=\"openpyxl\") as xw:\n    m.sort_values([\"Category\", \"Reference\"])[cols].to_excel(xw, sheet_name=\"Line by line\", index=False)\n    summary.to_excel(xw, sheet_name=\"Summary\", startrow=4)\nwb = load_workbook(path)\nws = wb[\"Summary\"]\nws[\"A1\"], ws[\"A1\"].font = \"Intercompany reconciliation UK ↔ DE, 30 September 2026 (GBP)\", Font(bold=True, size=13)\nws[\"A2\"], ws[\"B2\"] = \"UK: due from DE\", round(uk_g[\"GBP\"].sum(), 2)\nws[\"A3\"], ws[\"B3\"] = \"DE: due to UK\", round(de_g[\"GBP\"].sum(), 2)\nws[\"A4\"], ws[\"B4\"] = \"Gap\", \"=B2-B3\"\nfor c in (\"B2\", \"B3\", \"B4\"):\n    ws[c].number_format = \"#,##0.00\"\nwb.save(path)\nprint(wb.sheetnames)\n",[32,1411,1412,1425,1437,1441,1451,1494,1522,1546,1577,1600,1610,1624,1667,1701,1735,1759,1785,1795,1801],{"__ignoreMap":30},[35,1413,1414,1417,1420,1422],{"class":37,"line":38},[35,1415,1416],{"class":80},"from",[35,1418,1419],{"class":84}," openpyxl ",[35,1421,81],{"class":80},[35,1423,1424],{"class":84}," load_workbook\n",[35,1426,1427,1429,1432,1434],{"class":37,"line":94},[35,1428,1416],{"class":80},[35,1430,1431],{"class":84}," openpyxl.styles ",[35,1433,81],{"class":80},[35,1435,1436],{"class":84}," Font\n",[35,1438,1439],{"class":37,"line":101},[35,1440,98],{"emptyLinePlaceholder":97},[35,1442,1443,1446,1448],{"class":37,"line":142},[35,1444,1445],{"class":84},"path ",[35,1447,107],{"class":80},[35,1449,1450],{"class":45}," \"ic_recon_UK_DE_2026-09.xlsx\"\n",[35,1452,1453,1456,1458,1461,1463,1465,1468,1470,1473,1475,1477,1479,1482,1484,1486,1488,1491],{"class":37,"line":174},[35,1454,1455],{"class":84},"cols ",[35,1457,107],{"class":80},[35,1459,1460],{"class":84}," [",[35,1462,423],{"class":45},[35,1464,116],{"class":84},[35,1466,1467],{"class":45},"\"Date_UK\"",[35,1469,116],{"class":84},[35,1471,1472],{"class":45},"\"Date_DE\"",[35,1474,116],{"class":84},[35,1476,709],{"class":45},[35,1478,116],{"class":84},[35,1480,1481],{"class":45},"\"Description_DE\"",[35,1483,116],{"class":84},[35,1485,637],{"class":45},[35,1487,116],{"class":84},[35,1489,1490],{"class":45},"\"Amount_UK\"",[35,1492,1493],{"class":84},",\n",[35,1495,1496,1499,1501,1504,1506,1508,1510,1512,1514,1516,1518,1520],{"class":37,"line":202},[35,1497,1498],{"class":45},"        \"Currency_DE\"",[35,1500,116],{"class":84},[35,1502,1503],{"class":45},"\"Amount_DE\"",[35,1505,116],{"class":84},[35,1507,470],{"class":45},[35,1509,116],{"class":84},[35,1511,475],{"class":45},[35,1513,116],{"class":84},[35,1515,505],{"class":45},[35,1517,116],{"class":84},[35,1519,678],{"class":45},[35,1521,199],{"class":84},[35,1523,1524,1527,1530,1533,1535,1538,1541,1543],{"class":37,"line":207},[35,1525,1526],{"class":80},"with",[35,1528,1529],{"class":84}," pd.ExcelWriter(path, ",[35,1531,1532],{"class":119},"engine",[35,1534,107],{"class":80},[35,1536,1537],{"class":45},"\"openpyxl\"",[35,1539,1540],{"class":84},") ",[35,1542,88],{"class":80},[35,1544,1545],{"class":84}," xw:\n",[35,1547,1548,1551,1553,1555,1557,1560,1562,1564,1567,1569,1571,1573,1575],{"class":37,"line":220},[35,1549,1550],{"class":84},"    m.sort_values([",[35,1552,678],{"class":45},[35,1554,116],{"class":84},[35,1556,423],{"class":45},[35,1558,1559],{"class":84},"])[cols].to_excel(xw, ",[35,1561,120],{"class":119},[35,1563,107],{"class":80},[35,1565,1566],{"class":45},"\"Line by line\"",[35,1568,116],{"class":84},[35,1570,731],{"class":119},[35,1572,107],{"class":80},[35,1574,326],{"class":272},[35,1576,139],{"class":84},[35,1578,1579,1582,1584,1586,1589,1591,1594,1596,1598],{"class":37,"line":231},[35,1580,1581],{"class":84},"    summary.to_excel(xw, ",[35,1583,120],{"class":119},[35,1585,107],{"class":80},[35,1587,1588],{"class":45},"\"Summary\"",[35,1590,116],{"class":84},[35,1592,1593],{"class":119},"startrow",[35,1595,107],{"class":80},[35,1597,772],{"class":272},[35,1599,139],{"class":84},[35,1601,1602,1605,1607],{"class":37,"line":296},[35,1603,1604],{"class":84},"wb ",[35,1606,107],{"class":80},[35,1608,1609],{"class":84}," load_workbook(path)\n",[35,1611,1612,1615,1617,1620,1622],{"class":37,"line":305},[35,1613,1614],{"class":84},"ws ",[35,1616,107],{"class":80},[35,1618,1619],{"class":84}," wb[",[35,1621,1588],{"class":45},[35,1623,199],{"class":84},[35,1625,1626,1629,1632,1635,1637,1640,1642,1645,1648,1651,1653,1655,1657,1660,1662,1665],{"class":37,"line":310},[35,1627,1628],{"class":84},"ws[",[35,1630,1631],{"class":45},"\"A1\"",[35,1633,1634],{"class":84},"], ws[",[35,1636,1631],{"class":45},[35,1638,1639],{"class":84},"].font ",[35,1641,107],{"class":80},[35,1643,1644],{"class":45}," \"Intercompany reconciliation UK ↔ DE, 30 September 2026 (GBP)\"",[35,1646,1647],{"class":84},", Font(",[35,1649,1650],{"class":119},"bold",[35,1652,107],{"class":80},[35,1654,336],{"class":272},[35,1656,116],{"class":84},[35,1658,1659],{"class":119},"size",[35,1661,107],{"class":80},[35,1663,1664],{"class":272},"13",[35,1666,139],{"class":84},[35,1668,1669,1671,1674,1676,1679,1681,1683,1686,1688,1691,1693,1695,1697,1699],{"class":37,"line":341},[35,1670,1628],{"class":84},[35,1672,1673],{"class":45},"\"A2\"",[35,1675,1634],{"class":84},[35,1677,1678],{"class":45},"\"B2\"",[35,1680,240],{"class":84},[35,1682,107],{"class":80},[35,1684,1685],{"class":45}," \"UK: due from DE\"",[35,1687,116],{"class":84},[35,1689,1690],{"class":272},"round",[35,1692,1036],{"class":84},[35,1694,237],{"class":45},[35,1696,1051],{"class":84},[35,1698,291],{"class":272},[35,1700,139],{"class":84},[35,1702,1703,1705,1708,1710,1713,1715,1717,1720,1722,1724,1727,1729,1731,1733],{"class":37,"line":660},[35,1704,1628],{"class":84},[35,1706,1707],{"class":45},"\"A3\"",[35,1709,1634],{"class":84},[35,1711,1712],{"class":45},"\"B3\"",[35,1714,240],{"class":84},[35,1716,107],{"class":80},[35,1718,1719],{"class":45}," \"DE: due to UK\"",[35,1721,116],{"class":84},[35,1723,1690],{"class":272},[35,1725,1726],{"class":84},"(de_g[",[35,1728,237],{"class":45},[35,1730,1051],{"class":84},[35,1732,291],{"class":272},[35,1734,139],{"class":84},[35,1736,1737,1739,1742,1744,1747,1749,1751,1754,1756],{"class":37,"line":668},[35,1738,1628],{"class":84},[35,1740,1741],{"class":45},"\"A4\"",[35,1743,1634],{"class":84},[35,1745,1746],{"class":45},"\"B4\"",[35,1748,240],{"class":84},[35,1750,107],{"class":80},[35,1752,1753],{"class":45}," \"Gap\"",[35,1755,116],{"class":84},[35,1757,1758],{"class":45},"\"=B2-B3\"\n",[35,1760,1761,1764,1767,1770,1772,1774,1776,1778,1780,1782],{"class":37,"line":673},[35,1762,1763],{"class":80},"for",[35,1765,1766],{"class":84}," c ",[35,1768,1769],{"class":80},"in",[35,1771,266],{"class":84},[35,1773,1678],{"class":45},[35,1775,116],{"class":84},[35,1777,1712],{"class":45},[35,1779,116],{"class":84},[35,1781,1746],{"class":45},[35,1783,1784],{"class":84},"):\n",[35,1786,1787,1790,1792],{"class":37,"line":697},[35,1788,1789],{"class":84},"    ws[c].number_format ",[35,1791,107],{"class":80},[35,1793,1794],{"class":45}," \"#,##0.00\"\n",[35,1796,1798],{"class":37,"line":1797},18,[35,1799,1800],{"class":84},"wb.save(path)\n",[35,1802,1804,1806],{"class":37,"line":1803},19,[35,1805,344],{"class":272},[35,1807,1808],{"class":84},"(wb.sheetnames)\n",[10,1810,1811,1812,1815,1816,1819],{},"The ",[57,1813,1814],{},"Summary"," sheet states both balances, the gap and its explanation by category; the ",[57,1817,1818],{},"Line by line"," sheet shows each reference with both sides' dates, descriptions, original currencies and amounts and the sterling comparison, sorted by category so each team can work through its own list — the German team confirms receipt of the in-transit goods, the UK team raises or disputes the freight recharge. With more than two companies, run the same comparison for every pair, and add a matrix of net balances between all entities; the group as a whole eliminates only when every pair does.",[20,1821,1823],{"id":1822},"making-the-matching-reliable","Making the matching reliable",[10,1825,1826],{},"The whole reconciliation depends on both companies recording the same reference for the same transaction. Where that discipline exists, the merge on reference does nearly all the work. Where it does not, references must be agreed first: the selling company's invoice number is the natural key, and the buying company should record it in its own entry. Without a shared reference, matching falls back on amount and date within a window — workable, but ambiguous when several transactions have similar amounts. It also helps to agree a cut-off: if both companies stop posting intercompany entries a day before month end, in-transit items mostly disappear. And book intercompany invoices in one agreed currency, usually the seller's, so the buying company converts once and both sides use the same amount, which removes most exchange differences before they arise.",[20,1828,1830],{"id":1829},"common-pitfalls","Common pitfalls",[1832,1833,1834,1842,1848,1854,1860],"ul",{},[1835,1836,1837,1841],"li",{},[1838,1839,1840],"strong",{},"Comparing without flipping signs."," A receivable is positive, the matching payable negative.",[1835,1843,1844,1847],{},[1838,1845,1846],{},"Mixing currencies."," Convert both sides to the group currency at one rate.",[1835,1849,1850,1853],{},[1838,1851,1852],{},"An inner merge."," Use an outer merge so one-sided entries appear.",[1835,1855,1856,1859],{},[1838,1857,1858],{},"Explaining the total, not the lines."," Classify every line and show they sum to the gap.",[1835,1861,1862,1865],{},[1838,1863,1864],{},"Treating FX as an error."," Exchange differences follow group policy, not corrections.",[20,1867,1869],{"id":1868},"conclusion","Conclusion",[10,1871,1872],{},"Reconcile intercompany balances by flipping the payable side's signs, converting both sides to the group currency, and outer-merging the entries on a shared reference. Classify each line as matched, exchange difference, amount error, or one-sided — in transit or not booked — check that the categories add up to the gap between balances, and isolate what remains after timing and exchange. Write a summary and a line-by-line sheet so both finance teams can clear their items before consolidation.",[20,1874,1876],{"id":1875},"frequently-asked-questions","Frequently asked questions",[10,1878,1879,1882],{},[1838,1880,1881],{},"How do I reconcile intercompany balances in Python?","\nLoad both companies' intercompany ledger lines, flip the signs on the payable side, convert to one currency, outer-merge on the transaction reference and classify each line by how the two sides differ.",[10,1884,1885,1888],{},[1838,1886,1887],{},"What are typical causes of intercompany differences?","\nItems in transit at month end, exchange differences when the two sides record different currencies, entries booked by only one side, and amount or account errors.",[10,1890,1891,1894],{},[1838,1892,1893],{},"How do I check that intercompany balances eliminate?","\nAfter converting to the group currency, the receivable on one side and the payable on the other must be equal; explain any gap line by line.",[10,1896,1897,1900],{},[1838,1898,1899],{},"What if the two companies use different references?","\nAgree a shared key, usually the seller's invoice number, or fall back to matching by amount and date within a window, which is less reliable.",[20,1902,1904],{"id":1903},"related","Related",[1832,1906,1907,1913,1920,1927],{},[1835,1908,1909,1910,1912],{},"Up one level: ",[14,1911,17],{"href":16}," — finance reports from Python.",[1835,1914,1915,1919],{},[14,1916,1918],{"href":1917},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fconvert-multi-currency-transactions-with-an-fx-rate-table\u002F","Convert Multi-Currency Transactions with an FX Rate Table"," — the currency step.",[1835,1921,1922,1926],{},[14,1923,1925],{"href":1924},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-foreign-exchange-revaluation-report\u002F","Build a Foreign Exchange Revaluation Report"," — exchange differences at month end.",[1835,1928,1929,1933],{},[14,1930,1932],{"href":1931},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Ffind-rows-in-one-excel-file-missing-from-another\u002F","Find Rows in One Excel File Missing from Another"," — one-sided matching.",[1935,1936,1937],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":30,"searchDepth":94,"depth":94,"links":1939},[1940,1941,1942,1943,1944,1945,1946,1947,1948,1949],{"id":22,"depth":94,"text":23},{"id":67,"depth":94,"text":68},{"id":399,"depth":94,"text":400},{"id":950,"depth":94,"text":951},{"id":1405,"depth":94,"text":1406},{"id":1822,"depth":94,"text":1823},{"id":1829,"depth":94,"text":1830},{"id":1868,"depth":94,"text":1869},{"id":1875,"depth":94,"text":1876},{"id":1903,"depth":94,"text":1904},"2026-10-02","Reconcile what one group company says another owes it against what the other company says it owes, with pandas: match intercompany transactions from both ledgers by reference, convert to a common currency, separate timing differences, exchange differences and genuine mismatches, check that balances eliminate on consolidation, and write a reconciliation both finance teams can work from.","md",[1954,1956,1958,1960],{"q":1881,"a":1955},"Load both companies' intercompany ledger lines, flip the signs on the payable side, convert to one currency, outer-merge on the transaction reference and classify each line by how the two sides differ.",{"q":1887,"a":1957},"Items in transit at month end, exchange differences when the two sides record different currencies, entries booked by only one side, and amount or account errors.",{"q":1893,"a":1959},"After converting to the group currency, the receivable on one side and the payable on the other must be equal; explain any gap line by line.",{"q":1899,"a":1961},"Agree a shared key, usually the seller's invoice number, or fall back to matching by amount and date within a window, which is less reliable.","intercompany reconciliation python",null,{"breadcrumb":1965},[1966,1969,1972],{"name":1967,"item":1968},"Home","\u002F",{"name":1970,"item":1971},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":1973,"item":16},"Building Finance and Operations Reports in Excel with Python","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation",{"title":1976,"description":1977},"Build an Intercompany Reconciliation with Python and Excel","Intercompany reconciliation in pandas: matching receivable and payable entries by reference with an outer merge, sign conventions, currency conversion, in-transit items, FX differences, unmatched items, the elimination check and an Excel workbook.","build-an-intercompany-reconciliation","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-intercompany-reconciliation\u002Findex",[1981,1982],"report-layouts","joins-and-lookups","how-to","E_O2ZXjxaW6HG1qKzeHTxhJrECQhyWXHu8veVoPZyZY",[1986,1990],{"title":1987,"path":1988,"stem":1989,"children":-1},"Build an Energy Consumption Report from Meter Readings","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-energy-consumption-report-from-meter-readings","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-energy-consumption-report-from-meter-readings\u002Findex",{"title":1991,"path":1992,"stem":1993,"children":-1},"Build an Inventory Reorder Report with Python and Excel","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-inventory-reorder-report","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-an-inventory-reorder-report\u002Findex",[1995,1997],{"path":1996,"title":1973},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports",{"path":1998,"title":1970},"\u002Fautomating-reporting-workflows",[],[2001,2005,2008,2011,2014,2017],{"path":2002,"title":2003,"kind":2004},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards","Building Multi-Sheet Excel Dashboards","guide",{"path":2006,"title":2007,"kind":1983},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-data-dictionary-sheet-to-an-excel-report","Add a Data Dictionary Sheet to an Excel Report",{"path":2009,"title":2010,"kind":1983},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-kpi-summary-block-to-an-excel-dashboard","Add a KPI Summary Block to an Excel Dashboard",{"path":2012,"title":2013,"kind":1983},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-table-of-contents-sheet-with-hyperlinks-in-excel","Add a Table of Contents Sheet with Hyperlinks in Excel",{"path":2015,"title":2016,"kind":1983},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-slicer-style-filters-to-an-excel-dashboard","Add a Dropdown Filter That Drives an Excel Dashboard",{"path":2018,"title":2019,"kind":1983},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-summary-sheet-to-excel-report-python","Add a Summary Sheet to an Excel Report with Python",1790972127726]