A AION Academy
← Back to the costing guide

Learn / Costing

Period close in 2 days — the costing close mechanics

Most F&B factories take 2-3 weeks to close their books because every cost adjustment is a manual journal entry. AION's 5-step costing close with crash recovery makes 2 days achievable for an SMB factory. Here's what each step does and why each one matters.

9 min read · Published 2026-05-15

Period close in most F&B factories takes 10–20 working days. The financial books that should reflect February’s reality come out in late March. By that time, the operational decisions that should drive are already out of date.

The close timing isn’t about size. It’s about how much of the work is manual. Every manual journal entry, every paper reconciliation, every “the accountant has to wait for the warehouse to send a spreadsheet” step adds days. Eliminate them and 2-day close becomes achievable for an SMB F&B factory.

This article walks through how AION’s 5-step costing close mechanically works.

Why the costing close is the hard part

A full month-end close has many sub-closes: AR, AP, payroll, bank reconciliation, intercompany eliminations, fixed assets, tax. Most of these are reasonably mechanical given a proper subledger system.

The costing close is the one that traditionally takes the most time because:

  1. Volume. A factory issuing material 100 times a day produces 2,000+ cost-affecting transactions a month.
  2. Dependency. You can’t close cost until purchases are valued (you need receipt landing). You can’t close FG cost until WIP is valued (you need production complete). One step depends on the previous.
  3. Accuracy needs. Cost feeds COGS, which determines reported profit. Get cost wrong and the auditor will eventually catch it.

AION’s costing close handles all three with 5 sequenced steps.

The 5 steps

Step 1: Import previous period averages

The first action of the close is rolling the prior period’s final unit costs forward as the opening basis for this period. Every item that was costed at the close of last month gets its closing average copied to this month’s opening balance record.

Source: close-costing-period.use-case.ts Step 3 (IMPORT_PREVIOUS in the close steps enum). It’s actually the third numbered step in the code but functionally the first thing that matters — it’s the foundation everything else builds on.

Why it matters: without this step, average cost calculations for the new period would start from zero, which would corrupt the FIFO carry-forward of inventory value.

Step 2: Update purchased item costs

Every receipt during the period gets its landed cost composed (PO price + freight + customs + handling allocations) and the per-item average recalculated based on opening + receipts.

This step is where multi-currency comes in. A USD receipt of mango concentrate landed during the period had its FX captured at receipt; the SAR-equivalent cost gets averaged into the SAR-denominated item cost. The historical FX rate is preserved so you can audit later why an average moved.

Source: close-costing-period.use-case.ts Step 2 (UPDATE_PURCHASED_ITEM_COSTS).

Why it matters: this is the step that surfaces the impact of supplier price changes during the period. The new average cost is what FG rollups will use for the next month.

Step 3: Cost job orders

Production runs that completed during the period get their full cost computed: material at the period average × actual issued quantity, labour at the standard rate × actual hours, overhead at the absorption rate × hours.

This step is on the costing audit’s roadmap for “primary feature” treatment — today the average-cost flow handles job costing as a side effect of average recalculation rather than a dedicated job-cost step. For an SMB F&B factory using average cost, this is operationally fine; for a factory wanting full standard cost variance posting per job, it’s a roadmap item.

Source: close-costing-period.use-case.ts Step 5 (COST_JOB_ORDERS — placeholder; returns {count: 0, errors: 0} for the average-cost path).

Step 4: Update produced item costs

Finished goods that were produced during the period get their unit cost finalised. The cost rolled up from the period’s actual production runs becomes the FG’s average cost.

This is where the variance reporting really comes alive. The FG was produced at standard cost; the actual cost differs by the material usage variance + labour efficiency variance + overhead variance for the jobs that ran. The aggregate of those variances is what makes the actual cost different from the standard.

Source: close-costing-period.use-case.ts Step 6 (UPDATE_PRODUCED_ITEM_COSTS).

Step 5: Finalise

Three things happen in finalisation:

  1. Sweep uncosted issues. Any material issue that was posted during the period at a provisional cost (typically the prior period’s average) gets retroactively costed at the final period average. The variance posts to a cost adjustment account.
  2. Reconcile the period. Total receipts + opening - issues - closing should net to zero for each item. Any imbalance posts to a reconciliation account for investigation.
  3. Mark the period as closed. The period status changes from OPEN to CLOSED. New transactions for that period are rejected (or routed to a journal entry adjustment workflow if you have closing entries).

Source: close-costing-period.use-case.ts Step 8 (FINALIZE).

The crash recovery model

Each of these steps writes its outcome to inv_costing_period_close_steps, which tracks:

  • Step name
  • Started at / completed at timestamps
  • Records processed
  • Errors

If the API process dies during step 4 — power outage, container restart, network hiccup — the close knows where it left off. Restart the close, and it picks up at step 4 instead of starting from step 1.

This matters because:

  • A real close run for a factory at Oasis Fresh scale touches 5,000–20,000 records
  • Starting over from scratch wastes 20–60 minutes per attempt
  • During month-end, you might run close 2–3 times as you investigate variances, fix issues, and re-run

The crash recovery turns hours of frustration into minutes of resume.

What the SLA engine does in parallel

While the costing close is running, the SLA engine (costing-close-processor.ts) is also active. It scans for cost transactions that don’t yet have a matching GL journal — typically because they were posted at the very end of the period and the SLA event hasn’t fired yet — and generates the journals for them.

This is the difference between “close finishes and your books are clean” vs “close finishes and you spend three days reconciling subledger to GL.” The SLA processor closes the gap automatically.

Worked example — closing March 2026 at Oasis Fresh

Walking through the close as cfo.saudi:

Day 1, 9am: Trigger the costing close for March 2026.

  • Step 1 imports February closing averages. ~2 minutes for ~200 items.
  • Step 2 lands all March receipts and recalculates averages. ~10 minutes for ~150 receipts.
  • Step 3 (placeholder for now) marks job orders as costed at average. ~1 minute.
  • Step 4 updates FG and WIP costs. ~5 minutes.
  • Step 5 sweeps ~300 uncosted issues to final average and reconciles. ~8 minutes.
  • Total ~25 minutes from trigger to close mark.

Day 1, 10am: Open variance reports. Review material usage variance (10–15 minutes), labour efficiency variance (10 minutes), overhead variance (5 minutes). Investigate outliers, post adjustments if needed.

Day 1, 2pm: Trial balance generated. Review. Cross-check inventory subledger to GL inventory account.

Day 2: Tax reports (VAT remittance for KSA, WHT for Egypt analogue), management reports, dividend / distribution calculations.

Day 2, end of day: Books closed. Reports distributed.

Two days. Not three weeks.

Common mistakes

Triggering close too early. If you trigger before all March transactions are posted, the close will mark them as April when they’re posted late. Wait for end of period plus a 24-hour grace window.

Not investigating variances during close. The variance accounts give you information that’s actionable only in the close month. Six months later, no one remembers what happened. Investigate within the first 48 hours.

Re-running close after closing the period. Some teams re-run close repeatedly to “see if anything changed.” Each re-run resets the period status, requires reversing the close mark, and accumulates audit-trail noise. Run once, investigate, then close definitively.

The takeaway

The 2-day close isn’t aspirational. It’s mechanical once the underlying systems are right:

  • SLA engine generating GL journals from operational transactions in real time
  • Costing close with crash recovery
  • Standard reports that the CFO can read without spelunking

If your factory still takes 3 weeks to close, none of those three are usually in place. Each one alone is a 2x improvement; together they make weekly cycles possible.

The reports your CFO should actually be looking at every week (not just at close) are covered in 7 costing reports every F&B CFO should run weekly. The WIP picture that the close has to resolve is covered in WIP valuation — the hidden number on the F&B balance sheet.

See this in the Oasis Fresh demo

Log into the Oasis Fresh (Saudi) BG as cfo.saudi

Common questions

What are the 5 steps of AION's costing close?

1. Import previous period averages (opening balances roll forward). 2. Update purchased item costs (receipt landing + average recalc). 3. Cost job orders (marked as roadmap for primary feature use). 4. Update produced item costs (FG and WIP cost refresh). 5. Finalise (sweep uncosted issues, mark period closed). Source: close-costing-period.use-case.ts.

What happens if the close fails midway?

The close is resumable. Each step is a unit of work tracked in inv_costing_period_close_steps. If the API restarts during step 4, the next close run picks up at step 4 — no need to start over. This matters because real close runs touch millions of rows and a restart-from-zero is expensive.

Why does the SLA engine matter for fast close?

The SLA (Subledger Accounting) engine posts GL journals from operational transactions in real time — every receipt, issue, completion, scrap, transfer. By the time you start the costing close, the GL is already mostly accurate. The close just trues up cost averages and applies them to issues that hadn't been costed yet. Without SLA, every transaction is a manual journal and close time grows linearly with transaction count.