๐Ÿ“š ERP Documentation Viewer

Beautiful, colorful documentation for your ERP system

Project Material Operations Controller Documentation

File: /controllers/projectoperationController.php

Purpose: Manage material issuance to projects with inventory tracking and accounting integration

Last Updated: 2024-12-20

---

๐Ÿ“‹ Overview

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables

Table NamePurposeKey Columns
projectexchmaterialMaterial issue headerid, serilno, projectid, storeid, totalbuyprice, supplierid
projectexchmaterialdetailMaterial issue linesprojectexchid, productid, pronumber, probuyprice, expensestypeid
storedetailInventory quantitiesstoredetailid, productid, storeid, productquantity
storereportInventory movement logproductid, storeid, processname, productbefore, productafter
### Secondary Tables (Referenced)

Table NamePurposeRelationship
projectProject masterForeign Key: projectexchmaterial.projectid
storeWarehouse/locationForeign Key: projectexchmaterial.storeid
productProduct masterForeign Key: projectexchmaterialdetail.productid
supplierSupplier masterForeign Key: projectexchmaterial.supplierid
expensestypeExpense categoriesForeign Key: projectexchmaterialdetail.expensestypeid
accountstreeAccounting structureFor financial entries
---

๐Ÿ”ง Key Functions

1. add($id)

Purpose: Issue materials to project with inventory and accounting updates

Called By: POST action to ?do=add

Parameters:

Returns: Creates material issue transaction

Database Operations:

Business Logic:

1. Accounting Tree Setup:

   $treeData = $accountsTreeDAO->queryByName($projectName);
   if (count($treeData) == 0) {
       $treeid = addTreeElement($projectName, 23, 3, 0, 1, '', 0, $finaltotalprice);
       $treeproid = addTreeElement('ุจุถุงุนุฉ ุชุญุช ุงู„ุชุณูˆูŠุฉ (' . $txtName . ')', 39, 1, 0, 1, '', 0, $finaltotalprice);
   }
   ```

2. **Inventory Processing**:
   ```php
   for ($i = 1; $i <= $offerhidden_itr; $i++) {
       $productid = filter_input(INPUT_POST, 'projectproudctid' . $i);
       $productnumber = filter_input(INPUT_POST, 'productnumber' . $i);
       
       if (isset($productid) && $productid != '-1') {
           $product = $productDAO->load($productid);
           if ($product->isService != 1) {
               $storedetailFromData = getStoredetailData($storeid, $productid);
               $productquantityFromAfter = decreaseProductQuantity($storedetailFromId, $productquantityFromBefore, $productnumber);
               insertStorereport($productid, $storeid, $productnumber, $productquantityFromBefore, $productquantityFromAfter, 1, $projmaterialid, "ุตุฑู ู…ูˆุงุฏ ู„ู„ู…ุดุฑูˆุน " . $projectName, "projectoperationController.php");
           }
       }
   }
   ```

3. **Accounting Entry**:
   ```php
   function entryinsert_data($projectname, $value, $clientid, $projectid) {
       $dailyEntry->entryComment = 'ุชู… ุตุฑู ู…ูˆุงุฏ ู„ู„ู…ุดุฑูˆุน';
       
       // Credit: Goods Under Settlement
       $dailyEntryCreditor->value = $value;
       $dailyEntryCreditor->accountstreeid = $projectid;
       
       // Debit: Project Account
       $dailyEntryDebtor->value = $value;
       $dailyEntryDebtor->accountstreeid = $clientid;
       
       return insertEntery($dailyEntry, $dailyEntryDebtorArray, $dailyEntryCreditorArray);
   }
   ```

### 2. update()
**Purpose**: Update material issue by delete and re-add  
**Called By**: POST action to `?do=update`  
**Parameters**: Same as add() plus `$editid`

**Business Logic**:
php

function update() {

$editid = filter_input(INPUT_POST, 'editid', FILTER_DEFAULT);

delete($editid); // Remove existing transaction

add($editid); // Recreate with new data

}

### 3. delete($id)
**Purpose**: Reverse material issue and restore inventory  
**Called By**: GET action to `?do=delete&id=$id`  
**Parameters**:
- `$id` (int) - Transaction ID to delete

**Database Operations**:
- SELECT transaction details
- UPDATE `storedetail` - Restore inventory quantities
- INSERT into `storereport` - Log restoration
- DELETE transaction records
- Reverse accounting entries

**Business Logic**:
1. **Inventory Restoration**:
   ```php
   foreach ($details as $value) {
       if (isset($value->productid) && $value->productid != '-1') {
           $product = $productDAO->load($productid);
           if ($product->isService != 1) {
               $storedetailFromData = getStoredetailData($storeid, $productid);
               $productquantityFromAfter = increaseProductQuantity($storedetailFromId, $productquantityFromBefore, $productnumber);
               insertStorereport($productid, $storeid, $productnumber, $productquantityFromBefore, $productquantityFromAfter, 0, $id, "ุญุฐู ุตุฑู ู…ูˆุงุฏ ู„ู„ู…ุดุฑูˆุน " . $projectName, "projectoperationController.php");
           }
       }
   }
   ```

### 4. getserails()
**Purpose**: Generate unique serial numbers  
**Returns**: Year + 4 random digits

**Business Logic**:
php

function generateRandomString($length = 4) {

$newnum = substr(str_shuffle("0123456789"), 0, $length);

return date("Y") . '' . $newnum;

}

$number = generateRandomString();

$checkifthere = $ProjectexchmaterialEx->queryAllbyserialno($number);

if (count($checkifthere) > 0) {

$number = generateRandomString(); // Regenerate if duplicate

}

### 5. Inventory Management Functions

**getStoredetailData($storeid, $productid)**:
php

function getStoredetailData($storeid, $productid) {

$storedetailData = $myStoredetailEx->queryWithStoreAndProduct($productid, $storeid);

$storedetailId = $storedetailData->storedetailid;

$productquantityBefore = $storedetailData->productquantity;

return array($storedetailData, $storedetailId, $productquantityBefore);

}

**decreaseProductQuantity($storedetailId, $productquantityBefore, $productChangeAmount)**:
php

function decreaseProductQuantity($storedetailId, $productquantityBefore, $productChangeAmount) {

$productquantityAfter = $productquantityBefore - $productChangeAmount;

$myStoredetail->storedetailid = $storedetailId;

$myStoredetail->productquantity = $productquantityAfter;

$myStoredetailEx->updateProductquantity($myStoredetail);

return $productquantityAfter;

}

---

## ๐Ÿ“Š Main Workflows

### Workflow 1: Material Issuance

1. Select Project & Store

โ†“

2. Add Material Lines

โ”œโ”€โ”€ Product Selection

โ”œโ”€โ”€ Quantity Entry

โ”œโ”€โ”€ Price Entry

โ””โ”€โ”€ Expense Type

โ†“

3. Calculate Totals

โ†“

4. Submit Transaction

โ†“

5. Create Accounting Trees (if needed)

โ†“

6. Create Accounting Entry

โ†“

7. Update Inventory Quantities

โ†“

8. Create Audit Trail

โ†“

9. Success Response

**Files Involved**:
- View: `/views/default/projectoperationview/add.html`
- Model: `/models/dto/Projectexchmaterial.class.php`
- DAO: `/models/mysql/ProjectexchmaterialMySqlDAO.class.php`

### Workflow 2: Inventory Impact

For Each Material Line:

1. Check if Product is Service

โ”œโ”€โ”€ If Service: Skip inventory

โ””โ”€โ”€ If Physical: Continue

โ†“

2. Get Current Store Quantity

โ†“

3. Validate Sufficient Quantity

โ†“

4. Decrease Store Quantity

โ†“

5. Create Store Movement Report

โ†“

6. Update Audit Trail

### Workflow 3: Accounting Integration

1. Locate/Create Project Tree Accounts

โ”œโ”€โ”€ Project Account (Debit Side)

โ””โ”€โ”€ Goods Under Settlement (Credit Side)

โ†“

2. Create Double Entry:

โ”œโ”€โ”€ DR: Project Account

โ””โ”€โ”€ CR: Goods Under Settlement

โ†“

3. Link to Transaction

โ†“

4. Update Account Balances

---

## ๐Ÿ”— File Dependencies

### Includes
php

include("../public/impOpreation.php");

include_once("../public/config.php");

include("../public/include_dao.php");

include_once("dailyentryfun.php");

### Required Models
- Project, Client, Supplier, Costcenter, Accountstree
- Store, Expensestype, Product, Programsettings  
- Projectexchmaterial, Projectexchmaterialdetail
- Dailyentry, Dailyentrycreditor, Dailyentrydebtor
- Storedetail, Storereport

### Related Views
- `/views/default/projectoperationview/add.html` - Material issue form
- `/views/default/projectoperationview/show.html` - Transaction listing
- `/views/default/projectoperationview/edit.html` - Transaction editing

---

## ๐ŸŽฏ URL Routes & Actions

| Action (`?do=`) | Method | Description | View Template |
|-----------------|--------|-------------|---------------|
| (empty) | GET | Display issue form | add.html |
| show | GET/POST | List transactions with filters | show.html |
| add | POST | Create material issue | - |
| edit | GET | Display edit form | edit.html |
| update | POST | Update existing transaction | - |
| delete | GET | Reverse transaction | - |
| sucess | GET | Success message | succes.html |
| error | GET | Error message | error.html |

---

## โš ๏ธ Known Issues & Fixes

### Issue 1: Undefined Variable in Tree Creation (Line 433)
**Problem**: `$txtName` used instead of `$projectName`  
**Cause**: Copy-paste error  
**Fix**: Replace with `$projectName`  
**File**: Line 433

### Issue 2: Missing Product Validation (Line 717)
**Problem**: `$productid` used but `$value->productid` should be used  
**Cause**: Variable scope error  
**Fix**: Use `$value->productid` consistently  
**File**: Line 717

### Issue 3: Incomplete Store Assignment (Line 436)
**Problem**: `$treeproid = $store['treeId']` may be null  
**Cause**: Store may not have tree ID  
**Fix**: Add null check and default handling  
**File**: Line 436

### Issue 4: Large Function Complexity
**Problem**: `add()` function is very large (200+ lines)  
**Cause**: Multiple responsibilities in single function  
**Fix**: Break into smaller, focused functions  
**File**: Lines 388-559

---

## ๐Ÿ” Permissions & Security

### Required Permissions
- Project material management
- Store inventory access
- Accounting entry creation

### Security Checks
php

include_once("../public/authentication.php");

### Business Rules
- Cannot issue more than available inventory
- Services don't affect inventory quantities
- All transactions create accounting entries
- Serial numbers must be unique

### Session Filtering
php

if( $_SESSION['projectids'] != 0){

$queryString .= ' AND projectexchmaterial.projectid in (' . $_SESSION['projectids'] . ')';

}

---

## ๐Ÿ”ข Accounting Integration

### Chart of Accounts Structure

23 = Project Accounts (Debit/Asset)

39 = Goods Under Settlement (Credit/Liability)

28 = Alternative goods account

### Double Entry Logic

Material Issue Transaction:

DR: Project Account (Asset) $amount

CR: Goods Under Settlement $amount

Comment: "ุชู… ุตุฑู ู…ูˆุงุฏ ู„ู„ู…ุดุฑูˆุน {project_name}"

### Reversal Logic

Material Issue Deletion:

DR: Goods Under Settlement (Asset) $amount

CR: Project Account $amount

Comment: "ุงู„ุบุงุก ุตุฑู ู…ูˆุงุฏ ู„ู„ู…ุดุฑูˆุน {project_name}"

```

---

๐Ÿ“ Notes

Important Considerations

Performance Considerations

Future Improvements

---

๐Ÿ“š Related Documentation

โ†‘