# Phase 11: Returns & Credit Notes - COMPLETE ✅

## Overview
Phase 11 implements a comprehensive return processing system with UID validation, inventory updates, and credit note generation. The system supports creating returns for sold items, validating that returned UIDs belong to the original sale, updating inventory status, and generating credit notes linked to fiscal receipts.

## Implementation Details

### 1. Return Service
**File:** `server/modules/returns/services/index.js`

Implemented the following functions:

#### createReturn
Creates a new return with items (DRAFT status):
- Validates sale exists
- Validates return items:
  - Validates sale_item_id exists in the original sale
  - Validates inventory_item_id exists and status is SOLD
  - Validates inventory item belongs to the sale item (product/variant match)
  - If sale item has inventory_item_id, validates it matches the returned item
- Calculates return amounts based on original sale item prices:
  - Uses original unit_price and vat_rate from sale item
  - Calculates line total, VAT amount, and item total
  - Sums all item totals for return total_amount
- Creates Return and ReturnItem records in a transaction
- Returns created return with all associations

#### getReturn
Retrieves a return by ID with complete associations:
- Includes sale and sale items
- Includes return items with sale items, products, variants
- Includes inventory items with products
- Includes credit notes (FiscalReceipt records)

#### listReturns
Lists returns with optional filters and pagination:
- Supports filtering by sale_id and status
- Paginated results with metadata
- Ordered by return date descending

#### completeReturn
Completes a return by updating inventory and generating credit note:
- **Transaction-based**: Entire operation is atomic (all or nothing)
- **Inventory Updates**:
  - Updates each inventory item status to RETURNED
  - Increments quantity in quantity-based inventory
  - Creates inventory movements with reason SALE_RETURN
- **Credit Note Generation**:
  - Creates FiscalReceipt with receipt_category='CREDIT_NOTE'
  - Links credit note to return via return_id
  - Sets receipt_type from original sale
  - Sets fiscal_status to PENDING (to be fiscalised)
- Updates return status to COMPLETED
- Returns completed return with credit note

### 2. Return Amount Calculation
**Function:** `calculateReturnItemAmount`

Calculates return amounts based on original sale item:
- Uses original unit_price and vat_rate from sale item
- Calculates line total: quantity × unit_price
- Calculates VAT amount: line_total × vat_rate / 100
- Calculates item total: line_total + vat_amount
- All amounts rounded to 2 decimal places

### 3. UID Validation
The return service validates that returned inventory items:
- Exist in the system
- Have status SOLD (not already returned or in stock)
- Belong to the original sale item:
  - Product ID matches
  - Variant ID matches (if applicable)
  - If sale item has inventory_item_id, it must match the returned item
- This ensures traceability and prevents invalid returns

### 4. Inventory Integration
When completing a return:
- **UID-Based Inventory**:
  - Updates InventoryItem status from SOLD to RETURNED
- **Quantity-Based Inventory**:
  - Increments inventory quantity by 1 for each returned item
- **Inventory Movements**:
  - Creates InventoryMovement with reason SALE_RETURN
  - Links movement to return via reference_id
  - Records inventory_item_id for UID traceability
  - Records quantity_change (+1)

### 5. Credit Note Generation
When completing a return:
- Creates FiscalReceipt record:
  - receipt_category: 'CREDIT_NOTE'
  - return_id: Links to the return
  - receipt_type: From original sale (POS or INVOICE)
  - fiscal_status: 'PENDING' (to be fiscalised via KRA eTIMS)
  - sale_id: null (credit notes are not linked to sales)

### 6. Controllers
**File:** `server/modules/returns/controllers/index.js`

Implemented controllers for:
- createReturn: Creates a new return
- getReturn: Retrieves a return by ID
- listReturns: Lists returns with filters
- completeReturn: Completes a return

All controllers:
- Use asyncHandler for error handling
- Extract data from request (body, params, query)
- Call appropriate service functions
- Return standardized responses using successResponse helper
- Log operations using logger

### 7. Validations
**File:** `server/modules/returns/validations/index.js`

Implemented comprehensive validation rules for:
- createReturn:
  - sale_id (required, positive integer)
  - items (required, array, min 1)
  - items[].sale_item_id (required, positive integer)
  - items[].inventory_item_id (required, positive integer)
  - items[].quantity (required, positive number)
  - items[].reason (optional, max 255 chars)
  - reason (optional, max 1000 chars)
- getReturn: return ID (required, positive integer)
- listReturns: Optional filters (sale_id, status, page, limit)
- completeReturn: return ID (required, positive integer)

### 8. Routes
**File:** `server/modules/returns/routes/index.js`

Implemented RESTful routes:
- `POST /api/returns` - Create return (manager, system_admin, cashier)
- `GET /api/returns` - List returns (authenticated)
- `GET /api/returns/:id` - Get return by ID (authenticated)
- `POST /api/returns/:id/complete` - Complete return (manager, system_admin)

All routes:
- Use authentication middleware
- Use role-based access control where appropriate
- Include request validation
- Have Swagger documentation

### 9. Routes Integration
**File:** `server/routes/index.js`

Added return routes to main routes file:
- `router.use('/returns', returnRoutes)`

## Key Features

### 1. UID Traceability
- Validates returned items belong to original sale
- Ensures inventory items were actually sold
- Prevents returns of items not from the original sale
- Maintains complete audit trail

### 2. Return Amount Calculation
- Uses original sale prices (unit_price, vat_rate)
- Calculates accurate refund/credit amounts
- Maintains consistency with original sale

### 3. Dual Inventory Support
- Updates both UID-based and quantity-based inventory
- Synchronizes inventory layers
- Tracks all changes through InventoryMovement

### 4. Transaction Safety
- Return completion is fully transactional
- All inventory updates or none
- Credit note generation is atomic with inventory updates
- Ensures data consistency

### 5. Credit Note Integration
- Generates credit notes linked to returns
- Ready for fiscalisation via KRA eTIMS
- Maintains link to original sale type

## API Endpoints Summary

### Return Endpoints
- `POST /api/returns` - Create return
- `GET /api/returns` - List returns
- `GET /api/returns/:id` - Get return by ID
- `POST /api/returns/:id/complete` - Complete return

## Testing Checklist

- [x] Create return for a sale with UID-tracked items
- [x] Validate UID belongs to original sale
- [x] Validate inventory item status is SOLD
- [x] Calculate return amounts correctly
- [x] Create return with multiple items
- [x] Get return with all associations
- [x] List returns with filters
- [x] Complete return (update inventory status)
- [x] Complete return (create inventory movements)
- [x] Complete return (generate credit note)
- [x] Verify inventory quantity updated
- [x] Verify transaction rollback on error

## Dependencies

- Phase 4: Sales (Sale, SaleItem models)
- Phase 6: Inventory (InventoryItem, Inventory, InventoryMovement models and services)
- FiscalReceipt model (for credit notes)

## Notes

1. **UID Validation**: Strict validation ensures returned items belong to the original sale
2. **Return Amounts**: Calculated from original sale prices for accuracy
3. **Inventory Status**: Items are marked as RETURNED (not back to IN_STOCK automatically)
4. **Credit Notes**: Generated as FiscalReceipt records, ready for fiscalisation
5. **Transaction Safety**: All operations are transactional for data consistency
6. **Audit Trail**: All inventory changes tracked through InventoryMovement records

## Next Steps

Phase 11 is complete. The return processing system is fully functional and integrated with inventory and fiscal receipt systems. All endpoints are operational and ready for use.

