# 🔍 DECATUR DEMO - MODULE & PACKAGE SYSTEM ANALYSIS

**Analysis Date:** March 30, 2026  
**Database:** missio37282_missiov2  
**Target Package:** ID 50  
**Target Company:** ID 105

---

## 📊 **SYSTEM ARCHITECTURE**

### **3-TIER MODULE SYSTEM:**

```
1. MAIN_MODULES (23 records) → Top-level navigation groups
   └─► Example: Finance (ID: 8), HRIQ (ID: 7), Store (ID: 9)

2. MODULES (140+ records) → Individual feature modules
   └─► Example: invoices, expenses, budget, employees
   └─► Linked to MAIN_MODULES via main_module_id

3. PACKAGES → Subscription plans
   └─► Contains: module_in_package (JSON array of module_names)
   └─► Example: ["invoices","expenses","employees","attendance"]
```

---

## 🎯 **HOW IT WORKS**

### **Package → Module Control:**

**NO PIVOT TABLE EXISTS!**

Packages control modules via **JSON field**:
```sql
packages.module_in_package = '["invoices","expenses","employees","attendance"]'
```

### **Company → Package Assignment:**
```sql
companies.package_id = 50  -- Links company to package
```

### **Module Activation Logic:**
```php
// From ModuleSetting.php line 174:
$moduleInPackage = collect(json_decode($company->package->module_in_package));

// Module is active if:
$moduleInPackage->contains($module) ? 'active' : 'deactive'
```

---

## 📋 **CURRENT MAIN_MODULES (Visible Navigation)**

| ID | Name | Slug | Status | Notes |
|---|---|---|---|---|
| 1 | Dashboard | dashboard | 1 | Keep |
| 2 | Website | cms | 1 | 🔴 HIDE for demo |
| 3 | Funnel | funnel | 1 | 🔴 HIDE |
| 4 | Events | events | 1 | 🔴 HIDE |
| 5 | Appointments | appointments | 1 | 🔴 HIDE |
| 6 | Client CRM | crm | 1 | 🔴 HIDE |
| 7 | HRIQ | hr | 1 | ✅ KEEP → Rename "Human Resources" |
| 8 | Finance | finance | 1 | ✅ KEEP → Add Budget modules |
| 9 | Store | store | 1 | ✅ KEEP → Rename "Procurement" |
| 10 | Tickets | tickets | 1 | 🔴 HIDE |
| 11 | Marketing | Marketing | 1 | 🔴 HIDE |
| 12 | Notice Board | notice_board | 1 | Maybe keep? |
| 13 | TalentIQ | recruit | 1 | 🔴 HIDE |
| 14 | Help Center | knowledge_base | 1 | 🔴 HIDE |
| 15 | Reports | reports | 1 | ✅ KEEP |
| 16 | Settings | settings | 1 | ✅ KEEP |
| 17 | TimeIQ | work | 1 | ✅ KEEP → Rename "Time & Attendance" |
| 18 | Donor CRM | donor-crm | 1 | 🔴 HIDE |
| 19 | Fundraising & Events | event_fundraising | 1 | 🔴 HIDE |
| 21 | Membership | membership | 1 | 🔴 HIDE |
| 22 | Content | content | 1 | 🔴 HIDE |
| 23 | Forums | Forums | 1 | 🔴 HIDE |
| 24 | GrantIQ | grantiq | 1 | ✅ KEEP |

---

## 🗂️ **MODULE GROUPS** (From Module.php)

Used in package edit UI for organizing checkboxes:

```php
'finance' => [
    'estimates',
    'invoices', 
    'payments',
    'bankaccount',
    'expenses',
    'estimate-template',
    'creditnotes',
    'proposals',
]

'hriq' => [
    'attendance',
    'leaves',
    'holidays',
    'clients',
    'employees',
    'shifts',
    'designations',
    'departments',
    'appreciations',
    'tickets',
]

'store' => [
    'products',
    'orders',
    'productCategory',
    'attributes',
    'customers',
    'customer-groups'
]
```

---

## ✅ **ANSWERS TO YOUR QUESTIONS**

### **1. Do you have a company_modules pivot table?**
**NO!** There is NO pivot table for company↔module relationships.

### **2. What's the structure?**
```
Companies → package_id → Package → module_in_package (JSON)
```

### **3. How does package_id 50 control modules?**
```sql
-- Package 50 has:
packages.module_in_package = '["invoices","expenses","employees","attendance",...]'

-- When company_id 105 has package_id = 50:
companies.package_id = 50

-- System checks:
$company->package->module_in_package // Returns JSON array

-- Module is enabled if its module_name exists in that array
```

### **4. Is there a package_modules table?**
**NO!** No separate table.

### **5. Or does it use module_in_package JSON field?**
**YES!** This is exactly how it works:
```sql
SELECT module_in_package FROM packages WHERE id = 50;
-- Returns: ["invoices","expenses","employees","attendance",...]
```

---

## 🛠️ **IMPLEMENTATION STRATEGY FOR DECATUR**

### **STEP 1: Add New MAIN_MODULES**
```sql
-- Add Workflow main module
INSERT INTO main_modules (name, slug, description, status, order_by) VALUES
('Workflow', 'workflow', 'Approval workflows and inbox', 1, 25);
```

### **STEP 2: Add New MODULES to Existing Main Modules**

**Finance (main_module_id = 8):**
```sql
INSERT INTO modules (main_module_id, module_name, module_slug, module_fname, description, status) VALUES
(8, 'budget', 'budget', 'Budget', 'Budget management and allocation tracking', 1),
(8, 'budget-allocations', 'budget-allocations', 'Budget Allocations', 'Department and fund budget allocations', 1),
(8, 'budget-transfers', 'budget-transfers', 'Budget Transfers', 'Transfer budget between allocations', 1),
(8, 'general-ledger', 'general-ledger', 'General Ledger', 'Chart of accounts and GL entries', 1),
(8, 'accounts-payable', 'accounts-payable', 'Accounts Payable', 'AP management', 1),
(8, 'accounts-receivable', 'accounts-receivable', 'Accounts Receivable', 'AR management', 1);
```

**HRIQ (main_module_id = 7):**
```sql
INSERT INTO modules (main_module_id, module_name, module_slug, module_fname, description, status) VALUES
(7, 'payroll', 'payroll', 'Payroll', 'Payroll integration', 1),
(7, 'positions', 'positions', 'Positions', 'Position control budgeting', 1);
```

**Store → Procurement (main_module_id = 9):**
```sql
-- First rename the main module
UPDATE main_modules SET name = 'Procurement', slug = 'procurement' WHERE id = 9;

-- Then add procurement modules
INSERT INTO modules (main_module_id, module_name, module_slug, module_fname, description, status) VALUES
(9, 'requisitions', 'requisitions', 'Requisitions', 'Purchase requisitions', 1),
(9, 'purchase-orders', 'purchase-orders', 'Purchase Orders', 'PO management', 1),
(9, 'receiving', 'receiving', 'Receiving', 'Goods receipt', 1),
(9, 'vendors', 'vendors', 'Vendors', 'Vendor management', 1);
```

**Workflow (main_module_id = 25, NEW):**
```sql
INSERT INTO modules (main_module_id, module_name, module_slug, module_fname, description, status) VALUES
(25, 'workflow-inbox', 'workflow-inbox', 'Workflow Inbox', 'Approval inbox', 1),
(25, 'workflow-rules', 'workflow-rules', 'Workflow Rules', 'Routing rules', 1),
(25, 'workflow-history', 'workflow-history', 'Workflow History', 'Audit trail', 1);
```

### **STEP 3: Update Package 50's module_in_package**

```sql
-- Get current value
SELECT module_in_package FROM packages WHERE id = 50;

-- Update to include new modules
UPDATE packages SET module_in_package = '[
    "employees",
    "attendance",
    "leaves",
    "holidays",
    "shifts",
    "designations",
    "departments",
    "positions",
    "payroll",
    "invoices",
    "payments",
    "expenses",
    "bankaccount",
    "budget",
    "budget-allocations",
    "budget-transfers",
    "general-ledger",
    "accounts-payable",
    "accounts-receivable",
    "products",
    "orders",
    "requisitions",
    "purchase-orders",
    "receiving",
    "vendors",
    "projects",
    "tasks",
    "timelogs",
    "reports",
    "workflow-inbox",
    "workflow-rules",
    "workflow-history",
    "grants",
    "applications",
    "workflow-tasks",
    "awards-loans",
    "documents-compliance"
]' WHERE id = 50;
```

### **STEP 4: Update Module.php $ListModulesByGroup**

Add new groups to organize in package UI:

```php
// In app/Models/Module.php

'finance' => [
    'estimates',
    'invoices',
    'payments',
    'bankaccount',
    'expenses',
    'budget',              // NEW
    'budget-allocations',  // NEW
    'budget-transfers',    // NEW
    'general-ledger',      // NEW
    'accounts-payable',    // NEW
    'accounts-receivable', // NEW
    'creditnotes',
    'proposals',
],

'procurement' => [        // RENAMED from 'store'
    'products',
    'orders',
    'requisitions',       // NEW
    'purchase-orders',    // NEW
    'receiving',          // NEW
    'vendors',            // NEW
    'productCategory',
    'attributes',
    'customers',
],

'hriq' => [
    'attendance',
    'leaves',
    'holidays',
    'employees',
    'positions',          // NEW
    'payroll',            // NEW
    'shifts',
    'designations',
    'departments',
],

'workflow' => [          // NEW GROUP
    'workflow-inbox',
    'workflow-rules',
    'workflow-history',
],
```

### **STEP 5: Hide Non-ERP Modules for Company 105**

**Option A: Conditional Navigation (Recommended)**
In navigation blade file, add company check:
```php
@if(company()->id != 105)
    // Show Donor CRM, Events, etc.
@endif
```

**Option B: Custom Package Type**
Create a `package_type` field:
```sql
ALTER TABLE packages ADD COLUMN package_type VARCHAR(50) DEFAULT 'saas';
UPDATE packages SET package_type = 'school_erp' WHERE id = 50;
```

Then in navigation:
```php
@if(company()->package->package_type == 'school_erp')
    // Show ERP navigation
@else
    // Show SaaS navigation
@endif
```

---

## 📝 **MODULE.PHP UPDATE REQUIRED**

Add these to `Module::MODULE_LIST`:

```php
[
    'module_name' => 'budget',
    'permissions' => [
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'add_budget'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'view_budget'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'edit_budget'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'delete_budget'],
    ]
],
[
    'module_name' => 'budget-allocations',
    'permissions' => [
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'add_budget_allocation'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'view_budget_allocation'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'edit_budget_allocation'],
        ['allowed_permissions' => Permission::ALL_NONE, 'is_custom' => 0, 'name' => 'delete_budget_allocation'],
    ]
],
// ... etc for each new module
```

---

## 🚀 **EXECUTION PLAN**

### **Day 1 (Monday):**
1. ✅ Create SQL migration script
2. ✅ Add new main_modules (Workflow)
3. ✅ Add new modules to Finance, HRIQ, Procurement
4. ✅ Update package 50's module_in_package JSON
5. ✅ Run database migrations

### **Day 2-3 (Tuesday-Wednesday):**
1. ✅ Update Module.php with new module definitions
2. ✅ Update Module.php $ListModulesByGroup
3. ✅ Create Budget/Procurement/Workflow controllers, models, migrations
4. ✅ Add routes

### **Day 4 (Thursday):**
1. ✅ Update navigation to hide non-ERP modules for company 105
2. ✅ Test module activation for company 105
3. ✅ UI polish

---

## 🔍 **KEY FILES TO MODIFY**

```
1. database/migrations/[new]_add_decatur_modules.php
2. app/Models/Module.php (MODULE_LIST + ListModulesByGroup)
3. resources/views/sections/menu_MW_930.blade.php (navigation)
4. app/Http/Controllers/BudgetController.php (NEW)
5. app/Models/Budget.php (NEW)
6. routes/budget.php (NEW)
```

---

## ✅ **VERIFICATION QUERIES**

```sql
-- Check package 50 modules
SELECT module_in_package FROM packages WHERE id = 50;

-- Check company 105 package
SELECT id, company_name, package_id FROM companies WHERE id = 105;

-- Check available modules
SELECT id, module_name, module_slug, main_module_id 
FROM modules 
WHERE status = 1 
ORDER BY main_module_id, module_name;

-- Check main modules
SELECT * FROM main_modules WHERE status = 1 ORDER BY order_by;
```

---

## 🎯 **NEXT STEPS**

**Ready to start? I can create:**

1. ✅ SQL migration script for new modules
2. ✅ Module.php updates
3. ✅ Budget/Procurement controllers & models
4. ✅ Database migrations for new tables
5. ✅ Navigation update script

**Which should I start with?** 🚀
