System Changes & Release Notes
Future updates will appear here in reverse-chronological order.
System Overview
NastyCookie ERP is an integrated enterprise resource planning system designed for cookie and food manufacturing. It covers the full business cycle — from purchasing raw materials through production to delivering finished goods to customers — with real-time inventory tracking, financial reconciliation, and team-wide audit trails.
Inventory, SKUs, picking, locations
Purchase orders, suppliers, GRN
Sales orders, dispatch, invoices
Scheduling, batches, QC
Reconciliation, invoices
Users, settings, notifications
Access via Tailscale: Remote users connect to http://100.86.94.99:8888 after joining the Tailscale network. The host machine must be running both the API server (port 3000) and UI server (port 8888).
Logging In
- 1Open the ERP URL in your browser (e.g.
http://100.86.94.99:8888on the office network). - 2Enter your email address and password. First-time users enter the temporary password provided by the administrator.
- 3If this is your first login, you will be prompted to set a new password before continuing.
- 4After login you land on the Dashboard which shows KPI summaries for all modules you have access to.
Forgot your password? Contact your system administrator. They can reset it and the new temporary password will be emailed to you automatically.
Logging Out
Click your name in the top-right header → Logout. Or navigate to Management → User Management and click the Logout button in the session bar. Your session is cleared immediately.
Roles & Permissions
Every user is assigned one or more roles. Each role grants a set of permissions that control exactly which pages and actions are available.
| Role | Typical Users | Key Access |
|---|---|---|
| super_admin | IT / Owner | Unrestricted access to everything — protected, cannot be edited or deleted |
| erp_admin | ERP Manager | Full system across all modules — protected |
| management_admin | Operations Head | User management, roles, settings, audit logs |
| warehouse_manager | Warehouse Manager | Full warehouse, receiving, dispatch oversight |
| warehouse_operator | Warehouse Team | Inventory, picking, stock movement |
| inbound_manager | Purchasing | POs, GRNs, supplier approvals, QC |
| receiving_clerk | Receiving Staff | Goods receipt operations, view POs |
| outbound_manager | Sales / Dispatch | Sales orders, dispatch, customer invoices |
| finance_manager | Finance Team | Finance overview, bank reconciliation, invoices |
| executive_viewer | Observers | Dashboard and overview pages only, read-only |
Administrators can create custom roles with any combination of permissions. Go to Management → User Management → Roles tab → New Role. Requires management.users.assign_roles.
Permission Naming Convention
Permissions follow the pattern module.resource.action. For example:
warehouse.inventory.read— view inventory levelsoutbound.sales_orders.approve— approve a sales ordermanagement.users.create— create new user accountsfinance.reconciliation.write— edit bank reconciliation
Finance Permission Catalogue
| Permission | What it grants |
|---|---|
finance.overview.read | View Finance Overview page and KPI summary |
finance.reconciliation.read | View bank reconciliation periods and transaction details |
finance.reconciliation.write | Create/edit periods, upload statements, reconcile categories, manage parked entries |
finance.reconciliation.admin | Lock (complete) periods, delete periods, export journal entries |
finance.invoices.read | View supplier and customer invoices in the Finance module |
User Management Permission Catalogue
| Permission | What it grants |
|---|---|
management.users.read | View the User Management page and user list |
management.users.create | Create new user accounts (shows Add User button) |
management.users.update_profile | Edit user name and department |
management.users.reset_password | Generate a new temporary password for a user |
management.users.lock_unlock | Lock or unlock user accounts |
management.users.assign_roles | Assign roles to users and create/edit roles in the Roles tab |
management.users.activate_deactivate | Change account status between Active and Inactive |
Warehouse Module
Manages all physical stock — what you have, where it is, and when to reorder. The warehouse is the source of truth for inventory across all other modules.
Inventory
Displays all SKUs with on-hand, allocated, and available quantities grouped by product. Drill down to see per-location breakdowns including batch and lot numbers.
| Column | Meaning |
|---|---|
| On Hand | Total physical stock in the warehouse |
| Allocated | Reserved for approved sales orders (not yet shipped) |
| Available | On Hand minus Allocated — what you can actually sell |
Row Colour Coding & Sort Priority
Inventory rows are automatically sorted and colour-coded by urgency. Higher-priority rows always appear above lower-priority ones.
| Priority | Condition | Row colour | Left border |
|---|---|---|---|
| 1 — Highest | Available stock is below the SKU's Minimum Reorder Point | Light red | Red |
| 2 | Halal cert expiry is within 90 days or already expired — sorted earliest-first within this group | Amber / Yellow | Amber |
| 3 — Normal | No alert conditions — standard inventory rows | White / light grey | None |
Halal badge: Alerting rows show a "Halal Exp: DD MMM YYYY" tag under the product name. Rows whose cert has already lapsed show "Halal EXPIRED" in the same amber badge. A SKU only enters this group if its Halal Cert Expiry field is populated in the SKU Master.
SKU Master
The product catalogue. Every item in the warehouse must have an SKU record. SKU codes are auto-generated by category prefix:
RM-xxxx— Raw MaterialsFG-xxxx— Finished GoodsPK-xxxx— PackagingWP-xxxx— Work In Progress
Each SKU stores minimum stock, reorder point, cost per unit, selling price, storage type (ambient/refrigerated/frozen), and halal certification expiry.
Picking Lists
Picking lists are auto-generated when a Sales Order is approved. They guide warehouse staff to pick the right quantities from the right locations.
Locations
Defines warehouse bins and racks. Each location belongs to a zone (A, B, C, FG, Cold) and has a capacity in kg. Stock is tracked per-location for precise inventory control.
Stock Count
Conduct a physical count of actual stock. After counting, the system shows variances between system quantity and physical count. A manager must approve variances before they are applied.
- 1Click New Stock Count and select the scope (full warehouse or specific zone).
- 2Warehouse staff physically counts items and enters quantities.
- 3System highlights discrepancies in red.
- 4Manager reviews and approves — system adjusts inventory accordingly.
Inbound Module
Manages everything coming INTO the company — purchase orders to suppliers, receiving goods, and quality checks.
Purchase Orders (PO)
Raise purchase orders to buy materials from suppliers. POs go through an approval workflow before being sent.
Creating a PO
- 1Go to Inbound → Purchase Orders → New PO.
- 2Select supplier and expected delivery date.
- 3Add line items (SKU, quantity, unit price).
- 4Save as Draft or Submit for approval.
- 5A manager approves and marks as Sent to supplier.
Multi-Currency POs
When creating a PO, select the supplier's billing currency from the Currency dropdown. The system will:
- Show the exchange rate (e.g. 1 SGD = MYR 3.14)
- Accept item prices in the selected currency
- Convert and store all amounts in MYR automatically
- Display an amber SGD badge on non-MYR rows in the PO list
- Show both currency amounts in the PO detail view
Note: The exchange rate is locked at the time of PO creation. To update rates, go to Settings → Tax & Finance → Currencies.
Goods Receiving (GRN)
When goods arrive, raise a Goods Receipt Note (GRN) against the approved PO. Received items are added to warehouse stock automatically.
- 1Go to Warehouse → Goods Receiving and find the corresponding PO.
- 2Enter received quantities (may differ from ordered).
- 3Enter batch numbers and expiry dates for traceable items.
- 4Post the GRN — stock levels update immediately.
QC Hold
Items that fail inspection at goods receiving are placed on QC Hold. They cannot be used in production or sold until released or rejected.
- Release — item passes QC, returned to available stock
- Reject — item fails QC, triggers supplier return process
Outbound Module
Manages everything going OUT to customers — quotations, sales orders, picking, dispatch, and invoicing.
Quotations
Send price quotes to customers before committing to a sale. Quotations can be converted directly into Sales Orders when accepted.
Sales Orders (SO)
Confirmed orders from customers. Approving an SO triggers automatic stock reservation (FIFO allocation) and picking list generation.
Secondary status badges in the SO list show both the order status AND the pick status (e.g. Picking In Progress).
Dispatch
The dispatch page uses a two-panel layout:
- Left panel — Staged Queue: SOs where picking is complete and goods are ready to ship. Tick one or more SOs to include in a dispatch run.
- Right panel — Dispatch Plans: Created dispatch plans showing driver, vehicle, and linked SOs. Click Mark All Delivered to complete a run.
- 1Select one or more staged orders on the left.
- 2Click Create Dispatch Plan, enter driver and vehicle details.
- 3When goods are delivered, click Mark All Delivered — all linked SOs advance to Delivered and invoices are created.
Customer Returns
Log returned goods from customers. Returns are reviewed and either restocked (good condition) or written off (damaged). Credit notes are generated automatically.
Production Module
The Production module is the manufacturing core of NastyCookie ERP. It orchestrates the full production lifecycle — from scheduling baking jobs and managing room and manpower capacity, through ingredient fulfilment and real-time batch tracking, to quality control, finished goods handover, and cost analysis. It integrates tightly with Warehouse (ingredient supply and finished goods receipt), Inbound (raw material availability), Outbound (finished goods for sale), and Finance (cost of goods sold).
Sub-modules: Production Overview · Room Templates · Job Templates · Manpower Templates · Production Users & Skills · Production Scheduler · Schedule Views · Ingredient Requests · Production Inventory · Production QC · Finished Goods · Production In/Out · Costing
How Production Interacts With Other Modules
| Module | Direction | What Flows |
|---|---|---|
| Inbound | → Production | Received raw materials are added to Warehouse stock via GRN. Production then requests them via Ingredient Requests. |
| Warehouse | ↔ Production | In: Ingredients pulled from Warehouse into Production Inventory via approved Ingredient Requests. Out: QC-passed Finished Goods pushed back to Warehouse via Production In/Out. |
| Outbound | Production → | Once Finished Goods are received by the Warehouse, they become available stock for Sales Orders and Dispatch. |
| Finance | Production → | Costing module produces per-batch cost (raw materials + labour) which informs COGS reporting and margin analysis. |
| Management | → Production | Recipes (BOMs) are maintained under Management → Recipes (Restricted). Only approved recipe versions can be used in Job Templates and the Scheduler. |
Production Overview
The Production Overview is the daily command centre. It shows live KPI cards and four real-time activity panels that surface items requiring immediate attention.
| KPI Card | What It Shows |
|---|---|
| In Progress | Number of jobs currently running on the production floor |
| Awaiting QC | Completed batches that have not yet been quality-checked |
| Completed Today | Batches that have passed QC and closed out today |
Activity Panels
- Active Jobs — running scheduler jobs with quick link to Scheduler.
- Awaiting QC — batches pending quality inspection with quick link to Production QC.
- Ingredient Requests — pending or partially fulfilled ingredient requests with quick link to that page.
- Finished Goods Pending — QC-passed batches not yet transferred to Warehouse with quick link to Finished Goods.
Room Templates
Rooms are the physical production spaces where work happens. Each Room Template defines a space that the Scheduler can book. Rooms must be configured before any jobs can be scheduled.
| Field | Description |
|---|---|
| Room Code | Unique identifier, e.g. MIX-01, BAKE-02 |
| Room Name | Descriptive label shown in the Scheduler timeline |
| Type | Mixing Shaping Baking Cooling Packing |
| Workspace | Physical area or bench description (informational) |
| Capacity | Maximum batch volume this room can handle simultaneously |
| Status | Active rooms appear in the Scheduler; Inactive rooms are hidden |
Room types map directly to production stages. A typical cookie run requires a Mixing room, then a Shaping room, then a Baking room, then a Cooling room, then a Packing room — modelled as separate processes in a Job Template, each booked against the relevant room type.
Manpower Templates
Manpower Templates define categories of labour used in production (e.g. Baker, Mixer Operator, Packer). They are not individual people — individual workers are registered separately in Production Users.
| Field | Description |
|---|---|
| Code | Short identifier, e.g. BAKER, PACKER, QC-OFFICER |
| Name | Role name displayed on schedule cards and costing reports |
| Description | Responsibilities and scope |
| Hourly Cost | Labour rate per hour — fed into the Costing module to calculate total job labour expense |
| Status | Active / Inactive |
Costing link: Hourly Cost × actual hours worked per manpower type (summed across all job processes) = total labour cost for a batch. Keep hourly costs current to ensure accurate batch costing.
Job Templates
A Job Template is a reusable production blueprint. It links an approved recipe to an ordered sequence of processes, each assigned to a room type and manpower type. The Scheduler uses Job Templates to pre-fill all job settings when a new run is inserted.
| Field | Description |
|---|---|
| Template Code | Unique identifier, e.g. JT-CHOC-001 |
| Name | Human-readable label, e.g. "Chocolate Chip Cookie — Standard Run" |
| Recipe | Links to an approved recipe from Management → Recipes. Dictates which ingredients are consumed and in what quantities per batch. |
| Batches | Default batch count (overridable at scheduling time) |
| Duration | Total expected run time in minutes (sum of all process durations) |
| Processes | Ordered list of sub-steps (e.g. Mix → Shape → Bake → Cool → Pack), each specifying room type, manpower type, and duration |
| Status | Active / Inactive |
Recipe must be approved before a Job Template can reference it. Unapproved recipe versions are locked for production use. Approve recipes under Management → Recipes (Restricted) — requires management.recipes.update.
Production Users & Skills
Register individual production workers and assign them skills. The Scheduler uses skills to validate that workers assigned to a process are qualified for it.
Production Users (left panel)
- Each worker has a name, employee ID, and one or more assigned skills.
- Filter workers by skill using the dropdown in the search bar to quickly identify qualified staff for a given process.
- Inactive workers are hidden from the Scheduler's manpower assignment panel.
Skills (right panel)
- Skills are defined here (e.g. "Chocolate Mixing", "Oven Operation", "Packaging Machine").
- Click a skill to toggle assignment for the selected worker. Skills can also be assigned by drag-and-drop onto a worker card.
- Skills are immediately reflected in the Scheduler without a page reload.
Best practice: Register all production staff and assign their skills before building Job Templates. This ensures the Scheduler can immediately suggest qualified workers when a job is inserted.
Production Scheduler
The Scheduler is the operational heart of the Production module. It presents a drag-and-drop weekly timeline where jobs are placed into time slots against rooms and manpower. Each week is saved as a named schedule and persists until overwritten.
Layout
| Element | Description |
|---|---|
| Job Queue (left panel) | Jobs inserted but not yet placed on the timeline. Collapsible. Click Insert Job to add a new job from a template. |
| Timeline (main panel) | Weekly grid. Rows = rooms; columns = time slots. Drag jobs from the queue onto the grid to schedule them. |
| Week Navigator | Shows the active week. Use chevrons to browse; New Week starts a fresh schedule for the coming week. |
| Zoom Controls | Switch between 15 min, 30 min, and 1 hr column increments to suit the density of the schedule. |
| Delivery Plan Reference | If a delivery plan exists for the current week it appears at the bottom as a read-only strip — use it to align production timing with dispatch deadlines. |
Scheduling a Job — Step by Step
- 1Click Insert Job in the Job Queue panel. Select a Job Template and set the number of batches for this run.
- 2The job card appears in the queue showing expected duration and ingredient summary drawn from the template's linked recipe.
- 3Drag the job card onto the timeline at the desired start time and room row.
- 4Click the placed job block to open its detail panel. Assign workers whose skills match each process requirement.
- 5Click Save Schedule. The week's schedule is persisted and immediately visible to all production staff.
Job Lifecycle
Time Settings
Click the Time Settings (clock) button to configure the factory's working-hours window. Default: 08:00–17:30. The timeline enforces this window and will visually flag jobs placed outside it.
Undo
The Undo button reverses the last drag action on the timeline. It is only active before saving — it cannot undo a saved schedule.
Stock is not auto-blocked: The Scheduler does not prevent scheduling if ingredients are insufficient. The planner must manually verify Production Inventory → Live Stock (or confirm a pending Ingredient Request) before placing a job.
Schedule Views
Schedule Views are read-only visualisations of the current week's saved schedule in three formats. Use these for shift briefings, management reporting, and sharing with staff who do not need edit access to the Scheduler.
| View | Layout | Best Used For |
|---|---|---|
| Room View | Timetable grid — rows = rooms, columns = time slots. Shows which jobs occupy which rooms at every moment. | Shift planning, room utilisation, identifying gaps |
| Gantt | Classic Gantt chart — jobs as horizontal duration bars on a time axis. | Timeline overview, management reporting, deadline tracking |
| User View | Schedule grouped by worker — shows each person's assignments and time blocks. | Individual staff briefings, overtime checks, manpower conflicts |
Schedule Views always reflect the last saved state of the scheduler. Unsaved changes in the Scheduler will not appear here.
Ingredient Requests
Ingredient Requests are the formal mechanism by which Production requisitions raw materials from the Warehouse. Stock does not move until the request is approved and fulfilled by the Warehouse team.
Key Rules
- Each request is linked to a scheduled job so ingredient consumption is traceable per batch.
- Partial fulfilment is supported — Warehouse can deliver part of the request now and mark the remainder pending.
- Raw materials on QC Hold in the Warehouse cannot be transferred to Production until QC releases them.
- The Production Overview's Ingredient Requests panel shows all pending requests in real time.
Cross-module: Ingredient Requests appear in both the Production module (raised here) and the Warehouse module (approved and fulfilled there). Both sides see live status updates.
Production Inventory
Production maintains its own inventory ledger — separate from the main Warehouse — covering raw materials, packaging, and finished goods physically held in the production facility. It has three tabs:
Live Stock Tab
| Column | Meaning |
|---|---|
| Expecting | Quantity from approved Ingredient Requests not yet physically received into the production space |
| Existing | Quantity physically on hand in the production facility right now |
| Available | Existing minus quantities reserved for currently scheduled jobs |
Filter by category (Raw Material / Finished Good / Packaging) or search by SKU / product name.
Inventory Count Tab
Conduct a physical count of production stock. Staff enters actual quantities; the system calculates variance against the system figure. A variance summary appears in the header before submission.
- 1Enter actual physical counts in the Actual Count column for each SKU line.
- 2System calculates variance (actual − system). Negative = missing stock; positive = surplus.
- 3Add notes for any lines with significant variance.
- 4Click Submit Count to commit adjustments. Production Inventory levels update immediately.
Count History Tab
Full audit trail of all past production inventory counts: Count #, Date, Items counted, Net Variance, Status, Type, and who submitted it.
The Reset Inventory button (admin-only, hidden by default) wipes all production inventory records. Use only during initial system setup or at the start of a new accounting period — this action is irreversible.
Production QC
After a batch finishes production it moves to QC before the output can enter Finished Goods. This gate prevents substandard product from reaching the Warehouse or customers.
QC Statuses
| Status | Meaning | Next Action |
|---|---|---|
| In Progress | Batch still running — QC not yet applicable | Wait for batch completion |
| Awaiting QC | Batch finished; pending quality inspection | QC officer opens the batch and records checks |
| QC Passed | All checks passed; approved for Finished Goods | Batch entry created in Finished Goods; costing calculated |
| QC Failed | Critical failure; batch rejected | Batch written off or scrapped; non-conformance note recorded |
| Rework Required | Minor issues; batch returned to production for correction | Rework job inserted in Scheduler; batch re-QC'd after completion |
QC Table Columns
Batch #, Recipe, Planned Qty, Actual Qty, Batch Status, QC Status, Actions. The Planned vs Actual Qty gap is the primary quality signal — a large discrepancy indicates waste, a recipe deviation, or a weighing error that should be investigated before passing.
Cross-module: QC Passed batches automatically create a Finished Goods record. They do not immediately appear in Warehouse inventory — the formal handover happens in Production In/Out → Out.
Finished Goods
Finished Goods is a holding ledger for QC-passed batches that are ready to be transferred to the Warehouse but have not yet been handed over. Think of it as the production side of the transfer waiting room.
- Each entry shows recipe, batch number, quantity produced, and production date.
- Items here do not appear in Warehouse inventory and cannot be allocated to Sales Orders.
- To move stock to the Warehouse, use Production In/Out → Out.
- The Production Overview's "Finished Goods Pending" panel surfaces unshipped items — monitor this daily to prevent expiry of perishable products.
Perishable risk: Cookies have short shelf lives. Finished Goods that are not transferred promptly may approach their best-before date before reaching the customer. The production manager should target same-day or next-day transfer for fresh-baked goods.
Production In / Out
Production In/Out is the transfer gateway between the Production and Warehouse modules. It handles both directions of stock movement and provides a full audit trail for every transfer.
In — Inbound Receipts
Records raw materials physically arriving into the production facility from the Warehouse (fulfilling an approved Ingredient Request).
- 1Warehouse dispatches ingredients against an approved Ingredient Request; status moves to "Dispatched".
- 2Production sees the pending receipt here under the Pending Receipt filter.
- 3Production opens the receipt modal, verifies expected vs actually received quantities per ingredient line, and adds notes for any discrepancy.
- 4Production confirms receipt — Production Inventory is updated (ingredients move from "Expecting" to "Existing").
Out — Transfer to Warehouse
Records Finished Goods being handed from Production to the Warehouse. This is the exact moment products enter Warehouse inventory and become available for Sales Orders.
- 1Production initiates a transfer for one or more Finished Goods batches (from the Out tab).
- 2Status changes to Dispatched — Awaiting Warehouse; Warehouse is notified.
- 3Warehouse receives goods physically, confirms quantities in their module, and marks Received.
- 4Warehouse inventory is updated — Finished Goods SKU is now available for Sales Orders and Dispatch.
Cross-module: The "Received by Warehouse" confirmation step is the precise handover point. Until this step, the product is Production's responsibility and cannot be sold. After it, the product is under Warehouse control and can be allocated to Outbound orders.
Costing
The Costing sub-module calculates the total cost of each production batch. Results feed into Finance for COGS reporting and can be compared against selling prices (from the SKU Master) for margin analysis.
| Cost Component | Source Data | Calculation |
|---|---|---|
| Raw Material Cost | Recipe BOM quantities + SKU Master unit cost | Qty consumed per ingredient × unit cost, summed across all BOM lines |
| Labour Cost | Manpower Template hourly rates + actual hours per process | Hours worked × hourly cost per manpower type, summed across all job processes |
| Total Batch Cost | — | Raw Material Cost + Labour Cost |
| Cost Per Unit | QC Actual Qty output | Total Batch Cost ÷ Actual Qty produced (from QC record) |
Cross-module: Cost Per Unit flows to Finance for COGS calculations and can be benchmarked against the selling price in the SKU Master (set in the Warehouse module) to produce per-SKU margin reports.
Production Permissions
| Permission | What It Grants |
|---|---|
production.overview.read | View the Production Overview KPI and activity panels |
production.scheduler.read | View the Scheduler timeline (read-only) |
production.scheduler.write | Create, modify, and save schedules; insert and move jobs on the timeline |
production.templates.read | View Room, Job, and Manpower templates |
production.templates.write | Create and edit Room, Job, and Manpower templates |
production.users.read | View Production Users list and skill assignments |
production.users.write | Add/edit production workers and assign skills |
production.qc.read | View QC records, batch statuses, and planned vs actual quantities |
production.qc.write | Record QC results; set batches to Pass, Fail, or Rework |
production.inventory.read | View Production Inventory (live stock, count history) |
production.inventory.write | Submit inventory count adjustments |
production.inventory.admin | Reset production inventory — destructive, admins only |
production.inout.read | View Production In/Out transfer records and statuses |
production.inout.write | Confirm inbound ingredient receipts; initiate outbound finished goods transfers |
production.costing.read | View batch cost breakdowns and per-unit cost reports |
management.recipes.read | View recipes (BOMs) — required for Job Template creation |
management.recipes.update | Edit and approve recipe versions — required to unlock recipes for production use |
End-to-End Production Workflow
Complete sequence from initial setup through to finished product available for sale.
- 1One-time setup: Configure Room Templates (production spaces), Manpower Templates (labour categories), register Production Users and assign their skills.
- 2Recipe approved: Management approves the recipe version under Management → Recipes (Restricted). An unapproved recipe blocks Job Template creation.
- 3Job Template created: Link the approved recipe to an ordered process sequence (rooms + manpower types). Set default batch size and per-process durations.
- 4Ingredient availability check: Review Production Inventory → Live Stock. If insufficient raw materials are on hand, raise an Ingredient Request against the Warehouse.
- 5Ingredient Request fulfilled: Warehouse approves and delivers. Production confirms receipt in Production In/Out → In. Ingredients move from "Expecting" to "Existing" in Production Inventory.
- 6Job scheduled: In Production Scheduler, click Insert Job → select the template → drag onto the timeline → assign workers → Save Schedule.
- 7Production runs: Batch status advances to In Progress. Production staff use Schedule Views (Room View / User View) for shift-level instructions.
- 8Batch completes → QC: Status changes to Awaiting QC. QC officer records checks in Production QC and marks Pass, Fail, or Rework. Failed batches are written off; rework batches re-enter the Scheduler.
- 9QC Passed → Finished Goods: Batch appears in Finished Goods as a pending transfer. Costing is calculated automatically at this point.
- 10Transfer to Warehouse: Production initiates the transfer via Production In/Out → Out. Status changes to Dispatched.
- 11Warehouse receives: Warehouse confirms quantities and marks the transfer Received. Finished Goods SKU is added to Warehouse inventory.
- 12Available for sale: Warehouse inventory is live — the product can now be allocated to Sales Orders and dispatched to customers via the Outbound module.
Finance Module
The Finance module covers two areas: Bank Reconciliation (matching bank statement lines to outlet payment records) and Invoices (AP supplier invoices and AR customer invoices).
Access requires: finance.overview.read (Finance Overview), finance.reconciliation.read (view reconciliation), finance.reconciliation.write (create/edit), finance.reconciliation.admin (lock periods, journal export), finance.invoices.read (invoice visibility). Assign the built-in Finance Manager role or create a custom role with the required permissions.
Bank Reconciliation — Overview
Bank Reconciliation works on monthly periods. Each period holds uploaded bank statement transactions, per-category reconciliation state, parked entries, and journal adjustments. Periods can be re-opened until explicitly locked.
- 1Create a period — Finance → Bank Reconciliation → New Period. Select month and year.
- 2Upload bank statement — Click Upload Statement. Accepts CSV or Excel. The system auto-categorises each transaction row by description keyword (e.g. "ALLINPAY" → Kpay, "GPAY" → Grab).
- 3Reconcile by category — Click each category tile. The right panel shows the matching logic and lets you mark the category reconciled once the difference is zero.
- 4Park exceptions — For transactions that cannot be matched, create a Parked Entry. Optionally flag it as an Independent Journal Entry so it is included in the export regardless of park state.
- 5Journal adjustments — Add standalone journal entries (debit/credit pairs) for items like bank charges, interest, or corrections that have no corresponding bank transaction.
- 6Lock period — Once all categories reconcile and the comparison totals show zero difference, click Complete Period. This prevents further edits.
- 7Export journal entries — Click Create Journal Entries to download a CSV of all adjustments for the period for posting into your accounting system.
Category Reconciliation Rules
Each category has its own matching logic. Understanding the rules prevents reconciliation errors.
Grab
Bank transactions identified by GPAY / GRAY NETWORK / FAST GRAY keywords. Matching is sum-based by outlet UID — the bank payout for a given outlet UID must equal the sum of all Grab system amounts for that outlet's UID. Outlet UIDs are mapped to locations (Marina Square → 65383, Orchard Gateway → 33861, Vivo → 80569). Category completes when every outlet UID's bank sum matches its Grab sum.
Kpay (Allinpay)
Bank transactions identified by ALLINPAY keyword. Matching is session-based by outlet name — each bank transaction is matched to a Kpay session with the same outlet and a close amount. Multiple sessions per outlet are possible. Category completes when all bank transactions are matched to sessions with zero unmatched remainder.
Foodpanda
Bank transactions identified by DELIVERY HERO / FOODPANDA keywords. Matching is per-outlet session — each Foodpanda payout references a 4-character outlet code (GEYA = Marina Square, EL8T = Orchard Gateway, LTR0 = Vivo, B7PL = Westgate). Each payout is matched to the Foodpanda system records for that outlet code. Category completes when every payout is matched.
Tabsquare
Bank transactions identified by ADYEN keyword. Matching is month sum-based — the sum of all Tabsquare bank payouts for the period must equal the total Tabsquare system report for the month. No per-outlet breakdown. Single difference check.
Shopback
Bank transactions identified by SHOPBACK keyword. Matching is total sum — the sum of all Shopback bank transactions must equal the total Shopback system report for the period. Single difference check.
Cash Deposit
Bank transactions identified by CASH DEPOSIT / CASH DEP / CDM keywords. Matching is individual checkbox — each cash deposit transaction must be manually checked off against a corresponding outlet cash count record. All transactions must be matched (checked) for the category to complete.
Svc Chg (Service Charges)
Bank transactions identified by SERVICE CHARGE / SVC CHG / SC / BANK CHARGE / BK CHG keywords. These are bank fees and charges — no reconciliation required. The category auto-completes. Transactions are listed for reference only.
Others
Any transaction not matched by the above keyword rules falls into Others. These are handled manually: create a journal entry for each unmatched item, selecting the correct account code (debit/credit). The category can be marked complete even if the running difference is non-zero, because Others uses journal entries as the authoritative record rather than a sum match.
Deliveroo
Bank transactions identified by DELIVEROO keyword. Matching works similarly to Foodpanda — each payout is matched to the Deliveroo system report for the corresponding outlet and period.
Parked Entries
Parked entries are temporary holding records for transactions that need follow-up before they can be reconciled. They are per-category and per-period.
| Field | Description |
|---|---|
| Description | What this parked entry represents |
| Amount | The unmatched amount being parked |
| Independent JE | When checked, the entry is saved to the database and included in journal exports permanently — even after unparking |
When a parked entry is resolved, click Unpark — the entry is removed and the running difference in the category updates immediately. Parked entries with Independent JE checked persist in the journal adjustment log even after unparking.
Parked entries temporarily inflate the "unreconciled" count in a category. Do not mark a category complete while there are outstanding parked entries unless you have intentionally journalled them as Independent JEs.
Journal Adjustments
Journal adjustments are standalone double-entry records that are always included in the period's journal export. Unlike parked entries they are not tied to a specific bank transaction.
Use cases: bank interest income, bank charges not categorised above, rounding adjustments, contra entries for prior-period corrections.
Each entry requires: Date, Description, Account Code, Debit amount, Credit amount. The entry is saved permanently and survives park/unpark cycles in the same period.
Journal adjustments are also auto-created when outlet category entries are captured from the Grab, Kpay, Foodpanda, and Tabsquare panels — the system creates the corresponding JE automatically so the journal export is always complete.
Invoices (AP & AR)
The Finance module provides a read-only view of all invoices in the system. Supplier invoices (AP) are created when a GRN is posted. Customer invoices (AR) are created when a Delivery Order is marked delivered.
| Type | Source | Actions available in Finance |
|---|---|---|
| Supplier Invoice (AP) | Auto-created from posted GRN | View details, mark paid, add supplier reference |
| Customer Invoice (AR) | Auto-created from delivered DO | View details, mark paid, confirm |
Full invoice editing (amounts, line items) is done in Inbound → Supplier Invoices and Outbound → Customer Invoices respectively. The Finance view is for payment tracking and overview.
User Management
Accessible via Management → User Management. Requires management.users.read. The page has two tabs: Users and Roles.
Creating a User
Requires management.users.create (shows the Add User button).
- 1Click Add User (top-right of the User Management page).
- 2Fill in Full Name, Email, Department, and select an initial Role.
- 3Click Create User. Default password is
changeme123— the user must change it on first login. - 4If email notifications are configured, the new user receives a welcome email with their credentials automatically.
Managing User Roles
Requires management.users.assign_roles. Click the icon on any user row to open the Assign Roles modal. Tick the roles to grant — changes take effect on next login.
Password Reset
Requires management.users.reset_password. Click the key icon → Generate Password. The temporary password is shown on screen and optionally emailed to the user. It is not shown again after the modal is closed.
Edit User Profile
Requires management.users.update_profile. Click the pen icon to change the user's display name, department, or account status (active/inactive).
Lock / Unlock Accounts
Requires management.users.lock_unlock. Click the lock icon to lock an account. Locked users cannot log in even with the correct password. Unlock by clicking again.
Roles Tab
Requires management.users.assign_roles to create or edit roles. The Roles tab shows all roles with their user count and permission breakdown. Click New Role to create a custom role with a hand-picked permission set. Click Edit to modify an existing role's grants. Click Delete to remove an unused role (blocked if users are assigned to it).
Super Admin protection: The super_admin and erp_admin roles are permanently protected — their Edit and Delete buttons are hidden. Users who hold the super_admin role are also protected: their Edit, Reset Password, Lock/Unlock, and Assign Roles actions are hidden from all non-superadmin operators. Only another Super Admin can manage a Super Admin account. The super_admin role is not visible in the role dropdown when creating a user or assigning roles, unless the operator is themselves a Super Admin. This prevents privilege escalation.
Setting Up a Finance Department User (Example)
- 1Create the user account with department = Finance.
- 2Open Assign Roles and tick Finance Manager (grants
finance.*plus read access to inbound/outbound overviews). - 3Or create a custom role: New Role → tick
finance.overview.read,finance.reconciliation.read,finance.reconciliation.write,finance.invoices.read. - 4The user can now access Finance → Finance Overview and Finance → Bank Reconciliation on their next login.
Setting Up an Operations Head User (Example)
- 1Create the user account with department = Operations.
- 2Assign the Management Admin role (grants
management.*, includingmanagement.users.createandmanagement.users.assign_roles). - 3The user can now create users, edit roles, and assign permissions to other staff — but cannot edit or assign the Super Admin role unless they are themselves a Super Admin.
Email Notifications
The system can send automated emails for key events. Configure SMTP settings in Management → Notifications.
Setting Up Email (SMTP)
- 1Go to Management → Notifications.
- 2Toggle Email Notifications to Enabled.
- 3Enter your SMTP details: host, port, username, and password.
- 4Enter a test email address and click Send Test to verify the connection.
- 5Enable individual notification triggers as needed.
- 6Click Save Notification Settings.
Gmail users: You must use an App Password, not your regular Google password. Generate one at: Google Account → Security → 2-Step Verification → App Passwords. SMTP Host: smtp.gmail.com, Port: 587.
Available Notification Triggers
| Trigger | When it fires | Recipient |
|---|---|---|
| New User Created | Admin creates a new user account | The new user (welcome email with credentials) |
| Password Reset | Admin resets a user's password | The affected user (temp password email) |
| PO Approved | A purchase order is approved | PO Recipients group (configurable) |
| SO Approved | A sales order is approved and picking starts | SO Recipients group (configurable) |
| Low Stock Alert | SKU quantity drops below minimum level | Low Stock Recipients group (configurable) |
Email Log
The bottom of the Notifications settings page shows a log of all emails sent, their status (sent / failed), and error messages for failed attempts. Click Refresh to update.
System Settings
Accessible via Management → Tax & Finance Settings. Requires management.settings.read.
| Setting | Description |
|---|---|
| Outbound Tax Rate (%) | Applied to all Sales Orders and Customer Invoices |
| Inbound Tax Rate (%) | Applied to all Purchase Orders and Supplier Invoices |
| Default Payment Terms | Default days for new customer accounts |
| Credit Limit Warning | Alert when a customer has used this % of their credit limit |
| Currency Code | ISO 4217 code (e.g. SGD, USD, MYR) |
| Currency Symbol | Displayed prefix (e.g. $, RM, £) |
| Require PO Approval | If on, POs must be approved before being sent to suppliers |
| Require SO Approval | If on, SOs must be approved before picking begins |
| Auto-Create Picking List | Automatically generate a picking list when a SO is approved |
| Stock Valuation Method | FIFO (first-in first-out) or Weighted Average for cost calculations |
File Repository & Import
Accessible via Management → File Repository. Serves as document storage, data export centre, and master data import hub.
Data Import (CSV)
Import master data directly from CSV files. Supported datasets:
| Dataset | Key Field | What gets overwritten |
|---|---|---|
| SKU Catalogue | skuCode | Product details, pricing, storage type |
| Warehouse Locations | locationId | Location type, capacity, zone |
| Supplier Directory | code | Contact details, lead times |
| Customer Directory | code | Contact details, payment terms, credit limits |
Import Workflow
- 1Click Template on the dataset card to download the CSV template with correct headers and sample data.
- 2Fill in your data following the template format. The key column (e.g. skuCode) identifies existing records to update.
- 3Click Import, select your CSV file. The system validates that all required headers are present.
- 4A preview shows the record count and first 5 rows. Review before confirming.
- 5Click Import & Overwrite. The system automatically archives the current data to the Archives folder before applying changes.
- 6A results summary shows how many records were created, updated, and skipped.
Automatic archiving: Before any import overwrites data, the current dataset is saved as a timestamped CSV in File Repository / Archives. You can download the archived file at any time to restore previous data.
Master Data Export
The Export Center card lets you export Suppliers, SKUs, Inventory, Users, Locations, and Roles in Excel, CSV, or JSON format in one click.
Key Workflows
🛒 Purchase-to-Pay (P2P)
📦 Order-to-Cash (O2C)
🏭 Production Cycle
Troubleshooting
| Problem | Likely Cause | Fix |
|---|---|---|
| Blank screen / page won't load | UI server not running | Run npx serve -l 8888 . in the cookie-erp-ui folder |
| Login fails / API error | API server not running | Run npm run dev in cookie-erp-api folder |
| Tailscale user can't connect | Firewall blocking port 8888 or 3000 | Run open-firewall-admin.bat as Administrator |
| Inventory / Locations show loading forever | API unreachable from browser | Check both servers are running; hard-refresh (Ctrl+Shift+R) |
| Email notifications not sending | SMTP not configured or disabled | Go to Management → Notifications → configure SMTP → Send Test |
| CSV import fails header validation | Column headers don't match template | Download the template, fill it in exactly — don't rename headers |
| "Access denied" on a page | Your role lacks the required permission | Ask an administrator to assign the correct role |
| Picking list not generating after SO approval | Auto-create picking list setting is off | Management → Tax & Finance Settings → enable Auto-Create Picking List |
NastyCookie ERP