# LIS Cost Calculation System — Design Document

**Date:** 2026-03-07
**Status:** Approved
**Project:** LIS (Support Project ID: 3)

## Goal

Calculate the cost of each LIS investigation using one of 3 switchable models, and integrate with accounting (COGS journal entries on invoice post).

## Cost Models

### Model A: Static
- `investigation.cost` — manually entered flat cost
- Simplest, no dependencies

### Model B: Reagent-Based
- `cost = SUM(consumable.quantity_per_test x reagent.effective_cost)`
- Reagent effective_cost = `product.average_cost` (if linked to inventory) OR `reagent.cost_per_unit` (manual)

### Model C: Full
- `cost = reagent_cost + machine_cost + labor_cost + overhead`
- Machine: `cost_per_test` (flat) OR `hourly_cost x minutes/60` (time-based) — per machine
- Labor: `(labor_cost_override OR global_rate) x labor_minutes/60`
- Overhead: `subtotal x (investigation_override OR section_override OR global_pct) / 100`

## Configuration

- **Global setting** selects which model is active for the entire lab
- Stored in `lis_settings` as `cost_model = static | reagent_based | full`
- Global settings: `labor_cost_per_hour`, `overhead_percentage`, `cogs_account_id`, `lab_expense_account_id`

## Data Model Changes

### New Table: `lis_investigation_consumables`
| Column | Type | Description |
|--------|------|-------------|
| id | BIGINT PK | |
| investigation_id | FK | Links to investigation |
| reagent_id | FK | Links to reagent |
| quantity_per_test | DECIMAL(10,4) | Amount consumed per test |
| is_active | BOOLEAN | |
| notes | VARCHAR(255) | |

### Extend: `lis_reagents`
| New Column | Type | Description |
|------------|------|-------------|
| cost_per_unit | DECIMAL(15,4) | Manual cost |
| product_id | FK nullable | Link to inventory product |
| cost_source | ENUM(manual, product) | Where cost comes from |

### Extend: `lis_machines`
| New Column | Type | Description |
|------------|------|-------------|
| cost_type | ENUM(per_test, time_based) | |
| cost_per_test | DECIMAL(15,4) | Flat per-test cost |
| hourly_cost | DECIMAL(15,4) | Time-based cost |
| purchase_cost | DECIMAL(15,4) | Original price |
| useful_life_months | INT | For depreciation |
| salvage_value | DECIMAL(15,4) | End-of-life value |
| monthly_maintenance | DECIMAL(15,4) | Recurring cost |

### Extend: `lis_investigations`
| New Column | Type | Description |
|------------|------|-------------|
| machine_id | FK nullable | Which machine |
| machine_minutes | DECIMAL(8,2) | Time per test |
| labor_minutes | DECIMAL(8,2) | Technician time |
| labor_cost_override | DECIMAL nullable | Override global rate |
| overhead_override | DECIMAL nullable | Override global/section % |
| calculated_cost | DECIMAL(15,4) | Auto-calculated |

### Extend: `lis_sections`
| New Column | Type | Description |
|------------|------|-------------|
| cost_center_id | FK nullable | Accounting cost center |
| overhead_percentage | DECIMAL | Section overhead % |
| monthly_overhead | DECIMAL | Fixed monthly overhead |

### Extend: `lis_invoices` / `lis_invoice_items`
| New Column | Type | Description |
|------------|------|-------------|
| invoice.cogs_journal_entry_id | FK nullable | COGS JE |
| invoice.total_cost | DECIMAL | Sum of item costs |
| item.unit_cost | DECIMAL | From calculated_cost |
| item.total_cost | DECIMAL | unit_cost x qty |

## Accounting Integration

On LIS invoice post:
1. Create COGS journal entry
2. Debit: `cogs_account_id` (from settings)
3. Credit: `lab_expense_account_id` (from settings)
4. Cost center from investigation's section
5. Store `cogs_journal_entry_id` on invoice
6. On cancel: reverse the COGS JE

## Frontend Screens

1. **Reagent form** — add cost_per_unit + product link
2. **Machine form** — add cost fields + depreciation
3. **Section form** — add cost_center_id + overhead
4. **Investigation form** — add machine, labor, overhead fields
5. **Investigation Cost tab** — consumables CRUD + full cost breakdown
6. **Cost Settings** — model selector + global rates + accounts
7. **Investigation list** — cost + margin columns
8. **Request wizard** — cost info in test selection + financial summary
9. **Invoice** — cost columns + profit display
10. **Cost dashboard** — KPIs, charts, top/bottom margin tables
11. **Profitability report** — filterable table with export

## Tickets

### Phase 1: Foundation (no sprint)
| # | Type | Title | Ticket |
|---|------|-------|--------|
| 1 | BE | Add cost fields to reagents, machines, sections + cost settings API | #344 |
| 2 | FE | Cost fields on reagent/machine/section forms + cost settings UI | #345 |

### Sprint 1: Cost Calculation Engine
| # | Type | Title | Ticket |
|---|------|-------|--------|
| 3 | BE | Investigation consumables CRUD + cost calculation engine | #346 |
| 4 | BE | COGS journal entry on LIS invoice post | #347 |
| 5 | FE | Investigation cost tab with consumables management | #348 |
| 6 | FE | Cost column in investigation list + cost in request wizard + invoice | #349 |

### Phase 3: Dashboard & Reports (no sprint)
| # | Type | Title | Ticket |
|---|------|-------|--------|
| 7 | BE | Profitability report + cost dashboard APIs | #350 |
| 8 | FE | Cost dashboard screen + profitability reports | #351 |

## Dependencies

```
#344 (BE foundation) --> #345 (FE foundation)
#344 --> #346 (BE consumables + engine)
#346 --> #347 (BE COGS journal)
#346 --> #348 (FE cost tab)
#348 --> #349 (FE cost display)
#347 --> #350 (BE dashboard APIs)
#350 --> #351 (FE dashboard)
```
