# Bills Functions Buy Controller Documentation

**File**: `/controllers/billsfunctionsbuy.php`  
**Purpose**: Purchase bill processing utilities for optical inventory procurement  
**Last Updated**: December 20, 2024  
**Total Functions**: 20+  
**Lines of Code**: ~1,118

---

## 📋 Overview

The Bills Functions Buy Controller provides comprehensive purchase bill processing for optical inventory procurement. It handles:
- Purchase bill creation and management
- Supplier debt tracking and payments
- Inventory receiving and costing
- Multi-payment method processing
- Bank account integration
- Financial accounting entries
- Product cost averaging
- Store operation management
- Purchase order fulfillment
- Supplier relationship management

### Primary Functions
- [x] Purchase bill creation and processing
- [x] Supplier debt management
- [x] Inventory receiving and costing
- [x] Multi-payment processing (cash/bank/insurance)
- [x] Financial accounting integration
- [x] Product cost tracking (FIFO/Average)
- [x] Bank account management
- [x] Store inventory updates
- [x] Supplier payment tracking
- [x] Purchase analytics and reporting

### Related Controllers
- [billsfunctions.php](billsfunctions.md) - Sales utilities
- [buyBillController.php](buyBillController.md) - Purchase operations
- [sellbillController.php](sellbillController.md) - Sales operations

---

## 🗄️ Database Tables

### Primary Purchase Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **billsbuy** | Purchase bill master | billid, clientid, billno, finalnetbillvalue, waitvalue, dailyentryid |
| **billsproductsbuy** | Purchase line items | id, billid, productid, productno, productprice, producttotalprice, storeid |
| **supplier** | Supplier master data | supplierid, suppliername, suppliercurrentDebt, treeId |
| **supplierdebtchange** | Supplier debt tracking | id, supplierid, supplierdebtchangeamount, supplierdebtchangetype, tablename |

### Financial & Banking Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **bank** | Bank master data | bankid, bankname |
| **bankaccount** | Bank account details | accountid, bankid, accountname, treeId |
| **dailyentry** | Accounting journal entries | dailyentryid, dDateTime, entryComment |
| **dailyentrycreditor** | Credit entries | id, dailyentryid, accountstreeid, value |
| **dailyentrydebtor** | Debit entries | id, dailyentryid, accountstreeid, value |

### Inventory & Product Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Product master | productid, productName, productBuyPrice, lastbuyprice, meanbuyprice |
| **storedetail** | Current inventory | storedetailid, productid, storeid, productquantity |
| **storereport** | Inventory movement log | id, productid, storeid, productbefore, productafter, tablename |

---

## 🔑 Key Functions

### 1. **addBuy()** - Complete Purchase Bill Processing
**Location**: Line 149  
**Purpose**: Main function for creating purchase bills with full payment processing

**Function Signature**:
```php
function addBuy()
// Returns: [flag, billId, detailResult]
```

**Process Flow**:
1. Save bill details via `saveBillDetailsBuy()`
2. Save bill products via `saveBillProductsBuy()`
3. Handle payment processing and accounting
4. Return processing results

**Features**:
- Comprehensive purchase bill creation
- Multiple payment method support
- Supplier debt management
- Inventory receiving updates
- Automatic cost calculations

---

### 2. **saveBillDetailsBuy()** - Purchase Bill Creation
**Location**: Line 160  
**Purpose**: Create purchase bill master record with payment integration

**Function Signature**:
```php
function saveBillDetailsBuy()
// Returns: Array with flag, note, billId
```

**Key Processing Steps**:
1. **Bill Validation**: Check bill number uniqueness
2. **Supplier Management**: Load supplier and debt information
3. **Payment Processing**: Handle multiple payment methods
4. **Debt Tracking**: Update supplier debt balances
5. **Accounting**: Create financial journal entries

**Supplier Debt Logic**:
```php
$client = $supplierDAO->load($clientId);
$clientdebtBefore = $client->suppliercurrentDebt;
$clientdebtAfter = $clientdebtBefore + $waitvalue; // Increase supplier debt
```

---

### 3. **savePaymentDetailsBuy()** - Purchase Payment Processing
**Location**: Line 268  
**Purpose**: Process multiple payment methods for purchase bills

**Function Signature**:
```php
function savePaymentDetailsBuy($billsBuy, $waitvalue, $affectNetworkNow = 0)
```

**Payment Methods Supported**:
1. **Cash Payment**: Direct cash payment to supplier
2. **Bank Payment**: Bank transfer or check payment
3. **Insurance Payment**: Insurance company payment processing

**Payment Processing Logic**:
```php
$paymentamethods = $_POST['paymentamethods'];
foreach ($paymentamethods as $method) {
    switch($method) {
        case 'cash': $billsBuy = saveCashPaymentBuy($billsBuy); break;
        case 'card': $billsBuy = saveCardPaymentBuy($billsBuy); break; // Bank
        case 'insurance': $billsBuy = saveInsurancePaymentBuy($billsBuy); break;
    }
}
```

---

### 4. **saveDailyEntryBuy()** - Purchase Accounting Integration
**Location**: Line 356  
**Purpose**: Create comprehensive accounting entries for purchases

**Function Signature**:
```php
function saveDailyEntryBuy($insurance, $card, $cash, $waitvalue, $billId, $discountAsMoney)
```

**Accounting Structure**:
1. **Debit**: Inventory/Purchases account (receives goods)
2. **Credits**: 
   - Cash account (if cash payment)
   - Bank account (if bank payment)
   - Supplier payable (if credit terms)
   - Discount account (if discount given)

**Account Mapping**:
```php
// Main accounts for purchases
$purchasesAccount = 12;        // Inventory/Purchases
$cashAccount = $save->treeId;  // Cash register
$supplierAccount = $supplier->treeId; // Supplier payable
$discountAccount = 52;         // Purchase discounts
```

---

### 5. **saveBillProductsBuy()** - Purchase Product Processing
**Location**: Line 575  
**Purpose**: Process purchase line items with inventory and costing updates

**Function Signature**:
```php
function saveBillProductsBuy($billId, $affectNetworkNow = 0)
```

**Product Processing Steps**:
1. **Line Item Creation**: Save purchase product records
2. **Inventory Updates**: Increase stock quantities
3. **Cost Calculations**: Update product cost information
4. **Movement Logging**: Record inventory transactions

**Inventory Increase Logic**:
```php
if ($product->isService != 1) {
    $storeDetail = $storeDetailEX->getProductQuantity($productId, $storeId);
    $productbefore = $storeDetail->productquantity;
    $productafter = $productbefore + $productNum; // Increase inventory
    $storeDetail->productquantity = $productafter;
    $storeDetailDAO->update($storeDetail);
}
```

---

### 6. **lastAndMeanBuyPrice_SellOpticBuy()** - Advanced Cost Tracking
**Location**: Line 1069  
**Purpose**: Calculate and update product cost averages using weighted average method

**Function Signature**:
```php
function lastAndMeanBuyPrice_SellOpticBuy($productquantityBefore, $productChangeAmount, 
                                         $productquantityAfter, $lastBuyPriceOnePiece, 
                                         $detailId, $productId)
```

**Weighted Average Calculation**:
```php
// Calculate new weighted average cost
$Bast = ($productquantityBefore * $buyProduct->meanbuyprice) + 
        ($productChangeAmount * $lastBuyPriceOnePiece);
$makam = $productquantityAfter;
$meanBuyPrice = round(($Bast / $makam), 3);

// Update product costs
$buyProduct->meanbuyprice = $meanBuyPrice;    // Weighted average
$buyProduct->lastbuyprice = $lastBuyPriceOnePiece; // Most recent
$productDAO->update($buyProduct);
```

---

### 7. **updateSupplierDebt()** - Supplier Account Management
**Location**: Line 103  
**Purpose**: Update supplier debt balances with proper tracking

**Function Signature**:
```php
function updateSupplierDebt($supplierId, $supplierdebtAfter)
```

---

### 8. **insertSupplierDebtChangeupdate()** - Supplier Debt Tracking
**Location**: Line 113  
**Purpose**: Log all supplier debt changes for audit and reporting

**Function Signature**:
```php
function insertSupplierDebtChangeupdate($supplierId, $before, $amount, $type, 
                                       $processname, $modelid, $after, $tablename, 
                                       $comment, $date)
```

---

### 9. **getBillDetailsBuy()** - Purchase Bill Display
**Location**: Line 654  
**Purpose**: Load and format purchase bill data for display/printing

**Function Signature**:
```php
function getBillDetailsBuy($billId)
```

**Data Assembly**:
1. **Bill Master**: Purchase bill details
2. **Supplier Data**: Supplier information
3. **Bank Details**: Payment account information
4. **Products**: Line items with specifications
5. **Branch Info**: Store location details

---

## 🔄 Workflows

### Workflow 1: Complete Purchase Bill Processing
```
┌─────────────────────────────────────────────────────────────┐
│              START: Create Purchase Bill                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Bill Initialization                                     │
│     - Validate supplier information                         │
│     - Generate/validate bill number                         │
│     - Parse product and payment data                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Payment Method Processing                               │
│     FOR EACH selected payment method:                       │
│       │                                                     │
│       ├─→ Cash Payment:                                     │
│       │   └─ Record cash amount paid                       │
│       │                                                     │
│       ├─→ Bank Payment:                                     │
│       │   ├─ Select bank and account                       │
│       │   ├─ Record transfer amount                        │
│       │   └─ Link to bank account record                   │
│       │                                                     │
│       └─→ Insurance Payment:                                │
│           ├─ Process insurance claim                       │
│           ├─ Calculate coverage amounts                     │
│           └─ Upload supporting documents                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Product Receiving                                       │
│     FOR EACH product purchased:                             │
│       │                                                     │
│       ├─→ Create purchase line item                        │
│       │                                                     │
│       ├─→ Update inventory (if physical product):          │
│       │   ├─ Get current stock quantity                    │
│       │   ├─ Add received quantity                         │
│       │   └─ Log inventory movement                        │
│       │                                                     │
│       └─→ Update product costing:                          │
│           ├─ Calculate new weighted average cost           │
│           ├─ Update last purchase price                    │
│           └─ Save cost history                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Supplier Account Management                             │
│     - Calculate supplier debt change                        │
│     - Update supplier balance                               │
│     - Log debt change transaction                           │
│     - Handle credit terms if applicable                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Financial Accounting                                    │
│     Create journal entries:                                 │
│       │                                                     │
│       ├─→ Debit: Inventory/Purchases Account               │
│       │   (Total bill amount)                              │
│       │                                                     │
│       ├─→ Credit: Cash Account                             │
│       │   (If cash payment made)                           │
│       │                                                     │
│       ├─→ Credit: Bank Account                             │
│       │   (If bank payment made)                           │
│       │                                                     │
│       ├─→ Credit: Supplier Payable                         │
│       │   (If credit terms)                                │
│       │                                                     │
│       └─→ Credit: Purchase Discount                        │
│           (If discount received)                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Finalization                                            │
│     - Commit all database transactions                      │
│     - Generate purchase order confirmation                  │
│     - Update supplier payment status                        │
│     - Return processing results                             │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Product Cost Calculation (Weighted Average)
```
┌─────────────────────────────────────────────────────────────┐
│            START: Update Product Costs                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Current Product Data                               │
│     - Get current inventory quantity                        │
│     - Get current weighted average cost                     │
│     - Get last purchase price                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Calculate Weighted Average Cost                         │
│     Formula:                                                │
│       │                                                     │
│       ├─→ Current Value = Qty_Before × Current_Avg_Cost     │
│       │                                                     │
│       ├─→ Purchase Value = Qty_Purchased × Purchase_Price   │
│       │                                                     │
│       ├─→ Total Value = Current_Value + Purchase_Value      │
│       │                                                     │
│       ├─→ Total Quantity = Qty_Before + Qty_Purchased       │
│       │                                                     │
│       └─→ New_Avg_Cost = Total_Value ÷ Total_Quantity       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Update Product Cost Records                             │
│     - Save new weighted average cost                        │
│     - Save last purchase price                              │
│     - Update purchase line item costs                       │
│     - Log cost change transaction                           │
└─────────────────────────────────────────────────────────────┘
```

---

## 🧮 Purchase-Specific Calculations

### Supplier Debt Management
```php
// Purchase increases supplier debt (amount we owe)
$supplierDebtBefore = $supplier->suppliercurrentDebt;
$supplierDebtAfter = $supplierDebtBefore + $waitvalue;

// Log debt change
insertSupplierDebtChangeupdate($supplierId, $supplierDebtBefore, $waitvalue, 
                              0, "Purchase Bill", $billId, $supplierDebtAfter, 
                              "billsbuy.php", "Purchase transaction", $billDate);
```

### Discount Processing
```php
function calculatePurchaseDiscount($billsBuy) {
    $discountAsMoney = 0;
    if ($billsBuy->discounttype == 1) {
        // Fixed amount discount
        $discountAsMoney = $billsBuy->discountvalue;
    } else {
        // Percentage discount
        $discountAsMoney = $billsBuy->netbillvalue * $billsBuy->discountvalue / 100;
    }
    return $discountAsMoney;
}
```

### Inventory Costing (FIFO/Weighted Average)
```php
function updateProductCosts($productId, $purchaseQty, $purchasePrice) {
    $product = $productDAO->load($productId);
    $currentQty = $storeDetail->productquantity;
    $currentAvgCost = $product->meanbuyprice;
    
    // Weighted average calculation
    $totalValue = ($currentQty * $currentAvgCost) + ($purchaseQty * $purchasePrice);
    $totalQty = $currentQty + $purchaseQty;
    $newAvgCost = round($totalValue / $totalQty, 3);
    
    // Update product costs
    $product->meanbuyprice = $newAvgCost;
    $product->lastbuyprice = $purchasePrice;
    $productDAO->update($product);
}
```

---

## 🌐 Bank Account Integration

### Bank Payment Processing
```php
function saveCardPaymentBuy($billsBuy) {
    // In purchase context, "card" represents bank payments
    $billsBuy->paymentnetworkid = $_POST['paymentNetworks']; // Bank ID
    $billsBuy->cardvalue = $_POST['cardValue'];              // Amount
    $billsBuy->netdiscountpercent = $_POST['accountid'];     // Account ID
    return $billsBuy;
}
```

### Bank Account Linking
```php
// Link payment to specific bank account
$accountid = filter_input(INPUT_POST, "accountid");
$accountData = $accountDAO->load($accountid);

if ($accountData->treeId > 0) {
    $treeId = $accountData->treeId;
} else {
    // Create chart of accounts entry for bank account
    $bankData = $bankDAO->load($billsBuy->paymentnetworkid);
    $treeId = addTreeElement("$accountData->accountname / $bankData->bankname", 
                            38, 3, 0, 1, '', 0, 0);
}
```

---

## 🔒 Security & Permissions

### Transaction Integrity
```php
$mytransactions = new Transaction();
try {
    // All purchase operations
    $mytransactions->commit();
} catch (Exception $ex) {
    $mytransactions->rollback();
}
```

### Input Validation
```php
$clientId = filter_input(INPUT_POST, "client");
$billNo = filter_input(INPUT_POST, "billno");
$netbillvalue = filter_input(INPUT_POST, "netBillValue");
```

### User Context
- User ID from `$_SESSION['userid']`
- Branch ID from `$_SESSION['branchId']`
- Save ID from `$_SESSION['saveid']`

---

## 📊 Performance Considerations

### Database Optimization
1. **Critical Indexes**:
   - `billsbuy(clientid, billdate, deleted)`
   - `billsproductsbuy(billid, productid)`
   - `supplier(supplierid)`
   - `supplierdebtchange(supplierid, supplierdebtchangedate)`

2. **Inventory Performance**:
   - Efficient stock quantity updates
   - Batch product cost calculations
   - Optimized movement logging

3. **Financial Calculations**:
   - Minimize decimal precision issues
   - Efficient weighted average computations
   - Fast account tree lookups

---

## 🐛 Common Issues & Troubleshooting

### 1. **Cost Calculation Errors**
**Issue**: Incorrect weighted average costs  
**Cause**: Division by zero or precision issues

**Debug**:
```php
// Check for valid quantities before calculation
if ($totalQty > 0) {
    $newAvgCost = round($totalValue / $totalQty, 3);
} else {
    // Handle zero quantity case
    $newAvgCost = $purchasePrice;
}
```

### 2. **Supplier Debt Discrepancies**
**Issue**: Supplier balances don't match purchase totals  
**Cause**: Missing debt change records

**Debug**:
```sql
-- Verify supplier debt changes
SELECT 
    SUM(CASE WHEN supplierdebtchangetype = 0 THEN supplierdebtchangeamount ELSE 0 END) as purchases,
    SUM(CASE WHEN supplierdebtchangetype = 1 THEN supplierdebtchangeamount ELSE 0 END) as payments
FROM supplierdebtchange 
WHERE supplierid = [SUPPLIER_ID];
```

### 3. **Bank Account Linking Issues**
**Issue**: Payments not properly linked to bank accounts  
**Cause**: Missing account setup or tree ID issues

**Solution**:
- Ensure all bank accounts have valid tree IDs
- Verify account creation logic
- Check chart of accounts integration

---

## 🚀 Future Enhancement Opportunities

### 1. **Advanced Procurement**
- Purchase order workflow
- Supplier performance tracking
- Automatic reordering
- Quote comparison tools

### 2. **Enhanced Costing**
- Standard cost variance analysis
- Landed cost calculations
- Currency conversion handling
- Cost center allocation

### 3. **Bank Integration**
- Real-time bank feeds
- Automatic reconciliation
- Electronic payments
- Multi-currency support

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [billsfunctions.md](billsfunctions.md) - Sales utilities
- [buyBillController.md](buyBillController.md) - Purchase operations

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When procurement features are enhanced