Projectoperation Documentation
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
- โ Material issuance to projects
- โ Inventory quantity management
- โ Accounting integration for materials
- โ Supplier relationship tracking
- โ Service vs physical product handling
- โ Store reporting and audit trail
Related Controllers
- โข projectController.php - Project master data
- โข projectoperationControllerreturn.php - Material returns
- โข storedetailController.php - Inventory management
---
๐๏ธ Database Tables
Primary Tables
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| projectexchmaterial | Material issue header | id, serilno, projectid, storeid, totalbuyprice, supplierid | |
| projectexchmaterialdetail | Material issue lines | projectexchid, productid, pronumber, probuyprice, expensestypeid | |
| storedetail | Inventory quantities | storedetailid, productid, storeid, productquantity | |
| storereport | Inventory movement log | productid, storeid, processname, productbefore, productafter |
| Table Name | Purpose | Relationship | |
|---|---|---|---|
| project | Project master | Foreign Key: projectexchmaterial.projectid | |
| store | Warehouse/location | Foreign Key: projectexchmaterial.storeid | |
| product | Product master | Foreign Key: projectexchmaterialdetail.productid | |
| supplier | Supplier master | Foreign Key: projectexchmaterial.supplierid | |
| expensestype | Expense categories | Foreign Key: projectexchmaterialdetail.expensestypeid | |
| accountstree | Accounting structure | For 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:
- โข
$serialno(string) - Transaction serial number - โข
$projectid(int) - Target project - โข
$storeid(int) - Source warehouse - โข
$finaltotalprice(float) - Total material value - โข
$offerhidden_itr(int) - Number of material lines
Returns: Creates material issue transaction
Database Operations:
- โข INSERT into
projectexchmaterial- Transaction header - โข INSERT into
projectexchmaterialdetail- Material lines - โข UPDATE
storedetail- Decrease inventory quantities - โข INSERT into
storereport- Audit trail - โข INSERT into
dailyentry- Accounting entries
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
- โข Services (isService = 1) don't affect inventory
- โข All inventory changes are logged in storereport
- โข Accounting trees are created automatically for new projects
- โข Serial numbers prevent duplicate transactions
- โข Update operation uses delete/re-add pattern
Performance Considerations
- โข Large transactions may timeout
- โข Consider batch processing for many lines
- โข Inventory calculations are transaction-based
Future Improvements
- โป๏ธ Add material approval workflow
- โป๏ธ Implement batch operations
- โป๏ธ Add barcode scanning
- โป๏ธ Create mobile material issue
- โป๏ธ Add cost center validation
- โป๏ธ Implement material reservations
---
๐ Related Documentation
- โข Project Master
- โข Material Returns
- โข Inventory Management
- โข Accounting Integration