# Company Produces Controller Documentation

**File**: `/controllers/companyproduces.php`  
**Purpose**: Manages company/manufacturer information including logos, descriptions, and status management  
**Last Updated**: December 20, 2024  
**Total Functions**: 6 main functions  
**Lines of Code**: ~110

---

## 📋 Overview

The Company Produces Controller manages manufacturing company information and branding within the ERP system. It handles:
- Company/manufacturer master data management
- Multilingual company information (Arabic/English)
- Logo/image upload and management
- Company status management (active/inactive)
- AJAX search functionality for company selection
- File upload handling with image processing

### Primary Functions
- [x] Add new manufacturing companies
- [x] Edit existing company information
- [x] Display company listings
- [x] Soft delete companies (mark as deleted)
- [x] Toggle company active/inactive status
- [x] AJAX search for company selection
- [x] Logo upload and management
- [x] Multilingual support (Arabic/English)

### Related Controllers
- [productController.php](productController.md) - Products may be linked to companies
- [supplierController.php](supplierController.md) - Similar manufacturer management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **companyproduces** | Manufacturing companies | id, companyname, name_en, description_ar, description_en, logo, status, del, addtoday, adduserid, updatetoday, updateuserid, deltoday, deluserid, created_at |

---

## 🔑 Key Functions

### 1. **Default Action** (empty `do`) - Add Company Form
**Location**: Lines 8-11  
**Purpose**: Display the add company form

**Process Flow**:
1. Display header template
2. Display add company form (`companyproducesview/add.html`)
3. Display footer template

**Template**: `companyproducesview/add.html`

---

### 2. **Show Companies** (`do=show`) - Company Listing
**Location**: Lines 12-17  
**Purpose**: Display all active companies in a list/table format

**Process Flow**:
1. Query all companies with `del < 2` (not permanently deleted)
2. Assign company data to template
3. Display listing via `companyproducesview/show.html`

**Data Retrieved**:
```php
$companyproduces = R::findAll('companyproduces', 'del < 2');
```

**Template Variables**:
- `$companyproduces` - Array of company objects

---

### 3. **Edit Company** (`do=edit`) - Edit Form
**Location**: Lines 18-24  
**Purpose**: Display edit form for existing company

**Process Flow**:
1. Get company ID from GET parameter
2. Load company record from database
3. Assign company data to template
4. Display edit form via `companyproducesview/edit.html`

**Parameters**:
- `id` - Company ID to edit

**Data Loading**:
```php
$id = filter_input(INPUT_GET, 'id');
$companyproduces = R::load('companyproduces', $id);
```

---

### 4. **Save Data** (`do=savedata`) - Insert/Update Company
**Location**: Lines 25-70  
**Purpose**: Process form submission for adding or updating companies

**Process Flow**:
1. Filter and validate input parameters
2. Handle file upload for logo
3. Determine if adding new or updating existing
4. Set appropriate audit fields (add vs update)
5. Save company data to database
6. Redirect to show page or error page

**Input Parameters**:
```php
$companyname = filter_input(INPUT_POST, 'companyname');
$companyid = filter_input(INPUT_POST, 'companyid');
$name_en = filter_input(INPUT_POST, 'name_en');
$description_ar = filter_input(INPUT_POST, 'description_ar'); 
$description_en = filter_input(INPUT_POST, 'description_en');
$status = filter_input(INPUT_POST, 'status', FILTER_VALIDATE_INT);
```

**Add New Company Logic**:
```php
if (!$companyid) {
    $companyproduces = R::dispense('companyproduces');
    $companyproduces->del = 0;
    $companyproduces->addtoday = date("Y-m-d H:i:s");
    $companyproduces->adduserid = $_SESSION['userid'];
    $companyproduces->deltoday = '';
    $companyproduces->deluserid = '';
    $companyproduces->created_at = date('Y-m-d H:i:s');
}
```

**Update Existing Logic**:
```php
else {
    $companyproduces = R::load('companyproduces', $companyid);
    $companyproduces->del = 1; // Mark as updated
    $companyproduces->updatetoday = date("Y-m-d H:i:s");
    $companyproduces->updateuserid = $_SESSION['userid'];
    unlink('../upload/companyproduces/' . $companyproduces->logo); // Remove old logo
}
```

**Image Upload Handling**:
```php
$handle = new upload($_FILES['logo']);
$image = updateImagesWithoutresiz($handle, "oldlogo", '../upload/companyproduces');
$companyproduces->logo = $image;
```

---

### 5. **Delete Company** (`do=delete`) - Soft Delete
**Location**: Lines 71-78  
**Purpose**: Mark company as deleted (soft delete)

**Process Flow**:
1. Get company ID from GET parameter
2. Load company record
3. Set deletion audit fields
4. Save updated record
5. Redirect to show page

**Soft Delete Logic**:
```php
$tables = R::load('companyproduces', $id);
$tables->del = 2; // Mark as deleted
$tables->deltoday = date("Y-m-d H:i:s");
$tables->deluserid = $_SESSION['userid'];
```

---

### 6. **AJAX Search** (`do=companyproduces`) - Company Search
**Location**: Lines 79-93  
**Purpose**: Provide AJAX search functionality for company selection

**Process Flow**:
1. Get search term from POST data
2. Query companies matching search term
3. Format results for Select2 dropdown
4. Return JSON response

**Search Query**:
```sql
SELECT id, companyname as name
FROM companyproduces 
WHERE del < 2 and companyname LIKE '%searchTerm%' 
LIMIT 50
```

**JSON Response Format**:
```php
$row_array['id'] = $pro['id'];
$row_array['text'] = $pro['name'];
array_push($return_arr, $row_array);
echo json_encode($return_arr);
```

---

### 7. **Toggle Status** (`do=toggleStatus`) - Active/Inactive Toggle
**Location**: Lines 94-108  
**Purpose**: Toggle company status between active (1) and inactive (0)

**Process Flow**:
1. Get company ID from GET parameter
2. Load company record
3. Toggle status (0 to 1, or 1 to 0)
4. Save updated record
5. Redirect to show page

**Toggle Logic**:
```php
$row = R::load('companyproduces', $id);
$row->status = $row->status ? 0 : 1; // Toggle boolean
R::store($row);
```

---

## 🔄 Workflows

### Workflow 1: Adding New Company
```
┌─────────────────────────────────────────────────────────────┐
│                START: Add New Company                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Add Form                                        │
│     - Show companyproducesview/add.html                     │
│     - User fills company information                        │
│     - User uploads logo file                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Form Submission (do=savedata)                           │
│     - Validate input fields                                 │
│     - Create new companyproduces record                     │
│     - Set audit fields (add user, date)                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Handle File Upload                                      │
│     - Process logo upload                                   │
│     - Create upload directory if needed                     │
│     - Use upload class for file handling                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Save to Database                                        │
│     - Store company record using RedBeanPHP                 │
│     - Handle success/error conditions                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Redirect                                                │
│     - Success: Redirect to show page                        │
│     - Error: Redirect to add form                           │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Editing Existing Company
```
┌─────────────────────────────────────────────────────────────┐
│              START: Edit Company (from list)                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Company Data                                       │
│     - Get ID from URL parameter                             │
│     - Load existing company record                          │
│     - Pre-populate edit form                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Display Edit Form                                       │
│     - Show companyproducesview/edit.html                    │
│     - Form pre-filled with existing data                    │
│     - User modifies information                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Form Submission (do=savedata)                           │
│     - Detect existing company (has ID)                      │
│     - Set update audit fields                               │
│     - Remove old logo file if new one uploaded              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Handle File Upload                                      │
│     - Process new logo if uploaded                          │
│     - Delete old logo file                                  │
│     - Update logo field                                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Update Database                                         │
│     - Save updated record                                   │
│     - Handle success/error conditions                       │
│     - Redirect to show page                                 │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display add company form |
| `do=show` | Show listing | Display all active companies |
| `do=edit&id=X` | Edit form | Display edit form for company X |
| `do=savedata` | Save/Update | Process form submission |
| `do=delete&id=X` | Soft delete | Mark company X as deleted |
| `do=companyproduces` | AJAX search | Return JSON search results |
| `do=toggleStatus&id=X` | Toggle status | Switch active/inactive status |

### Required Parameters by Action

**Edit Company** (`do=edit`):
- `id` - Company ID to edit

**Delete Company** (`do=delete`):
- `id` - Company ID to delete

**Toggle Status** (`do=toggleStatus`):
- `id` - Company ID to toggle

**Save Data** (`do=savedata`):
- `companyname` - Company name (required)
- `companyid` - Company ID (empty for new, filled for update)
- `name_en` - English name (optional)
- `description_ar` - Arabic description (optional)
- `description_en` - English description (optional)
- `status` - Active status (checkbox)
- `logo` - Logo file upload

---

## 🔒 Security & Permissions

### Input Sanitization
```php
// All inputs filtered using filter_input()
$companyname = filter_input(INPUT_POST, 'companyname');
$status = filter_input(INPUT_POST, 'status', FILTER_VALIDATE_INT);
$id = filter_input(INPUT_GET, 'id');
```

### File Upload Security
- Logo files stored in `/upload/companyproduces/` directory
- Uses upload class for file handling
- Directory permissions set to 0777 for write access
- Old logo files deleted when updating

**Upload Directory Creation**:
```php
$uploadDir = '../views/default/images/company_logos/';
if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0777, true);
}
```

### Soft Delete Implementation
- Records never permanently deleted from database
- Uses `del` field: 0=active, 1=updated, 2=deleted
- Deleted records excluded from normal queries

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Required**:
   - `companyproduces(del)` - For filtering active records
   - `companyproduces(companyname)` - For search functionality
   - `companyproduces(status)` - For filtering active companies

2. **Query Performance**:
   - AJAX search limited to 50 results
   - Simple WHERE clauses for fast filtering
   - No complex JOINs required

3. **File Upload Performance**:
   - Logo files stored on filesystem, not in database
   - Directory structure allows direct file serving
   - Old files cleaned up during updates

### Known Performance Considerations
```sql
-- AJAX search may be slow without proper indexing
SELECT id, companyname as name
FROM companyproduces 
WHERE del < 2 and companyname LIKE '%searchTerm%' 
LIMIT 50;

-- Optimize with index:
CREATE INDEX idx_companyproduces_name_del ON companyproduces(companyname, del);
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **File Upload Failures**
**Issue**: Logo upload fails or files not saved  
**Cause**: Directory permissions or upload class issues

**Debug**:
```php
// Check upload directory exists and writable
if (!is_dir('../upload/companyproduces/')) {
    echo "Upload directory missing";
}
if (!is_writable('../upload/companyproduces/')) {
    echo "Upload directory not writable";
}
```

**Fix**:
```bash
# Set proper permissions
chmod 755 /path/to/upload/companyproduces/
chown www-data:www-data /path/to/upload/companyproduces/
```

### 2. **Old Logo Files Not Deleted**
**Issue**: Old logo files remain after update  
**Cause**: File path issues in unlink() call

**Debug**:
```php
// Check if file exists before trying to delete
$oldLogoPath = '../upload/companyproduces/' . $companyproduces->logo;
if (file_exists($oldLogoPath)) {
    unlink($oldLogoPath);
} else {
    echo "File not found: " . $oldLogoPath;
}
```

### 3. **AJAX Search Not Working**
**Issue**: Search dropdown returns no results  
**Cause**: JSON encoding issues or SQL errors

**Debug**:
```php
// Add error checking to AJAX response
$productsData = R::getAll("SELECT id, companyname as name...");
if (empty($productsData)) {
    error_log("No companies found for search term: " . $name);
}
```

### 4. **Status Toggle Issues**
**Issue**: Status not changing properly  
**Cause**: Boolean logic or database save failures

**Debug**:
```php
// Check current status before toggle
$row = R::load('companyproduces', $id);
echo "Current status: " . $row->status;
$row->status = $row->status ? 0 : 1;
echo "New status: " . $row->status;
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Company Management
```
1. Add new company with all fields filled
2. Verify company appears in listing
3. Edit company information
4. Verify changes saved correctly
5. Delete company (soft delete)
6. Verify company no longer in listing
```

### Test Case 2: File Upload Handling
```
1. Add company with logo upload
2. Verify logo file saved in correct directory
3. Edit company and upload new logo  
4. Verify old logo deleted and new logo saved
5. Test with various image formats (JPG, PNG, GIF)
```

### Test Case 3: AJAX Search Functionality
```
1. Create companies with different names
2. Test search with partial company names
3. Verify JSON response format
4. Test search with special characters
5. Verify search results limited to 50 records
```

### Test Case 4: Status Management
```
1. Create active company (status = 1)
2. Toggle to inactive (status = 0)
3. Verify status change in database
4. Toggle back to active
5. Test status filtering in listings
```

### Debug Mode Enable
```php
// Add at top of controller for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Debug RedBeanPHP queries
R::debug(true);

// Debug file upload
echo "<pre>";
print_r($_FILES);
echo "</pre>";
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productController.md](productController.md) - Product management operations
- [Database Schema Documentation](#) - Table relationships and structure
- [File Upload Documentation](#) - Upload class usage and security

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur