# Unit Unification Plan: Measurement Units → Catalog Units

## Executive Summary

The system currently has **3 separate unit systems** that need to be unified into a single **Catalog Units** system. This document outlines the current state, field comparisons, and tasks required for unification.

---

## 1. Current State Analysis

### 1.1 Existing Unit Systems

| System | Table | Model | Domain | Status |
|--------|-------|-------|--------|--------|
| **Catalog Units** | `catalog_units` | `App\Domains\Catalog\Units\Models\Unit` | Catalog | **Target (Modern)** |
| **Measurement Units** | `measurement_units` | `App\Domains\Accounting\Entities\Models\MeasurementUnit` | Accounting | Legacy - To Migrate |
| **Construction Units** | `units` | `App\Domains\Construction\Unit\Models\Unit` | Construction | Legacy - To Migrate |

### 1.2 Unit Categories (Catalog System)

| Code | Name | Base Unit |
|------|------|-----------|
| weight | Weight Units | kg |
| length | Length Units | m |
| volume | Volume Units | L |
| area | Area Units | m² |
| count | Count Units | pcs |
| standard | Standard/Packaging | - |

---

## 2. Field Comparison

### 2.1 Main Unit Tables

| Field | Catalog Units (`catalog_units`) | Measurement Units (`measurement_units`) | Construction Units (`units`) | Notes |
|-------|--------------------------------|----------------------------------------|------------------------------|-------|
| `id` | ✅ PK | ✅ PK | ✅ PK | - |
| `code` | ✅ UNIQUE | ✅ (added later) | ✅ | Need mapping |
| `name` | ✅ String | ✅ String (deprecated) | ❌ | Catalog uses plain string |
| `title` | ❌ | ✅ JSON (translatable) | ✅ JSON (translatable) | **Gap**: Catalog lacks translations |
| `symbol` | ✅ Nullable | ✅ | ❌ | - |
| `is_base` | ✅ Boolean | ✅ Boolean | ❌ | - |
| `active` | ❌ | ✅ Boolean | ✅ (status) | **Gap**: Catalog lacks active flag |
| `for_procurement` | ❌ | ✅ Boolean | ❌ | **Gap**: Catalog lacks procurement flag |
| `unit_category_id` | ✅ FK | ❌ | ❌ | Measurement units lack categories |
| `timestamps` | ✅ | ✅ | ✅ | - |
| `soft_deletes` | ✅ | ❌ | ✅ | - |

### 2.2 Unit Conversion Tables

| Field | Catalog Conversions (`catalog_unit_conversions`) | Measurement Conversions (`unit_conversions`) | Notes |
|-------|------------------------------------------------|---------------------------------------------|-------|
| `id` | ✅ PK | ✅ PK | - |
| `from_unit_id` | ✅ FK → catalog_units | ❌ | Different naming |
| `to_unit_id` | ✅ FK → catalog_units | ❌ | Different naming |
| `base_unit_id` | ❌ | ✅ FK → measurement_units | Different naming |
| `sub_unit_id` | ❌ | ✅ FK → measurement_units | Different naming |
| `multiplier` | ✅ decimal(15,6) | ❌ | Different naming |
| `conversion_factor` | ❌ | ✅ decimal(18,8) | Different naming |
| `soft_deletes` | ✅ | ❌ | - |

### 2.3 Feature Comparison

| Feature | Catalog Units | Measurement Units | Construction Units |
|---------|--------------|-------------------|-------------------|
| **Multi-language Support** | ❌ No | ✅ Yes (Spatie) | ✅ Yes (Spatie) |
| **Categories/Grouping** | ✅ Yes | ❌ No | ❌ No |
| **Unit Conversions** | ✅ Yes | ✅ Yes | ❌ No |
| **Soft Deletes** | ✅ Yes | ❌ No | ✅ Yes |
| **Active/Status Flag** | ❌ No | ✅ Yes | ✅ Yes |
| **Procurement Flag** | ❌ No | ✅ Yes | ❌ No |
| **Auto Code Generation** | ❌ No | ✅ Yes (UOM prefix) | ❌ No |
| **Import/Export** | ❌ No | ✅ Yes | ❌ No |

---

## 3. Foreign Key Dependencies

### 3.1 Tables Referencing `measurement_units`

| Table | Column | On Delete | Domain |
|-------|--------|-----------|--------|
| `purchase_products` | `unit_id` | RESTRICT | Procurement |
| `item_phases` | `unit_id` | CASCADE | Construction |
| `materials` | `unit_id` | - | Construction |
| `materials_received` | `unit_id` | - | Construction |
| `materials_consumed` | `unit_id` | - | Construction |
| `product_stores` | `unit_id` | - | Inventory |
| `store_first_term_products` | `unit_id` | - | Inventory |
| `completed_works` | `unit_id` | - | Construction |
| `purchase_orders` | `unit_id` | - | Procurement |
| `sup_supplier_quotes` | `unit_id` | - | Suppliers |
| `inventory_valuations` | `unit_id` | - | Inventory |
| `unit_conversions` | `base_unit_id`, `sub_unit_id` | - | Accounting |

### 3.2 Tables Referencing `catalog_units`

| Table | Column | On Delete | Domain |
|-------|--------|-----------|--------|
| `catalog_product_variant_units` | `unit_id` | CASCADE | Catalog |
| `catalog_product_variant_materials` | `base_unit_id`, `converted_unit_id` | - | Catalog |
| `catalog_unit_conversions` | `from_unit_id`, `to_unit_id` | CASCADE | Catalog |

### 3.3 Tables Referencing `units` (Construction)

*(Requires further investigation)*

---

## 4. Unit Data Comparison (Seeder Data)

### 4.1 Common Units (Present in Both Systems)

| Code | Catalog Name | Measurement Name (EN) | Category |
|------|-------------|----------------------|----------|
| kg | Kilogram | Kilogram | Weight |
| g | Gram | Gram | Weight |
| ton | Ton | Tonne | Weight |
| lb | Pound | Pound | Weight |
| oz | Ounce | Ounce | Weight |
| m | Meter | Meter | Length |
| cm | Centimeter | Centimeter | Length |
| mm | Millimeter | Millimeter | Length |
| km | Kilometer | Kilometer | Length |
| ft | Foot | Foot | Length |
| in | Inch | Inch | Length |
| yd | Yard | Yard | Length |
| l | Liter | Liter | Volume |
| m3 | Cubic Meter | Cubic Meter | Volume |
| cm3 | Cubic Centimeter | Cubic Centimeter | Volume |
| m2 | Square Meter | Square Meter | Area |
| cm2 | Square Centimeter | Square Centimeter | Area |
| ft2 | Square Foot | Square Foot | Area |
| in2 | Square Inch | Square Inch | Area |

### 4.2 Units Only in Measurement System

| Code | Name (EN) | Name (AR) | Category | for_procurement |
|------|-----------|-----------|----------|-----------------|
| mi | Mile | ميل | Length | No |
| mm2 | Square Millimeter | مليمتر مربع | Area | No |
| yd2 | Square Yard | ياردة مربعة | Area | No |
| in3 | Cubic Inch | بوصة مكعبة | Volume | No |
| ft3 | Cubic Foot | قدم مكعب | Volume | No |
| us_gal | US Gallon | غالون أمريكي | Volume | No |
| imp_gal | Imperial Gallon | غالون إمبراطوري | Volume | No |
| us_brl | US Barrel (Oil) | برميل أمريكي | Volume | No |
| shton | Short Ton (US) | طن قصير | Mass | No |
| Lton | Long Ton (Imperial) | طن طويل | Mass | No |
| g/ml | Gram/milliliter | غرام/مليلتر | Density | No |
| kg/m3 | Kilogram/cubic meter | كيلوغرام/متر مكعب | Density | No |
| lb/ft3 | Pound/cubic foot | رطل/قدم مكعب | Density | No |
| lb/in3 | Pound/cubic inch | رطل/بوصة مكعبة | Density | No |
| Res | Response | رد | Special | Yes |

### 4.3 Units Only in Catalog System

| Code | Name | Category |
|------|------|----------|
| mg | Milligram | Weight |
| ml | Milliliter | Volume |
| gal | Gallon | Volume |
| fl_oz | Fluid Ounce | Volume |
| km2 | Square Kilometer | Area |
| acre | Acre | Area |
| pcs | Pieces | Count |
| unit | Unit | Count |
| pair | Pair | Count |
| set | Set | Count |
| dozen | Dozen | Count |
| box | Box | Standard |
| pack | Pack | Standard |
| carton | Carton | Standard |
| bag | Bag | Standard |
| bundle | Bundle | Standard |
| roll | Roll | Standard |
| sheet | Sheet | Standard |
| drum | Drum | Standard |
| bucket | Bucket | Standard |
| case | Case | Standard |
| pallet | Pallet | Standard |

---

## 5. Tasks for Unification

### Phase 1: Schema Enhancement (Catalog Units)

- [ ] **Task 1.1**: Add `title` JSON field to `catalog_units` for multi-language support
- [ ] **Task 1.2**: Add `active` boolean field to `catalog_units`
- [ ] **Task 1.3**: Add `for_procurement` boolean field to `catalog_units`
- [ ] **Task 1.4**: Add HasTranslations trait to Catalog Unit model
- [ ] **Task 1.5**: Add new unit category for "Density" units
- [ ] **Task 1.6**: Update Catalog Unit API resources to include new fields

### Phase 2: Data Migration

- [ ] **Task 2.1**: Create migration to add missing units from MeasurementUnit to Catalog Units
- [ ] **Task 2.2**: Create ID mapping table (`unit_migration_map`) to track old_id → new_id
- [ ] **Task 2.3**: Migrate unit conversions from `unit_conversions` to `catalog_unit_conversions`
- [ ] **Task 2.4**: Copy Arabic translations from measurement_units to catalog_units

### Phase 3: Foreign Key Migration

- [ ] **Task 3.1**: Add `catalog_unit_id` column to all tables referencing `measurement_units`
- [ ] **Task 3.2**: Populate new columns using the ID mapping table
- [ ] **Task 3.3**: Update all models to reference Catalog Units
- [ ] **Task 3.4**: Update foreign key constraints to point to `catalog_units`
- [ ] **Task 3.5**: Drop old `unit_id` columns (after verification)

**Tables to Update:**
1. `purchase_products`
2. `item_phases`
3. `materials`
4. `materials_received`
5. `materials_consumed`
6. `product_stores`
7. `store_first_term_products`
8. `completed_works`
9. `purchase_orders`
10. `sup_supplier_quotes`
11. `inventory_valuations`

### Phase 4: Service Layer Updates

- [ ] **Task 4.1**: Add import/export functionality to Catalog Unit Service
- [ ] **Task 4.2**: Add unit conversion calculator to Catalog Unit Service
- [ ] **Task 4.3**: Update all Services using MeasurementUnit to use Catalog Unit
- [ ] **Task 4.4**: Update all Controllers referencing MeasurementUnit
- [ ] **Task 4.5**: Update all DTOs and Requests for new Unit structure

### Phase 5: API Route Consolidation

- [ ] **Task 5.1**: Deprecate Accounting Unit API routes
- [ ] **Task 5.2**: Add backward-compatible aliases if needed
- [ ] **Task 5.3**: Update API documentation

### Phase 6: Construction Unit Migration

- [ ] **Task 6.1**: Identify all references to Construction Unit
- [ ] **Task 6.2**: Map Construction Units to Catalog Units
- [ ] **Task 6.3**: Update Construction domain to use Catalog Units
- [ ] **Task 6.4**: Remove Construction Unit model and migration

### Phase 7: Cleanup

- [ ] **Task 7.1**: Remove MeasurementUnit model
- [ ] **Task 7.2**: Remove MeasurementUnit seeder
- [ ] **Task 7.3**: Remove unit_conversions table (Accounting)
- [ ] **Task 7.4**: Remove measurement_units table
- [ ] **Task 7.5**: Remove Construction Unit model
- [ ] **Task 7.6**: Remove units table (Construction)
- [ ] **Task 7.7**: Remove related services, controllers, and routes

---

## 6. Risk Assessment

| Risk | Impact | Mitigation |
|------|--------|------------|
| Data loss during migration | High | Create backup, use transactions, verify counts |
| Breaking existing APIs | High | Add deprecation notices, maintain aliases |
| Foreign key constraint violations | High | Proper ordering, disable checks temporarily |
| Missing unit mappings | Medium | Manual review of all unit codes |
| Translation data loss | Medium | Verify Arabic translations copied correctly |

---

## 7. Rollback Plan

1. Keep backup of all original tables
2. Maintain migration scripts that can be reversed
3. Keep old models until migration is verified
4. Use feature flags to switch between old/new systems

---

## 8. Files Affected Summary

### Models to Update
- `app/Domains/Catalog/Units/Models/Unit.php` - Add translations, active, for_procurement
- `app/Domains/Catalog/Units/Models/UnitCategory.php` - Add Density category

### Models to Remove (After Migration)
- `app/Domains/Accounting/Entities/Models/MeasurementUnit.php`
- `app/Domains/Accounting/Entities/Models/UnitConversion.php`
- `app/Domains/Construction/Unit/Models/Unit.php`

### Services to Update
- All services in `app/Domains/Accounting/Entities/Services/` using MeasurementUnit
- All services in `app/Domains/Construction/` using Unit

### Controllers to Update
- `app/Domains/Accounting/Entities/HTTP/Controllers/V1/UnitController.php`
- Any controller using MeasurementUnit

---

## 9. Estimated Scope

| Category | Count |
|----------|-------|
| Tables with FK changes | 11+ |
| Models to update | 15+ |
| Services to update | 10+ |
| New migrations needed | 8-10 |
| API routes affected | 20+ |

---

*Document Created: 2026-02-08*
*Status: Planning Phase*
