Meezan ERP POS user guide
Everything from the first launch to the closing trial balance — installing and activating, running a shift on the floor, buying and selling, costing your stock, posting the ledger, preparing ZATCA Phase-2 artifacts and keeping your data safe. Written for the shipped version 1.4.1.
Installing
Meezan ERP POS is a desktop application. There is no server to provision, no database engine to install alongside it and no account to create on someone else's website. You run one installer, and the application creates its own database file the first time it starts — nothing else to set up.
Pick the build for your machine from the download page:
| Platform | What you get |
|---|---|
| Windows 10/11 (x64) | NSIS installer, plus a portable .exe that runs without installing |
| macOS (Intel x64 and Apple silicon arm64) | .dmg and .zip |
| Linux | AppImage and .deb |
On Windows, run the installer and follow the prompts. If you would rather not install anything — a shared back-office machine, a demo on a laptop you do not own — use the portable executable instead; it keeps its data in the same user-data folder and behaves identically.
The first launch does three things before you see a screen: it creates the database file in your
operating system's user-data folder, applies the schema, and seeds a brand-new database with a
starting chart of accounts, a sample menu, a floor plan and the admin user. That only
happens once. Every launch after that opens the database that is already there.
Activating your licence
Activation is offline and node-locked. The application never contacts a licence server, because there isn't one. Instead, the machine tells you who it is and you exchange that for a code.
On first launch you will see the activation window. It shows a machine code derived from a stable hardware identifier on that computer, in this shape:
MZR-DE07-EB9C-0099-17AA-7118
Send that code to us. We return an activation code — an expiry date followed by a signature:
# the shape of an activation code
<YYYY-MM-DD>.<base64 signature>
Paste it into the activation window and the application unlocks. A licence is valid for a fixed period, one year by default.
Why a code cannot be forged or moved
The signature is Ed25519. Only the public key ships inside the application; the
private key never leaves us. The signed message is machineCode|expiry, which has two
useful consequences. A code issued for one machine is meaningless on another, because the machine
code is inside the signed message. And the expiry cannot be edited, because changing a single
character of the date breaks the signature.
Because the machine code comes from a stable machine identifier, and because the licence file is mirrored to the backup folder alongside your data, a reinstall stays activated. Uninstall the application, reinstall it, and it starts straight into the app.
First sign-in
The seeded administrator account is:
| Field | Value |
|---|---|
| Username | admin |
| Password | admin123 |
| Role | Admin |
Sign in, then change the password immediately in Settings ▸ My account. This is not a formality. The password is the only thing standing between a walk-up user and your ledger, and the default one is printed in this guide.
Passwords in the database are stored as entered, not hashed. This is a single-user desktop application with no server to send a hashed credential to, and being plain about that is better than implying a protection that is not there. If an account's password is lost, an Admin resets it; if the Admin password itself is lost, see Troubleshooting.
Switching to another account asks for that account's password before the view changes. There is no session token — closing the application, or switching users again, is what ends a sign-in.
Setting up your company
Open Settings and fill in your company details before you post anything: legal name, VAT registration number, address and the VAT rate. These fields print on invoices and feed the ZATCA e-invoice artifacts, so getting them right on day one saves reissuing documents later.
Two settings change how the whole application behaves.
Costing method
FIFO or weighted average, chosen once in Settings. This decides how the cost of goods sold is valued every time stock leaves. See FIFO vs weighted average.
Business nature
The nature of your business decides which modules appear in the sidebar. A restaurant does not need a projects module; a services company does not need warehouses. Rather than hiding clutter behind preferences, the application maps the nature straight onto the visible groups:
| Nature | Inventory | Manufacturing | POS | Tables | Projects |
|---|---|---|---|---|---|
| Restaurant | ✓ Included | Not included | ✓ Included | ✓ Included | Not included |
| Trading | ✓ Included | Not included | ✓ Included | Not included | Not included |
| Trading & Manufacturing | ✓ Included | ✓ Included | ✓ Included | Not included | Not included |
| Trading & Services | ✓ Included | Not included | ✓ Included | Not included | Not included |
| Manufacturing | ✓ Included | ✓ Included | Not included | Not included | Not included |
| Contracting | ✓ Included | Not included | Not included | Not included | ✓ Included |
| Services | Not included | Not included | Not included | Not included | Not included |
A restaurant therefore gets inventory, the POS terminal and the floor plan; recipes (Manufacturing) are off by default and switched on the same way, for a commissary kitchen producing across branches. A contracting business gets projects with IFRS 15 revenue recognition and progress billing, and loses the POS. A services company gets neither stock nor a till, and the sidebar shrinks to sales, purchases, money, payroll and accounting.
Users and the three roles
Every person who touches the system should have their own account. Sharing one login makes the audit trail worthless — you can see that a void happened, but not who did it.
There are three roles, as a label on each account:
| Role | Intended for |
|---|---|
| Admin | The owner or systems person. Settings, users, the chart of accounts, everything. |
| Accountant | The books: journal, ledger, reports, VAT, payroll, fixed assets. |
| Viewer | Read-only. An accountant's assistant, an investor, a landlord. |
This is a single-user desktop application with no separate server to enforce a role independently of the interface — the role is a label that identifies who is signed in, checked when switching between accounts, not a permission system with something behind it refusing individual actions. Read it as a way to know who did what, not as a wall between what different people can reach.
- Create an account per person, not per station.
- Keep one Admin in reserve that is not used day to day.
- Deactivate leavers rather than reusing their login for the next hire.
Running a POS shift
The POS terminal is built for speed at the counter: pick a product, adjust the quantity, take payment, print. It is reachable from the sidebar or with Ctrl + 2.
Opening
Sign in as the cashier who will be on the till. Confirm the terminal, check the receipt printer has paper, and count your float. The float itself is a cash movement — record it under Money ▸ Cash & Banking so the drawer you count at midnight matches the drawer the ledger expects.
Selling
Add lines, apply a discount if you are allowed to, then settle. A sale can be split between cash and card; both amounts are stored on the sale, which is what makes the end-of-shift reconciliation possible. Every completed sale posts its revenue, its VAT and its cost of goods sold, immediately. There is no overnight batch to forget to run.
Returns
A return is recorded against the original sale rather than as a negative sale typed from memory. That keeps the link between the refund and what was actually sold, and keeps the stock movement honest.
Closing — the shift summary
The shift summary is the Z-report. For a given day and terminal it totals every sale that is not voided and gives you:
| Figure | What it means |
|---|---|
| Count / returns | How many sales, and how many of them were refunds |
| Gross | The total taken, VAT included |
| Net | Gross with the VAT extracted |
| VAT | The tax portion of the day's takings |
| Discount | Everything given away at the till |
| Cash / card | The split you count the drawer against |
| COGS and gross profit | Net less the cost of what actually went out of stock |
Count the drawer, compare it to the cash figure, and investigate any difference on the day. A variance is much easier to explain while the shift is still in the building.
POS sessions and the drawer
A session wraps a shift on one register: it opens with a counted float, collects every sale rung on that register, and closes when the drawer has been counted and a supervisor has approved the count. Every POS sale requires an open session — that refusal is what makes the end-of-shift reconciliation mean something.
Opening
Open the session from the POS screen, on the register you are working, with the float counted into the drawer. Cash, card and bank receipts are tracked as separate tenders from that moment, and a sale can be split across them.
Payouts
Cash leaving the drawer mid-shift — a petty expense, a float lift — is recorded as a payout with a reason. It posts immediately and reduces the cash the session is expected to hold, so a legitimate payout never shows up later as a mystery shortage.
Closing and counting
At close you count each tender. The screen shows expected against counted against difference, on
one convention: counted − expected, so positive is over and negative is
short. Each tender reconciles against its own refunds — a card refund never leaves
the till, so it cannot manufacture a cash shortage.
Approval
Submitting posts nothing. The variance reaches the ledger only when a supervisor approves the close, as a single balanced Cash Over/Short journal entry. A cashier cannot approve the drawer they counted, and approval locks the session — no further sales, payouts or re-counts. A correction is a new document in the current shift, not an edit to a closed one.
The POS Sessions page is the supervisor’s side: filters by date, terminal, cashier and status, a variance column, the approve / return queue, and per-session sales and collection reports with Excel export and print. Every transition is written to an append-only audit trail.
Dine-in floor bills do not yet carry a terminal, so table takings sit outside the drawer reconciliation — counter sales are in. Count the floor’s takings against the shift summary as before.
Working the floor and tables
Dine-in is a different rhythm from counter sales, so it gets its own screen. Floor / Tables shows your plan grouped by area, each table marked free or occupied, with the running value of the open tab on it.
Opening a tab
Tap a free table to open a tab, recording the cover count and the waiter. Opening a table that already has an open tab simply returns you to that tab — you cannot accidentally run two bills on one table.
Punching items
Each round of items punched onto the tab is grouped into a batch. That grouping is what makes the kitchen ticket safe (see below), and it is also why the tab reads chronologically: starters, then mains, then the extra bread somebody asked for at the end.
Corrections
A line that has not yet gone to the kitchen can simply be deleted. A line that has been sent is refused with a clear message: "That item has already gone to the kitchen. Void it through a manager instead of deleting it." The kitchen has already started cooking it, so it is a void with a reason, not a quiet deletion.
Settling
Billing a table hands the tab to the POS for payment, so a dine-in bill and a counter sale settle through exactly the same path, post the same entries and appear in the same shift summary. The table returns to free.
Kitchen tickets and the reprint guard
The single most expensive mistake a restaurant POS can make is sending the same order to the kitchen twice. A reprint because the first ticket jammed, or because the chef could not read it, must not produce a second plate of everything.
Meezan handles this by tracking, per line, whether it has already been sent. Requesting a kitchen ticket collects only the un-printed lines, marks them printed, and returns that batch. Asking for a ticket again immediately afterwards returns an empty batch — there is nothing new to cook.
Practically, this means the workflow you want is: punch a round, send it, punch the next round, send it. Each send prints only what is new. If the physical ticket is lost, reprint the paper copy of that batch from the ticket itself — you are reprinting a document, not re-issuing an order.
The sales cycle
Sales support the full document chain and the short version of it, and both post correctly. Use whichever suits the customer in front of you.
The full chain
- Quotation — a priced offer. Nothing is committed and nothing posts.
- Sales order — the customer accepts. Still no ledger entry; this is a promise.
- Delivery — the goods leave. Stock moves here, and this is where the cost of goods sold is booked.
- Sales invoice — the bill. Revenue and VAT post; the receivable is created.
The short version
For a walk-in with an account, or a delivery that is billed on the spot, raise a direct sales invoice. The stock movement and the accounting both still happen — you have simply skipped the paperwork in between.
Revenue and COGS post as two entries, not one. Keeping them separate means the revenue entry reads as a revenue entry in the journal, and a cost correction never disturbs the sale.
Credit notes
A return or an allowance is a credit note. It reduces the receivable, reverses the VAT and — where goods come back — puts the stock back. Do not "fix" an issued invoice by editing it; issue the credit note. The customer has your original document, and so should your books.
What you can see afterwards
- Receivables (AR) — customer-wise balances with aging.
- Customer statement — invoices and receipts for one account, ready to send.
- Customer-wise and product-wise sales for any period.
- Product-wise gross profit — average selling price, average cost, per-unit GP.
- Customer-wise P&L — sales, cost of sales and gross profit by account.
The purchase cycle
Purchases mirror sales, in the other direction.
- Purchase order — what you asked the supplier for.
- Goods receipt — what actually arrived. Stock comes in here, at the cost on the receipt, forming the layer that later costing draws from.
- Vendor bill — what you were charged. This creates the payable and records input VAT.
As with sales, you can post a direct vendor bill when there was no order and no separate delivery note — the greengrocer who turns up with crates and an invoice.
Receive against the order rather than typing quantities fresh. Short deliveries and over-deliveries then show up as a difference between the order and the receipt instead of disappearing.
Debit notes
Goods sent back to a supplier, or a credit they have agreed, is a debit note. It reduces the payable and takes the stock back out.
On the reporting side you get Payables (AP) with aging, a vendor statement, and vendor-wise and product-wise purchase analysis.
Recording money in and out
The Money group is where cash and bank balances actually move. Invoices and bills create obligations; this is where they are settled.
| Screen | Use it for |
|---|---|
| Cash & Banking | Deposits, internal transfers between accounts, customer receipts and vendor payments |
| Expenses | Costs paid directly — rent, utilities, small purchases with no supplier account |
| Expense Report | What was spent, on what, over a period |
| Funds Movement | The flow between your cash and bank accounts |
| Payments & Receipts | The full list of money in and money out |
Two habits keep the money side clean. First, always settle against the document — receipt against the invoice, payment against the bill — so the aging report stays truthful. Second, record the till float, the bank deposit and the petty-cash top-up on the day they happen; these are the movements that quietly break a reconciliation weeks later.
Products and stock
Inventory ▸ Stock & Products is the master list: the menu item or the purchased good, its selling price, its unit, and where it sits in your accounts.
Stock is not a number you type. It is the result of movements — receipts in, deliveries and POS sales out, production, transfers and adjustments. Stock Moves shows every one of them, and it is the first place to look when a quantity is not what you expected. Every figure in the valuation report can be traced back to a move.
Stock by Warehouse answers the other question: not "how much of this do we have" but "how much of this is here". For a two-branch operation with a central store, that is the view you live in.
Warehouses, branches and locations
A warehouse in Meezan is any place stock can sit: a branch, a central store, a cold room, a bar store, a van. Create one per place you would ever count separately. If you would never count the walk-in fridge on its own, it does not need to be a warehouse.
Every movement names a warehouse, which is what makes per-location valuation possible. Receipts land in a warehouse, deliveries leave one, and production consumes from one and produces into one.
For multi-branch operators the usual shape is a central store that receives supplier deliveries, and one warehouse per branch that receives internal transfers. Branch managers then see their own stock without seeing — or consuming — someone else's.
Transfers, and why they post no journal entry
Inventory ▸ Stock Transfer moves stock from one warehouse to another. It creates two movements: out of the source, into the destination, carrying the cost with it.
A transfer deliberately posts no journal entry. This surprises people, so it is worth stating plainly: moving your own goods between your own locations does not change what your business owns. Total inventory value before the transfer and after it is identical. Posting a journal entry would move a number from one inventory account to the same inventory account, which is noise in the ledger and tells you nothing that the stock report does not.
Bills of materials and production
A bill of materials is a recipe. For a restaurant it is literally that: a shawarma is so many grams of chicken, one piece of bread, so much sauce. For a manufacturer it is the components of a finished item.
Build the recipe once under Manufacturing ▸ Bills of Materials, listing each component and the quantity per unit produced. Then a Production run does two things at once: it consumes the components out of stock at their costed value, and it brings the finished item into stock carrying that cost.
This is what makes food cost real rather than estimated. The gross profit on the burger is the selling price less what the ingredients actually cost when they were bought, not what somebody guessed they cost last year.
- Cost the recipe, not the plate. Enter the quantity you actually use per portion.
- Produce in the batch size you cook in — one stock pot, not one bowl.
- Update the recipe when the dish changes, or your margin report drifts from reality.
- Waste is an adjustment, not a smaller recipe.
The chart of accounts
A fresh database is seeded with a working chart of accounts, so you can trade from the first day without designing one. Extend it as you need — a separate account for delivery-platform commission, one for each branch's rent — but resist the urge to create an account per supplier. That is what the vendor ledger is for.
Accounts are validated on posting. A posting to an account that does not exist is rejected rather than silently creating an orphan posting that appears in no report — the entry fails and tells you why.
Do not delete an account that has been posted to. Deactivate it. History has to keep resolving, and a trial balance that cannot name one of its own lines is not a trial balance.
Journal and ledger — and why you reverse instead of edit
Accounting ▸ Journal & Ledger is double-entry throughout. Every document in the application — invoice, bill, receipt, payroll run, depreciation, POS sale — lands here as a balanced entry. You can also post a manual journal for the things no document covers: an accrual, a reclassification, an opening balance.
Two rules are enforced by the server, not by the interface:
- Unbalanced entries are rejected. If debits do not equal credits, nothing posts.
- Postings to unknown accounts are rejected. The account has to exist first.
Version 1 accepted both silently. That is the single biggest reason a set of books drifts away from balance without anyone noticing.
Corrections post a reversal
A posted journal entry cannot be edited in place. To correct one, post a reversal and then post the correct entry. The original stays visible in the journal, the reversal stays visible next to it, and anyone reading the books afterwards can see exactly what happened and when.
This is deliberately less convenient than rewriting the line, and it is the right trade. In version 1 an admin could rewrite a posted entry's lines with no trace at all, and the payroll edit path deleted journal rows outright. An audit trail that can be rewritten is not an audit trail.
FIFO vs weighted average
Both costing methods are fully supported. You choose one in Settings, and it governs how the cost of goods sold is valued every time stock leaves.
| Method | How the cost is taken | Suits |
|---|---|---|
| FIFO | Stock is held in dated layers. A sale consumes the oldest layer first, at that layer's actual cost. | Perishables and anything where the buying price moves — most restaurants |
| Weighted average | All units of a product share one running average cost, recalculated as stock arrives. | Bulk goods, commodities, businesses that want a smoother margin line |
A worked FIFO example from the test suite: ten units bought at 5.00 each, then all ten sold, gives a cost of goods sold of exactly 50.00. Nothing is estimated and nothing is rounded away.
VAT, and why POS pricing is inclusive
The VAT rate is set once in Settings. Sales invoices, POS sales, vendor bills and credit notes all carry their tax, and the VAT settlement figures come from the postings rather than from a separate spreadsheet.
The part worth understanding is how the till handles it. POS pricing is VAT-inclusive: the tax is extracted from the ticket price, not added on top. The number on your menu is the number the customer pays.
| Line | Amount |
|---|---|
| Gross ticket — what the customer hands over | 46.00 |
| VAT at 15%, extracted | 6.00 |
| Net revenue | 40.00 |
So a 46.00 ticket posts 40.00 to revenue and 6.00 to VAT payable. If VAT were added on top instead, the same menu price would produce 52.90 at the till, your customer would be surprised, and your revenue would be overstated by the tax.
POS net = 40.00 on a 46.00 gross ticket — VAT extracted, never added on top — is how
every POS sale is priced, consistently.
Sales invoices raised outside the till follow the ordinary convention — a net line with VAT shown separately — which is what a business customer expects to receive.
Fixed assets and depreciation
The Fixed Asset Register covers the equipment you buy once and use for years: the oven, the chillers, the furniture, the vehicle.
- Capitalise the asset with its cost, purchase date and useful life. It goes to the balance sheet rather than straight to expense.
- Depreciate it each period. Depreciation is straight line: the cost is spread evenly across the useful life.
- Dispose of it when it goes, recording any proceeds. The gain or loss on disposal posts automatically.
Run depreciation as part of your month-end routine, in the same order every month. Consistency here is worth more than precision.
Payroll, advances and salary payments
Payroll ▸ Employees & Payroll holds your staff, their salaries, the advances you have given them and the payments you have made.
The cycle is straightforward. Record each employee once with their salary. Post the salary expense for the period, which creates the liability to pay them. Record any advance when you give it — the money has left the business, and the employee owes it back. Then post the salary payment, settling the liability net of anything already advanced.
Keeping advances as their own record rather than netting them off quietly means an employee's statement adds up: this is what you earned, this is what you had already taken, this is what you were paid.
Budgeting and forecasting
Accounting ▸ Budgeting & Forecasting lets you set an expected figure per account per period and then compare it with what actually happened.
Budget versus actual is most useful on the handful of lines you can actually influence: food cost, labour, rent, utilities, delivery commission. A budget covering every account in the chart is a spreadsheet nobody reads. Four lines you check every month will change how the business runs.
The projection side extrapolates from what has been posted, which makes it worth exactly as much as the data behind it. Post promptly and the forecast is useful; post in arrears and it is arithmetic on stale numbers.
Cost centres
A cost centre is a reporting axis — a branch, a department, a kitchen — carried on the journal line, never inside the amounts. Tagging a posting cannot change what it posts, only which column it lands in when you read the reports.
The master lives in Setup: centres nest under a parent (a centre can never be made its own ancestor), carry a code, validity dates and an active flag, and a centre that already has postings deactivates instead of deleting, so history stays readable. Pick the cost centre on a document and it rides into the ledger — a sale order’s centre carries through to the invoice raised against it — and manual journal entries accept a centre per line, validated before posting, so one entry can split rent across branches.
Three reports, and none of them hide anything:
| Report | Answers |
|---|---|
| Movement | Opening, debit, credit, net and closing — per centre, over a period |
| P&L by centre | Which branch actually made the money, side by side |
| Budget vs actual | Spend against plan per centre and account, variance signed so positive is always good |
Every report keeps an explicit Unallocated column. Postings nobody tagged appear there, in their own column — visible, rather than quietly missing from every branch’s numbers.
The approval workflow
An approval workflow puts named sign-offs between preparing a document and posting it. The chain is yours to design in Setup ▸ Approval Workflows: any number of levels, each with a free-text action name (“Reviewed By”, “Finance Approval”), assigned to specific users and/or whole roles, with amount bands per document type so a small expense takes a short path and a large one takes the long one. Levels run in sequence; consecutive levels marked parallel form one stage whose members may act in any order but must all act.
Nothing posts until the last yes. A journal entry or expense caught by a workflow is held as a draft inside the approval instance — readable by every reviewer, posted by none of them. The final approval executes the posting in the same transaction and records the produced document’s id on the approval. The chain is frozen at submit: editing a workflow later never rewrites an approval already in flight.
Rejecting or returning requires a written reason. A returned document goes back to its preparer — only the preparer can correct and resubmit, and resubmission restarts the chain from the top. Every action lands on an append-only trail: level, user, time, comment and the status change, never edited, never removed.
Reviewers work from the Approvals inbox (Accounting ▸ Approvals): the “My queue” tab shows exactly the documents whose current stage waits on the signed-in user, with the draft, the chain and the trail in one dialog. A bell in the top bar carries the pending count everywhere in the application.
Reports
Reports read from the same postings the rest of the application writes. There is no separate reporting database and no rebuild step, so a report run one second after an invoice includes it.
| Report | Answers |
|---|---|
| Profit & loss | Did we make money over this period, and where did it go |
| Account balances / trial balance | Does the ledger balance, and what does each account hold |
| Inventory valuation | What is the stock on hand worth, at cost |
| Customer and vendor statements | What one account owes or is owed, document by document |
| Receivables and payables aging | How old the debts are — current, 30, 60, 90+ |
| Product-wise gross profit | Which lines actually earn, per unit and in total |
A sensible month-end sequence: post everything for the month, run depreciation, check the trial balance, reconcile cash and bank, then read the P&L. Reading the P&L first is how you end up explaining a number that was never going to be right.
Reports print through the ordinary File ▸ Print (Ctrl + P), which also gives you a PDF on every platform.
Combined customer / vendor statements
The same business often buys from you and sells to you — the produce supplier who also runs a staff canteen account. Link the customer record to the vendor record that is the same party in Setup ▸ Customers & Vendors. The link is explicit; names and VAT numbers are never matched automatically, because a wrong guess would fold a different company’s ledger into someone’s statement and nothing on screen would reveal it.
Once linked, the statement screen gains a Receivable / Payable / Both selector. “Both” re-derives the two sides in a single convention — your own books, debit positive — and interleaves invoices, receipts, bills and payments in date order on one running balance, each row tagged Receivable or Payable.
The closing figure is a net memo — what they owe you minus what you owe them, the number the settlement conversation actually needs. The AR and AP control accounts are untouched and nothing is offset in the ledger.
ZATCA e-invoicing
The e-invoicing module is built for ZATCA Phase 2. It is worth being exact about what it prepares and what it cannot prepare on your behalf, because a QR code that looks right and is not is worse than no QR code at all.
What the module prepares
- UBL 2.1 XML generated for the invoice.
- ICV — the invoice counter value, incrementing per document.
- The PIH hash chain, linking each document to the previous one. Chain integrity is verified on every read, not only when the document is created.
- The Base64 TLV QR payload, tags 1–5: seller name, VAT number, timestamp, invoice total and VAT total.
What needs your CSID
Tags 6–9 carry the XML digital signature and the signing certificate. Those require a CSID issued by ZATCA during device onboarding — a real credential tied to your business and your device. The application stores that credential once you have it. It will never fabricate one.
Until the CSID is in place, documents are flagged signed: false. That flag is honest
rather than cosmetic: it tells you the artifacts are prepared and the signed portion is outstanding.
The practical sequence
- Get your company details and VAT number exactly right in Settings — they go into the QR payload.
- Trade normally. Every invoice builds its UBL XML, takes the next ICV and links into the PIH chain.
- Complete device onboarding with ZATCA and obtain your CSID.
- Store the credential in the application. Tags 6–9 can then be produced.
Backups and where your data lives
Your data lives in two places on your own machine, and nowhere else.
The live database
A single JSON file in your operating system's user-data folder:
| Platform | Location |
|---|---|
| Windows | %APPDATA%\Meezan ERP POS\ |
| macOS | ~/Library/Application Support/ |
| Linux | ~/.config/ |
File ▸ Open Data Folder takes you straight there.
The uninstall-proof mirror
On a throttle, the database is mirrored to Documents/Meezan ERP Restaurant/ as a
human-readable JSON export plus a copy of the database file, with a rolling set of dated snapshots
alongside the latest. That folder is not touched by an uninstall. Remove the
application entirely, reinstall it later, and your books — and your activation — are still there.
Get to it with File ▸ Open Backup Folder.
How the writes are protected
- Atomic writes. A backup is written to a temporary file and then swapped into place, so a power cut cannot leave you with half a file.
- Writes are fsync'd rather than left in the operating system's cache.
- A rolling
.bakis kept beside the primary. - Automatic fallback. If the primary file is corrupt on open, the backup is used.
Documents/Meezan ERP Restaurant/ onto a USB stick or an external drive and take it out
of the building. A backup that lives in the same room as the computer does not survive the same
fire, flood or theft.
Moving to a new computer
Because everything is files, moving is a copy rather than a migration.
- On the old machine, take a fresh manual export: File ▸ Export Data Backup
(Ctrl + S). Also copy the whole
Documents/Meezan ERP Restaurant/folder. - Install Meezan ERP POS on the new machine.
- Copy the backup folder into
Documents/on the new machine, keeping the folder name. - Start the application. It will show an activation screen with a new machine code — the hardware is different, so the code is different.
- Send us that machine code and we will issue an activation for the new machine.
- Once inside, use File ▸ Import Data Backup (Ctrl + O) to bring your data in, then check the trial balance against the old machine's.
Bringing in opening balances
Where you have opening figures or a batch of invoices already worked out — in a spreadsheet, from an old system, from an accountant's file — a CSV importer brings them in rather than making you key each line by hand.
Opening data / General Ledger
Paste general-ledger lines directly, or upload a CSV. The importer parses the file into vouchers and shows you a preview — balanced and unbalanced counts, which accounts are missing — before anything is posted.
- Missing accounts can be created on the fly, optionally, rather than blocking the import until your chart of accounts is complete.
- Unbalanced lines can route to a suspense account instead of stopping the whole batch — tidy them up afterwards once the rest is in.
- A confirmation before posting states exactly how many lines and vouchers are about to be added.
Bulk invoices
A separate importer brings in a batch of sales or purchase invoices the same way — parse, preview, confirm, post — for when you are entering a backlog rather than starting from a blank ledger.
Export and import from the File menu
Alongside the automatic mirror there is a manual export you control:
| Menu item | Shortcut | What it does |
|---|---|---|
| File ▸ Export Data Backup… | Ctrl + S | Writes a complete backup to a location you choose, through a native save dialog |
| File ▸ Import Data Backup… | Ctrl + O | Restores from a backup file you select |
| File ▸ Open Backup Folder | — | Opens Documents/Meezan ERP Restaurant/ |
| File ▸ Open Data Folder | — | Opens the live user-data folder |
| File ▸ Open Log Folder | — | Opens the application logs — useful when reporting a problem |
Export before anything you would rather be able to undo: a bulk price change, a period close, a version upgrade, a first attempt at recipes. It takes seconds.
Architecture
For anyone evaluating the product technically, or maintaining it.
Meezan ERP POS is an Electron 33 desktop application, and unusually plainly built:
the whole interface — every screen, every report — is one renderer file
(renderer/index.html, around 34,500 lines). There is no separate build step for it, no
bundler: the React 18 UI is pre-compiled React.createElement calls written directly into
that file.
There is no backend API. No Express server, nothing listening on any port. The
renderer talks to the main process over a synchronous IPC bridge
(window.MEEZAN_FS, exposed by preload.js) that reads and writes one file.
There is likewise no relational database — the whole company's data is one
JSON document, read and rewritten as a whole by lib/store.js. No SQLite, no
Prisma, no tables with foreign keys.
| Layer | Shape |
|---|---|
| Renderer | 1 file |
| Screens in the sidebar (Restaurant setup) | 47 |
| Backend API | 0 |
| Relational tables | 0 — one JSON document |
| Automated tests | 49 |
Accounting and inventory are the two functions everything else builds on; every mutation — a POS sale, a delivery, a production run — goes through the same posting logic, which is why they cannot drift apart from each other.
Switching accounts compares the entered password against the one stored for that user — as plain text, not hashed — and there is no session token, since there is no server to issue one to. Three role labels ship in the seed data (Admin, Accountant, Viewer); nothing enforces them independently of the interface. See Where the honesty stops on the security page for the reasoning, and why it matters less on a single-user desktop machine than it would elsewhere.
Security posture is covered in detail on the security page:
contextIsolation: true, nodeIntegration: false, sandbox: true,
a CSP on every response, navigation and window-open guards, all permission requests denied, and no
filesystem surface in the renderer at all.
Building from source
The repository has one dependency: Electron itself. From the project directory:
npm install # installs Electron + electron-builder — nothing else
npm start # launches the app
npm test # 49 tests across three suites, 0 failing
npm run smoke # Electron integration smoke test
npm run dist # package installers with electron-builder
npm run dist packages installers with electron-builder for the platform you are on —
Windows NSIS and portable, macOS dmg and zip, Linux AppImage and deb.
The test suites
Three suites run with Node's built-in test runner, against real files on disk — nothing here is mocked:
npm test
PASS — 13/13 checks passed persistence (test/store.test.js)
PASS — 28/28 checks passed Electron-adaptation regression (test/patch.test.js)
PASS — 8/8 checks passed licensing (test/license.test.js)
That is 49 tests in total, all passing. The persistence suite covers durable writes, the rolling backup, and recovery from a corrupt primary file. The regression suite guards the Electron-specific adaptations (the CSP, the async prompt replacement, the drop guard) and — the larger part of it — checks real accounting behaviour against worked examples: cost-centre and combined-statement arithmetic, the approval engine's posting gates, POS-session cash-over/short, FIFO/weighted-average costing, and batch/lot FEFO consumption. The licensing suite covers the Ed25519 activation flow end to end.
A sample of what is actually asserted:
✓ FIFO cost follows the expiry-ordered batches, not receipt date
✓ combined statement close = 7,000 net, debit-positive both sides
✓ FEFO consumption drains the earliest-expiring batch first
✓ POS session cash-over/short posts as one balanced entry
✓ gated documents post nothing until the final approval
✓ reprint does not re-send to the kitchen
✓ financial reports carry a printed company letterhead
A separate Electron integration smoke test (npm run smoke) boots the packaged app in a
hidden window and probes it for a live render, a working IPC round-trip, and zero console errors.
Troubleshooting
The window does not appear after launch
Check the taskbar or dock first — the application may have started off-screen if a second monitor has been removed since it was last used, because it remembers its window position. Quit it fully and relaunch. If it still does not show, open the log folder via a running instance, or delete the saved window state in the user-data folder; the application will open with default geometry next time. On Windows, an overly aggressive security product can also stall the first paint — allow the application and try again.
The activation code is rejected
Work through these in order:
- Check the machine code on screen matches the one you sent us, character for character. A code issued for a different machine can never validate, by design.
- Paste the activation code rather than typing it. It contains a base64 signature where case matters and a single wrong character invalidates it.
- Make sure nothing was cut off by the clipboard or an email client wrapping the line.
- If the expiry date has passed, the code will be reported as expired rather than invalid. Ask us for a renewal.
- If the hardware changed — a new motherboard, a restored disk image on different hardware — the machine code has legitimately changed and you need a new activation. Send us the new code.
The printer is not found
Meezan prints through your operating system's printing stack, so if the printer is not visible to the OS it will not be visible to the application. Confirm the printer appears in your system's printer list and prints a test page. Restart the application after installing or changing a printer, so it picks up the refreshed list. For thermal receipt and kitchen printers, make sure the driver is installed and the paper width is configured in the driver, not only in the application. A shared network printer must be reachable from the machine running the POS — that is an ordinary printer share, not a Meezan setting.
The admin password has been forgotten
Passwords are not hashed — they are stored as entered, so a password can technically be read straight
out of the database file by anyone with access to this machine. That is one more reason to keep the
machine itself secured. If another account with the Admin role still works, sign in with that one and reset the
password from the user list. This is exactly why we recommend keeping a second Admin account in
reserve. If no Admin account is accessible at all, contact
finance@northbeam.sa before making any changes to the data
folder, and keep a copy of Documents/Meezan ERP Restaurant/ untouched in the meantime.
Restoring from a backup
Take an export of the current state first, even if you believe it is broken — it costs seconds and
it is the only way back if the file you restore turns out to be the wrong one. Then use File
▸ Import Data Backup and select the file. Backups live in
Documents/Meezan ERP Restaurant/: meezan-backup-latest.json plus dated
snapshots, so you can go back to a specific day rather than only to the most recent state. After
restoring, check the trial balance and open the last few documents you remember posting, to confirm
you have landed where you expected.
Something looks wrong in the numbers
Start from the movement, not the report. For stock, read Stock Moves for that product; every valuation figure resolves to a movement. For money, read the journal entry behind the document. If an entry is genuinely wrong, post a reversal and the correct entry — do not attempt to edit history, and note that the application will not let you.
Getting support
Support hours are Sunday to Thursday, 9:00–18:00 AST, and the response target is within one business day.
The fastest way to get a useful answer is to send us three things: what you did, what you expected, and what happened instead. If the application produced an error message, quote it exactly. If it is reproducible, list the steps. File ▸ Open Log Folder will take you to the logs, which are frequently enough to identify the cause on the first reply.
- Email — finance@northbeam.sa
- Contact form — contact.html
- Book a demo or a setup session — contact.html#demo
Please never send us a password. We do not need one, and we cannot read yours out of your database in any case.
Ready to run it on your own machine
Install it, activate it offline, and post your first invoice in an afternoon. Your books stay on your disk, in files you can copy.