[{"data":1,"prerenderedAt":355},["ShallowReactive",2],{"article-freight-forwarding-kpis-cargowise":3},{"id":4,"title":5,"author":6,"body":7,"category":337,"description":338,"extension":339,"featured":340,"image":341,"meta":342,"navigation":343,"path":344,"publishedAt":345,"readingTime":346,"seo":347,"stem":348,"tags":349,"updatedAt":353,"videoUrl":353,"__hash__":354},"articles\u002Farticles\u002Ffreight-forwarding-kpis-cargowise.md","CargoWise Reporting: Shipment Costs, Missing Charges and Useful KPIs","Don Dappa",{"type":8,"value":9,"toc":329},"minimark",[10,14,19,154,157,180,184,187,190,201,204,208,211,217,220,224,285,288,292,295,313,316],[11,12,13],"p",{},"Most CargoWise cost reports fail for a boring reason: they mix numbers that haven't settled yet with numbers that have. An operations lead pulls a shipment-cost view mid-month, sees a margin figure, and acts on it. Three weeks later the accrual is reversed, a credit note lands, and the margin was never real. Here's a report built to survive that.",[15,16,18],"h2",{"id":17},"example-report-illustrative-not-live-data","Example report (illustrative, not live data)",[20,21,22,50],"table",{},[23,24,25],"thead",{},[26,27,28,32,35,38,41,44,47],"tr",{},[29,30,31],"th",{},"Job No",[29,33,34],{},"Charge Code",[29,36,37],{},"Local Amount",[29,39,40],{},"Currency",[29,42,43],{},"Source",[29,45,46],{},"Posted?",[29,48,49],{},"Status",[51,52,53,77,97,116,135],"tbody",{},[26,54,55,59,62,65,68,71,74],{},[56,57,58],"td",{},"J-10234",[56,60,61],{},"OFR",[56,63,64],{},"1,850.00",[56,66,67],{},"USD",[56,69,70],{},"Job Costing",[56,72,73],{},"Yes",[56,75,76],{},"Posted AP",[26,78,79,81,84,87,89,91,94],{},[56,80,58],{},[56,82,83],{},"DOC",[56,85,86],{},"45.00",[56,88,67],{},[56,90,70],{},[56,92,93],{},"No",[56,95,96],{},"Accrued only",[26,98,99,101,104,107,109,111,113],{},[56,100,58],{},[56,102,103],{},"THC",[56,105,106],{},"—",[56,108,67],{},[56,110,70],{},[56,112,93],{},[56,114,115],{},"Missing value",[26,117,118,121,123,126,129,131,133],{},[56,119,120],{},"J-10891",[56,122,61],{},[56,124,125],{},"2,200.00",[56,127,128],{},"EUR",[56,130,70],{},[56,132,73],{},[56,134,76],{},[26,136,137,139,142,145,147,149,151],{},[56,138,120],{},[56,140,141],{},"FSC",[56,143,144],{},"310.00",[56,146,128],{},[56,148,70],{},[56,150,73],{},[56,152,153],{},"Posted AR",[11,155,156],{},"This is a fictional example, built to show structure, not a real client extract. Notice three things before any total gets calculated:",[158,159,160,168,174],"ol",{},[161,162,163,167],"li",{},[164,165,166],"strong",{},"Currency is kept per line, not converted on extraction."," Converting early hides which rate was used and when. Convert once, downstream, with a stated rate date.",[161,169,170,173],{},[164,171,172],{},"Posted status is a column, not an assumption."," A job costing line can exist long before the matching AP or AR invoice is posted. Reporting only posted lines understates cost; reporting only job costing lines can overstate it if an accrual is later reversed.",[161,175,176,179],{},[164,177,178],{},"A missing value is shown as missing, not zero."," A blank THC charge might mean the charge genuinely doesn't apply, or it might mean the line hasn't been keyed yet. Those are different facts and a report that silently treats both as zero will understate cost on exactly the jobs someone should be chasing.",[15,181,183],{"id":182},"job-costs-versus-posted-accounts-keep-them-in-separate-columns","Job costs versus posted accounts: keep them in separate columns",[11,185,186],{},"CargoWise carries two layers of financial truth on a job: the operational job costing (estimates, accruals, work in progress) and the posted accounting transactions (AP invoices from vendors, AR invoices to customers, credit notes). They converge eventually. Mid-shipment, they rarely match.",[11,188,189],{},"A reporting view that merges them into one \"cost\" number is making a silent choice about which layer wins. Don't make that choice invisibly. Carry both:",[191,192,197],"pre",{"className":193,"code":195,"language":196},[194],"language-text","job_no, charge_code, local_amount, currency,\nsource_layer (job_costing | posted_ap | posted_ar),\nis_posted (true | false),\nlast_updated\n","text",[198,199,195],"code",{"__ignoreMap":200},"",[11,202,203],{},"Anyone reading the report can then decide: do I want the operational view (what we expect this job to cost, useful for ops decisions today) or the accounting view (what has actually been invoiced, useful for finance close)? Both are legitimate. Confusing them is what produces margin numbers nobody trusts.",[15,205,207],{"id":206},"a-completeness-checkpoint-before-anything-else","A completeness checkpoint before anything else",[11,209,210],{},"Before you trust any total, check that the extraction actually got everything it should have. The simplest version: count jobs in the operational system for the period and count jobs that appear in your extracted report for the same period. If the extraction job skipped a page, hit a connector timeout, or filtered on the wrong date field, these two counts won't match and you'll never see it in the totals, because missing jobs don't show up as a wrong number. They show up as nothing.",[191,212,215],{"className":213,"code":214,"language":196},[194],"expected_job_count = count(jobs where ETA in reporting period)\nextracted_job_count = count(distinct job_no in report)\n\nif extracted_job_count \u003C expected_job_count:\n    flag \"incomplete extraction, do not report totals\"\n",[198,216,214],{"__ignoreMap":200},[11,218,219],{},"Run this check every time before the report goes anywhere near a margin dashboard. It costs almost nothing and it's the single most common way a CargoWise report quietly lies.",[15,221,223],{"id":222},"four-kpis-worth-keeping-and-what-breaks-them","Four KPIs worth keeping, and what breaks them",[20,225,226,239],{},[23,227,228],{},[26,229,230,233,236],{},[29,231,232],{},"KPI",[29,234,235],{},"What it needs",[29,237,238],{},"What breaks it",[51,240,241,252,263,274],{},[26,242,243,246,249],{},[56,244,245],{},"Cost variance (estimated vs actual)",[56,247,248],{},"Both job-costing estimate and the final posted AP amount, same charge code",[56,250,251],{},"Charge codes re-mapped mid-job; partial invoices not yet all posted",[26,253,254,257,260],{},[56,255,256],{},"Unbilled charges (cost posted, revenue not yet invoiced)",[56,258,259],{},"AP posted flag true, matching AR line posted flag false, past a reasonable grace window",[56,261,262],{},"Legitimate timing lag mistaken for leakage if the window is too short",[26,264,265,268,271],{},[56,266,267],{},"Days to invoice (job complete to AR posted)",[56,269,270],{},"A reliable \"job complete\" date and the AR posted date",[56,272,273],{},"Multi-leg or split jobs where \"complete\" isn't a single event",[26,275,276,279,282],{},[56,277,278],{},"Margin by trade lane or branch",[56,280,281],{},"Posted AR minus posted AP, grouped by lane\u002Fbranch, in one settled currency",[56,283,284],{},"Mixing posted and accrued lines; converting at inconsistent FX dates",[11,286,287],{},"Run cost variance and unbilled charges as your first two. They're the ones that catch real money: a job quietly costing more than estimated, or a cost that's been paid out but never passed on to the customer. Margin by lane is useful for trend-watching but needs a longer settlement window before you trust it, since posted accounts on freight jobs often lag the operational close by weeks.",[15,289,291],{"id":290},"before-you-act-on-any-of-these","Before you act on any of these",[11,293,294],{},"Check these on the extracted data, not on the dashboard, before presenting a number:",[296,297,298,301,304,307,310],"ul",{},[161,299,300],{},"Does the report state a currency and a conversion date, or is it silently mixing currencies?",[161,302,303],{},"Are posted and unposted lines labelled, or merged?",[161,305,306],{},"Did the completeness checkpoint pass for this run?",[161,308,309],{},"Is there a visible count of missing\u002Fnull charge lines, separate from zero-value lines?",[161,311,312],{},"Has a human who knows the job looked at any outlier before it's reported upward?",[11,314,315],{},"That last one doesn't go away. Automated extraction gets you a trustworthy base; it doesn't replace someone who knows why job J-10234 is missing its THC line.",[11,317,318,319,324,325,328],{},"For the mechanics of pulling this data out of CargoWise reliably, including pagination, truncation and date-field behaviour you need to verify against current vendor references, see ",[320,321,323],"a",{"href":322},"\u002Farticles\u002Fcargowise-data-extraction-preview\u002F","CargoWise data extraction",". When you're ready to build the extraction layer properly, the detailed walkthrough is at ",[320,326,327],{"href":327},"\u002Feadapter\u002Fdata-extraction\u002F",".",{"title":200,"searchDepth":330,"depth":330,"links":331},2,[332,333,334,335,336],{"id":17,"depth":330,"text":18},{"id":182,"depth":330,"text":183},{"id":206,"depth":330,"text":207},{"id":222,"depth":330,"text":223},{"id":290,"depth":330,"text":291},"insights","A worked example of a trustworthy CargoWise shipment-cost report: separating job costs from posted accounts, tracking missing values and picking KPIs that hold up.","md",false,"\u002Fimages\u002Farticles\u002Ffreight-forwarding-kpis-cargowise.jpg",{},true,"\u002Farticles\u002Ffreight-forwarding-kpis-cargowise","2026-10-01",7,{"title":5,"description":338},"articles\u002Ffreight-forwarding-kpis-cargowise",[350,351,352],"CargoWise Reporting","Freight Forwarding KPIs","Data Extraction",null,"6VcwNezfGU2pkAUvUp-pybghuxk5bq5m2AqhTeZU1pA",1790846895202]