# Solar ERP System Documentation

**Branch / codebase snapshot:** Inventory ERP + existing Solar project/billing platform  
**Generated from:** current application code (migrations, routes, controllers, services, views, APIs)  
**Purpose:** Single source of truth for what is built so far, and a foundation for next-phase planning  

---

## Table of contents

1. [Overall System Overview](#1-overall-system-overview)
2. [Database Documentation](#2-database-documentation)
3. [Code Flow & Architecture](#3-code-flow--architecture)
4. [Module Documentation](#4-module-documentation)
5. [UI Documentation](#5-ui-documentation)
6. [API Documentation](#6-api-documentation)
7. [Current Features](#7-current-features)
8. [Folder Structure](#8-folder-structure)
9. [ERP Workflow](#9-erp-workflow)
10. [Next Phase Preparation](#10-next-phase-preparation)

---

## 1. Overall System Overview

### 1.1 What this product is

The Solar Management System is a **multi-tenant** Laravel application with two major surfaces:

| Surface | Audience | Access |
|---------|----------|--------|
| **Mobile / API** (`/api/...`) | Service users + tenant admins (Sanctum) | Projects, payments, payouts, media, dashboards |
| **Inventory ERP Web** (`/admin/inventory/...`) | Tenant admins (session auth) | Masters, procurement, warehouse, dispatch, stock, project site overview |

Billing (customer payments, service-user payouts, GST/TDS/commission ledger) predates inventory ERP and remains primarily **API-driven**. Inventory ERP is a **web admin panel** that shares the same `tenants`, `users`, `projects`, and upload paths.

### 1.2 Modules implemented

| Domain | Status | Primary UI |
|--------|--------|------------|
| Tenants / users / roles | Complete (pre-ERP) | API + super-admin |
| Projects (create, approve, reject, complete, media) | Complete (API); web overview added | API + Inventory Projects |
| Payments & payouts (billing) | Complete (API) | API; summarized on project show |
| Inventory masters (units, taxes, brands, items, SKUs, suppliers, warehouses) | Complete | Inventory web |
| Purchase orders | Complete (draft → complete + PDF) | Inventory web |
| Goods receipts | Complete (draft → complete + PDF + batches) | Inventory web |
| Site dispatches | Complete (draft → complete + batch pick + PDF) | Inventory web |
| Stock positions & ledger | Complete (read + modal breakdown) | Inventory web |
| Stock adjustments | Complete (count → post) | Inventory web |
| Document attachments | Complete | Inventory web |
| Project revisions / material plans (BOM) | Basic UI | Inventory web |
| Project financial KPIs on web | Complete (reuses ledger + material cost) | Inventory project show |
| Material requests | Schema only | — |
| Returns / wastage / installations / QC | Schema / models only | — |
| Transfer receipts / project stores | **Removed** by migration | — |
| Multi-level approvals / inventory periods | Schema stubs | — |

### 1.3 Current development status

- **Production-usable for:** catalog masters, PO → GRN → warehouse stock → dispatch to project, stock adjustments, attachments, inventory dashboard, project site financial overview.
- **Partially usable:** project revisions & BOM (create/list; limited editing), reason codes (read-only list), settings flags (some not enforced in all flows).
- **Not built in UI/API for inventory:** material requests, returns, installations, QC workflow, wastage posting, reconciliation screen, warehouse bins UI, serial operations UI, approval workflow engine.
- **Project statuses** `installation`, `qc`, `commissioning` exist in the enum and filters but **have no transition API/UI** yet (see §4 Projects and §9).

### 1.4 High-level architecture

```text
┌─────────────────┐     Sanctum      ┌──────────────────────────────┐
│  Mobile App     │◄────────────────►│  routes/api.php              │
│  (service user  │                  │  App + TenantAdmin APIs      │
│   / tenant admin)│                  └───────────┬──────────────────┘
└─────────────────┘                              │
                                                 ▼
┌─────────────────┐   session auth   ┌──────────────────────────────┐
│ Inventory Web   │◄────────────────►│  routes/inventory.php        │
│ /admin/inventory│                  │  Web\Inventory\* Controllers │
└─────────────────┘                  └───────────┬──────────────────┘
                                                 │
                     ┌───────────────────────────┼───────────────────────────┐
                     ▼                           ▼                           ▼
            Services (Inventory/*,      Models (Inventory/*,         MySQL
            ProjectLedger,              Project, Payment,            (tenant-scoped)
            ProjectFinancialPresenter)  PayoutRequest, …)
```

**Key architectural decisions (as implemented):**

- **Tenant scoping** everywhere (`tenant_id` on inventory tables; route model binding via `TenantScopedRouteBindings`).
- **Document lifecycle:** `draft` → `completed` (optional `cancelled`) via `DocumentStatus`.
- **Stock truth:** `inventory_stock_positions` + immutable `inventory_movements` ledger; batches for FIFO / dispatch lot tracking.
- **Dispatch model:** warehouse → **project site** (`at_project`). Project-store warehouses and transfer receipts were removed.
- **GRN destination:** warehouse is the primary path; `destination_warehouse_id` is nullable in schema (direct-to-project GRN UI was removed from project materials tab; prefer warehouse + dispatch).
- **No repository layer:** controllers call services / Eloquent models directly.
- **No inventory observers/events:** stock posts run synchronously inside services.

---

## 2. Database Documentation

### 2.1 Shared document header pattern

Most transactional headers share:

| Field | Type | Notes |
|-------|------|-------|
| `tenant_id` | FK → tenants | Required |
| `document_number` | string(32) | Unique per tenant |
| `status` | string(32) | `draft` / `completed` / `cancelled` |
| `remarks` | text nullable | |
| `reference_number` / `reference_date` | nullable | External refs |
| `transaction_date` / `effective_date` | date | Business / ledger dates |
| `project_id` / `project_revision_id` | FK nullable (or required) | Project scope |
| `created_by` / `updated_by` / `approved_by` / `approved_at` | users FKs | Audit |

### 2.2 Shared document line pattern

| Field | Type | Notes |
|-------|------|-------|
| `line_number` | unsigned int | |
| `sku_id` | FK → skus | |
| `qty` | decimal(14,4) | Entered qty |
| `qty_in_base_uom` | decimal(14,4) | Converted |
| `unit_id` | FK → units | |
| `unit_price` | decimal nullable | |
| `tax_id` / `tax_amount` | nullable | Line tax |
| `line_remarks` | text nullable | |

### 2.3 Foundation tables

#### `tenant_settings`

| Column | Type | Constraints |
|--------|------|-------------|
| id | bigint PK | |
| tenant_id | FK tenants | **unique** |
| approval_enabled, material_request_enabled, multi_user_enabled, commissioning_enabled, allow_negative_stock, auto_reserve_inventory | boolean | defaults |
| inventory_costing_method | string(32) | default `fifo` |
| reconciliation_threshold | decimal(14,4) | |
| default_tax_id | FK taxes nullable | |
| document_number_padding | smallint | default 6 |

**Purpose:** Per-tenant ERP feature flags and defaults.

#### `document_sequences`

| Column | Type | Constraints |
|--------|------|-------------|
| tenant_id | FK | |
| document_type | string(64) | |
| prefix | string(16) | |
| next_number | bigint | |
| | | **unique** (tenant_id, document_type) |

**Purpose:** Atomic document number allocation (`DocumentNumberService`).

#### `approval_requests` / `inventory_comments`

Polymorphic stubs (`document_type` + `document_id`). **No operational UI.**

#### `attachments`

| Column | Type |
|--------|------|
| tenant_id, document_type, document_id | polymorphic target |
| file_name, file_path, mime_type | storage metadata |
| uploaded_by | FK users |

**Index:** `(document_type, document_id)`. Files under `uploads/{tenant_id}/`.

#### `project_revisions`

| Column | Type | Notes |
|--------|------|-------|
| tenant_id, project_id | FKs | |
| document_number | unique per tenant | e.g. REV-000001 |
| revision_number | int | |
| is_current | bool | |
| status, change_reason, customer_change_order_ref | | |
| approved_by, approved_at, created_by | | |
| superseded_by_revision_id | self FK nullable | |

**Index:** `(project_id, is_current)`.

#### `project_boqs` / `inventory_periods`

Schema stubs for BOQ versions and period close. **No enforcement UI.**

### 2.4 Catalog tables

| Table | Purpose | Key constraints |
|-------|---------|-----------------|
| `units` | UOM master | unique (tenant_id, symbol); unique (tenant_id, name, deleted_at); soft deletes |
| `taxes` | Tax rates | soft deletes |
| `brands` | Brand master | unique (tenant_id, name); soft deletes |
| `items` | Item + base_unit_id | unique (tenant_id, name); soft deletes |
| `item_variants` | Item × brand × variant | soft deletes |
| `skus` | Sellable/stock code | unique (tenant_id, sku_code); reorder_level; track_serial; soft deletes |
| `sku_uom_conversions` | Alternate UOM → base factor | unique (sku_id, unit_id) |
| `suppliers` | Supplier master | unique (tenant_id, name); soft deletes |
| `supplier_price_history` | Append-only prices from GRN | index (supplier_id, sku_id); optional grn_line_id |

**Hierarchy:** Item → ItemVariant → Sku.

### 2.5 Warehouse & stock tables

| Table | Purpose | Key constraints |
|-------|---------|-----------------|
| `warehouses` | Physical warehouses | type: `main` \| `regional` (project_store removed) |
| `warehouse_bins` | Bin/rack stub | unique (warehouse_id, code) |
| `inventory_stock_positions` | Qty by location + status | **unique** (tenant_id, sku_id, location_type, location_id, inventory_status) |
| `inventory_batches` | FIFO lots | qty_received/remaining, landed_unit_cost; optional source_batch_id (dispatch split) |
| `inventory_serial_numbers` | Serial tracking | unique (tenant_id, serial_no) |
| `inventory_reservations` | Reservation stub | — |

**`inventory_stock_positions` location model:**

- `location_type` = `warehouse` → `location_id` / `warehouse_id` = warehouse  
- `location_type` = `project` → `location_id` = project id; status typically `at_project`

### 2.6 Ledger: `inventory_movements`

Immutable stock ledger (table replaced in ERP migration).

| Column | Purpose |
|--------|---------|
| sku_id, tenant_id | |
| project_id, project_revision_id | optional project scope |
| movement_type, source_module | e.g. purchase_in, issue, adjustment |
| qty, qty_before, qty_after | signed qty |
| from_/to_ location_type, location_id, status | movement path |
| landed_unit_cost, issue_unit_cost | valuation |
| batch_id, serial_id | traceability |
| reference_type, reference_id, document_number | source document |
| transaction_date, effective_date | |

**Indexes:** `(tenant_id, sku_id, effective_date)`, `(reference_type, reference_id)`.

### 2.7 Planning & procurement

| Table | Purpose |
|-------|---------|
| `material_plans` / `material_plan_lines` | Project BOM (revision-scoped) |
| `material_requests` / `material_request_lines` | **Schema only** (Phase 2) |
| `purchase_orders` / `purchase_order_lines` | PO to supplier |
| `goods_receipts` / `grn_lines` | GRN into warehouse |
| `grn_landed_cost_components` | Extra cost components per GRN line |

**GRN extras:** `use_average_gst`, `average_gst_rate`, `average_gst_amount`; `destination_warehouse_id` **nullable**.

### 2.8 Operations tables

| Table | Purpose | UI? |
|-------|---------|-----|
| `inventory_reason_codes` | Codes for adjustment/return/wastage | Read-only list |
| `site_dispatches` / `site_dispatch_lines` | Warehouse → project | Yes |
| `stock_adjustments` / `stock_adjustment_lines` | Physical count adjustments (`system_qty`, `counted_qty`) | Yes |
| `returns` / `return_lines` | Return documents | No |
| `installations`, `installation_roofs`, `installation_strings` | Install records | No |
| `qc_approvals` | QC records | No |
| `material_wastage_records` | Wastage | No |

**Dispatch extras:** average GST fields; `project_revision_id` nullable; line `batch_id` → `inventory_batches`.

**Removed:** `transfer_receipts`, `transfer_receipt_lines`, `warehouses.project_id`, project_store warehouse type.

### 2.9 Pre-existing core tables (billing / projects)

Not created by inventory migrations but central to ERP:

| Table | Role |
|-------|------|
| `tenants`, `users`, `tenant_user` | Multi-tenant membership & roles |
| `projects` | Customer site / job; kw, costs, GST, media keys, status |
| `payments` | Credits (customer) / debits (payout) |
| `payout_requests` | Service-user payout requests (standard/GST, TDS) |
| `payout_accounts` | Service-user bank/UPI profiles |

### 2.10 Entity relationship (simplified)

```text
Tenant
  ├── Units, Taxes, Brands, Items → Variants → Skus
  ├── Suppliers → PurchaseOrders → GoodsReceipts → GrnLines → Batches
  ├── Warehouses → StockPositions / Batches
  ├── Projects → Revisions → MaterialPlans
  │              ├── SiteDispatches (from Warehouse)
  │              ├── Payments / PayoutRequests
  │              └── StockPositions (at_project)
  └── InventoryMovements (ledger for all stock changes)
```

---

## 3. Code Flow & Architecture

### 3.1 Request flow (Inventory Web)

```text
Browser
  → routes/inventory.php  (middleware: auth, tenant_admin_web)
  → Web\Inventory\*Controller
  → Services\Inventory\*  (business rules, stock posting)
  → Eloquent Models
  → MySQL
  → Blade views under resources/views/admin/inventory/
```

There is **no repository layer**. Controllers validate HTTP input, call services, redirect/flash, or return views/JSON.

### 3.2 Request flow (API)

```text
Mobile / client
  → routes/api.php
  → middleware: auth:sanctum → tenant.context → tenant.active → role
  → Api\App\* or Api\TenantAdmin\*
  → ProjectLedgerService / ProjectFinancialPresenter / ProjectMediaService / …
  → JSON response
```

### 3.3 Document complete pattern

`InventoryDocumentService` (abstract) defines:

1. Validate document is draft  
2. `validateDocument` (subclass)  
3. Transaction: `postLedger` → `updateStock` → mark `completed`  

Concrete services: `PurchaseOrderService`, `GoodsReceiptService`, `DispatchService`, `StockAdjustmentService`.

### 3.4 Stock posting pattern

`InventoryLedgerService`:

- `recordMovement(...)` writes `inventory_movements`  
- `applyPositionDelta(...)` upserts `inventory_stock_positions`  
- `getPositionQty(...)` for availability checks  

`InventoryBatchService` handles warehouse batch availability and consume-on-dispatch (creates project-side batch with `source_batch_id`).

### 3.5 Cross-cutting components

| Component | Role |
|-----------|------|
| `EnsureTenantAdminWeb` | Session tenant admin gate for inventory UI |
| `TenantScopedRouteBindings` | Bind `{project}`, `{purchase_order}`, etc. to current tenant |
| `DocumentNumberService` | Next `PREFIX-000001` style numbers |
| `UomConversionService` | Line qty → base UOM |
| `TenantUploadService` / `ProjectMediaService` | Shared upload keys with mobile |
| `AttachmentService` | Inventory document files |
| `InventoryBootstrapService` | Seed default units/taxes/reason codes for new tenants |
| `SendTenantPushJob` | Only notable job (push notifications); **no inventory observers** |

### 3.6 Enums (inventory / documents / projects)

| Enum | Cases |
|------|-------|
| `DocumentStatus` | draft, completed, cancelled |
| `InventoryMaterialStatus` | warehouse, reserved, in_transit, at_project, installed, qc_approved, returned, damaged, scrapped |
| `InventorySourceModule` | goods_receipt, dispatch, return, adjustment, installation, qc, wastage, reservation, transfer |
| `WarehouseType` | main, regional |
| `MasterStatus` | active, inactive |
| `ProjectStatus` | pending_approval, approved, installation, qc, commissioning, completed, rejected |
| `InventoryAttachmentDocumentType` | purchase_order, goods_receipt, site_dispatch, stock_adjustment, return, material_wastage_record, material_plan, project_revision |

---

## 4. Module Documentation

### 4.1 Projects (API + Inventory Web)

**Purpose:** Represent a customer solar site/job; drive billing, media, and inventory destination.

**Features implemented:**

- Create (app → pending; tenant admin → approved)  
- Approve / reject / complete (tenant admin API)  
- Media upload (photos_* + other_documents)  
- Financial summary (ledger + material costs)  
- Inventory web: list, show with KPIs + tabs (payments, payouts, materials, revisions, photos)

**Status transitions (wired):**

```text
pending_approval ──approve──► approved ──complete──► completed
       │
       └──reject──► rejected

(Admin create starts at approved)
(Payout approve may auto-complete when ledger says ready)
```

**Not wired:** `installation`, `qc`, `commissioning` (enum + filters only).

**Tables:** `projects`, `project_revisions`, `payments`, `payout_requests`, media columns on projects.

**UI:** `/admin/inventory/projects`, `/admin/inventory/projects/{id}?tab=...`

**APIs:** see §6.

### 4.2 Inventory masters

| Module | Purpose | Screens | Tables |
|--------|---------|---------|--------|
| Units | UOM | CRUD (+ destroy) | units |
| Taxes | GST/tax rates | CRUD (+ destroy) | taxes |
| Brands | Brands | CRUD | brands |
| Items | Catalog items + base unit | CRUD | items, item_variants (via forms) |
| SKUs | Stock codes | CRUD + search endpoint | skus, sku_uom_conversions |
| Suppliers | Vendors | CRUD | suppliers |
| Warehouses | Stock locations | CRUD | warehouses |

**Workflow:** Create masters → create SKUs → use in PO/GRN/dispatch lines via SKU picker.

### 4.3 Purchase orders

**Purpose:** Commit purchase from supplier (optionally linked to project / material plan).

**Features:** Draft create/edit, complete (no stock movement), PDF download, attachments.

**Tables:** `purchase_orders`, `purchase_order_lines`.

**Validation (typical):** supplier required; lines require sku_id, qty, unit_id; dates required.

**Workflow:** Draft → Complete → (optional) create GRN from PO prefill.

### 4.4 Goods receipts

**Purpose:** Receive stock into warehouse; create batches; update stock + price history.

**Features:** Draft create/edit, PO prefill JSON, average GST option, complete posts ledger/batches, PDF, attachments.

**Tables:** `goods_receipts`, `grn_lines`, `grn_landed_cost_components`, `inventory_batches`, `supplier_price_history`, `inventory_stock_positions`, `inventory_movements`.

**Workflow:** Draft (warehouse destination) → Complete → warehouse qty increases; batch rows created.

**Note:** Direct-to-project GRN is no longer surfaced on the project materials tab; warehouse + dispatch is the intended path.

### 4.5 Dispatches (site dispatch)

**Purpose:** Issue material from warehouse to project site.

**Features:** Draft create/edit, available qty + batch picker (AJAX), qty cannot exceed available, optional project revision, average GST, complete consumes batch / creates project batch, PDF, attachments.

**Tables:** `site_dispatches`, `site_dispatch_lines`, batches, stock positions, movements.

**On complete:** warehouse stock ↓; project `at_project` stock ↑; ledger with issue cost.

**Validation:** project + source warehouse required; lines need sku, qty, unit; batch availability checked server-side.

### 4.6 Stock & ledger

**Stock page:** One row per SKU; warehouse qty; modal shows locations (warehouse name or project + service user) and total inward qty.

**Ledger page:** Movement list (read-only).

**Tables:** `inventory_stock_positions`, `inventory_movements`.

### 4.7 Stock adjustments

**Purpose:** Physical count → system qty vs counted → reason code → post.

**Features:** Create draft from warehouse stock snapshot, complete posts adjustment movements.

**Tables:** `stock_adjustments`, `stock_adjustment_lines`, `inventory_reason_codes`.

### 4.8 Attachments

**Purpose:** Files on PO/GRN/dispatch/adjustment (and related types).

**UI:** Partial on document show pages (upload while draft; download always).

### 4.9 Material plans & revisions

**Revisions:** Create new current revision (supersedes previous).  
**Material plans:** Add BOM lines against current revision.

**Tables:** `project_revisions`, `material_plans`, `material_plan_lines`.

### 4.10 Billing (payments & payouts)

**Purpose:** Track customer receipts and service-user payouts; compute commission, GST liability, available-to-request.

**Implemented via API** (not full inventory CRUD screens). Project show tabs display payments/payouts read-only.

**Services:** `ProjectLedgerService`, `ProjectFinancialPresenter`.

### 4.11 Dashboard (inventory)

**KPIs:** Completed kW, in-progress kW, inventory value, warehouse/site qty, dead stock, reorder alerts, GRN inward cost, dispatch cost, project material cost, gross margin; charts.

**Service:** `InventoryDashboardService`.

### 4.12 Settings & reason codes

**Settings:** Feature flags (approval, MR, commissioning, negative stock, etc.), costing method, padding.  
**Reason codes:** Seeded list; used by adjustments; index is read-only.

### 4.13 Schema-only modules (no UI)

Material requests, returns, installations/QC, wastage, reservations, bins UI, inventory periods, approval_requests, inventory_comments, project_boqs (beyond stub).

---

## 5. UI Documentation

### 5.1 Shell & navigation

**Layout:** `resources/views/admin/layouts/inventory.blade.php`  
**Login:** `/admin/login` (tenant admin)  
**Base URL:** `/admin/inventory`

**Sidebar:**

- Dashboard  
- **Masters:** Units, Taxes, Brands, Items, SKUs, Suppliers, Warehouses  
- **Transactions:** Purchase orders, Goods receipts, Dispatches, Stock adjustments  
- **Projects:** Projects, Reason codes  
- **Reports:** Stock, Ledger, Settings  

### 5.2 Screen inventory

| Screen | Route name | What it does |
|--------|------------|--------------|
| Dashboard | `admin.inventory.dashboard` | KPIs + charts |
| Units / Taxes / Brands / Items / SKUs / Suppliers / Warehouses index+forms | `*.index/create/edit` | Master CRUD |
| Projects index | `projects.index` | Customer, service user, kW, location, status; open project |
| Project show | `projects.show` | KPI boxes + tabs: Overview, Payments, Payouts, Material on site, Revisions, Photos |
| Revisions | `projects.revisions.index` | List + create revision |
| Material plans | `projects.material-plans.index` | BOM lines |
| Project media | `projects.media.index` | Installation photos (same fields as mobile) |
| PO index/create/edit/show/pdf | `purchase-orders.*` | Draft/complete/PDF/download icon when completed |
| GRN index/create/edit/show/pdf | `goods-receipts.*` | Same pattern + PO prefill |
| Dispatch index/create/edit/show/pdf | `dispatches.*` | Batch pick, available qty, PDF |
| Stock adjustments index/create/show | `stock-adjustments.*` | Count & complete |
| Stock | `stock.index` | SKU availability + location modal |
| Ledger | `ledger.index` | Movements |
| Reason codes | `reason-codes.index` | Read-only |
| Settings | `settings.index` | Tenant ERP flags |

### 5.3 Common UI patterns

- **Action icons:** View / Download PDF / Edit  
- **Document show:** Meta card, line table, totals, Complete button (draft), attachments  
- **SKU picker:** Search endpoint `admin.inventory.skus.search`  
- **Flash messages:** success / error / validation list  

### 5.4 Navigation flow (happy path)

```text
Login → Dashboard
  → Masters (setup)
  → Purchase orders → Complete → Goods receipts (prefill) → Complete
  → Dispatches → Complete
  → Stock (verify warehouse qty)
  → Projects → Project show → Material on site / Payments / Payouts
```

---

## 6. API Documentation

Inventory ERP **does not** expose PO/GRN/dispatch REST APIs. Mobile continues to use project/billing APIs.

### 6.1 Authentication

| Layer | Requirement |
|-------|-------------|
| All protected routes | `Authorization: Bearer {token}` (`auth:sanctum`) |
| Tenant routes | Tenant context (`X-Tenant-ID` / membership) + tenant active |
| Tenant admin | `tenant_admin` middleware |
| Service user app | `tenant_member` + `service_user` |

### 6.2 Auth endpoints

| Method | Path | Notes |
|--------|------|-------|
| POST | `/api/auth/login` | Public |
| POST | `/api/auth/logout` | Sanctum |
| GET | `/api/auth/me` | Sanctum |

### 6.3 Tenant Admin — Projects

| Method | Path | Action |
|--------|------|--------|
| GET/POST | `/api/tenant-admin/projects` | List / create (status=approved) |
| GET/PATCH | `/api/tenant-admin/projects/{project}` | Show / update |
| PATCH | `/api/tenant-admin/projects/{project}/media` | Media |
| POST | `/api/tenant-admin/projects/{project}/approve` | pending → approved |
| POST | `/api/tenant-admin/projects/{project}/reject` | pending → rejected (`reason` required) |
| POST | `/api/tenant-admin/projects/{project}/complete` | **approved only** → completed |
| GET | `/api/tenant-admin/projects/{project}/financials` | Ledger summary + credits/payouts |

**Financials on project payloads** include presenter fields plus:

- `material_purchase_amount` / `material_received_cost` — what the company paid for material on site (direct-site GRN landed + tax + warehouse batch cost on dispatch, incl. allocated inbound tax)
- `material_dispatch_amount` / `material_issued_cost` — charged to site (site charge + dispatch unit price + tax)
- `material_margin` — dispatch − purchase
- `material_total_cost` — alias of purchase amount (backward compatible) 

### 6.4 Tenant Admin — Payments & payouts

| Method | Path |
|--------|------|
| GET/POST | `/api/tenant-admin/payments` |
| GET/PATCH/DELETE | `/api/tenant-admin/payments/{payment}` |
| GET | `/api/tenant-admin/payout-requests` |
| GET | `/api/tenant-admin/payout-requests/{id}` |
| POST | `.../approve` / `.../reject` |

### 6.5 App (service user) — Projects & billing

| Method | Path | Notes |
|--------|------|-------|
| GET/POST | `/api/app/projects` | Create → `pending_approval` |
| GET/PATCH | `/api/app/projects/{project}` | Update only while pending |
| PATCH | `/api/app/projects/{project}/media` | Allowed through installation/qc/commissioning |
| GET | `/api/app/payments`, `/payments/{id}` | Read |
| GET/POST | `/api/app/payments/{id}/comments` | Comments |
| CRUD | `/api/app/payout-accounts` | Bank/UPI |
| GET | `/api/app/projects/{project}/ledger` | Ledger |
| GET/POST | `/api/app/projects/{project}/payout-requests` | Request payout |
| GET | `/api/app/payout-requests`, `/{id}` | List/show |

### 6.6 Files

| Method | Path | Response |
|--------|------|----------|
| POST | `/api/tenant-admin/files/upload` | `{ "key": "uploads/{tenant_id}/..." }` |
| POST | `/api/app/files/upload` | Same |

### 6.7 Other API groups (non-inventory)

- Super-admin tenants/admins  
- Dashboards (`/api/tenant-admin/dashboard`, `/api/app/dashboard`)  
- Masters (`/api/*/masters`)  
- Service user management (tenant admin)

### 6.8 Inventory web JSON helpers (session auth, not mobile)

| Route | Purpose |
|-------|---------|
| `dispatches.warehouse-stock` | Available qty |
| `dispatches.warehouse-batches` | Batch list + costs |
| `goods-receipts.purchase-order-prefill` | Prefill GRN from PO |
| `stock-adjustments.warehouse-stock` | Positions for count |
| `skus.search` | SKU typeahead |

---

## 7. Current Features

### 7.1 Completed

- Multi-tenant inventory masters and document numbering  
- PO / GRN / Dispatch draft→complete with ledger + stock  
- FIFO-style batches; dispatch batch selection and cost carry  
- Average GST on GRN/dispatch documents  
- Stock positions UI (SKU rollup + location modal)  
- Stock adjustments with reason codes  
- Attachments on inventory documents  
- PDF for PO, GRN, Dispatch  
- Inventory dashboard (incl. completed / in-progress kW)  
- Project list + rich project show (financial KPIs + tabs)  
- Project media shared with mobile  
- Billing ledger financials extended with material cost fields on API  

### 7.2 Partially completed

- Project revisions / BOM (basic create/list)  
- Tenant settings flags (not all enforced in every service path)  
- Reason codes (seed + read-only; used by adjustments)  
- Project statuses installation/qc/commissioning (declared, not transitioned)  
- Landed cost components table (backend support; limited UI)  
- Material reconciliation service (code exists; no screen)  

### 7.3 Pending / TODO (from plan vs code)

- Material request module UI/workflow  
- Returns, wastage, installation, QC admin flows  
- Reconciliation UI  
- Warehouse bins / serial operations UI  
- Approval engine for documents  
- Inventory period close enforcement  
- Mobile APIs for inventory documents (if required)  
- Wire status transitions for installation → qc → commissioning → completed  
- Supplier price history screen  

---

## 8. Folder Structure

```text
app/
  Enums/                    # DocumentStatus, Inventory*, ProjectStatus, WarehouseType, …
  Http/Controllers/
    Api/App/                # Mobile service-user APIs
    Api/TenantAdmin/        # Tenant admin APIs (projects, payments, payouts)
    Web/Inventory/          # Inventory ERP web controllers
  Models/
    Inventory/              # ERP Eloquent models
    Concerns/               # HasInventoryDocumentHeader / Line
    Project.php, Payment.php, PayoutRequest.php, …
  Services/
    Inventory/              # Document + stock services
    ProjectLedgerService.php
    ProjectFinancialPresenter.php
    ProjectMediaService.php
    TenantUploadService.php
  Http/Middleware/
    EnsureTenantAdminWeb.php
  Support/
    TenantScopedRouteBindings.php

database/migrations/
  2026_07_09_*              # ERP foundation → operations
  2026_07_10_*              # GST, batches, revision nullable, unit unique

resources/views/admin/
  layouts/inventory.blade.php
  inventory/                # All ERP Blade screens + partials

routes/
  api.php                   # Mobile/admin JSON APIs
  web.php                   # requires inventory.php
  inventory.php             # ERP web routes

tests/Feature/Web/Inventory/
tests/Support/CreatesInventoryFixtures.php

docs/
  inventory_management_admin_panel_*.plan.md   # Original plan
  attachments_and_adjustments_*.plan.md
  erp_system.md                               # This document
```

**Naming conventions:**

- Controllers: resource-style methods (`index`, `store`, `show`, `complete`, `downloadPdf`)  
- Document services: `createDraft`, `updateDraft`, inherit `complete`  
- Route names: `admin.inventory.{resource}.{action}`  
- Views: `admin.inventory.{resource}.{action}`  

---

## 9. ERP Workflow

### 9.1 End-to-end business flow (implemented)

```text
1. Tenant + service users exist (pre-ERP)
2. Service user creates Project (pending_approval) via app
   OR tenant admin creates Project (approved)
3. Tenant admin approves project (if pending)
4. Inventory admin sets up masters (units, taxes, brands, items, SKUs, suppliers, warehouses)
5. Optional: create project revision + material plan (BOM)
6. Create Purchase Order (draft) → Complete
7. Create Goods Receipt against warehouse (optionally from PO) → Complete
      → Stock in warehouse + batches + price history + ledger
8. Create Site Dispatch to project (pick batches) → Complete
      → Stock moves warehouse → at_project + ledger + material cost on project
9. Customer payments recorded (tenant admin API)
10. Service user requests payouts; admin approves/rejects (API)
11. Project financials show commission, GST liability, material margin, cash balance
12. Tenant admin completes project (from approved) when work is done
```

### 9.2 Stock status path (implemented)

```text
GRN complete  → inventory_status = warehouse
Dispatch complete → warehouse ↓ ; at_project ↑
(Future) Installation / QC statuses exist on enum but are not posted by UI yet
```

### 9.3 Billing path (implemented, API)

```text
bill_to_customer / project_cost / gst_amount / commission
  → credits increase customer_received
  → available_to_request (two-phase):
      before credits >= project_cost: credits − paid − pending (may be negative; requests still allowed)
      after fully paid: max(0, project_cost − remaining GST − commission − paid − pending)
        (remaining GST avoids double-counting GST already paid out; floored at 0)
  → pending payouts reduce available_to_request
  → approved payouts create debit payments
  → remaining_gst_liability reduced by GST-type payouts
```

### 9.4 What is intentionally out of the current live path

- Project store + transfer receipt  
- Direct site GRN as primary UX  
- Automatic project status moves on dispatch/install  

---

## 10. Next Phase Preparation

### 10.1 Gaps vs original inventory plan

| Planned | Current |
|---------|---------|
| Warehouse → project_store → install | Warehouse → at_project only |
| TRN module | Removed |
| Installations / QC / commissioning UI | Models only; statuses enum-only |
| Material requests | Tables only |
| Returns / wastage | Tables only |
| Reconciliation screen | Service only |
| Document approvals | Stub table |
| Inventory APIs for mobile | Not built |

### 10.2 Recommended next priorities

1. **Project status workflow** — Admin (and/or API) actions:  
   `approved → installation → qc → commissioning → completed`  
   Update `complete` to accept late-stage statuses; sync mobile status labels.

2. **Installation + QC modules** — UI to post install qty/serials and QC; optionally auto-advance status; write movements to `installed` / `qc_approved`.

3. **Material reconciliation screen** — Wire `MaterialReconciliationService` to project show tab (planned vs dispatched vs installed).

4. **Returns & wastage** — Operational UI using existing tables + reason codes.

5. **Material requests (if needed)** — Enable when `material_request_enabled`; link to PO.

6. **Enforce settings** — Negative stock, approval_enabled, period close.

7. **Bins / serials** — Only if operationally required.

8. **Mobile inventory (optional)** — Read-only stock / dispatch status for service users.

### 10.3 Stability notes for mobile

- Additive financial fields (`material_*_cost`) are backward compatible.  
- New project status strings should be handled in UI even before transitions are wired.  
- File upload response shape unchanged (`key`).  
- Inventory admin routes are **web session only** — no impact on Sanctum clients unless new APIs are added.

### 10.4 Related documents

- `docs/inventory_management_admin_panel_c4e34150.plan.md` — Original ERP plan  
- `docs/attachments_and_adjustments_9dec33cb.plan.md` — Attachments & adjustments plan  

---

## Appendix A — Inventory web route map (summary)

Prefix: `/admin/inventory` · Name prefix: `admin.inventory.` · Middleware: `auth`, `tenant_admin_web`

| Area | Routes |
|------|--------|
| Dashboard | `GET /` |
| Masters | resource units, taxes, brands, items, skus, suppliers, warehouses |
| Projects | `GET projects`, `GET projects/{project}`, revisions, material-plans, media |
| Transactions | purchase-orders (+ complete, pdf), goods-receipts (+ prefill, complete, pdf), dispatches (+ stock/batches, complete, pdf), stock-adjustments (+ warehouse-stock, complete) |
| Attachments | store, download, destroy |
| Reports | stock, ledger, settings, reason-codes |
| Auth | `/admin/login`, `/admin/logout` |

## Appendix B — Key services cheat sheet

| Service | Responsibility |
|---------|----------------|
| `DocumentNumberService` | Next document number |
| `PurchaseOrderService` | PO draft/complete |
| `GoodsReceiptService` | GRN draft/complete → stock/batches |
| `DispatchService` | Dispatch draft/complete → site stock |
| `StockAdjustmentService` | Count adjustments |
| `InventoryLedgerService` | Movements + positions |
| `InventoryBatchService` | Batch availability / consume |
| `ProjectMaterialCostService` | Project material costs from movements |
| `InventoryDashboardService` | Dashboard metrics |
| `MaterialReconciliationService` | Planned vs actual (no UI yet) |
| `ProjectLedgerService` | Billing ledger math |
| `ProjectFinancialPresenter` | API/web financial DTO |

---

*End of document. Update this file when modules ship or architecture decisions change.*
