Software Requirements Specification (SRS) — Laundry Management System
| Field |
Value |
| Project |
Laundry Management System |
| Version |
1.0 |
| Language |
English |
| Tech Stack |
ASP.NET Core (Backend) + Angular + PrimeNG (Frontend) + PostgreSQL (Database) |
| Document Type |
Master Requirements Specification |
Table of Contents
- Introduction & Scope
- Glossary
- System Architecture & Technical Stack
- User Management & Permissions
- Branch Management (Online & Offline)
- Customer Management
- Customer Classifications
- Services & Garment Types
- Pricing Management
- Laundry Invoice Lifecycle
- Payments
- Discounts & Price Overrides
- Tax / VAT
- Multi-Currency
- Carpet Cleaning Module
- External Carpet Company Management
- Tailoring Module
- Inventory & Product Sales
- Piece-Level Garment Tracking (Barcodes)
- Returns, Refunds & Damage
- Corporate Monthly Billing
- Cashier Shift Management
- Notifications
- Reporting & Analytics
- Audit Trail & Logging
- Non-Functional Requirements
1. Introduction & Scope
1.1 Purpose
The Laundry Management System is a comprehensive business application designed to manage all operations of a laundry business, including clothing, carpets, tailoring, inventory sales, customers, payments, and financial accounting — with support for both online and completely offline branches.
1.2 Modules In Scope
| Module |
Description |
| User Management & Permissions |
Role-based access control (Admin, Reception, Accountant) |
| Branch Management |
Multi-branch architecture with online and offline modes |
| Customer Management |
Registered and transient customers with classifications |
| Services & Garment Types |
Configurable types of garments and services |
| Pricing |
Flexible price lists per classification, per service, per item |
| Laundry Invoices |
Full lifecycle from Draft to Delivered, with piece-level tracking |
| Payments |
Multi-method, partial, deferred, and advance payments |
| Carpet Cleaning |
Receipt without price → Final invoice after measurement |
| Carpet Companies |
External company management, payables, account statements |
| Tailoring |
Order management, tailor assignment, tailor payouts |
| Inventory & Sales |
Stock management, sales within or outside laundry invoices |
| Reporting & Analytics |
Backend-calculated, frontend-rendered reports |
| General Ledger & Accounting |
Double-entry accrual accounting |
| Audit Trail |
Every create/update/delete logged |
| Notifications |
Print receipts; SMS/WhatsApp readiness alerts |
| Tax / VAT |
Configurable toggle |
| Multi-Currency |
Single now, architected for multi-currency expansion |
2. Glossary
| Term |
Definition |
| Invoice |
A commercial document issued to a customer for laundry/tailoring/carpet services or inventory sales. |
| Receipt (Carpet) |
A non-financial document recording carpet intake without price or measured area. |
| General Ledger (GL) |
The master financial record where every debit and credit is posted. The single source of truth for all accounting. |
| Chart of Accounts (CoA) |
The hierarchical tree of account codes (Assets, Liabilities, Equity, Income, Expenses). |
| Journal Entry |
A header document grouping related GL rows for a single business event. |
| Operational Status |
The physical state of an order (Received, In Progress, Ready, Delivered). |
| Financial Status |
The payment state of an invoice (Unpaid, Partially Paid, Paid, Deferred). |
| UUID |
Universally Unique Identifier. Used as primary keys for safe offline-merge across branches. |
| Accrual Basis |
Revenue is recognized when service is delivered, not when cash is received. |
| Customer Credit |
A tracked positive balance owed back to the customer (from overpayment, refund, carpet advance excess). |
| Fiscal Year |
A user-defined 12-month financial reporting period (does not need to match the calendar year). |
| Price List |
A named collection of prices (e.g., Standard, VIP, Summer) that applies to a customer classification. |
| Settlement Model |
The accounting method defining when and how a carpet company or tailor is recorded as a liability or expense. |
| Piece Tag / Barcode |
A unique identifier attached to each individual garment for tracking. |
| Transient Customer |
A walk-in customer who is not registered in the system. Must pay in full. |
| Offline Branch |
A shop location with no internet connectivity, running a local instance. |
| Sync Batch |
A set of rows exported from an offline branch and imported into the central server. |
| Operational Data |
Business-facing tables (invoices, receipts, customers, items). |
| Accounting Data |
Financial-facing tables (journal_entries, general_ledger). |
3. System Architecture & Technical Stack
3.1 Stack Summary
| Layer |
Technology |
| Backend |
ASP.NET Core 10 (C#) |
| Frontend |
Angular 18+ with PrimeNG component library |
| Database |
PostgreSQL 16+ (central), SQLite (offline branches) |
| ORM |
Entity Framework Core with Npgsql provider |
| Reporting |
Backend JSON APIs (calculations) → Frontend rendering (display, print, Excel, PDF) |
| Authentication |
JWT Bearer Tokens |
| Background Jobs |
Quartz.NET |
| Logging |
Serilog |
| Frontend Excel |
SheetJS (xlsx) |
| Frontend PDF |
html2canvas + jspdf |
| Barcode |
jsbarcode / ngx-barcode (client-side) |
| Internationalization |
@ngx-translate/core |
3.2 Architecture Principles
- Double-Entry Bookkeeping: Every financial event posts at least one Debit and one Credit to the General Ledger. No direct balance updates.
- UUID Primary Keys: All tables use UUIDs generated client-side. This enables safe offline branch merging.
- Backend Calculates, Frontend Renders: All financial aggregates, running balances, tax, and totals are computed by the backend via SQL. The frontend receives final JSON and handles visual presentation, printing, and exporting to Excel/PDF.
- Separation of Operational & Accounting Data: Business tables (invoices, receipts) are separate from financial tables (journal_entries, general_ledger). GL entries are generated from business events via a Rules Engine.
- Atomic Transactions: Every business operation (CreateInvoice, RecordPayment) executes all related inserts within a single database transaction. Either all succeed or none do.
3.3 Deployment Modes
| Mode |
Description |
| Online Central Server |
Cloud or on-premise server with PostgreSQL. All online branches connect via REST API. |
| Online Branch |
Web browser accessing the central server. Real-time data. |
| Offline Branch |
Runs a local server (ASP.NET Core + SQLite) on the branch PC. Operates independently. Periodically generates a Data Export Package for manual transfer (USB/file) to the central server. |
| Hybrid Branch |
Primarily online, but caches recent data locally via Service Worker / PWA for brief disconnections. |
4. User Management & Permissions
4.1 System Roles
| Role |
Description |
| System Admin |
Full access. Manages users, branches, settings, chart of accounts, and sees all data including audit logs and costs. |
| Receptionist |
Counter staff. Creates invoices, receipts, customers, records payments, changes invoice status. Cannot delete finalized invoices. Cannot see costs or supplier/tailor payouts. |
| Accountant |
Financial staff. Views all invoices, manages payments, manages receivables/payables, processes refunds, manages tailor and company payouts, views reports. Cannot create new invoices or modify operational data. |
4.2 Permissions Rules
- Every API endpoint checks the user's role before executing.
- The system must prevent any user from performing an action outside their permissions.
- Permissions are defined in a separate Permissions Matrix document.
- The Admin can create additional custom roles with granular permissions in the future.
4.3 Authentication
- Username + password login.
- JWT tokens with configurable expiry.
- Password hashing via BCrypt.
- Session timeout with auto-logout after configurable idle time.
5. Branch Management (Online & Offline)
5.1 Branch Definition
Each branch has:
| Field |
Description |
| Branch ID |
UUID, globally unique |
| Branch Code |
Short unique code (e.g., "CAIRO-01") |
| Branch Name |
Display name |
| Mode |
Online or Offline |
| Currency |
Default currency for the branch |
| Fiscal Year |
Inherits from the central configuration |
| Status |
Active / Inactive |
5.2 Online Branch Behavior
- Connects directly to the central PostgreSQL database via REST API.
- All data is real-time.
- The manager can view consolidated data across all branches from the central system.
5.3 Offline Branch Behavior
- Runs a local ASP.NET Core instance with SQLite database.
- The schema is structurally identical to the central PostgreSQL schema.
- All primary keys are UUIDs generated locally.
- Operates fully independently — creates customers, invoices, payments, receipts, etc.
- No internet connection required for day-to-day operation.
5.4 Offline Sync Process
- Export: An authorized user (Admin) at the offline branch triggers "Export Data Package." The system exports all rows with
sync_status = 'pending' into a compressed JSON file (or SQL dump).
- Transfer: The file is transferred manually (USB drive, email, etc.) to the central server location.
- Import: The central Admin triggers "Import Branch Data." The system:
- Validates that every
branch_id in the file matches the expected source branch.
- Validates that
SUM(debit) == SUM(credit) within the sync batch.
- Checks that all
account_code values exist in the central Chart of Accounts.
- Inserts all rows using UUID-based upsert (no duplicates if imported twice).
- Marks the batch as
synced.
- Conflict Resolution: Since every primary key is a UUID generated at the offline branch, there are no ID collisions. If a customer record with the same phone number exists centrally, the system prompts the Admin to either link them or keep them separate.
5.5 Manager Consolidated View
- Online branches: The manager logs into the central system and sees live data from all online branches. Reports can filter by all branches or a specific branch.
- Offline branches: After importing the data package, the manager sees merged data in all reports. Each row is tagged with its originating
branch_id, so branch-specific filtering is always available.
- Every report clearly displays which branch data comes from.
6. Customer Management
6.1 Customer Types
| Type |
Description |
Deferred Payment Allowed |
| Individual |
Regular registered customer |
At Admin discretion |
| VIP |
Premium registered customer |
Yes |
| Company |
Corporate client |
Yes |
| Hotel |
Hotel client |
Yes |
| Transient |
Walk-in, unregistered |
No — must pay in full |
6.2 Customer Data
| Field |
Required |
Notes |
| Customer ID |
Auto |
UUID |
| Full Name |
Yes |
|
| Phone Number |
Yes |
Must be unique for registered customers |
| Classification |
Yes |
Links to a Classification |
| Notes |
No |
Free text |
| Registration Date |
Auto |
|
| Branch ID |
Auto |
The branch where the customer was created |
| Credit Limit |
No |
For deferred payments |
| Status |
Auto |
Active / Inactive |
6.3 Transient Customer Rules
- The system must support creating invoices for customers without registering them first.
- A transient customer requires at minimum a name (can be "---" or "Walk-in") and optionally a phone number.
- Transient customers cannot use deferred payment.
- Transient customer invoices must be paid in full (cash or card) before or at delivery.
6.4 Customer Credit
- The system must track a "Customer Credit" balance.
- Customer credit originates from:
- Carpet advance payment exceeding the final invoice.
- Refunds for returned/damaged items paid as credit.
- Manual credit adjustments (Admin only).
- Customer credit can be applied to future invoices.
- Customer credit can be refunded as cash (Admin only).
6.5 Customer Editing
- Allow modification of name, phone, classification, and notes.
- Changing a customer's classification does not retroactively change past invoices (invoices are frozen).
7. Customer Classifications
7.1 Classification Definition
| Field |
Description |
| Classification ID |
UUID |
| Name |
e.g., "VIP", "Hotel", "Company", "Standard" |
| Default Price List |
The price list applied to customers of this classification |
| Default Discount % |
Auto-applied discount percentage (optional) |
| Deferred Payment Allowed |
Yes/No |
| Is Default |
Flag indicating the default classification for new customers |
7.2 Classification Rules
- The system must support defining multiple customer classifications.
- Each customer is linked to exactly one classification.
- The classification determines:
- Which price list applies.
- Whether deferred payment is allowed.
- Default discount percentage.
7.3 Price List Assignment
Instead of hard-coding prices per classification, the system uses Price Lists:
- A price list is a named collection of prices (e.g., "Standard 2026", "VIP Summer", "Hotel Contract").
- A classification is assigned a default price list.
- Multiple classifications can share the same price list.
- The Admin can change which price list a classification uses at any time.
8. Services & Garment Types
8.1 Garment Types (Items)
| Field |
Description |
| Item ID |
UUID |
| Code |
Short code (e.g., "SHIRT", "TROUS") |
| Name (EN) |
e.g., "Shirt" |
| Name (AR) |
e.g., "قميص" |
| Category |
Clothing / Carpet / Other |
| Status |
Active / Inactive |
Examples: Shirt, Trousers, Jacket, Dress, Blanket, Curtain, Tablecloth.
8.2 Service Types
| Field |
Description |
| Service ID |
UUID |
| Code |
Short code (e.g., "WASH", "IRON", "WASH_IRON") |
| Name (EN) |
e.g., "Wash" |
| Name (AR) |
e.g., "غسيل" |
| Status |
Active / Inactive |
Examples: Wash, Iron, Wash & Iron, Dry Clean, Stain Removal.
8.3 Linking Rules
- Each garment type can be associated with one or more service types.
- Within an invoice, each line item specifies: Garment Type + Service Type + Quantity + Unit Price.
- A garment type can appear multiple times in the same invoice with different service types (e.g., 2 Shirts Wash, 1 Shirt Iron).
9. Pricing Management
9.1 Price List Structure
A price list (e.g., "Standard 2026") contains price entries:
| Field |
Description |
| Price List ID |
UUID |
| Garment Type |
Reference to garment type |
| Service Type |
Reference to service type |
| Base Price |
Default selling price |
| Effective From |
Date the price becomes active |
| Effective To |
Optional expiry date |
| Currency |
Reference to currency |
9.2 Flexible Pricing Rules
- The system must support multiple active price lists simultaneously.
- Each customer classification is assigned one default price list.
- When creating an invoice, the system auto-selects the price based on the customer's classification → price list → garment + service combination.
- The receptionist can override the price on any invoice line, but must provide a mandatory reason.
- Once an invoice is finalized, its prices are frozen — changing the price list later does not affect historical invoices.
9.3 Price Modification
- Admin can create new price lists or edit existing ones.
- Price list changes take effect for new invoices only.
- The system retains a history of all price changes.
10. Laundry Invoice Lifecycle
10.1 Invoice States
The system uses two independent state fields on every invoice:
Operational Status (physical state):
| Status |
Description |
| Draft |
Invoice being prepared. Not yet confirmed. Items can be added/removed. |
| Confirmed |
Invoice finalized. Garments tagged. Ready for processing. |
| In Progress |
Garments are being cleaned/processed. |
| Ready |
All garments are ready for customer pickup. Notification sent. |
| Delivered |
Customer has received all items. Revenue recognized. |
Financial Status (payment state):
| Status |
Description |
| Unpaid |
No payment recorded. |
| Partially Paid |
Some payment recorded, but not full amount. |
| Paid |
Full amount received. |
| Deferred |
Payment is scheduled for later (registered customers only). |
10.2 Invoice Fields
| Field |
Description |
| Invoice ID |
UUID |
| Invoice Number |
Auto-generated sequential number, unique per branch (e.g., INV-CAIRO-01-2026-000123) |
| Customer ID |
Reference to customer (or null for transient) |
| Branch ID |
Branch where invoice was created |
| Date |
Creation date |
| Due Date |
For deferred payments |
| Items |
List of invoice line items |
| Subtotal |
Sum of line totals before discounts |
| Discount Amount |
Total discount applied |
| Tax Amount |
VAT if enabled |
| Grand Total |
Final amount due |
| Paid Amount |
Sum of all payments against this invoice |
| Remaining Amount |
Grand Total - Paid Amount |
| Operational Status |
See states above |
| Financial Status |
See states above |
| Notes |
Free text |
| Created By |
User who created the invoice |
10.3 Invoice Line Item Fields
| Field |
Description |
| Line ID |
UUID |
| Invoice ID |
Parent invoice |
| Garment Type |
Reference |
| Service Type |
Reference |
| Quantity |
Number of pieces |
| Unit Price |
Price per piece per service |
| Line Total |
Quantity × Unit Price |
| Assigned Tailor |
Only for tailoring services |
| Tailor Cost |
Cost of the tailor (only for tailoring) |
| Tags |
List of barcode tag IDs attached to these garments |
10.4 Invoice Numbering
- Invoice numbers MUST be unique per branch.
- The numbering is sequential within each branch.
- Format:
INV-{BranchCode}-{Year}-{SequentialNumber}.
- Once assigned, an invoice number cannot be reused or changed.
10.5 Invoice Search
The system must support searching invoices by:
- Customer name
- Customer phone number
- Invoice number
- Date range
- Operational status
- Financial status
- Branch
- Invoice ID (UUID)
10.6 Draft Invoices
- Receptionists can save an incomplete invoice as a Draft.
- Draft invoices do not affect inventory or accounting.
- Draft invoices can be edited freely.
- Confirming a draft moves it to "Confirmed" status and triggers bucket-tag generation and accounting entries.
11. Payments
11.1 Payment Timing
The system must support three payment timings:
| Timing |
Description |
| At Receipt |
Customer pays when dropping off clothes. |
| At Delivery |
Customer pays when picking up clothes. |
| Deferred |
Payment is scheduled for a later date. Allowed only for registered customers whose classification permits it. |
11.2 Payment Methods
| Method |
Description |
| Cash |
Physical currency |
| Card |
Credit/debit card |
| Bank Transfer |
Direct deposit |
| Customer Credit |
Applied from existing credit balance |
| Other |
Configurable additional methods |
11.3 Multi-Payment
- A single invoice can be paid using multiple payment methods.
- Example: 200 EGP cash + 150 EGP card for a 350 EGP invoice.
11.4 Partial Payment
- The system must support partial payment.
- After each payment, the system updates:
Paid Amount
Remaining Amount
Financial Status (Unpaid → Partially Paid → Paid)
11.5 Payment Display
On every invoice view, the system must clearly display:
- Grand Total
- Paid Amount (sum of all payments)
- Remaining Amount (Grand Total - Paid Amount)
- Payment Status
12. Discounts & Price Overrides
12.1 Types of Discounts
| Type |
Description |
Auto/Manual |
| Classification Discount |
Auto-applied based on customer classification (e.g., VIP = 10%) |
Automatic |
| Prepayment Discount |
Discount given when customer pays in advance |
Optional, configurable |
| Manual Discount |
Receptionist applies a custom discount on the invoice |
Manual, requires reason |
| Line Item Discount |
Discount on a specific invoice line |
Manual, requires reason |
- Discounts can be applied as:
- Percentage (e.g., 10% off)
- Fixed Amount (e.g., 50 EGP off)
- Discounts are calculated within the invoice total.
12.3 Price Override Rules
- The unit price on any invoice line can be overridden by the receptionist.
- Every manual discount and price override must include a reason text.
- The reason is stored in the audit trail.
- Admin can review all price overrides and discounts in a dedicated report.
13. Tax / VAT
13.1 Configuration
- Tax is implemented as an optional, toggleable setting.
- Admin can enable or disable tax globally from the system settings.
- When disabled, tax fields and columns are hidden from the UI and not calculated.
13.2 Tax Settings (When Enabled)
| Setting |
Description |
| Tax Name |
e.g., "VAT", "Sales Tax" |
| Tax Rate |
Percentage (e.g., 15%) |
| Tax Inclusive |
Whether prices include tax or tax is added on top |
| Tax Account |
GL account code for tax liability posting |
13.3 Tax Calculation
- When tax is enabled, every invoice line calculates tax based on the tax settings.
- Tax is displayed as a separate line on the invoice.
- The General Ledger posts tax amounts to the designated Tax Liability account.
14. Multi-Currency
14.1 Current State
- The system currently operates in a single currency.
- However, the data model must be architected to support future multi-currency expansion.
14.2 Multi-Currency Architecture
| Design Rule |
Implementation |
| Currency Table |
Define a currencies table with code, name, symbol, decimal places. |
| Every Money Column |
All monetary columns (price, total, payment) store the amount + currency_id. |
| Exchange Rates |
A currency_rates table stores rates over time. |
| Default Currency |
Each branch has a default currency. The system can display in any configured currency. |
| Foreign Currency Transactions |
If a customer pays in a different currency, the system records the foreign amount and the converted base amount. |
15. Carpet Cleaning Module
15.1 Carpet Receipt (Without Price or Area)
A Carpet Receipt is a non-financial document that serves as proof of intake.
| Field |
Description |
| Receipt ID |
UUID |
| Receipt Number |
Auto-generated sequential (e.g., CRP-BRANCH-2026-000045) |
| Customer |
Customer reference |
| Branch ID |
Branch |
| Date |
Receipt date |
| Items |
List of carpet items |
| Advance Amount |
Optional advance payment |
| Advance Payment Method |
Cash, card, etc. |
| Notes |
Free text |
| Status |
Received → With Company → Ready → Delivered |
Carpet Item Fields:
| Field |
Description |
| Carpet Type |
e.g., "Persian Rug", "Machine-Made", "Wool Carpet" |
| Quantity |
Number of pieces |
| Estimated Size |
Rough estimate (optional, for reference) |
| Notes / Damages |
Description of existing damages or special instructions |
15.2 Carpet Delivery Receipt
The receipt must be printable as proof of handover for the customer. It includes:
- Receipt number and date
- Customer name and phone
- List of carpet items received
- Staff signature line (optional)
15.3 Final Carpet Invoice
After the carpet is cleaned and the actual area is measured, a Final Carpet Invoice is created.
| Field |
Description |
| Final Invoice ID |
UUID |
| Linked Receipt ID |
The original receipt (strict 1-to-1 relationship) |
| Invoice Number |
Sequential (e.g., FIN-CARPET-2026-000023) |
| Date |
Invoice date |
| Items |
List of carpet items with measured area |
| Pricing Strategy |
Selected per item |
| Subtotal |
Before discount/advance |
| Advance Deduction |
Auto-deducted from the receipt |
| Discount |
Any manual discount |
| Tax |
If enabled |
| Grand Total |
Final amount |
| Operational Status |
Ready / Delivered |
| Financial Status |
Unpaid / Paid / Partially Paid |
15.4 Carpet Pricing Strategies
The system must support three pricing strategies, selectable per carpet type or per invoice line:
| Strategy |
Calculation |
When to Use |
| Per Square Meter |
Final Price = Actual Area (m²) × Selling Rate per m² |
Standard wall-to-wall or large rugs |
| Per Piece (Flat Rate) |
Final Price = Number of Pieces × Fixed Price per Piece |
Small rugs or car mats |
| Cost-Plus Markup |
Final Price = External Company Cost × (1 + Markup %) |
When margin is guaranteed over the external company cost |
Strategy Rules:
- Each Carpet Type master record defines which strategies are available for it.
- The user selects the strategy when creating the final invoice.
- The system calculates the price automatically but allows manual override with a mandatory reason.
15.5 Advance Payment Handling
- The advance payment recorded on the receipt is automatically deducted from the final invoice.
- If Advance > Final Invoice Total:
- The excess becomes Customer Credit on the customer's account.
- The customer credit can be used on future invoices or refunded in cash.
- If Advance < Final Invoice Total:
- The customer pays the remaining balance.
15.6 Carpet Status Tracking
| Status |
Description |
| Received |
Items received, receipt issued |
| Assigned to Company |
Items sent to external company |
| Returned |
Items returned from company, area measured |
| Ready |
Final invoice created, items ready for customer |
| Delivered |
Customer has collected items |
16. External Carpet Company Management
16.1 Company Profile
| Field |
Description |
| Company ID |
UUID |
| Company Name |
|
| Contact Person |
|
| Phone |
|
| Address |
|
| Settlement Model |
Accrual / Cash / Prepayment |
| Default Currency |
|
| Notes |
|
16.2 Purchase Prices
For each carpet type, the system must record the purchase price from each company:
| Field |
Description |
| Company ID |
Reference |
| Carpet Type |
Reference |
| Price per m² |
For per-square-meter pricing |
| Price per Piece |
For flat-rate pricing |
| Effective Date |
When the price became effective |
16.3 Settlement Models
The Admin selects the settlement model when defining the company. The model can be overridden per transaction.
| Model |
Accounting Behavior |
| Accrual (Liability) |
When carpet is returned from the company, the system records: Debit Carpet Expense, Credit Accounts Payable - Company X. When payment is made: Debit Accounts Payable, Credit Cash. |
| Cash (Direct Expense) |
Expense is recorded only when payment is made: Debit Carpet Expense, Credit Cash. No payable tracking. |
| Prepayment |
When advance is paid: Debit Prepaid Expense - Company X, Credit Cash. When carpet is returned: Debit Carpet Expense, Credit Prepaid Expense. If advance > final cost, remainder stays as prepaid credit. |
16.4 Company Tracking
- Track all jobs assigned to each company.
- Track financial amounts owed to each company.
- Record payments made to companies.
- Provide an Account Statement report for each company showing all transactions and current balance.
17. Tailoring Module
17.1 Tailoring Order
A tailoring order can be linked to a laundry invoice or exist as a standalone tailoring order.
| Field |
Description |
| Tailoring Order ID |
UUID |
| Order Number |
Sequential |
| Customer |
Customer reference |
| Linked Invoice ID |
Optional — if part of a laundry invoice |
| Branch ID |
Branch |
| Date |
Order date |
| Items |
List of tailoring tasks |
| Operational Status |
Received → In Progress → Ready → Delivered |
| Financial Status |
Unpaid / Paid / Partially Paid |
17.2 Tailoring Task (Line Item)
| Field |
Description |
| Task ID |
UUID |
| Service |
e.g., Hemming, Zipper Replacement, Resize |
| Garment Type |
Type of garment |
| Quantity |
|
| Unit Price |
Selling price to customer |
| Assigned Tailor |
Reference to tailor |
| Tailor Cost |
Amount due to the tailor for this task |
| Status |
Pending → Completed |
17.3 Tailor Profile
| Field |
Description |
| Tailor ID |
UUID |
| Name |
|
| Phone |
|
| Payout Model |
Periodic / Per-Item / Salary-Commission |
| Default Cost Rate |
Optional — default cost per task |
| Status |
Active / Inactive |
17.4 Payout Models
| Model |
Accounting Behavior |
| Periodic Settlement |
Every completed task: Debit Tailoring COGS, Credit Accrued Tailor Payable - Tailor X. Admin generates a "Tailor Payout Report" (weekly/monthly). When paid: Debit Accrued Payable, Credit Cash. |
| Per-Item Instant |
Every completed task immediately creates a payable entry. Admin can pay instantly or let the balance accumulate. When paid: Debit Tailor Payable, Credit Cash. |
| Salary + Commission |
Fixed monthly salary recorded as a recurring expense. Completed tasks above a quota generate a bonus: Debit Tailoring Bonus Expense, Credit Tailor Payable. |
17.5 Tailor Financial Tracking
- Track earned amount per tailor.
- Track paid amount per tailor.
- Display remaining balance per tailor.
- Record payments to tailors.
- Provide a Tailor Account Statement report.
- Generate a Tailor Payout Report showing all completed tasks in a date range with calculated payout amounts.
18. Inventory & Product Sales
18.1 Inventory Item Definition
| Field |
Description |
| Item ID |
UUID |
| Code |
Short code |
| Name (EN) |
e.g., "Fabric Freshener 500ml" |
| Name (AR) |
e.g., "معطر أقمشة 500 مل" |
| Category |
e.g., Fragrance, Detergent, Accessories |
| Unit of Measure (UOM) |
Piece, Box, Liter, Bottle, etc. |
| Selling Price |
|
| Cost Price |
For accounting |
| Current Quantity |
Auto-managed |
| Reorder Level |
Alert when quantity falls below this |
| Status |
Active / Inactive |
18.2 Stock Management
- The system tracks available quantities for each item per branch.
- When an item is sold (within a laundry invoice or standalone), the quantity is automatically deducted.
- When an invoice containing inventory items is cancelled, the quantity is automatically restored.
- When new stock arrives, the Admin records a Stock Receipt that increases the quantity.
18.3 Sales Channels
Inventory items can be sold in two ways:
1. Within a Laundry Invoice: Items are added as additional line items to a laundry invoice.
2. As a Standalone Sales Invoice: A dedicated invoice for product sales only.
Both methods follow the same accounting rules (deduct inventory, recognize revenue, collect payment).
19. Piece-Level Garment Tracking (Barcodes)
19.1 Barcode Tagging
- Every individual garment received must be assigned a unique system-generated barcode tag.
- The barcode is generated when the invoice is Confirmed (moved from Draft).
- The barcode format is configurable (Code 128 recommended; QR code supported).
- The tag includes: Barcode ID, Invoice Number, Customer Name, Date.
19.2 Tag Lifecycle
| Stage |
Action |
| Confirmation |
Tags generated and printed. |
| Processing |
Tags remain attached to garments. |
| Ready |
Tags used to verify all items are present before notifying the customer. |
| Delivery |
Tags scanned to confirm all items are returned. If any tag is missing, the system flags it. |
19.3 Tag Scanning
- The system should support barcode scanning via:
- USB barcode scanner (acts as keyboard input).
- Camera-based QR/barcode scanning (mobile/tablet device).
- Scanning a tag displays the associated invoice and garment details.
20. Returns, Refunds & Damage
20.1 Invoice Cancellation
- An unpaid invoice can be cancelled.
- Cancelling an invoice:
- Reverses any inventory deductions.
- Cancels any unprinted garment tags.
- Creates a Reversing Journal Entry in the GL (does not delete the original entries).
- Requires a mandatory Cancellation Reason.
20.2 Refunds
- For paid invoices, a "Refund Document" is created instead of cancelling.
- The refund links back to the original invoice.
- The refund specifies:
- Which items are refunded (partial or full).
- Refund amount.
- Refund method (Cash, Customer Credit, Bank Transfer).
- Mandatory reason.
- The system creates the appropriate GL entries (Debit Refund Expense / Income Contra, Credit Cash / Customer Credit).
20.3 Damage & Loss
- Any invoice line item can be marked as Damaged or Lost (by Admin or Reception supervisor).
- When marked:
- A Compensation Value is recorded.
- The compensation is deducted from the invoice total (or paid to the customer if already paid).
- The item is removed from the customer's receivable.
- GL entries reflect the loss (Debit Damage/Loss Expense, Credit Income Contra).
- A Damage Report is generated for management review.
21. Corporate Monthly Billing
21.1 Consolidated Invoice
For customers classified as Company or Hotel:
- The system must support generating a Monthly Consolidated Statement.
- All delivered, unpaid invoices within a calendar month are grouped into a single statement.
- The statement includes:
- List of all individual invoices.
- Invoice-level totals.
- Consolidated grand total.
- Payment terms.
21.2 Payment Against Statement
- Payments can be recorded against the consolidated statement.
- The payment is allocated to individual invoices (FIFO or manual allocation).
- Each invoice's
Paid Amount and Remaining Amount is updated accordingly.
22. Cashier Shift Management
22.1 Shift Lifecycle
| Stage |
Description |
| Open Shift |
Cashier records the starting cash float when beginning a shift. |
| During Shift |
All cash transactions (sales, payments, refunds) are recorded against the shift. |
| Close Shift |
Cashier enters the actual counted cash. System compares with expected cash and flags discrepancies. |
22.2 Shift Fields
| Field |
Description |
| Shift ID |
UUID |
| User |
Cashier / Receptionist |
| Branch ID |
Branch |
| Open Time |
Shift start |
| Close Time |
Shift end |
| Opening Float |
Cash in drawer at shift start |
| Expected Cash |
Opening Float + Cash Sales - Cash Refunds - Cash Payouts |
| Actual Cash |
Cashier's counted cash at shift end |
| Discrepancy |
Expected Cash - Actual Cash |
| Notes |
If discrepancy exists, cashier must provide explanation |
22.3 Shift Report
- Each shift closing generates a Shift Report showing:
- All invoices created during the shift.
- All payments received.
- All refunds issued.
- Cash breakdown by payment method.
- Discrepancy (if any).
23. Notifications
23.1 Print Notifications
- The system must support printing a receipt upon customer request.
- Printing is handled via the browser's native print dialog (
window.print() with @media print CSS).
- For thermal printer support, the frontend includes a dedicated receipt component styled for 80mm width.
23.2 SMS / WhatsApp Notifications
- When an invoice status changes to Ready for Delivery, the system can optionally send an SMS or WhatsApp message to the customer.
- Notification is configurable (enabled/disabled globally).
- The message template is configurable (e.g., "Dear {name}, your laundry (Invoice #{number}) is ready for pickup.").
- Implementation: The backend fires an event. A notification handler (Quartz.NET job or external service) dispatches the message.
24. Reporting & Analytics
24.1 Reporting Architecture
Backend: Performs all calculations, aggregations, running balances, and filtering via SQL. Returns clean JSON via Report Data APIs.
Frontend: Receives JSON and handles all visual rendering (PrimeNG tables, charts), printing (browser print), Excel export (SheetJS), and PDF generation (html2canvas + jspdf).
24.2 Mandatory Reports
| Report |
Description |
Frequency |
| Daily Sales Summary |
Total revenue, cash, card, deferred, discounts, average invoice value per day. Filterable by branch. |
Daily |
| Cashier Shift Closing |
Individual shift report with float, sales, refunds, discrepancy. |
Per shift |
| Customer Statement |
Running balance of a customer showing all invoices, payments, credits. |
On demand |
| General Ledger |
Full GL with opening balance, debits, credits, closing balance per account. |
Monthly / on demand |
| Trial Balance |
Summary of all account balances (Debit = Credit verification). |
Monthly |
| Income Statement (P&L) |
Revenue - Expenses = Net Profit. Filterable by branch and date range. |
Monthly / Quarterly |
| Balance Sheet |
Assets = Liabilities + Equity snapshot. |
Monthly / Annual |
| Tailor Workload & Payout |
Items completed per tailor, earned amount, paid amount, remaining balance. |
Weekly / Monthly |
| Carpet Company Payables |
Amounts owed to each external carpet company with transaction history. |
On demand |
| Company Account Statement |
Full transaction history and current balance for each external carpet company. |
On demand |
| Inventory Levels |
Current stock, reorder alerts, sales history per item per branch. |
On demand |
| Best-Selling Services |
Ranking of services by revenue or quantity in a date range. |
Monthly |
| Monthly Corporate Summary |
Consolidated statement for Company/Hotel customers. |
Monthly |
| Damage Report |
All items marked as damaged or lost with compensation values. |
On demand |
| Discounts & Overrides Report |
All manual discounts and price overrides with reasons. |
Weekly / On demand |
| Branch Performance Comparison |
Side-by-side revenue, costs, and profit per branch. |
Monthly |
| Audit Log Report |
Filterable log of all create/update/delete actions. |
On demand |
24.3 Report API Contract
Every report endpoint follows this pattern:
{
"meta": {
"reportName": "...",
"generatedAt": "ISO datetime",
"branchId": "branch-uuid or 'all'",
"dateFrom": "YYYY-MM-DD",
"dateTo": "YYYY-MM-DD",
"currency": "EGP"
},
"summary": { /* aggregated fields */ },
"details": [ /* array of rows with pre-calculated values */ ],
"pagination": {
"page": 1,
"pageSize": 50,
"totalCount": 450
}
}
24.4 Frontend Export Options
For any report table, the frontend provides:
- Print: Browser print with @media print CSS.
- Excel: SheetJS (xlsx) converting the details array to .xlsx.
- PDF: html2canvas renders the table as an image, jspdf wraps it in a PDF.
25. Audit Trail & Logging
25.1 Audit Trail Requirements
| Data Logged |
Description |
| Entity Type |
Which table/entity was changed (Invoice, Customer, Payment, etc.) |
| Entity ID |
UUID of the affected record |
| Action |
Create / Update / Delete |
| User |
Who performed the action |
| Timestamp |
When the action occurred |
| Old Value |
JSON snapshot before change |
| New Value |
JSON snapshot after change |
| Branch ID |
Which branch the action originated from |
25.2 What Must Be Logged
- Price changes (price list edits).
- Invoice modifications (status changes, item changes, cancellations).
- Payment recordings and edits.
- Refund issuances.
- Customer data changes.
- User permission changes.
- Manual discounts and price overrides.
- Deletions of finalized records.
25.3 Audit Log Access
- Only the Admin role can view the audit log.
- The audit log cannot be modified or deleted.
- The audit log is filterable by date, user, entity type, action, and branch.
26. Non-Functional Requirements
| Category |
Requirement |
| Database |
PostgreSQL for central server. SQLite for offline branches. |
| ACID Compliance |
All financial transactions must be ACID-compliant. |
| UUID Keys |
All primary keys are UUIDs generated client-side. |
| Decimal Precision |
All monetary values use C# decimal mapped to NUMERIC(18,4) in PostgreSQL. No floating-point. |
| Performance |
Invoice creation (with tag generation) must complete under 2 seconds. Reports for 1 year of data must load within 5 seconds (paginated). |
| Concurrent Users |
Support at least 5 concurrent users per online branch without data corruption. |
| Security |
All passwords hashed via BCrypt. JWT tokens with configurable expiry. API endpoints enforce role-based authorization. |
| Offline Reliability |
Offline branches must operate without internet for up to 30 days. Data must remain consistent after merge. |
| Internationalization |
Arabic and English UI. Runtime language switching via @ngx-translate. |
| Browser Support |
Latest versions of Chrome and Firefox. |
| Backup |
Central PostgreSQL database backed up daily. Offline branches backed up before and after sync. |
| Data Retention |
Invoices and GL entries retained indefinitely (or configurable archiving policy). |
| Error Handling |
All API errors return structured JSON with error code and message. |
| Logging |
All errors, GL posts, payment transactions, and sync operations logged via Serilog to file/database. |
Revision History
| Date |
Version |
Author |
Changes |
| 2026-05-10 |
1.0 |
System Analyst |
Initial master requirements specification. |