The situation
An integrator recognises project revenue on percent complete, and its costs did not follow. Materials hit cost of goods sold when they shipped. Shipping and tariffs landed wherever they were posted, and labour sat on generic service items. Every month the accounting team wrote reclass journals by hand to move cost between cost of goods sold and deferred cost, so that each project's margin made sense. The work was slow, hard to review and different every month.
What we built
A set of automations, each of which takes one of those manual journals off the list.
- Custom GL Lines plug-in on invoices and credit memos. Items flagged as deferred post their revenue to the item's deferred revenue account instead of income, inside the transaction's own GL impact.
- Reclass on fulfilment. A User Event on the item fulfilment creates the reclass journal for shipping and tariff costs as the goods leave, linked to the project.
- Month-end deferral. A Map/Reduce looks at every active project and every direct-materials expense account on it. It compares the estimated cost on the sales order with the cost of goods sold already posted. It then moves the difference between cost of goods sold and deferred cost so the ratio matches the project's percent complete.
- Time reclassification. Time entries carry hours by activity category. A Map/Reduce splits any entry whose service item does not match its categories into one entry per target service item, so labour cost lands in the right place.
- Engineering and indirect materials. Two Suitelets post the engineering and indirect-materials journals for a chosen sales order, replacing two more spreadsheets.
What it does now
The month-end deferral runs as a job. It takes its inputs as of the end of the previous calendar month, so running it twice in the same month produces the same numbers, and it posts the journal on the first of the current month. It computes each expense account on its own, so one account's correction never hides another's.
Fulfilment reclasses and GL-level revenue deferral happen when transactions are saved, so the ledger is closer to right during the month as well as after close.
Under the hood
- The Custom GL Lines plug-in changes the GL impact of the transaction itself, instead of adding a correcting journal after it.
- Inputs are bounded by date, so a rerun of the deferral gives the same result and can be reviewed.
- The job filters sales order and return lines by their line creation date, and posting transactions by transaction date, so late edits do not shift earlier months.
- Time entries are split and never overwritten, which keeps the original hours traceable.
- Each automation replaces one named manual journal, so the team can retire them one at a time.