# Dava India ERP — `Modules/*` Reference (nwidart/laravel-modules)

> Each module under `Modules/` is a self-contained mini-Laravel-app: its own
> `Config/Console/Database/Entities/Http/Notifications/Providers/Resources/Routes/Tests`.
> See [`../CLAUDE.md`](../CLAUDE.md) for the project overview. Compiled 2026-07-30.

## Accounting

**Purpose**: A standard double-entry "Accounting" add-on module — full bookkeeping (chart of
accounts, journal entries, ledgers, budgets, fund transfers, financial reports) layered on top of
the core POS's simpler `Account`/payment model. Auto-posts core sales/purchase/expense/payment
transactions to the ledger via a configurable transaction-to-account mapping. **Generic
accounting functionality, not pharmacy-specific.**

- **Entities**: `AccountingAccount`, `AccountingAccountType`, `AccountingAccountsTransaction`
  (double-entry ledger posting), `AccountingAccTransMapping` (auto-journal config),
  `AccountingBudget`.
- **Controllers**: `AccountingController`, `CoaController` (chart of accounts), `AccountTypeController`,
  `JournalEntryController`, `TransactionController` (maps core transactions to accounts),
  `TransferController`, `BudgetController`, `ReportController` (Trial Balance/Balance Sheet/AR-AP
  ageing), `SettingsController`, `ReconcileController`, `DataController`/`InstallController`.
- **Routes**: `/accounting` prefix.
- **Tables**: `accounting_account_types`, `accounting_accounts`, `accounts_transactions`,
  `accounting_acc_trans_mapping`, `accounting_budgets`.

## AssetManagement

**Purpose**: A standard add-on module for tracking non-inventory business assets (equipment,
furniture, vehicles) — purchase info, warranty periods, allocation/revocation to employees or
locations, maintenance history/cost. **No pharmacy-specific customization.**

- **Entities**: `Asset`, `AssetTransaction` (allocation/revocation history), `AssetWarranty`,
  `AssetMaintenance`.
- **Controllers**: `AssetController`, `AssetAllocationController`, `RevokeAllocatedAssetController`,
  `AssetMaitenanceController`, `AssetSettingsController`, `DataController`/`InstallController`.
- **Routes**: `/asset` prefix.
- **Tables**: `assets`, `asset_transactions`, `asset_warranties`, `asset_maintenances`.

## Connector

**Purpose**: REST API gateway for the whole ERP — issues OAuth2 (Passport) API tokens per business
and exposes almost the entire POS surface (products, sales, contacts, expenses, cash registers, HR
attendance, CRM leads/follow-ups, field-force visits) as JSON endpoints for a companion
mobile/POS-terminal app or external integration.

- **Entities**: none of its own — pure API facade over core app models + Passport OAuth clients.
- **Controllers (web)**: `ConnectorController` (landing page), `ClientController` (issues/regenerates
  Passport `password_client` API credentials per business), `InstallController`/`DataController`.
- **Controllers (API, ~20)**: `BusinessLocationController`, `ContactController`, `UnitController`,
  `CategoryController`, `BrandController`, `ProductController`, `TaxController`, `TableController`,
  `UserController`, `TypesOfServiceController`, `CommonResourceController`, `SellController`,
  `ExpenseController`, `CashRegisterController`, `SuperadminController`, `AttendanceController`,
  `ProductSellController`, `Crm\FollowUpController`/`Crm\CallLogsController`,
  `FieldForce\FieldForceController`.
- **Routes**: `/connector` (web, install + client-key UI); `connector/api/*` (token auth via
  `auth:api`) for the actual REST surface.
- **Migrations**: only adds the module version to `system` — no new business data tables.

## Essentials

**Purpose**: A general-purpose "Essentials" module — full HRM (attendance,
shifts, leave, holidays, payroll with allowances/deductions, sales targets) bundled with
general-purpose productivity tools (to-dos, reminders, internal messaging, document sharing,
knowledge base). **No pharmacy-specific customization observed** — looks unmodified.

- **Entities**: `EssentialsAttendance`, `EssentialsLeave`/`EssentialsLeaveType`, `EssentialsHoliday`,
  `Shift`/`EssentialsUserShift`, `PayrollGroup`/`PayrollGroupTransaction`,
  `EssentialsAllowanceAndDeduction`/`EssentialsUserAllowancesAndDeduction`,
  `EssentialsUserSalesTarget`, `Document`/`DocumentShare`, `ToDo`/`EssentialsTodoComment`,
  `Reminder`, `EssentialsMessage`, `KnowledgeBase`.
- **Controllers**: `DashboardController`, `AttendanceController`, `EssentialsLeaveController`/
  `EssentialsLeaveTypeController`, `EssentialsHolidayController`, `ShiftController`,
  `PayrollController`, `SalesTargetController`, `EssentialsAllowanceAndDeductionController`,
  `DocumentController`/`DocumentShareController`, `ToDoController`, `ReminderController`,
  `EssentialsMessageController`, `KnowledgeBaseController`, `EssentialsSettingsController`.
- **Routes**: `/essentials` (docs/todos/reminders/messages/allowance/KB) and `/hrm`
  (leave/attendance/payroll/shifts/sales targets).

## Spreadsheet

**Purpose**: A genuinely distinctive module (not a typical add-on for this class of product) — a
lightweight in-app spreadsheet/grid editor (data stored as JSON per sheet) with folder organization
and sharing to specific employees, roles, or linked to-dos. A mini internal Google-Sheets-like tool,
not a bulk-import/reporting engine.

- **Entities**: `Spreadsheet` (table `sheet_spreadsheets`, `sheet_data` JSON column, folder support),
  `SpreadsheetShare`.
- **Controllers**: `SpreadsheetController`, `DataController`/`InstallController`.
- **Routes**: `/spreadsheet` prefix.
- **Tables**: `sheet_spreadsheets`, `spreadsheet_shares`.

## Superadmin

**Purpose**: Retains its core role as the SaaS super-admin panel (packages,
subscriptions/billing via multiple payment gateways, tenant business management, bulk communicator,
CMS pages) — but in this fork has been substantially extended into a **central control tower for a
multi-warehouse pharmacy distribution chain**.

- **Entities**: `Package` (subscription plans), `Subscription`, `SuperadminCommunicatorLog`,
  `SuperadminFrontendPage` (CMS pages).
- **Stock controllers**: `SuperadminController`, `BusinessController` (tenant CRUD),
  `PackagesController`, `SubscriptionController` (PayPal/Flutterwave/Paystack/Pesapal checkout),
  `CommunicatorController`, `PageController`, `PricingController`, `SuperadminSettingsController`.
- **Custom additions (chain HQ console)**:
  - `SuperadminProductController` — superadmin-curated **master product** catalog synced to all
    tenant businesses
  - `SupplierLoginController` — provisions login-less warehouse/supplier portal accounts
  - `ManufacturerPurchaseOrderController` — oversight/resend of auto-generated Warehouse→TPM POs
  - `WarehouseOversightController` — cross-warehouse QC decisions, returns, rebalancing, cycle
    counts; lets superadmin "open"/"close" into a warehouse's own panel (`session('sa_warehouse_id')`)
  - `WarehouseSupplyReportController` — cross-business warehouse→store supply reporting
  - `BatchTraceabilityController` — batch/lot recall tracking
  - `ScheduleDrugRegisterController` — India Schedule H/H1/X controlled-drug register
  - `DrugLicenseReportController` — chain-wide drug-license validity (Form 20/21 & 20B/21B)
  - `MovementTagController` — global/per-location movement-tag config + min/max stock settings,
    with an auto-calculation run
  - `SuperadminCustomerController` — cross-business/"universal" customer management
  - `InvoiceAssignmentController` — centralized invoice scheme/layout assignment and GST-wise
    numbering series across businesses
  - `SupportTicketOversightController` — chain-wide console for `SupportTicket` damage/loss claims
  - `ComplianceController` (2026-08) — chain-wide licence register (Form 20/21, 20B/21B, trade,
    shop & establishment, FSSAI) bucketed by days-to-expiry, with a renewal/status trail in
    `business_license_logs`. A *renewed* status writes the new number/expiry back to `business`
  - `ExpiryAnalyticsController` (2026-08) — chain-wide expiry board: expired value at purchase
    cost, ageing, forward pipeline, expiry ratio per product, trend, seasonality, over-ordering
    signals, site comparison, generated insights; plus batch and disposal-register drilldowns
  - `BounceRateController` — chain-wide unfulfilled-demand board fed by POS searches
- **Routes**: `/superadmin` prefix, gated by `superadmin` middleware — which is a config-file
  USERNAME whitelist (`constants.administrator_usernames`), not a permission. The Compliance and
  Expiry-Analytics routes deliberately sit in the auth-only group instead, keeping the
  `/superadmin` URL prefix but gating in the controller on an EXPLICITLY granted permission
  (`hasPermissionTo()`, not `can()`), so a compliance officer can be given the board without
  being made a super admin — and so `Gate::before`'s blanket for every `Admin#<business>` role
  does not hand a chain-wide board to every individual store admin.
- **Migrations note**: a 2026-07-15 batch adds `is_master_product`/`master_product_id` to
  `products` and `master_variation_id` to `variations`, **dropping old superadmin products
  tables** — i.e. a prior "superadmin product catalog" implementation was migrated onto the core
  `products`/`variations` tables directly.

## SupportTicket

**Purpose**: A genuinely bespoke module (all 2026-dated migrations, not part of the core
module set) — a helpdesk-style workflow purpose-built to manage **damage and short/lost-quantity
claims on purchase orders/GRNs**, especially against login-less Third-Party-Manufacturer (TPM)
suppliers feeding warehouses.

- **Entities**: `SupportTicket` (tied to a `PurchaseLine`/`Transaction`; `ticket_type`:
  `loss_short`/`in_transit_damage`/`mixed`; `status`: `open`/`delayed`/`closed`; TAT deadline
  `tat_due_at`), `SupportTicketClosureReason` (business-scoped or global, `requires_resend` flag
  to trigger a replacement-goods workflow).
- **Controllers**: `SupportTicketController` (dashboard, create from a purchase line, list/show/
  store, investigation log, close with reason), `DataController`.
- **Routes**: `web.php` only — `support-tickets/dashboard`, `create/{purchase_line_id}`,
  `{id}/close`, `{id}/log`.
- **Behavior**: when a GRN records damaged/lost quantity, a ticket auto-generates (or is raised
  manually), carries a configurable TAT deadline (auto-flagged "Delayed" if overdue, via
  `supportticket:flag-delayed` every 30 min), and closes via a reason that can trigger a "resend"
  (reopens exactly the damaged/lost quantity for a replacement GRN, emailing the manufacturer since
  TPMs have no portal login). Integrates with Superadmin's `SupportTicketOversightController` for a
  cross-warehouse claims console.
