From raw export to numbers you can defend

Binzagr's proof of value, told with Binzagr's own data: the files as they arrived, how we cleaned them without inventing anything, what we had to simulate, and the anomalies we found on the way.

4,604,674Jeddah warehouse scans
325,544Riyadh invoice lines
18,809customers in the master
23,497product rows

As received

Eight monthly warehouse exports, Feb to Sep 2026, one block each. Every file also carried the whole first day of the next month: 65,141 rows sent twice, shown in red.

Cleaned

Duplicates removed only where proven at raw-text level; nothing estimated. Every surviving row keeps its file and line number: 4,539,533 rows.

Simulated

Around the scans sits paid time the scans cannot see: 58.9% of paid hours on the payroll head count. That layer is modelled from law, research and stated assumptions, and labelled Simulated.

Scroll
Chapter 1

What Binzagr sent

Twenty-two files, received in October 2026: eight months of the Jeddah warehouse log, Riyadh van sales from 1 March to 20 October with the customer, product and salesman masters, and four mapping files that explain Binzagr's WMS codes. The originals were never edited; every step below works on copies.

4.60Mwarehouse scans, 1 Feb to 30 Sep 2026, in 8 monthly CSV files
SAR 40.41Mvan-sales revenue in 325,544 invoice lines, 1 Mar to 20 Oct 2026
387badges scanning across 9 warehouse ids in Jeddah
4,961outlets that bought in Riyadh, from a master of 18,809
The inventory

Every dataset, as it arrived

Rows as received on a log scale, so a 28-row lookup and a 4.6-million-row log fit on one line. The blue tick marks the row count after cleaning.

Show data
Specimens

What the raw files actually look like

Real lines, copied character for character from the files Binzagr sent. Only the badge logins are masked. Highlights mark what had to be dealt with.

Chapter 2

How we cleaned it

Cleaning here means fixing what the export broke and flagging what looks wrong, without estimating a single value. Anything inferred or modelled lives in chapter 3, under its own label.

65,141rows removed, every one proven to be a second copy
155products rebuilt from 7 damaged spreadsheet rows
SAR 0.00difference between raw and cleaned van-sales revenue
47 of 49smoke tests pass, re-derived from the raw files; 2 explained warnings
Six rules

The rules every change had to follow

No estimation

Nothing is filled, smoothed, imputed or inferred in the cleaned layer.

Remove only what is proven redundant

The only rows removed anywhere are second copies proven at raw-text level.

Null only provable placeholders

1900 dates and quantities that are really pallet ids become empty, always with a flag.

Flag, don't fix, the suspicious

Badge sharing, identical rows, negative balances and zero-value lines are marked, not changed.

Lineage on every row

Each cleaned row points back to its source file and line, or its spreadsheet row.

Keep only what is needed

Contact, bank and tax-id columns are dropped; WMS user names are never stored.

The pipeline

Seven steps from export to model-ready tables

Each step runs in order and is re-checked against the raw files by an independent test, so a mistake in one step cannot hide behind the next.

Techniques

How each problem was solved, and proven

Proof

49 smoke tests, written against the raw files

The tests do not reuse pipeline code. They read raw CSV text, raw spreadsheet cells and Binzagr's mapping files, and re-derive each result independently. Select a tile to see what it checks.

47pass
2warnings, both explained
0fail
Select a test.
How it looks now

One warehouse scan, before and after

The same record as Binzagr exported it and as it sits in the cleaned tables: typed, flagged where needed, joined to Binzagr's own mappings, tied to a person and a work session, and traceable back to its line.

Riyadh in 3D

Where the van-sales customers are, and how much they buy

Chapter 3

What we had to simulate

Some numbers the proof of value needs are in no file Binzagr has sent yet: what people are paid, when they are on shift, what each client is charged. We filled each gap with a stated model or a published figure, never silently, and every table says which kind of number it holds.

24data gaps, each with a stand-in and an owner at Binzagr
41parameters, each with a low, base and high value
40cited sources: law, statistics, surveys and Binzagr statements
22 of 24simulation checks pass; 2 information warnings
Evidence labels

Five labels, on every table and every figure

The gaps

24 things only Binzagr can give us, and what stands in for each today

Priority 1 items block the Jeddah P&L comparison. Each arrival replaces a simulated table one for one.

Labour cost

What one warehouse operative costs a month

No pay data has arrived yet, so the monthly cost of an expatriate operative is built from Saudi labour law, government fees, published wages and job postings. Each component has a low, base and high value; the Monte Carlo further down draws from all of them.

Sources include GASTAT wage survey, GOSI rates, expat levy and iqama fees, Labour Law articles 84, 98, 101, 107 and 109, and Jeddah and Riyadh job postings.

One real shift

How a shift turns into paid, observed and earned hours

Standard times

How long a task should take, from Binzagr's own shifts

For each activity and line size (cases per line), the standard is the median of the badge-month average cycle times, from badge-months with at least 30 such scans. Line size matters: a one-case pick takes about two and a half minutes, an 11 to 25 case pick almost five.

Seconds per line, idle cap 30 minutes. Lenient (P60) and tight (P40) variants feed the Monte Carlo.

Paid time

Three ways to count who is paid

Scans show who worked, not who was paid. Binzagr's user list shows who holds a login, not who turns up. So paid time is computed three ways, and the middle one is the base: payroll-confirmed people are paid every working day from their first to their last scan.

On that base, 58.9% of paid hours have no scan behind them. No saving is claimed on that time; attendance by payroll number is what can explain it.

Benchmark your own shifts

The saving comes from Binzagr's own best shifts, not an outside standard

For every full shift (30 scans or more over at least 4 hours), productivity is earned standard hours divided by observed hours. The target is what the top quarter of shifts in the same role already achieves; the gap is captured at 70%. Move the sliders to see how the answer changes.

Annual figures. The base case (top quarter, 70%) is the SAR 639,485 used in the value roll-up. Wage assumptions move it far less than these two choices do.

Monte Carlo

5,000 versions of the answer

Every uncertain input is drawn from a triangular low-base-high distribution, the standard variant, idle cap and paid-time basis are drawn as well, and the model runs again. Each dot below is one of the 5,000 real draws.

Badge sharing, in 3D

23,589 work sessions, scored by rules and an anomaly model

Each point is one person's work session, placed by its length, its scan rate and an IsolationForest anomaly score (300 trees). Rules then add what the model cannot know: sessions longer than the 12-hour legal limit, two badges of one person active at once, site switches within 2 minutes. Drag to turn it.

Receivables

Ageing rebuilt from one balance snapshot

Binzagr's customer master holds one outstanding balance per customer, as of 20 Oct 2026, with no invoice behind it. Assuming payments clear the oldest invoices first, each balance is laid over the customer's most recent van-sales invoices, and each invoice's due date comes from its payment term.

The animation replays that for one real customer (code masked). Across all 1,616 credit customers with a balance, SAR 336,231 cannot be matched to any invoice in the window.

Hijri calendar

Events checked against what the data shows

Ramadan, both Eids, Founding Day and National Day come from official announcements, then are checked against the warehouse log: it closes on 21 to 23 March, 26 to 28 May and 23 September, and runs about 13% above its normal weekday level during Ramadan.

Scenarios

Three cases, and one honest caution

Conservative, base and stretch combine the cost parameters, the paid-time basis, the standard, the target and the capture rate.

The simulated P&L earns 6.5% by construction. Its rate card is set to recover cost at a benchmark margin, so only the change in EBIT is a result. Labour as a share of revenue is not evidence either way until Binzagr's actual P&L arrives.
Chapter 4

The anomalies we raised

Every anomaly is sized, given a severity by what it puts at risk, and turned into one question for Binzagr. Some were fixed in cleaning, some are flagged and kept, and some only Binzagr can answer.

6high: they change money or head count
9medium: they limit a use case until confirmed
8information: data hygiene, already handled
SAR 1.59Ma year of below-median pricing: one lead to check
What turns Simulated into Actual

Six inputs from Binzagr replace the largest assumptions

Each one swaps a simulated table for an actual one, one for one, and upgrades every figure that depends on it.

Actual Jeddah P&L, Feb to Sep

Replaces the cost-recovery P&L that earns 6.5% by construction; makes labour share of revenue a real number.

Attendance by payroll number

Explains the 58.9% of paid hours with no scan, and settles badge sharing case by case.

Labour cost and head count by site and role

Replaces the researched wage build-up; every SAR figure in the warehouse model scales with it.

Rate card by client and activity

Replaces cost-recovery rates with real prices; shows which clients cover their case-picking labour.

Site register

Names, temperature zones and the 2100-01 to 2100-07 move, so sites can be benchmarked fairly.

Cost per case and per pallet by site

The quickest check of the whole labour model, in Binzagr's own unit.