# Shipper Companies Controller Documentation

**File**: `/controllers/shippercompaniesController.php`  
**Purpose**: Manages shipping companies and their representatives for logistics and delivery operations  
**Last Updated**: December 20, 2024  
**Total Functions**: 8  
**Lines of Code**: 508

---

## 📋 Overview

The Shipper Companies Controller manages shipping/logistics companies and their representative contacts in the ERP system. It handles:
- Creating and editing shipping companies
- Managing company representatives (multiple per company)
- Dynamic representative management (add/remove via interface)
- Soft delete functionality (temporary delete/restore)
- Bulk operations on multiple companies
- Integration with shipping policies and bills
- Validation for policy dependencies before deletion

### Primary Functions
- [x] Create new shipping companies with multiple representatives
- [x] Edit existing companies and their representatives
- [x] Delete companies (with policy validation)
- [x] Temporary delete (soft delete)
- [x] Restore deleted companies
- [x] View all companies with representatives
- [x] Bulk operations (delete/restore multiple companies)
- [x] Representative contact management

### Related Controllers
- [sellbillController.php](sellbillController.md) - Sales with shipping integration
- [buyBillController.php](buyBillController.md) - Purchase operations
- [clientController.php](clientController.md) - Client management
- [supplierController.php](supplierController.md) - Supplier management
- [storeController.php](storeController.md) - Warehouse management
- [productController.php](productController.md) - Product management
- [currencyController.php](currencyController.md) - Currency management
- [taxController.php](taxController.md) - Tax management
- [userController.php](userController.md) - User management
- [branchesController.php](branchesController.md) - Branch management
- [programsettingsController.php](programsettingsController.md) - System settings
- [shippingFilesController.php](shippingFilesController.md) - Shipping document management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **shippercompanies** | Shipping company master data | companyId, companyName, otherInfo, tempdele |
| **representativecompany** | Company representatives | representativecompanyId, representativeName, representativePhone, companyId, otherInfo |

### Related Tables
| Table Name | Purpose | Relationship |
|------------|---------|--------------|
| **policy** | Shipping policies | policy.companyId → shippercompanies.companyId |
| **youtubelink** | Help video links | General help system integration |

### Reference Tables
| Table Name | Purpose | Relationship |
|------------|---------|--------------|
| **user** | System users | Created/modified by tracking |
| **programsettings** | System configuration | Global settings lookup |

---

## 🔧 Key Functions

### 1. **add()** - Create New Shipping Company
**Location**: Line 257  
**Purpose**: Creates a new shipping company with multiple representatives

**Function Signature**:
```php
function add()
```

**Parameters** (via $_POST):
- `companyName` - Shipping company name
- `otherInfo` - Additional company information
- `hidden_itr` - Number of representatives being added
- `representativeName{n}` - Representative names (dynamic, n=1 to hidden_itr)
- `representativePhone{n}` - Representative phone numbers
- `otherInfo{n}` - Additional representative information

**Process Flow**:
```
┌─────────────────┐
│ Receive Company │
│ & Representative│
│ Data via $_POST │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Create Company  │
│ Object & Insert │
│ Get companyId   │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Loop Through    │
│ Representatives │
│ (1 to hidden_itr)│
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Validate Each   │
│ Representative  │
│ Name & Phone    │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Insert Valid    │
│ Representatives │
│ to Database     │
└─────────────────┘
```

**Code Example**:
```php
// Create company first
$myShippercompanies->companyName = $_POST['companyName'];
$myShippercompanies->tempdele = 0; // Active by default
$companyId = $myShippercompaniesRecord->insert($myShippercompanies, $otherInfo);

// Add representatives
for ($h = 1; $h <= $itr; $h++) {
    $representativeName = $_POST['representativeName' . $h];
    $representativePhone = $_POST['representativePhone' . $h];
    
    if (isset($representativeName) && $representativeName != "" && 
        isset($representativePhone) && $representativePhone != "") {
        
        $myRepresentativecompany->companyId = $companyId;
        $myRepresentativecompany->representativeName = $representativeName;
        $myRepresentativecompany->representativePhone = $representativePhone;
        
        $myRepresentativecompanyRecord->insert($myRepresentativecompany, $otherInfo);
    }
}
```

---

### 2. **show()** - Display All Shipping Companies
**Location**: Line 295  
**Purpose**: Retrieves all shipping companies for display

**Function Signature**:
```php
function show()
```

**Return Value**: Array of all shipping company records

**Process Flow**:
```
┌─────────────────┐
│ Call queryAll() │
│ from DAO        │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Return Array of │
│ All Companies   │
│ (with tempdele  │
│ status)         │
└─────────────────┘
```

---

### 3. **deletetemp()** - Soft Delete Company
**Location**: Line 305  
**Purpose**: Temporarily hide shipping company (soft delete)

**Function Signature**:
```php
function deletetemp($companyId)
```

**Parameters**:
- `$companyId` - Company ID to soft delete

**Return Value**: Status message ("success" or error message)

**Process Flow**:
```
┌─────────────────┐
│ Validate        │
│ Company ID      │
└─────────┬───────┘
          ▼
┌─────────────────┐    ┌─────────────────┐
│ Set tempdele=1  │ ←──│ Handle          │
│ via Extended    │    │ Exception       │
│ DAO Method      │    └─────────────────┘
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Return Success  │
│ or Error Message│
└─────────────────┘
```

**Code Example**:
```php
$myShippercompanies->companyId = $companyId;
$myShippercompanies->tempdele = 1; // Mark as deleted
$myShippercompaniesEx->updateTempdele($myShippercompanies);
```

---

### 4. **returndelete()** - Restore Deleted Company
**Location**: Line 331  
**Purpose**: Restore temporarily deleted shipping company

**Function Signature**:
```php
function returndelete($companyId)
```

**Parameters**:
- `$companyId` - Company ID to restore

**Return Value**: Status message ("success" or error message)

**Process Flow**:
```
┌─────────────────┐
│ Validate        │
│ Company ID      │
└─────────┬───────┘
          ▼
┌─────────────────┐    ┌─────────────────┐
│ Set tempdele=0  │ ←──│ Handle          │
│ via Extended    │    │ Exception       │
│ DAO Method      │    └─────────────────┘
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Return Success  │
│ or Error Message│
└─────────────────┘
```

---

### 5. **delete()** - Permanent Delete with Validation
**Location**: Line 357  
**Purpose**: Permanently delete shipping company after policy validation

**Function Signature**:
```php
function delete($companyId)
```

**Parameters**:
- `$companyId` - Company ID to delete

**Return Value**: Array `[policyValid, statusMessage]`
- `policyValid`: 0 = can delete, 1 = has policies (cannot delete)
- `statusMessage`: Success or error message

**Process Flow**:
```
┌─────────────────┐
│ Validate        │
│ Company ID      │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Check for       │
│ Existing        │
│ Policies        │
└─────────┬───────┘
          ▼
     ┌─────────────┐    ┌─────────────────┐
     │ Policies    │    │ No Policies     │
     │ Found?      │    │ Found           │
     └─────┬───────┘    └─────┬───────────┘
           │                  │
           ▼                  ▼
┌─────────────────┐    ┌─────────────────┐
│ Return Error    │    │ Delete Reps     │
│ Cannot Delete   │    │ Delete Company  │
│ policyValid=1   │    │ policyValid=0   │
└─────────────────┘    └─────────────────┘
```

**Code Example**:
```php
// Check for dependent policies
$policyData = $myPolicyRecord->queryByCompanyId($companyId);

if (count($policyData) > 0) {
    $policyValid = 1;
    $note = "لا يمكن حذف هذه الشركة لوجود بوليصة شحن مرتيطة بها";
} else {
    // Safe to delete
    $myRepresentativecompanyRecord->deleteByCompanyId($companyId);
    $myShippercompaniesRecord->delete($companyId);
    $policyValid = 0;
    $note = "success";
}

return array($policyValid, $note);
```

---

### 6. **edit()** - Load Company for Editing
**Location**: Line 396  
**Purpose**: Load shipping company and representative data for editing

**Function Signature**:
```php
function edit($companyId)
```

**Parameters**:
- `$companyId` - Company ID to edit

**Return Value**: Array `[loadData, representativecompanyData, representativecompanyNum]`
- `loadData`: Company master data object
- `representativecompanyData`: Array of representative records
- `representativecompanyNum`: Count of representatives

**Process Flow**:
```
┌─────────────────┐
│ Load Company    │
│ Master Data     │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Load All        │
│ Representatives │
│ for Company     │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Count Reps &    │
│ Return Combined │
│ Data Array      │
└─────────────────┘
```

---

### 7. **update()** - Update Company and Representatives
**Location**: Line 414  
**Purpose**: Update company information and rebuild representative list

**Function Signature**:
```php
function update()
```

**Parameters** (via $_POST):
- `companyName` - Updated company name
- `companyId` - Company ID being updated
- `tempdele` - Company active status
- `otherInfo` - Additional company information
- `hidden_itr` - Number of representatives
- Representative arrays (same as add function)

**Process Flow**:
```
┌─────────────────┐
│ Update Company  │
│ Master Data     │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Delete ALL      │
│ Existing Reps   │
│ for Company     │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Re-insert ALL   │
│ Representatives │
│ from Form       │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Process Complete│
│ (Replace All)   │
└─────────────────┘
```

⚠️ **Important**: This function completely replaces all representatives rather than updating individual records.

---

### 8. **executeOperation()** - Bulk Operations
**Location**: Line 458  
**Purpose**: Perform bulk operations on multiple selected companies

**Function Signature**:
```php
function executeOperation()
```

**Parameters** (via $_POST):
- `operation` - Operation type (1=temp delete, 2=restore, 3=permanent delete)
- `choosedItem` - Array of company IDs to process

**Return Value**: Sets Smarty variables for result display

**Process Flow**:
```
┌─────────────────┐
│ Get Operation   │
│ Type & Selected │
│ Company IDs     │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Loop Through    │
│ Each Selected   │
│ Company ID      │
└─────────┬───────┘
          ▼
  ┌───────────────────────────────────┐
  │     Switch Operation Type         │
  └┬─────────┬─────────┬─────────────┘
   │         │         │
   ▼         ▼         ▼
┌──────┐ ┌──────┐ ┌──────────┐
│ Temp │ │Restore│ │Permanent │
│Delete│ │Delete │ │ Delete   │
└──────┘ └──────┘ └──────────┘
   │         │         │
   └─────────┼─────────┘
             ▼
   ┌─────────────────┐
   │ Collect Results │
   │ & Display       │
   └─────────────────┘
```

**Code Example**:
```php
$operationType = $_POST['operation'];
$choosedItemArr = $_POST['choosedItem'];

foreach ($choosedItemArr as $companyId) {
    $shippercompaniesData = $myShippercompaniesRecord->load($companyId);
    $companyName = $shippercompaniesData->companyName;
    
    if ($operationType == '1') {
        // Temp delete
        $note = deletetemp($companyId);
    } elseif ($operationType == "2") {
        // Restore
        $note = returndelete($companyId);
    } elseif ($operationType == "3") {
        // Permanent delete
        $note = delete($companyId);
    }
    
    // Collect output for display
    $outputString .= $companyName . ": " . $result . "<br/>";
}
```

---

## 🔄 Business Logic Flow

### Complete Company Management Workflow
```
        ┌─────────────────┐
        │ Main Controller │
        │ Entry Point     │
        └─────────┬───────┘
                  ▼
   ┌──────────────────────────────────────────┐
   │            Route by $do parameter         │
   └┬─────┬─────┬─────┬─────┬─────┬─────┬────┘
    │     │     │     │     │     │     │
    ▼     ▼     ▼     ▼     ▼     ▼     ▼
  empty  add   show  edit  update delete executeOperation
    │     │     │     │     │     │     │
    │     │     │     │     │     │     └── Bulk Operations
    │     │     │     │     │     └──────── Permanent Delete
    │     │     │     │     └─────────────── Update Company
    │     │     │     └───────────────────── Load for Edit
    │     │     └─────────────────────────── Display All
    │     └───────────────────────────────── Create New
    └─────────────────────────────────────── Display Form
```

### Representative Management Logic
```
┌─────────────────┐
│ Dynamic Form    │
│ Interface       │
│ (Add/Remove)    │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Submit with     │
│ hidden_itr      │
│ Counter         │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Loop 1 to       │
│ hidden_itr      │
│ Process Each    │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Validate Name   │
│ & Phone Not     │
│ Empty           │
└─────────┬───────┘
          ▼
┌─────────────────┐
│ Insert Valid    │
│ Representatives │
│ Only            │
└─────────────────┘
```

---

## ⚠️ Common Issues

### 1. **Policy Dependency Validation**
- **Issue**: Cannot delete companies with active shipping policies
- **Solution**: System checks `policy.companyId` before allowing deletion
- **User Experience**: Clear error message with policy reference
- **Status**: ✅ Implemented

### 2. **Representative Management**
- **Issue**: Update replaces all representatives instead of individual updates
- **Impact**: May cause concurrency issues with multiple users
- **Current Behavior**: Delete all → Re-insert all
- **Recommendation**: Implement individual representative update tracking

### 3. **Bulk Operation Performance**
- **Issue**: Bulk operations process one by one (not transactional)
- **Impact**: Partial failures possible
- **Current Status**: Individual try-catch per item
- **Recommendation**: Wrap in database transaction

### 4. **Input Validation**
- **Issue**: Limited server-side validation
- **Current**: Basic empty string checks for representatives
- **Missing**: Company name uniqueness, phone number format validation
- **Recommendation**: Add comprehensive validation layer

---

## 🔗 Dependencies

### Required Files
- `/public/impOpreation.php` - Core operations and system utilities
- `/public/config.php` - Database and system configuration
- `/public/include_dao.php` - All DAO class inclusions
- `/public/authentication.php` - User authentication and session management

### DAO Classes
- `ShippercompaniesDAO.class.php` - Data access interface for companies
- `Shippercompanie.class.php` - Company data transfer object
- `ShippercompaniesMySqlDAO.class.php` - MySQL implementation for companies
- `ShippercompaniesMySqlExtDAO.class.php` - Extended MySQL operations (soft delete)
- `RepresentativecompanyDAO.class.php` - Representative data access interface
- `Representativecompany.class.php` - Representative data transfer object
- `RepresentativecompanyMySqlDAO.class.php` - MySQL implementation for representatives
- `PolicyDAO.class.php` - Policy dependency validation
- `YoutubeLinkDAO.class.php` - Help system integration

### Template Dependencies
- `shippercompaniesview/add.html` - Add form template
- `shippercompaniesview/show.html` - List view template with bulk operations
- `shippercompaniesview/edit.html` - Edit form template
- `header.html`, `footer.html` - Layout templates
- `succes.html`, `error.html` - Status page templates
- `notes2.html` - Special notes display for policy conflicts

### JavaScript Dependencies
- Custom validation scripts (`customValidation = 1`)
- Shipper-specific UI enhancements (`customShipper = 1`)
- Bank and check-related UI features (`customBank = 1`, `customCheck = 1`)

---

## 🎯 Usage Examples

### Creating a Shipping Company with Representatives
```php
// POST data for new shipping company
$_POST = [
    'companyName' => 'Express Logistics LLC',
    'otherInfo' => 'Nationwide shipping coverage',
    'hidden_itr' => 3, // 3 representatives
    'representativeName1' => 'John Smith',
    'representativePhone1' => '+1234567890',
    'otherInfo1' => 'Sales Manager',
    'representativeName2' => 'Jane Doe',
    'representativePhone2' => '+1234567891',
    'otherInfo2' => 'Operations Manager',
    'representativeName3' => 'Bob Wilson',
    'representativePhone3' => '+1234567892',
    'otherInfo3' => 'Customer Service'
];

// Controller call: ?do=add
// Result: Company + 3 representatives created
```

### Bulk Operations
```php
// POST data for bulk operations
$_POST = [
    'operation' => '1', // Temp delete
    'choosedItem' => ['1', '3', '5'] // Company IDs
];

// Controller call: ?do=executeOperation
// Result: Companies 1, 3, 5 temporarily deleted
```

### Policy Validation Before Deletion
```php
// Attempt permanent deletion
// GET: ?do=delete&companyId=123

// If policies exist:
// Result: Error page with message
// "لا يمكن حذف هذه الشركة لوجود بوليصة شحن مرتيطة بها"

// If no policies:
// Result: Company and all representatives deleted
```

---

## 🔍 Business Rules

1. **Company Creation**: Must have company name, representatives are optional
2. **Representative Validation**: Both name and phone required for each representative
3. **Soft Delete Priority**: Prefer temporary delete over permanent deletion
4. **Policy Protection**: Cannot permanently delete companies with active policies
5. **Bulk Operations**: Support mass temporary delete, restore, and permanent delete
6. **Representative Management**: Complete replacement on update (not individual updates)
7. **Status Tracking**: `tempdele` field manages soft delete status (0=active, 1=deleted)

---

**Performance Notes**:
- Dynamic representative management via looping (scalable for reasonable numbers)
- Policy validation adds database query overhead on deletion
- Bulk operations are not transactional (individual processing)
- Standard DAO pattern for database operations

**Security Notes**:
- Requires authentication for all operations
- Uses parameterized queries via DAO layer
- Input sanitization handled by DAO implementations
- Session validation on each controller action
- Foreign key validation prevents orphaned policy records