pratikbackend / docs /BUSINESS_LOGIC.md
Antaram's picture
Upload 96 files
7647b38 verified
|
Raw
History Blame Contribute Delete
22 kB

Mirchi Trading - Business Logic & Backend Architecture

Business Flow Analysis

Bill Types Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        BILL TYPE CLASSIFICATION                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚   ALL BILLS     โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚                             โ”‚
      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
      โ”‚   REGULAR     โ”‚             โ”‚    PATTI      โ”‚
      โ”‚   (R)         โ”‚             โ”‚    (P)        โ”‚
      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                             โ”‚
       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚             โ”‚              โ”‚             โ”‚
   โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”
   โ”‚ AWAAK โ”‚    โ”‚JAWAAK โ”‚      โ”‚ AWAAK โ”‚    โ”‚JAWAAK โ”‚
   โ”‚ (Buy) โ”‚    โ”‚ (Sell)โ”‚      โ”‚ (Buy) โ”‚    โ”‚ (Sell)โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚             โ”‚              โ”‚             โ”‚
       โ”‚             โ”‚              โ”‚             โ”‚
   Stock IN       Stock OUT     Stock IN      Stock OUT
   (Purchase)     (Sales)       (Purchase)    (Sales)

1. REGULAR BILLS (Awaak/Jawaak)

Awaak Regular (Purchase/Buy)

  • Purpose: Buying mirchi from farmers/suppliers
  • Stock Impact: INCREASES stock
  • Payment Flow: We PAY money to party
  • Balance: Party gets CREDIT (Jama for them)

Data Captured:

- Party details (farmer/supplier)
- Mirchi items with:
  โ€ข Poti count
  โ€ข Poti weights (individual bag weights)
  โ€ข Net weight (total)
  โ€ข Rate per kg
  โ€ข Amount
- Expenses:
  โ€ข Poti amount (packing)
  โ€ข CESS
  โ€ข Adat (commission)
  โ€ข Hamali (labor)
  โ€ข Packaging hamali
  โ€ข Gaadi bharni (transport)
  โ€ข Other expenses
- Payment details:
  โ€ข Cash, UPI, Bank, Due

Jawaak Regular (Sales/Sell)

  • Purpose: Selling mirchi to buyers
  • Stock Impact: DECREASES stock
  • Payment Flow: We RECEIVE money from party
  • Balance: Party gets DEBIT (Udha for them)

Data Captured:

- Same as Awaak but:
  โ€ข Stock goes OUT
  โ€ข We receive payment
  โ€ข Balance is what party OWES us

2. PATTI BILLS (Special Trading)

Patti Awaak (Patti Purchase)

  • Purpose: Buying mirchi on behalf of another party (patti system)
  • Stock Impact: NO direct stock change (held in patti)
  • Key Difference: NO lot/weight initially - just basic purchase

Data Captured:

- Party (patti holder)
- Mirchi items with:
  โ€ข Poti count
  โ€ข Poti weights
  โ€ข Net weight
  โ€ข Rate per kg
- Patti-specific expenses:
  โ€ข Packing
  โ€ข Godown (storage)
  โ€ข Commission
  โ€ข Hamali
  โ€ข Gaadi bhade (transport)
  โ€ข Other expenses
- NO lot number initially
- NO stock entry until processed

Patti Jawaak (Patti Sales with Lot/Weight)

  • Purpose: Selling patti mirchi with lot tracking
  • Stock Impact: Stock OUT from patti holdings
  • Key Feature: HAS lot number and weightage

Data Captured:

- Party (patti holder)
- Lot number (MANDATORY)
- Mirchi items with:
  โ€ข Poti count
  โ€ข Poti weights (detailed)
  โ€ข Net weight (calculated)
  โ€ข Rate per kg
- Weightage details:
  โ€ข Gross weight
  โ€ข Tare weight
  โ€ข Net weight verification
- Expenses same as Patti Awaak
- Stock adjustment from patti holdings

3. MIXED BILLS (Regular + Patti Combined)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    MIXED BILL STRUCTURE                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Item 1: เคธเคพเคตเคฟเคคเฅเคฐเฅ€ (source: normal)  - Regular stock        โ”‚
โ”‚  Item 2: เคœเฅเคฏเฅ‹เคคเคฟ   (source: patti)   - Patti stock          โ”‚
โ”‚  Item 3: เคจเคพเค—เคฟเคจ   (source: normal)  - Regular stock        โ”‚
โ”‚  Item 4: เคฌเฅเคฏเคพเคกเค—เฅ€  (source: patti)   - Patti stock          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Combined expenses from both sources                        โ”‚
โ”‚  Combined payment tracking                                  โ”‚
โ”‚  Stock adjustment for BOTH regular and patti               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. BILL NUMBERING SYSTEM

Format: {PREFIX}{BATCH}{NUMBER}

Year: 2025
โ”œโ”€โ”€ A Batch: A1, A2, A3 ... A500     (Regular Awaak)
โ”œโ”€โ”€ B Batch: B1, B2, B3 ... B500     (Regular Awaak overflow)
โ”œโ”€โ”€ C Batch: C1, C2, C3 ... C500     (Regular Awaak overflow)
โ”‚   ... continues till Z500
โ”œโ”€โ”€ J Batch: J1, J2, J3 ... J500     (Regular Jawaak)
โ”‚   ... continues
โ”œโ”€โ”€ PA Batch: PA1, PA2 ... PA500     (Patti Awaak)
โ”œโ”€โ”€ PJ Batch: PJ1, PJ2 ... PJ500     (Patti Jawaak)
โ””โ”€โ”€ M Batch: M1, M2, M3 ... M500     (Mixed bills)

Next Year: 2026
โ”œโ”€โ”€ All batches RESET to 1
โ””โ”€โ”€ Format: {PREFIX}{YEAR}{BATCH}{NUMBER}
    Example: A2026A1, A2026A2, ... A2026A500

Bill Number Structure

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  BILL NUMBER FORMAT                                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                               โ”‚
โ”‚  Regular:   {TYPE}{YEAR}{BATCH}{NUMBER}                      โ”‚
โ”‚             A2025A001  = Awaak 2025, Batch A, Bill 1         โ”‚
โ”‚             A2025A500  = Awaak 2025, Batch A, Bill 500       โ”‚
โ”‚             A2025B001  = Awaak 2025, Batch B, Bill 1         โ”‚
โ”‚             J2025A001  = Jawaak 2025, Batch A, Bill 1        โ”‚
โ”‚                                                               โ”‚
โ”‚  Patti:     {TYPE}{YEAR}{BATCH}{NUMBER}                      โ”‚
โ”‚             PA2025A001 = Patti Awaak 2025, Batch A, Bill 1   โ”‚
โ”‚             PJ2025A001 = Patti Jawaak 2025, Batch A, Bill 1  โ”‚
โ”‚                                                               โ”‚
โ”‚  Mixed:     M{YEAR}{BATCH}{NUMBER}                           โ”‚
โ”‚             M2025A001  = Mixed 2025, Batch A, Bill 1         โ”‚
โ”‚                                                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Database Table for Bill Number Tracking

CREATE TABLE bill_number_sequences (
    id SERIAL PRIMARY KEY,
    bill_type VARCHAR(10) NOT NULL,      -- 'A', 'J', 'PA', 'PJ', 'M'
    year INT NOT NULL,                    -- 2025, 2026
    batch VARCHAR(1) NOT NULL,            -- 'A' to 'Z'
    current_number INT NOT NULL DEFAULT 0, -- 0 to 500
    is_full BOOLEAN DEFAULT FALSE,        -- True when reaches 500
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    
    UNIQUE (bill_type, year, batch)
);

-- Index for fast lookup
CREATE INDEX idx_bill_seq ON bill_number_sequences (bill_type, year, batch);

5. PARTY RENAME SCENARIO

Problem Statement

Initial State:
- Party ID: p-abc123
- Party Name: "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคŸเฅเคฐเฅ‡เคกเคฐเฅเคธ"
- 10 transactions with this party

User Action:
- Rename party to "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ"

Question:
- What happens to old transactions?
- Should they show old name or new name?

Solution: Denormalized + Historical Tracking

-- Parties table
CREATE TABLE parties (
    id VARCHAR(50) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,              -- Current name
    previous_names JSONB,                    -- History of name changes
    phone VARCHAR(20),
    city VARCHAR(255),
    party_type VARCHAR(20),
    ...
);

-- Transactions table
CREATE TABLE transactions (
    id VARCHAR(50) PRIMARY KEY,
    bill_number VARCHAR(20) UNIQUE,
    party_id VARCHAR(50) REFERENCES parties(id),
    party_name VARCHAR(255) NOT NULL,        -- SNAPSHOT at bill time
    party_name_current VARCHAR(255),          -- Current name (for search)
    ...
);

Name Change Flow

1. User renames party "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคŸเฅเคฐเฅ‡เคกเคฐเฅเคธ" โ†’ "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ"

2. Backend updates:
   - parties.name = "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ"
   - parties.previous_names = [
       {"old_name": "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคŸเฅเคฐเฅ‡เคกเคฐเฅเคธ", "changed_at": "2025-03-13"}
     ]
   
3. New transactions will use:
   - party_name = "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ" (snapshot)
   - party_name_current = "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ"

4. Old transactions keep:
   - party_name = "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคŸเฅเคฐเฅ‡เคกเคฐเฅเคธ" (original snapshot)
   - party_name_current = "เคฐเคพเคฎเคšเค‚เคฆเฅเคฐ เคเค‚เคก เคธเค‚เคธ" (for search)

5. Reports/Invoices show:
   - Historical: Original name at time of transaction
   - Search: Works with current name

6. REVERT LOGIC

Revert Scenarios

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      REVERT FLOW                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                 โ”‚
โ”‚  Regular Awaak Revert:                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    Revert     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚ Stock: +100 โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ Stock: -100 โ”‚                โ”‚
โ”‚  โ”‚ Balance: +โ‚น5000 โ”‚           โ”‚ Balance: -โ‚น5000 โ”‚            โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                                 โ”‚
โ”‚  Regular Jawaak Revert:                                        โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    Revert     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚ Stock: -50  โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ Stock: +50  โ”‚                โ”‚
โ”‚  โ”‚ Balance: +โ‚น3000 โ”‚           โ”‚ Balance: -โ‚น3000 โ”‚            โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                                 โ”‚
โ”‚  Patti Revert:                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    Revert     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚ Patti Stock โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ Patti Stock โ”‚                โ”‚
โ”‚  โ”‚ Balance     โ”‚               โ”‚ Reversed    โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Revert Rules

  1. Can Revert: Bill has no payments or all payments reversed

  2. Cannot Revert:

    • Already reverted
    • Has unreversed payments
    • Referenced by other bills
    • Stock already adjusted by later transactions
  3. Revert Creates:

    • is_return = True on original
    • New return bill with reference to original
    • Stock adjustment entry
    • Balance adjustment entry

7. STOCK MANAGEMENT

Stock Tracking

CREATE TABLE stock_ledger (
    id VARCHAR(50) PRIMARY KEY,
    mirchi_name VARCHAR(255) NOT NULL,
    mirchi_id VARCHAR(50) REFERENCES mirchi_types(id),
    
    -- Transaction reference
    transaction_id VARCHAR(50),
    patti_transaction_id VARCHAR(50),
    
    -- Stock movement
    movement_type VARCHAR(20) NOT NULL,  -- 'IN', 'OUT', 'RETURN_IN', 'RETURN_OUT'
    quantity_in FLOAT DEFAULT 0,
    quantity_out FLOAT DEFAULT 0,
    balance_after FLOAT NOT NULL,
    
    -- Lot tracking (for patti)
    lot_number VARCHAR(50),
    
    -- Timestamps
    created_at TIMESTAMP DEFAULT NOW(),
    
    -- Audit
    created_by VARCHAR(50),
    notes TEXT
);

8. IMPROVED DATABASE SCHEMA

Core Tables

-- Parties with name history
CREATE TABLE parties (
    id VARCHAR(50) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    previous_names JSONB DEFAULT '[]',
    phone VARCHAR(20) NOT NULL DEFAULT '',
    city VARCHAR(255) NOT NULL DEFAULT '',
    party_type VARCHAR(20) NOT NULL DEFAULT 'both',
    notes TEXT,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Mirchi Types
CREATE TABLE mirchi_types (
    id VARCHAR(50) PRIMARY KEY,
    name VARCHAR(255) NOT NULL UNIQUE,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Bill Number Sequences
CREATE TABLE bill_number_sequences (
    id SERIAL PRIMARY KEY,
    bill_type VARCHAR(10) NOT NULL,
    year INT NOT NULL,
    batch VARCHAR(1) NOT NULL,
    current_number INT NOT NULL DEFAULT 0,
    is_full BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE (bill_type, year, batch)
);

-- Regular Transactions
CREATE TABLE transactions (
    id VARCHAR(50) PRIMARY KEY,
    bill_number VARCHAR(20) NOT NULL UNIQUE,
    bill_date DATE NOT NULL,
    bill_type VARCHAR(20) NOT NULL,  -- 'awaak', 'jawaak'
    
    -- Party reference with snapshot
    party_id VARCHAR(50) NOT NULL REFERENCES parties(id),
    party_name VARCHAR(255) NOT NULL,           -- Snapshot at creation
    party_phone VARCHAR(20) DEFAULT '',
    
    -- Financials
    subtotal FLOAT DEFAULT 0,
    total_amount FLOAT DEFAULT 0,
    paid_amount FLOAT DEFAULT 0,
    balance_amount FLOAT DEFAULT 0,
    
    -- Expenses (JSONB for flexibility)
    expenses JSONB,
    
    -- Lot number (optional for regular)
    lot_number VARCHAR(50),
    
    -- Return tracking
    is_return BOOLEAN DEFAULT FALSE,
    original_bill_id VARCHAR(50) REFERENCES transactions(id),
    return_bill_id VARCHAR(50) REFERENCES transactions(id),
    
    -- Mixed bill flag
    is_mixed BOOLEAN DEFAULT FALSE,
    
    -- Timestamps
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Transaction Items
CREATE TABLE transaction_items (
    id VARCHAR(50) PRIMARY KEY,
    transaction_id VARCHAR(50) NOT NULL REFERENCES transactions(id) ON DELETE CASCADE,
    
    mirchi_name VARCHAR(255) NOT NULL,
    mirchi_id VARCHAR(50) REFERENCES mirchi_types(id),
    
    poti_count INT DEFAULT 0,
    poti_weights TEXT,              -- JSON array of weights
    net_weight FLOAT DEFAULT 0,
    rate_per_kg FLOAT DEFAULT 0,
    amount FLOAT DEFAULT 0,
    
    -- Source for mixed bills
    source VARCHAR(20) DEFAULT 'normal',  -- 'normal', 'patti'
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Transaction Payments
CREATE TABLE transaction_payments (
    id VARCHAR(50) PRIMARY KEY,
    transaction_id VARCHAR(50) NOT NULL REFERENCES transactions(id) ON DELETE CASCADE,
    
    amount FLOAT NOT NULL,
    mode VARCHAR(20) NOT NULL,      -- 'cash', 'upi', 'bank', 'due'
    reference VARCHAR(255),
    paid_at DATE,
    
    -- Revert tracking
    is_reversed BOOLEAN DEFAULT FALSE,
    reversed_at TIMESTAMP WITH TIME ZONE,
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Patti Transactions
CREATE TABLE patti_transactions (
    id VARCHAR(50) PRIMARY KEY,
    bill_number VARCHAR(20) NOT NULL UNIQUE,
    bill_date DATE NOT NULL,
    bill_type VARCHAR(20) NOT NULL,  -- 'patti_awaak', 'patti_jawaak'
    
    -- Party reference
    party_id VARCHAR(50) NOT NULL REFERENCES parties(id),
    party_name VARCHAR(255) NOT NULL,
    party_phone VARCHAR(20) DEFAULT '',
    
    -- Financials
    subtotal FLOAT DEFAULT 0,
    total_amount FLOAT DEFAULT 0,
    paid_amount FLOAT DEFAULT 0,
    balance_amount FLOAT DEFAULT 0,
    
    -- Patti expenses
    expenses JSONB,
    
    -- Lot number (MANDATORY for patti_jawaak)
    lot_number VARCHAR(50),
    
    -- Weightage details (for patti_jawaak)
    gross_weight FLOAT,
    tare_weight FLOAT,
    verified_net_weight FLOAT,
    
    -- Return tracking
    is_return BOOLEAN DEFAULT FALSE,
    original_bill_id VARCHAR(50) REFERENCES patti_transactions(id),
    
    -- Timestamps
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Patti Transaction Items
CREATE TABLE patti_transaction_items (
    id VARCHAR(50) PRIMARY KEY,
    transaction_id VARCHAR(50) NOT NULL REFERENCES patti_transactions(id) ON DELETE CASCADE,
    
    mirchi_name VARCHAR(255) NOT NULL,
    mirchi_id VARCHAR(50) REFERENCES mirchi_types(id),
    
    poti_count INT DEFAULT 0,
    poti_weights TEXT,
    net_weight FLOAT DEFAULT 0,
    rate_per_kg FLOAT DEFAULT 0,
    amount FLOAT DEFAULT 0,
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Stock Ledger
CREATE TABLE stock_ledger (
    id VARCHAR(50) PRIMARY KEY,
    mirchi_name VARCHAR(255) NOT NULL,
    mirchi_id VARCHAR(50) REFERENCES mirchi_types(id),
    
    -- References
    transaction_id VARCHAR(50) REFERENCES transactions(id),
    patti_transaction_id VARCHAR(50) REFERENCES patti_transactions(id),
    
    -- Movement
    movement_type VARCHAR(20) NOT NULL,
    quantity_in FLOAT DEFAULT 0,
    quantity_out FLOAT DEFAULT 0,
    balance_after FLOAT NOT NULL,
    
    -- Lot tracking
    lot_number VARCHAR(50),
    
    -- Timestamps
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Party Jama Entries (for balance tracking)
CREATE TABLE party_jama_entries (
    id VARCHAR(50) PRIMARY KEY,
    party_id VARCHAR(50) NOT NULL REFERENCES parties(id) ON DELETE CASCADE,
    
    entry_date DATE NOT NULL,
    amount FLOAT NOT NULL,
    entry_type VARCHAR(20) NOT NULL,  -- 'jama' (credit), 'udha' (debit)
    
    -- Reference
    transaction_id VARCHAR(50) REFERENCES transactions(id),
    patti_transaction_id VARCHAR(50) REFERENCES patti_transactions(id),
    reference VARCHAR(255),
    notes TEXT,
    
    -- Revert tracking
    is_reversed BOOLEAN DEFAULT FALSE,
    reversed_at TIMESTAMP WITH TIME ZONE,
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

9. API ENDPOINTS SUMMARY

Parties

  • GET /api/parties - List all parties
  • GET /api/parties/{id} - Get party details
  • POST /api/parties - Create party
  • PUT /api/parties/{id} - Update party (handles rename)
  • DELETE /api/parties/{id} - Soft delete party

Mirchi Types

  • GET /api/mirchi-types - List all types
  • POST /api/mirchi-types - Create type
  • PUT /api/mirchi-types/{id} - Update type
  • DELETE /api/mirchi-types/{id} - Soft delete

Transactions

  • GET /api/transactions - List with filters
  • GET /api/transactions/next-bill-number?type={type} - Get next bill number
  • GET /api/transactions/{id} - Get details
  • POST /api/transactions - Create transaction
  • PUT /api/transactions/{id} - Update transaction
  • POST /api/transactions/{id}/payment - Add payment
  • POST /api/transactions/{id}/revert - Revert transaction

Patti Transactions

  • Same structure as regular transactions
  • Additional endpoints for lot/weightage

Reports

  • GET /api/reports/stock - Stock report
  • GET /api/reports/party-ledger/{id} - Party ledger
  • GET /api/reports/daily-summary - Daily summary