RMAX Custom — User Guide
Complete guide for administrators and branch users to work with the RMAX Custom app on ERPNext.
POS Sales
Cash & Credit invoices with payment popup
Branch Setup
Auto-managed permissions per branch
Stock Transfers
Transfer with approval workflow
Inter-Company
Auto Purchase Invoice on submit
Landed Cost CBM
Distribute charges by cubic meters
Quick Customer
Create customer directly from invoice
🏢 Branch Master Admin
The Branch master is the first record you create for a new physical / commercial branch. Every Branch Configuration, per-branch document numbering series, and per-branch letterhead is keyed off this record.
How to Create a Branch
- Search for Branch and click + Add Branch.
- Enter the Branch name (e.g. "Azzizziyah", "Warehouse Jeddah", "HQ Awtad"). This becomes the record ID.
- Set Doc Prefix — the short alphanumeric prefix used in this branch's document numbers. The prefix MUST end with a hyphen. Examples:
WJ-,AZZ-,HO-,CL1-. - Set Branch Name (Arabic) — used inside per-branch bilingual letterheads.
- (Optional) Set Letter Head if you want to override the auto-generated
RMAX - <Branch>letterhead with a different one. - Click Save.
- Branch Naming Series rows are seeded for 16 doctypes (Sales Invoice, Delivery Note, Purchase Receipt, Purchase Invoice, Payment Entry, Stock Entry, Stock Reconciliation, Quotation, Material Request, Stock Transfer, Journal Entry, Sales Order, Purchase Order, Damage Slip, Damage Transfer, No VAT Sale).
- Templates like
WJ-INV-.YYYY.-.####,WJ-DN-.YYYY.-.####,WJ-PE-.YYYY.-.####are added to each doctype's series picker. - Return variants are seeded for SI / DN / PI — e.g. SI →
WJ-CN-.YYYY.-.####(Credit Note), DN →WJ-DRN-.YYYY.-.####, PI →WJ-DN-.YYYY.-.####(Debit Note). - RMAX - <Branch> Letter Head is created with the branch's Arabic name + bilingual address (when the branch is in the shipped data list).
- Inter-Branch GL accounts —
Due from <Branch>andDue to <Branch>— are added under each root Company.
Doc Prefix must be globally unique — two branches sharing a prefix will collide on the per-doctype series counter. Standard practice: 2–4 letters that map to the branch name.⚙ Branch Configuration Admin
Branch Configuration is the per-Branch operational config — exactly one row per Branch master. It controls which Company, Warehouses, Cost Centers, Users, and Modes of Payment belong to the branch. When you save, user permissions are automatically created for every user in the list.
How to Create a Branch Configuration
- Go to the search bar and type Branch Configuration, then click + Add Branch Configuration.
- Select the Branch (e.g. "Jeddah").
- Select the Company this branch belongs to (e.g. "Clearlight New Co."). This is required.
- In the Modes of Payment table, add the Cash and Bank Modes of Payment that branch users may collect against (e.g. Cash, Mada, Bank Transfer - HSBC). Only MoPs with type Cash or Bank appear in the picker. BNPL providers (Tabby/Tamara) are NOT added here — they are common to every branch.
- In the Warehouse table, add the warehouses for this branch. They will be filtered to show only warehouses from the selected company. The first warehouse becomes the user's default.
- In the Cost Center table, add cost centers. They are also filtered by company. The first cost center becomes the default.
- In the User table, add all users who work in this branch (e.g. shameel@rmax.com, naseef@rmaxled.com).
- Click Save.
What Happens Automatically
| Action | Result |
|---|---|
| Save with users | User Permissions created for Company, Branch, Warehouse, Cost Center |
| Remove a user | Their permissions are automatically deleted |
| Change Company | Old company permission removed, new one created |
| User logs in | Default Company, Warehouse, Cost Center auto-fill in new documents |
🔢 Branch Naming Series Admin
Every branch gets its own document number prefix per doctype. Counters are independent per doctype per branch, so Sales Invoice AZZ-INV-2026-0001 and Payment Entry AZZ-PE-2026-0001 are unrelated — they don't share a counter.
Template Pattern
| Doctype | Abbrev | Example template | Return variant |
|---|---|---|---|
| Sales Invoice | INV | AZZ-INV-.YYYY.-.#### | AZZ-CN-.YYYY.-.#### (Credit Note) |
| Delivery Note | DN | AZZ-DN-.YYYY.-.#### | AZZ-DRN-.YYYY.-.#### |
| Purchase Invoice | PI | AZZ-PI-.YYYY.-.#### | AZZ-DN-.YYYY.-.#### (Debit Note) |
| Purchase Receipt | PR | AZZ-PR-.YYYY.-.#### | — |
| Payment Entry | PE | AZZ-PE-.YYYY.-.#### | — |
| Stock Entry | SE | AZZ-SE-.YYYY.-.#### | — |
| Stock Reconciliation | SR | AZZ-SR-.YYYY.-.#### | — |
| Quotation | QT | AZZ-QT-.YYYY.-.#### | — |
| Material Request | MR | AZZ-MR-.YYYY.-.#### | — |
| Stock Transfer | ST | AZZ-ST-.YYYY.-.#### | — |
| Journal Entry | JV | AZZ-JV-.YYYY.-.#### | — |
| Sales Order | SO | AZZ-SO-.YYYY.-.#### | — |
| Purchase Order | PO | AZZ-PO-.YYYY.-.#### | — |
| Damage Slip | DS | AZZ-DS-.YYYY.-.#### | — |
| Damage Transfer | DT | AZZ-DT-.YYYY.-.#### | — |
| No VAT Sale | NVS | AZZ-NVS-.YYYY.-.#### | — |
📝 Branch Letterheads Admin
Each branch ships with a bilingual (English / Arabic) letterhead containing the company name, branch address, VAT number, CR number, and website. Branch-specific data — the address block in both languages and the mobile number — comes from the branch's letterhead record.
How Letterhead Resolution Works
- If the document has an explicit Letter Head field set, that one is used.
- Otherwise, the system looks up
RMAX - <Branch>matching the doc's branch (e.g.RMAX - Azzizziyah). - Falls back to the RMAX - Clear Light master letterhead if neither of the above exists.
Editing a Branch Letterhead
- Search Letter Head → open
RMAX - <Branch>. - Set Source to HTML (not Image).
- Edit the HTML body. Standard placeholders like
{{ company.company_name }},{{ company.tax_id }},{{ co_address.address_line1 }}are supported via Jinja. - Save.
👥 Branch User Role Admin
The Branch User role is automatically assigned when a user is added to a Branch Configuration. It grants permissions for daily branch operations.
Automatic Role Assignment
| Action | Result |
|---|---|
| Add user to Branch Configuration | "Branch User" role auto-assigned |
| Remove user from ALL Branch Configurations | "Branch User" role auto-removed |
Permission Matrix
| DocType | Read | Write | Create | Submit | Cancel |
|---|---|---|---|---|---|
| Sales Invoice | Yes | Yes | Yes | Yes | Yes |
| Quotation | Yes | Yes | Yes | Yes | No |
| Customer | Yes | Yes | Yes | - | - |
| Payment Entry | Yes | Yes | Yes | Yes | No |
| Purchase Receipt | Yes | Yes | Yes | Yes | Yes |
| Delivery Note | Yes | Yes | Yes | Yes | No |
| Purchase Invoice | Yes | Yes | Yes | Yes | No |
| Stock Transfer | Yes | Yes | Yes | Yes | No |
| Material Request | Yes | Yes | Yes | Yes | No |
| Item | Yes | No | No | - | - |
| Price List | Yes | No | No | - | - |
| Stock Entry | Yes | No | No | - | - |
| Inter Company Branch | Yes | No | No | - | - |
| No VAT Sale | No access — Sales Manager only (changed Apr 2026). | ||||
Three User Roles
| Role | Purpose |
|---|---|
| Branch User | Sales staff at branches. Full access to sales/purchase documents. Restricted on stock/cost data. |
| Warehouse User | Stock keepers. Can view MRs, create stock transfers, view stock reports. (Default ERPNext role) |
| Stock Manager | Full stock control. Can approve transfers, see all data. (Default ERPNext role) |
🔄 Inter Company Branch Admin
Used when you sell from one company to another (internal customer). This configuration tells the system which Cost Center and Warehouse to use when auto-creating the Purchase Invoice in the buying company.
Setup Steps
- Go to Inter Company Branch list and click + Add.
- Enter a Branch Name (e.g. "Jeddah Branch").
- In the Company Cost Centers table, add a row for each company involved:
• Select the Company (the buying company)
• Select the Cost Center for that company
• Select the Warehouse for that company - Save.
Auto-Created Purchase Invoice Details
| Field | Source |
|---|---|
| Supplier Invoice No | Sales Invoice name |
| Supplier Invoice Date | Sales Invoice posting date |
| Cost Center | Inter Company Branch → Company row |
| Warehouse | Inter Company Branch → Company row |
| Taxes | Default Purchase Taxes template for the buying company |
🔃 Workflows Admin
The Stock Transfer document uses an approval workflow.
Stock Transfer Workflow
| State | Who Can Act | What Happens |
|---|---|---|
| Draft | Any user | User creates and fills in the transfer details |
| Pending | Any user | Transfer submitted for approval |
| Approved | Approver role | Stock Entry (Material Transfer) is auto-created and submitted |
| Rejected | Approver role | Transfer is rejected, no stock movement |
💰 Sales Invoice — Cash Mode
The most common daily operation. Create a sales invoice with cash payment.
Step-by-Step
- Open a New Sales Invoice. The Company, Warehouse, and Cost Center will auto-fill from your branch defaults.
- Set Payment Mode to Cash.
- Select or create a Customer. (You can use the "Create New Customer" button to quickly add one.)
- Add items to the Items table. Use Enter to move between columns and rows.
The system will check stock automatically and warn you if quantity exceeds available stock. - Click Save. A Payment Popup will appear.
- In the popup, allocate payment amounts across different payment modes (Cash, Card, etc.):
• Click a payment mode button to fill the full amount to that mode
• Or click the input field to auto-fill the remaining balance
• You can split payments across multiple modes - Click Save & Submit to submit the invoice and create Payment Entries automatically.
💳 Sales Invoice — Credit Mode
For credit sales where the customer pays later.
Step-by-Step
- Create a New Sales Invoice as usual.
- Set Payment Mode to Credit.
- Notice that the Customer dropdown is now filtered to show only customers with a credit limit.
- Select a customer and add items.
- Click Save. A confirmation dialog will ask: "Do you want to Submit this Sales Invoice now?"
• Click Yes to submit immediately
• Click No to save as draft
💸 Tabby / Tamara BNPL — Overview
RMAX accepts Tabby and Tamara as BNPL (Buy Now Pay Later) payment methods. Both providers deduct an 8% commission when they settle to RMAX's bank, so the selling price is automatically uplifted by 8.6957% (÷ 0.92) on the post-discount rate. The customer pays the uplifted amount via Tabby/Tamara; the provider deducts 8% and remits the original intended amount to RMAX. The uplift is applied only to the BNPL-funded portion of the invoice — cash or card splits are not affected.
base_rate / 0.92.How money flows
- Customer buys goods worth SAR 100 (post-discount). Invoice is raised at SAR 108.70 with Tabby as Mode of Payment.
- Tabby pays the customer's instalments and holds the SAR 108.70 in a clearing account.
- 1–2 days later Tabby remits SAR 100.00 net to RMAX's bank, after deducting their 8% commission (SAR 8.70).
- Accounts team opens a new Journal Entry (Bank Entry) and clicks Load BNPL Settlement — dialog asks for Mode of Payment + Bank Account, pre-fills three rows (Dr Bank, Dr BNPL Fee Expense, Cr Tabby Clearing). Operator types the actual amounts from the provider statement and submits.
- Net P&L impact: gross profit on the original SAR 100 sale is preserved — the surcharge collected exactly offsets the provider's commission.
⚙ BNPL Setup Admin
One-time configuration per Company. The Chart of Account heads listed below are auto-created by the app on the next bench migrate. The accountant only needs to wire them to the right Mode of Payment / Company records.
Step 1 — Account heads (auto-created per Company)
The app provisions these accounts the first time it migrates after install. Replace <abbr> with the Company abbreviation (e.g. R for "RMAX").
| Account Name | Parent Group | Account Type | Root Type | Purpose |
|---|---|---|---|---|
Tabby Clearing - <abbr> |
Bank Accounts | Bank | Asset | Holds gross Tabby receivable between SI submit and settlement. |
Tamara Clearing - <abbr> |
Bank Accounts | Bank | Asset | Holds gross Tamara receivable between SI submit and settlement. |
BNPL Fee Expense - <abbr> |
Indirect Expenses | Expense Account | Expense | Records provider commission (Tabby/Tamara fees) on settlement. |
Tabby - <abbr> as a Receivable account, ERPNext will refuse to auto-post the Payment Entry on Sales Invoice submit ("Customer is required against Receivable account..."). Switch to a Bank-type clearing account using the auto-created Tabby Clearing - <abbr>.Step 2 — Configure Mode of Payment (Tabby, Tamara)
For each BNPL provider:
- Go to Accounting → Mode of Payment. Open Tabby (create the record if it does not exist; type = General).
- Set Surcharge Percentage =
8.6957. - Set BNPL Clearing Account =
Tabby Clearing - <abbr>. - In the standard Accounts child table at the bottom, add a row per Company: Default Account = the same
Tabby Clearing - <abbr>. This is what ERPNext uses when auto-creating the Payment Entry on SI submit. - Save.
- Repeat for Tamara using
Tamara Clearing - <abbr>and the same Surcharge Percentage.
Step 3 — Verify Company default fee account
The app sets Company.custom_bnpl_fee_account automatically the first time it provisions accounts. To check or change it:
- Open Accounting → Company → <your company>.
- Scroll to the section containing BNPL Fee Expense Account.
- Confirm it points to
BNPL Fee Expense - <abbr>. Change it if your CoA uses a different head. - Save.
Step 4 — Smoke test
Create a small test Sales Invoice (1 item, SAR 100, Customer = a real customer with credit limit). Use Cash mode first to confirm normal POS flow works. Then create a fresh test invoice with Tabby and verify:
- Item rate jumps from
100.00to108.70when Tabby is selected. - The Original Rate (Pre-Uplift) column shows
100.00on the item line. - The BNPL Portion Ratio field on the parent shows
100.0000%. - On Submit, no "Customer is required against Receivable" error appears.
- General Ledger shows: Dr Tabby Clearing 108.70 (gross), Cr Customer Receivable 108.70.
💰 BNPL on Sales Invoice
Day-to-day invoice flow for cashiers and sales users. The uplift is fully automatic — no manual rate adjustment is required.
Full BNPL payment (100% Tabby or Tamara)
- Create a New Sales Invoice as usual. Set Payment Mode = Cash (the existing RMAX category, kept separate from BNPL).
- Add the customer and the items. Apply any line discount or invoice discount first; the uplift always operates on the post-discount rate.
- In the POS-style Enter Payment Amounts popup, set the full invoice total against Tabby (or Tamara). Cash row should be
0.00. - The line rates jump up by ÷ 0.92 in real time. The BNPL Portion Ratio shows
100%. - Click Save & Submit.
Split payment (cash + BNPL)
Example: SAR 1,000 invoice paid SAR 400 cash + SAR 600 Tabby.
- Add Cash row = SAR 400. Add Tabby row = SAR 600.
- BNPL Portion Ratio = 60%. Effective uplift factor = 1 + (0.60 × 0.086957) =
1.05217. - Each line rate is uplifted by 5.217% — the cash portion is not uplifted, only the Tabby-funded share. The customer-facing invoice shows a single uplifted total.
Returns / Credit Notes
When you return a Tabby-paid invoice through the standard Create → Return / Credit Note action, the credit note inherits the uplifted rates from the parent invoice. The customer is refunded the amount they originally paid through the BNPL provider, not the pre-uplift rate. No manual adjustment is needed.
Audit fields on the invoice
- BNPL Portion Ratio (parent) — proportion of the invoice funded via BNPL. Read-only.
- Original Rate (Pre-Uplift) (item line) — the post-discount rate before uplift. Used for audit.
- BNPL Uplift Amount (item line) — absolute SAR uplift on that line. Used by reports.
- BNPL Portion Ratio + BNPL Total Uplift (parent) — bookkeeping figures used by the Surcharge Collected report. (Settlement-link fields were removed Apr 2026 — reconciliation now happens via Bank Reconciliation against the clearing account.)
💵 BNPL Settlement (Manual JE) Accounts
Used when Tabby/Tamara wires the net amount (gross − commission) to RMAX's bank account, typically 1–2 working days after the sale. Settlement is recorded as a plain Journal Entry (Bank Entry) with the three account heads pre-filled by the Load BNPL Settlement button.
Step-by-Step
- Open a new Journal Entry. Set Voucher Type = Bank Entry (or Journal Entry) and pick the Company.
- Click the Load BNPL Settlement button in the toolbar.
- In the dialog, pick the Mode of Payment (Tabby or Tamara). The dialog shows the resolved Clearing Account, Currency, and live GL Balance for context.
- Pick the Bank Account that received the provider's payout.
- Click Load Heads. The system clears any existing accounts table and inserts three rows: Dr Bank, Dr BNPL Fee Expense, Cr Clearing.
- Type the actual amounts from the Tabby / Tamara settlement statement: bank credit (net), fee (commission), clearing credit (gross = bank + fee). The Difference column should be zero.
- Optionally attach the provider's settlement statement PDF / CSV under Attachments.
- Click Save, review for any orange warnings, then Submit.
📊 BNPL Reports
BNPL Surcharge Collected
Lists submitted BNPL invoices with the SAR uplift attributed per Mode of Payment (Tabby / Tamara), based on the POS payment snapshot stamped at sale time. Use it to reconcile the surcharge collected against the provider's commission deductions on settlement statements — the two should match closely.
Filters: Company (required), From Date, To Date, Mode of Payment.
Columns: Sales Invoice, Posting Date, Customer, Mode of Payment, BNPL Uplift Attributed, Original Items Total.
🔒 No VAT Sale Sales Manager
The No VAT Sale doctype books a non-VAT-able cash sale. On submit it posts a Journal Entry (cash receipt) and a Stock Entry (Material Issue) against the company’s Naseef & Damage Written Off accounts.
Approval Workflow
Every No VAT Sale moves through a four-state workflow before it submits:
| Status | Who acts | What happens |
|---|---|---|
| Draft | Creator | Fill items, pick branch + warehouse + approver, click Send for Approval. |
| Pending Approval | Named approver | Receives a ToDo + email assignment. Clicks Approve & Submit (with optional remarks) or Reject (mandatory reason). |
| Approved | System | Doc is submitted. JE + SE post automatically. |
| Rejected | Creator | Doc stays Draft with reason. Creator edits and resends. |
Step-by-Step (Creator)
- Open No VAT Sale → + New.
- Pick Branch. The Warehouse dropdown is now restricted to that branch’s configured warehouses.
- Pick Warehouse, customer name, mode of payment.
- Add item rows. Selling rate auto-fetches from No VAT Price price list, valuation rate from the Bin.
- Pick Approved By. Required.
- Save the draft.
- Click Approval → Send for Approval. Status flips to Pending Approval and the approver gets notified.
Step-by-Step (Approver)
- Open the ToDo or click the email link.
- Review items, totals, and warehouse.
- Click Approval → Approve & Submit. Optional remarks dialog. Doc is submitted; JE + SE post.
- Or click Approval → Reject. Mandatory reason. Doc stays Draft, creator can edit + resend.
👤 Create Customer (Quick)
Create a new customer directly from the Sales Invoice without leaving the form.
Step-by-Step
- On a new Sales Invoice, click the + Create New Customer button above the Customer field.
- Fill in the dialog:
• Customer Name (required)
• Mobile No (required)
• Email ID (optional)
• VAT Registration Number (optional, exactly 15 digits) - If VAT number is entered, address fields become mandatory:
• Address Line 1, Building Number, Area/District, City, Country, Postal Code - Click Create Customer.
- The new customer is automatically set on the Sales Invoice.
📦 Warehouse Stock Panel
See real-time stock levels across all warehouses when selecting items on Sales Invoice.
How It Works
- On a Sales Invoice (or Quotation), click on an item row in the Items table.
- A stock panel appears below the items table showing stock quantities across all warehouses.
- The currently selected warehouse is highlighted.
- Click on any warehouse row to set that warehouse on the item.
- Click Show All to see all warehouses (default shows top 5).
🚚 Material Request (Transfer)
Request stock to be transferred from one warehouse to another. The default type is set to "Material Transfer".
Step-by-Step
- Open a New Material Request. The type defaults to Material Transfer.
- The Target Warehouse (Set Warehouse) auto-fills from your default warehouse permission.
- Select the Source Warehouse (Set From Warehouse). It is filtered to exclude the target warehouse.
- Add items and quantities. Schedule Date is auto-set to today.
- Save and Submit.
📦 Stock Transfer
Transfer stock between warehouses with an approval workflow. When approved, a Stock Entry is automatically created.
Step-by-Step (Requester)
- Open a New Stock Transfer.
- The Source Warehouse auto-fills from your default warehouse.
- Select the Target Warehouse (filtered to exclude source, ignores user permissions so you can send to any warehouse).
- Add items: select Item Code, set Quantity, and choose UOM (filtered to the item's available UOMs).
- Save to create as Draft.
- Click Submit to send for approval (state changes to Pending).
Step-by-Step (Approver)
- Open the Stock Transfer in Pending state.
- Review the items and quantities.
- Click Approve to approve — a Stock Entry (Material Transfer) is automatically created and submitted.
- Or click Reject to reject the transfer.
📜 Purchase Receipt — Final GRN
Replace an existing Purchase Receipt with a corrected one. The original is automatically cancelled when the new one is submitted.
Step-by-Step
- Open the existing Purchase Receipt you want to replace.
- Click Create → Final GRN.
- A new Purchase Receipt opens with all data copied:
• Header fields (supplier, company, currency, etc.)
• All item rows with quantities, rates, and warehouses
• Tax rows
• Posting time is set to 10 minutes before the original - Make your corrections (edit quantities, items, etc.).
- Click Submit.
- The original Purchase Receipt is automatically cancelled (if submitted) or deleted (if draft).
📋 Bulk Purchase Invoice
Create a single Purchase Invoice from multiple Purchase Receipts at once.
Step-by-Step
- Go to the Purchase Receipt list.
- Select multiple Purchase Receipts using the checkboxes (they must be from the same supplier).
- Click Actions → Create Single Purchase Invoice.
- Confirm the action. A single Purchase Invoice is created with all items from all selected receipts.
- A success message with a link to the new Purchase Invoice appears.
📄 Quotation to Sales Invoice
Convert a submitted Quotation directly into a Sales Invoice.
Step-by-Step
- Open a submitted Quotation.
- Click Create → Sales Invoice.
- A new Sales Invoice opens with all items and details mapped from the Quotation.
- Review, adjust if needed, and Save/Submit.
🖶 Landed Cost Voucher — CBM Distribution
Distribute landed costs across items proportionally based on their CBM (Cubic Meters) values, instead of the standard Qty or Amount methods.
Step-by-Step
- Open a Landed Cost Voucher and add the Purchase Receipt(s).
- Set Distribute Charges Based On to Distribute Manually.
- Check the Distribute by CBM checkbox (appears after selecting Distribute Manually).
- In the items table, enter the CBM value for each item.
- Add the tax/charge row in the Taxes and Charges table.
- The Applicable Charges column auto-fills proportionally based on each item's CBM ratio.
- Save and Submit.
📋 LCV Charge Template & Purchase Receipt Checklist
Load the standard import charges (Freight, Duty, Port, Mawani, etc.) onto a Purchase Receipt with one click, and track whether every charge has been booked via a Landed Cost Voucher.
Pick a template on the PR
- Open any Purchase Receipt and expand the LCV Charges Checklist section.
- Select LCV Charge Template — the default Standard Import KSA ships with 11 charges.
- Save the PR. The checklist populates with each charge + the correct expense account for the PR's company.
- A coloured indicator appears at the top of the form showing the status:
- Not Started — no charge booked yet (grey).
- Pending — mandatory charges missing (red).
- Partial — mandatory charges done, optional still pending (orange).
- Complete — every charge booked (green).
Create the LCV from the template
- From the PR, click LCV Checklist → Create LCV from Template.
- A Draft Landed Cost Voucher opens pre-populated with only the pending charges (already-booked rows are skipped).
- If every pending charge is CBM-based, the LCV is pre-set to Distribute Manually + Distribute by CBM.
- Enter the actual shipment amounts for each row and submit.
- Back on the PR, the indicator flips to Complete and each checklist row shows the LCV reference + amount.
Exchange Rate field; enter the rate so the SAR base amount posts correctly.Standard Import KSA — shipped charges
Every Company gets these 11 expense accounts (under Indirect Expenses → Landed Cost Charges) and one template row each:
| # | Charge | Currency | Distribute By |
|---|---|---|---|
| 1 | Freight Sea/Air | USD | CBM |
| 2 | Duty | SAR | Value |
| 3 | DO Charges | SAR | CBM |
| 4 | Port Charges | SAR | CBM |
| 5 | Mawani | SAR | CBM |
| 6 | Fasah Appointment Fees | SAR | CBM |
| 7 | Custom Clearance Charges | SAR | CBM |
| 8 | Transportation to Warehouse | SAR | CBM |
| 9 | Doc Charges | SAR | CBM |
| 10 | Local Unloading Expense | SAR | CBM |
| 11 | Overtime (Kafeel) | SAR | CBM |
Duplicate the template if you need a variant (e.g. Air-only, road freight) — copy Standard Import KSA, rename, tweak rows. The app will never overwrite a template that isn't the shipped default.
Example — one shipment, three items
| Item | CBM | Share of 100 |
|---|---|---|
| LED Panel | 5 | 50% |
| Spot Light | 3 | 30% |
| UFO 300W | 2 | 20% |
If Freight = 2,500 SAR (after exchange), Port = 800 SAR, Mawani = 300 SAR (total 3,600 SAR), the app distributes each charge by the CBM share:
- LED Panel absorbs 1,800 SAR (50%)
- Spot Light absorbs 1,080 SAR (30%)
- UFO 300W absorbs 720 SAR (20%)
Stock valuations (Stock In Hand Dr) increase by those amounts; each expense account (Freight, Port, Mawani) is credited with its own GL entry.
✅ VAT & Contact Validation
The system enforces Saudi VAT and phone number rules automatically.
VAT Rules (Customer)
| Rule | Detail |
|---|---|
| Digits only | Only numeric characters allowed in VAT field |
| Exactly 15 digits | VAT must be exactly 15 digits to save |
| Unique | No two customers (except "Branch" type) can have the same VAT number |
Phone Number Rules
| Rule | Detail |
|---|---|
| Minimum 10 digits | Both mobile and phone numbers must have at least 10 digits |
| Validated on | Customer form (primary contact) and Contact form (all phone numbers) |
Customer Type
Customer Type options include: Company, Individual, Partnership, Branch.
Duplicate VAT — Sales Manager Override
Genuine cases exist where two Customer records share one VAT number (e.g. subsidiaries under one parent legal entity, the same VAT-registered chain invoicing under two storefronts). Without an override the system rejects the second Customer with:
VAT Registration Number already used by Customer: CUST-0042. A Sales Manager can tick 'Allow Duplicate VAT' to override.
Roles allowed to unlock: Sales Manager, Sales Master Manager, System Manager.
- Open the new Customer (the one you are trying to save).
- Tick Allow Duplicate VAT (Manager Override).
- Fill Duplicate VAT Reason — mandatory. Example: "Branch of CUST-0042, same legal entity, separate storefront".
- Save. The duplicate check is skipped for this Customer only.
💰 Sales Invoice Defaults & Update Stock Lock
Every new Sales Invoice already ships ready for over-the-counter sales — operators only pick customer + items.
What is pre-filled on a new SI
| Field | Default |
|---|---|
| Update Stock | Ticked on |
| Source Warehouse | User's default warehouse (from their branch configuration) |
Branch User lock
For plain Branch Users the Update Stock field is read-only. This prevents accidental credits that skip stock movement. A description appears under the field: “Locked for Branch Users. Contact a Sales Manager to change.”
Users who hold any of these additional roles can still untick the field when needed: Sales Manager, Sales Master Manager, Stock Manager, System Manager, Administrator.
Why this matters
When Update Stock is ticked, submitting the Sales Invoice reduces stock in the selected warehouse immediately — no separate Delivery Note needed. Useful for counter / cash sales.
When it is unticked, stock stays put and you are expected to create a Delivery Note to dispatch goods later (credit-sale flow).
💼 HR Defaults (Sponsorship / Non-Sponsorship) Admin
The app ships a first-run HR seed so the client can start running payroll immediately on new companies.
What gets created
- Employee Grades: Sponsorship, Non-Sponsorship.
- Salary Components: Basic, Housing Allowance, Transportation Allowance, Food Allowance, Other Allowance, GOSI Employee.
- Salary Structure:
RMAX Sponsorship KSA - <CompanyAbbr>per Company, in Draft. Split shown below. - No default structure for Non-Sponsorship — attach a custom one per employee if needed.
Sponsorship structure — sample payout on base 10,000 SAR
| Component | Formula | Amount (SAR) |
|---|---|---|
| Basic | base * 0.60 | 6,000 |
| Housing Allowance | base * 0.25 | 2,500 |
| Transportation Allowance | base * 0.10 | 1,000 |
| Food Allowance | base * 0.05 | 500 |
| Gross | 10,000 |
Enter a monthly base figure on the Salary Structure Assignment for an employee and the components compute automatically. GOSI Employee (deduction) is not pre-filled — add it per employee nationality (Saudi / GCC / expat rules differ).
What to do on day one
- Open HR → Employee Grade — confirm Sponsorship / Non-Sponsorship exist.
- Open Salary Structure → RMAX Sponsorship KSA - <CompanyAbbr> (Draft). Review earnings, add deductions if required (GOSI, advances, etc.), then Submit.
- For each expat employee, create a Salary Structure Assignment picking the shipped structure + entering their monthly
base. - Non-Sponsorship employees: create a matching Salary Structure (free form) and assign it separately.
bench migrate.bench --site <site> execute rmax_custom.hr_defaults.reset_sponsorship_salary_structures --kwargs '{"force": 1}'. The helper refuses to delete submitted structures or those already assigned to an employee.🔄 Inter-Company Delivery Notes → Consolidated Sales Invoice Accounts
RMAX trades stock between sister Companies (e.g. Head Office ↔ Clearlight Munavar). Goods move via Delivery Notes first, then accounts batches multiple DNs into a single Sales Invoice on the selling side. The system auto-creates the matching Purchase Invoice on the buying side.
Setup (one-time)
- Open Inter Company Branch master → create one row per (Selling Company, Buying Company) pair. Set the cost center + warehouse the buying side will use when its PI is auto-created.
- Ensure the Inter Company Price price list exists (auto-created by
after_migrate) and item rates are loaded for inter-company prices. - Mark the customer record as Internal Customer + set Represents Company on the customer for the buying side.
Daily Flow
- Branch creates Delivery Note(s) as usual. For inter-company DNs, tick Is Inter-Company and set Inter-Company Branch on the DN. Submit (stock leaves the selling company’s warehouse).
- Accounts opens the Delivery Note list. Select 2+ submitted inter-company DNs that share the same Customer, Represents Company, Currency, and Inter-Company Branch.
- Click the list action Create Inter-Company SI.
- System builds one Draft Sales Invoice on the selling side:
- Taxes inherited from the first selected DN.
- Cost Center + Source Warehouse pulled from Inter Company Branch for the selling Company.
- Update Stock = OFF (DNs already moved stock; this SI is purely the inter-company invoice).
- Each row mirrors the underlying DN row at the inter-company Price List rate.
- Each source DN gets stamped: Inter-Company SI = the new SI, Inter-Company Status = Consolidated. They are now locked from being batched again.
- Review the Draft SI → Submit. On submit:
- System auto-creates the matching Purchase Invoice on the buying Company.
- Buying side’s PI uses the cost center + warehouse from Inter Company Branch.
- If the SI is a return, the system links to the original PI and sets Is Return on the PI side too.
Validation Rules
- Selected DNs must be submitted (docstatus=1).
- Each must have Is Inter-Company ticked.
- All must share the same Customer, Represents Company, Currency, and Inter-Company Branch.
- None already linked to a non-cancelled SI via Inter-Company SI.
- Inter Company Branch master must have a row for the selling Company with valid Cost Center + Warehouse for the buying side.
Any violation aborts the batch with a clear message.
⚠ Damage Workflow Branch + Damage User
Three-step process to move damaged stock out of branch warehouses, inspect, and write off the loss to a dedicated GL account. Tracks supplier code + photo evidence per item for audit.
Roles & DocTypes
| DocType | Naming | Created by | Action |
|---|---|---|---|
| Damage Slip | DS-##### | Branch User | Records damaged items at the branch warehouse. |
| Damage Transfer | DT-##### | Damage User | Pulls in pending slips, inspects, posts Stock Entry to Damage warehouse. |
| Stock Entry (Material Issue) | auto-created | System / Admin | Write-off to Damage Loss Account. |
Step 1 — Branch User: Damage Slip
- Open Damage Slip → New.
- Pick Branch Warehouse (the branch warehouse where the damaged stock currently sits).
- Pick Damage Warehouse (filtered to Damage Jeddah - CNC or Damage Riyadh - CNC).
- Add item rows (item code + qty).
- Save + Submit. Status flips to Pending.
Step 2 — Damage User: Damage Transfer (inspection)
- Open Damage Transfer → New.
- Pick the Damage Warehouse.
- Click Get Pending Slips — pulls in submitted Damage Slips for that warehouse.
- For each item row: attach at least one image (proof of damage) and pick the Supplier Code (Clear Desk / Clear Light / RMAX / Clear Desk USD).
- Save + Submit. The system auto-creates a Stock Entry (Material Transfer) moving items from the branch warehouse → Damage warehouse.
- Linked Damage Slips switch from Pending to Transferred.
Step 3 — Admin: Write Off
- Open the submitted Damage Transfer.
- Click Write Off (top-right action button).
- System creates a Stock Entry (Material Issue): Dr Damage / Loss Account, Cr Stock In Hand. Quantity leaves the Damage warehouse permanently.
- Damage Transfer status → Written Off.
Selling Damaged Stock as Scrap
If damaged items still have salvage value (e.g. metal scrap, returnable shells), see the Scrap Sale section. Sell from the Damage warehouse (where items sit after Damage Transfer) instead of writing them off — preserves the recoverable value as scrap revenue.
📱 Damage PWA — Mobile App Damage User
The Damage PWA lets Damage Users capture inspection photos and submit Damage Transfers from a mobile device without opening the full ERP desk.
Install on Android (APK)
- Download the latest APK from GitHub Releases → v1.0.19.
- On the device: Settings → Security → Install from unknown sources (enable).
- Open the downloaded
rmax-wh-v1.0.19.apkand tap Install. - App name: RMAX WH. Points to
rmaxerp.enfonoerp.com.
Each update is a new APK download. Check Releases page for the latest version.
Install on iOS / Any Browser (PWA)
- Open Safari on the iPhone (must be Safari for Add to Home Screen).
- Go to:
https://rmaxerp.enfonoerp.com/damage-pwa - Tap the Share icon → Add to Home Screen.
- The PWA appears as an app icon on the home screen.
Login
- Use your ERP username and PIN (set under your User profile in the ERP).
- The app works online only — an active internet connection is required.
📊 Inter-Branch Receivables & Payables Accounts
When a single Company runs multiple branches (Head Office, Riyadh, Jeddah, Snowlite, Malaz, Bahra…), every cross-branch transaction must show in each branch’s own books even though the consolidated company books stay balanced. This module captures those obligations automatically — you record the actual business event, the system adds the matching Due-from / Due-to legs in the background.
One-Time Setup
- Foundation accounts (Inter-Branch Receivable — Asset, group, under Current Assets — and Inter-Branch Payable — Liability, group, under Current Liabilities) are created automatically per root Company by
after_migrate. - Per-counterparty leaf accounts (Due from <Branch>, Due to <Branch>) are created lazily the first time they’re needed, plus immediately when a new Branch is added.
- Open Company → pick the Company → set Inter-Branch Cut-Over Date. Auto-injector is now ON for entries on/after this date.
- For multi-branch (3+) Journal Entries, set Inter-Branch Bridge Branch on the Company. Every other branch in the JE pairs against the bridge.
Scenario A — HO pays rent for Branch Riyadh
- Open Accounting → Journal Entry → New.
- Pick Posting Date and Company.
- Add line 1:
Rent Expense, Debit 1,000, Branch = Riyadh. - Add line 2:
HO Bank Account, Credit 1,000, Branch = HO. - Save.
The system auto-adds:
| Account | Branch | Dr | Cr |
|---|---|---|---|
| Rent Expense | Riyadh | 1000 | |
| HO Bank Account | HO | 1000 | |
| Due to HO | Riyadh | 1000 | |
| Due from Riyadh | HO | 1000 |
Submit the JE. Each branch’s books balance independently; consolidated still nets to zero.
Scenario B — Cash transfer HO → Branch
Same flow as A: enter Riyadh Bank Dr 5000, HO Bank Cr 5000. System adds the Due-from/Due-to legs.
Scenario C — Stock transfer between branches (automatic)
Two routes, identical accounting:
- Stock Transfer workflow (preferred for branch users): Material Request → Stock Transfer → Approval. On approval, the system creates the Stock Entry as usual. If source warehouse and target warehouse belong to different branches, a companion Journal Entry records the inter-branch obligation at valuation cost. Source DocType =
Stock Transfer. - Direct Stock Entry (Material Transfer): Stock Manager opens Stock Entry directly. On submit the system resolves each warehouse → Branch via Branch Configuration. Same-branch warehouse pair (e.g. WH-HO-1 ↔ WH-HO-2 both under HO) — no companion JE. Cross-branch — system re-tags the SE’s own GL legs by branch and creates the companion JE. Source DocType =
Stock Entry.
Cancelling the source document (Stock Transfer or Stock Entry) auto-cancels the companion JE.
Multi-Branch (3+) JEs — Bridge Mode
If a single JE involves 3 or more branches, the system needs an explicit pivot to know how to pair Due-from/Due-to legs. Set Inter-Branch Bridge Branch on the Company (typically HO) and ensure the bridge is one of the branches in the JE. Every non-bridge branch is then paired against the bridge.
Without a bridge configured, the system rejects 3+ branch JEs with a clear error so you don’t accidentally post unbalanced per-branch books.
Reconciliation Report
Open Reports → Inter-Branch Reconciliation. Matrix view: rows = from branch, columns = to branch, cells = net Due balance for the period. Health check: every (A→B + B→A) pair must sum to zero — non-zero rows flag missing reversals or unmatched legs.
Roles: Accounts Manager, Accounts User, Auditor, System Manager.
🔍 Branch-wise List Filtering
Branch Users automatically see only documents related to their branch. No manual filtering needed.
Filtered DocTypes
| DocType | Filter Logic |
|---|---|
| Sales Invoice | Items warehouse matches branch warehouse, OR user is the creator |
| Purchase Invoice | Items warehouse matches branch warehouse, OR user is the creator |
| Delivery Note | Items warehouse matches branch warehouse, OR user is the creator |
| Purchase Receipt | Items warehouse matches branch warehouse, OR user is the creator |
| Payment Entry | User is the creator |
| Quotation | User is the creator |
Sales Invoice List — Extra Filters
The Sales Invoice list view includes additional standard filters in the header:
| Filter | Description |
|---|---|
| Grand Total | Filter invoices by total amount (with tax) |
| Total Qty | Filter by total quantity of items |
| Contact Mobile | Search by customer mobile number |
🛠 Architecture Overview Developer
Technical architecture of the RMAX Custom app for ERPNext v15.
App Structure
rmax_custom/ ├── hooks.py # App config: JS includes, doc_events, fixtures, permissions ├── setup.py # after_migrate: Branch User role + DocType permissions ├── inter_company.py # Auto PI creation on SI submit ├── landed_cost.py # LCV distribution helper ├── branch_defaults.py # Cost center override for branch users ├── branch_filters.py # permission_query_conditions for list filtering ├── overrides/ │ └── landed_cost_voucher.py # LCV class override (CBM distribution) ├── api/ │ ├── customer.py # Quick customer creation + VAT validation │ ├── sales_invoice_payment.py # POS payment popup backend │ ├── warehouse_stock.py # Stock balance across warehouses │ ├── material_request.py # MR creation API │ ├── purchase_invoice.py # Bulk PI from multiple PRs │ └── item.py # Party Specific Item creation ├── public/js/ │ ├── enter_navigation_global.js # Global Enter key → Tab behavior │ ├── warehouse_stock_popup.js # Stock panel below items grid │ ├── sales_invoice_pos_total_popup.js # POS payment dialog │ ├── sales_invoice_popup.js # SI form enhancements │ ├── create_customer.js # Quick customer dialog on SI │ ├── create_multiple_supplier.js # Bulk supplier linking on Item │ ├── materiel_request.js # MR warehouse defaults │ ├── vat_validation.js # Customer VAT + phone rules │ ├── contact_validation.js # Contact phone validation │ ├── item_branch_user.js # Hide cost fields for Branch User │ ├── purchase receipt.js # Final GRN flow │ ├── purchase_receipt_list.js # Bulk PI from list │ ├── material_request_list.js # Urgent indicator │ ├── sales_invoice_list.js # Extra list filters │ └── landed_cost_voucher.js # CBM distribution client ├── rmax_custom/ │ ├── doctype/ │ │ ├── branch_configuration/ # Branch → Company/WH/CC/Users mapping │ │ ├── inter_company_branch/ # Inter-company CC/WH config │ │ ├── stock_transfer/ # Custom transfer with approval workflow │ │ └── (child tables) # Config User/WH/CC, ST Item, IC Branch CC │ └── custom_scripts/quotation/ # Create SI from Quotation button └── fixtures/ ├── workflow.json # Stock Transfer workflow (4 states) ├── role.json # Branch User role definition ├── custom_field.json # Custom fields (payment mode, CBM, VAT, urgent) └── property_setter.json # Field tweaks (MR defaults, SI filters, customer type)
Data Flow Diagrams
Sales Invoice (Cash) Flow
User creates SI (Cash mode)
→ Items added (stock check + warehouse popup)
→ Click Submit → Payment Popup appears
→ Allocate amounts across payment modes
→ "Save & Submit"
→ before_validate: cost center override (branch_defaults.py)
→ SI saved + submitted
→ Payment Entries auto-created (one per mode)
→ on_submit: if inter-company → auto-create draft PI (inter_company.py)
Branch Configuration Flow
Admin saves Branch Configuration
→ validate(): check WH/CC belong to Company
→ before_save(): delete permissions for removed users
→ on_update() → create_permissions():
→ User Permission: Company (is_default=1)
→ User Permission: Branch
→ User Permission: Warehouse (first=default)
→ User Permission: Cost Center (first=default)
→ User Permission: Company default CC (is_default=0, access only)
→ Assign "Branch User" role to user
Stock Transfer Approval Flow
User creates Stock Transfer → Draft → Send For Approval → Pending → Target branch user opens it → validate(): check user in target branch's Branch Configuration → Approve → on_submit() → create Stock Entry (Material Transfer) → OR Reject → stays as draft
🔗 Hooks & Events Developer
All Frappe hooks configured by the app.
app_include_js (loaded on every desk page)
| File | Purpose |
|---|---|
| enter_navigation_global.js | Global Enter key → Tab navigation |
| warehouse_stock_popup.js | Stock display panel below items grid |
| sales_invoice_pos_total_popup.js | POS payment popup for Cash mode |
| sales_invoice_popup.js | SI: New Invoice button, update_stock, stock check |
| create_customer.js | Quick customer creation from SI |
| create_multiple_supplier.js | Bulk supplier linking on Item |
| materiel_request.js | MR: default warehouse, query filters |
| vat_validation.js | Customer VAT + phone validation |
| contact_validation.js | Contact phone validation |
| item_branch_user.js | Hide cost fields for Branch User |
doc_events (server-side hooks)
| DocType | Event | Handler | Logic |
|---|---|---|---|
| Sales Invoice | before_validate | branch_defaults.override_cost_center_from_branch | Replace inaccessible cost centers with user's default |
| Sales Invoice | on_submit | inter_company.sales_invoice_on_submit | Auto-create draft Purchase Invoice for internal customers |
| Purchase Invoice | before_validate | branch_defaults.override_cost_center_from_branch | Same cost center override |
| Payment Entry | before_validate | branch_defaults.override_cost_center_from_branch | Same cost center override |
| Delivery Note | before_validate | branch_defaults.override_cost_center_from_branch | Same cost center override |
| Purchase Receipt | before_validate | branch_defaults.override_cost_center_from_branch | Same cost center override |
permission_query_conditions (list filtering)
| DocType | Handler | Logic |
|---|---|---|
| Sales Invoice | branch_filters.si_permission_query | Filter by branch WH (items/set_warehouse) OR owner |
| Purchase Invoice | branch_filters.pi_permission_query | Same warehouse-based filter |
| Delivery Note | branch_filters.dn_permission_query | Same warehouse-based filter |
| Purchase Receipt | branch_filters.pr_permission_query | Same warehouse-based filter |
| Payment Entry | branch_filters.pe_permission_query | Owner-only filter |
| Quotation | branch_filters.quotation_permission_query | Owner-only filter |
override_doctype_class
| DocType | Override Class | Purpose |
|---|---|---|
| Landed Cost Voucher | rmax_custom.overrides.landed_cost_voucher.LandedCostVoucher | CBM-based charge distribution |
after_migrate
| Handler | Purpose |
|---|---|
| rmax_custom.setup.after_migrate | Create/update Custom DocPerm records for Branch User role (14 DocTypes) |
🔌 API Reference Developer
All whitelisted API endpoints provided by the app.
Customer APIs
| Endpoint | Parameters | Returns |
|---|---|---|
| rmax_custom.api.customer.create_customer_with_address | customer_name, mobile_no, email_id, address fields, VAT, country | {customer, address, message} |
| rmax_custom.api.customer.validate_vat_customer | vat, customer_type, name | Throws if duplicate |
| rmax_custom.api.customer.validate_phone_numbers | mobile_no, phone_no | Throws if <10 digits |
Payment APIs
| Endpoint | Parameters | Returns |
|---|---|---|
| rmax_custom.api.sales_invoice_payment.get_payment_modes_with_account | company, mode_list (optional) | List of valid mode names |
| rmax_custom.api.sales_invoice_payment.create_pos_payments_for_invoice | sales_invoice, payments (JSON array) | List of created PE names |
Stock & Item APIs
| Endpoint | Parameters | Returns |
|---|---|---|
| rmax_custom.api.warehouse_stock.get_item_warehouse_stock | item_code, company, limit, target_warehouse | List of {warehouse, stock_qty} |
| rmax_custom.api.material_request.create_material_request | item_code, from/to warehouse, qty, schedule_date, company | MR name |
| rmax_custom.api.purchase_invoice.create_single_purchase_invoice | receipt_names (JSON array) | PI name |
| rmax_custom.api.item.create_party_specific_items | item, suppliers (JSON array) | "Done" |
| rmax_custom.rmax_custom.doctype.stock_transfer.stock_transfer.get_item_uom_conversion | item_code, uom | Conversion factor (float) |
🔒 Permission System Developer
How the multi-layer permission system works together.
Layer 1: User Permissions (from Branch Configuration)
When a Branch Configuration is saved, these User Permissions are created per user:
| Allow | Value | is_default | Purpose |
|---|---|---|---|
| Company | Branch company | 1 | Default company for new docs |
| Branch | Branch name | 0 | Branch access |
| Warehouse | First branch WH | 1 | Default warehouse |
| Warehouse | Other branch WHs | 0 | Access only |
| Cost Center | First branch CC | 1 | Default cost center |
| Cost Center | Other branch CCs | 0 | Access only |
| Cost Center | Company default CC | 0 | Access for tax templates (e.g. Main - CNC) |
Layer 2: DocType Permissions (from setup.py after_migrate)
Custom DocPerm records control which DocTypes the Branch User can read/write/create/submit. These are created programmatically on every bench migrate.
Layer 3: permission_query_conditions (from branch_filters.py)
SQL WHERE clauses injected into list queries to filter documents by branch warehouses. Only affects Branch User role; Admin/Stock Manager bypass.
Logic for SI/PI/DN/PR:
WHERE ( set_warehouse IN (user's branch warehouses) OR name IN (SELECT parent FROM items WHERE warehouse IN (user's WHs)) OR owner = current_user )
Layer 4: Cost Center Override (from branch_defaults.py)
Server-side before_validate hook that replaces cost centers the user doesn't have access to. Catches cases where a tax template or item default injects a cost center the branch user can't access.
Layer 5: Client-side Restrictions (from item_branch_user.js)
Hides cost/valuation fields on Item form for Branch Users. Checks frappe.user_roles and only applies if user has Branch User but NOT Stock Manager or System Manager.
📁 Fixtures & Custom Fields Developer
All fixtures exported by the app.
Custom Fields
| Name | Type | Purpose |
|---|---|---|
| Sales Invoice → custom_payment_mode | Select (Cash/Credit) | Drives POS popup vs Credit behavior |
| Sales Invoice → custom_inter_company_branch | Link | Selects branch for inter-company PI |
| Quotation → custom_payment_mode | Select | Payment mode on quotation |
| Customer → custom_vat_registration_number | Data | 15-digit Saudi VAT number |
| LCV → custom_distribute_by_cbm | Check | Enable CBM distribution |
| Landed Cost Item → custom_cbm | Float | CBM value per item |
| Material Request → custom_is_urgent | Check | Urgent priority flag |
Workflows
| Workflow | DocType | States |
|---|---|---|
| Stock Transfer Workflow | Stock Transfer | Draft → Pending → Approved (docstatus=1) / Rejected |
Key: Approval is branch-based — only users from the target warehouse's Branch Configuration can approve/reject. Validated in stock_transfer.py → validate().
Dependencies
| App | Usage |
|---|---|
| ERPNext v15 | Core ERP (SI, PI, PE, Stock Entry, etc.) |
| sf_trading | apply_patch/restore_patch for inter-company PI creation (bypasses session defaults) |
♻ Scrap Sale Workflow
Use this workflow to sell damaged, written-off, or end-of-life items as scrap to an external buyer. This keeps inventory accurate and records the scrap revenue separately.
Before a scrap sale, the items must already be written off (removed from active stock) via a Damage Transfer & write-off Stock Entry, or a direct Stock Entry (Material Issue). Verify in Stock Balance that the qty is zero in the source warehouse.
Go to Accounting → Sales Invoice → New. Select or create the scrap buyer as Customer. Add the scrap items with the agreed scrap selling price. Set warehouse to the Damage warehouse (e.g. Damage Jeddah - CNC) where the items currently sit.
In the Sales Invoice, enable Update Stock so that submitting the invoice automatically reduces the stock from the damage warehouse. This creates a Stock Ledger Entry deducting the scrap qty.
On submit, the system:
• Debits Accounts Receivable (or Cash)
• Credits Sales / Scrap Revenue account
• Reduces stock qty from the damage warehouse
Create a Payment Entry against the Sales Invoice to mark it as paid. Link it to the scrap buyer and the correct bank/cash account.
📋 Purchase Invoice — Non-Stock Items Important
When purchasing items that have already been written off (e.g. returned damaged goods, scrap repurchase, or cost adjustments), create the Purchase Invoice as a non-stock item transaction. This prevents double-counting in inventory.
Go to Buying → Purchase Invoice → New. Select the supplier. Do NOT tick "Update Stock" — leave it unchecked.
Add the written-off items to the invoice. Since these are already written off, set the Expense Account on each item line to an appropriate expense or loss account (e.g. Cost of Goods Sold or Write-Off Expense). Do not set a warehouse.
The system will automatically set the Cost Center from the branch configuration. Verify it reflects the correct branch before submitting.
Submit the Purchase Invoice. This records the liability to the supplier without touching stock. The accounting entry will be:
• Debit: Expense / Loss account
• Credit: Accounts Payable (Supplier)
Create a Payment Entry against this Purchase Invoice to record the payment to the supplier.
| Scenario | Update Stock | Expense Account |
|---|---|---|
| Regular purchase (new stock) | Yes | Stock / COGS |
| Written-off / scrap repurchase | No | Write-Off or COGS |
| Service / freight / expense | No | Relevant expense account |
RMAX Custom App — User & Developer Guide — Built by Enfono