# Product Movement Controller Documentation

**File**: `/controllers/productmovmentController.php`  
**Purpose**: Comprehensive product movement analysis across stores with profit calculations  
**Last Updated**: December 20, 2024  
**Total Functions**: 20+  
**Lines of Code**: ~958

---

## 📋 Overview

The Product Movement Controller provides detailed analysis of product movements across stores including:
- Multi-store movement tracking
- Profit and loss calculations
- Settlement and inventory adjustments
- Buy/sell transaction analysis
- Store-specific balance calculations
- Size/color variant support

### Primary Functions
- [x] Multi-store product movement tracking
- [x] Buy/sell transaction analysis
- [x] Settlement and inventory adjustments
- [x] Profit/loss calculations
- [x] Store balance calculations
- [x] Unit conversion handling

---

## 🗄️ Database Tables

### Core Movement Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **storereport** | Product movement history | storereportid, productid, storeid, productafter, storereportdate, tablename |
| **sellbilldetail** | Sales transactions | sellbilldetailid, sellbilldetailproductid, sellbilldetailquantity, sellbilldetailprice |
| **buybilldetail** | Purchase transactions | buybilldetailid, buybilldetailproductid, buybilldetailquantity |
| **billsproducts** | Service bill items | productid, productno |

### Master Data Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Product information | productId, productName, productCatId |
| **store** | Store information | storeId, storeName |
| **productunit** | Unit conversions | productunitid, productId, productnumber |

---

## 🔑 Key Functions

### 1. **show()** - Main Report Display
**Location**: Line 188  
**Purpose**: Generate multi-store product movement report

**Process Flow**:
1. **Parameter Processing**:
   ```php
   $productSearchId = $_REQUEST['productId'];
   $startDate = $_REQUEST['from'];
   $endDate = $_REQUEST['to'];
   ```

2. **Size/Color Variant Handling**:
   ```php
   if (strpos($productSearchId, "hasSizeColor") !== false) {
       $productIdComplex = explode('-', str_replace("hasSizeColor", "", $productSearchId));
       $productSearchId = $productIdComplex[0];
       $sizeId = $productIdComplex[1];
       $colorId = $productIdComplex[2];
   }
   ```

3. **Report Generation**:
   ```php
   getProductInBillByDateAndProductId($startDate, $endDate, $productSearchId);
   ```

### 2. **getProductInBillByDateAndProductId()** - Core Analysis Engine
**Location**: Line 255  
**Purpose**: Generate comprehensive movement analysis for all stores

**Multi-Store Processing**:
```php
$i = 1;
foreach ($allstor as $myallstor) {
    $storeId = $myallstor->storeId;
    
    // Get latest balance
    $storreportdata = $StorereportEX->queryAlllastdealNew($queryString);
    $productafter = (int) $storreportdata->productafter;
    
    // Calculate sales
    $totalsell = $sellPriceData[1] + $sellPricePulsData[1] + $billsData;
    
    // Calculate returns
    $totalreturnsell = $returnSellPricePulsData[1] + $returnSellPriceData[1] + $billsReturnData;
    
    // Calculate purchases
    $totalbuy = $buybilldata[0];
    $totalreturnbuy = $buybilldata[1];
    
    // Calculate settlements
    $settlementAdd = R::getCell('select sum(productquantity) from storereport where...');
    $settlementSub = R::getCell('select sum(productquantity) from storereport where...');
    
    // Final calculation
    $final = ($buydif + $productafter + $settleFinal) - $selldif;
    
    $smarty->assign("final" . $i, $final);
    $i++;
}
```

### 3. **getTotalSellPriceByDateAndProductId()** - Sales Analysis
**Location**: Line 426  
**Purpose**: Calculate sales quantities and prices with discount handling

**Discount Processing**:
```php
// Percentage discount
if ($sellbillDiscountType == 2) {
    $sellbillDiscount = ($sellbillDiscount / 100) * $sellbillTotalBill;
}

// Price calculation
$sellPriceForOneProduct = $totalPriceBeforeDiscount - (($discountValue * $quantity) + $sellbillDiscount);

// Unit conversion
$quantityUnit += ($quantity * $productnumber);
```

### 4. **getTotalBuyPriceByDateAndProductId()** - Purchase Analysis
**Location**: Line 702  
**Purpose**: Calculate purchase and return quantities across multiple bill types

**Multi-Source Purchase Calculation**:
```php
// Regular purchases
$buybilldataData = $myBuybilldetailEx->queryWithDateAndConditionsAndProductIdandstorNew($queryString);
foreach ($buybilldataData as $mybuybilldataData) {
    $quantity = $mybuybilldataData->buybilldetailquantity;
    $productnumber = $myProductunitEx->getProductNumber($productunitId);
    $quantityUnit += ($quantity * $productnumber);
}

// Combined purchases
$buyandruturn = $myBuyandruternbilldetailEx->queryWithDateAndConditionsAndTypeAndProductIdandstoreNew(0, $queryString2);

// Purchase returns
$ruturndata = $myReturnbuybilldetailEx->queryWithDateAndConditionsAndProductIdandstoreNew($queryString3);

return array($quantityUnit, $ruturnquntity);
```

---

## 🔄 Workflows

### Workflow: Multi-Store Movement Analysis
```
┌─────────────────────────────────────────────────────────────┐
│             START: Movement Analysis Request               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Parameter Processing                                    │
│     - Extract product ID                                    │
│     - Handle size/color variants                            │
│     - Parse date range                                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Store Iteration                                         │
│     FOR EACH store:                                         │
│       │                                                     │
│       ├─→ Get latest product balance                       │
│       ├─→ Calculate sales transactions                     │
│       ├─→ Calculate purchase transactions                  │
│       ├─→ Calculate returns (buy & sell)                   │
│       ├─→ Calculate settlement adjustments                 │
│       └─→ Calculate final balance                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Data Processing                                         │
│     - Apply unit conversions                                │
│     - Handle discount calculations                          │
│     - Process settlement entries                            │
│     - Calculate net movements                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Report Generation                                       │
│     - Assign store-specific data                            │
│     - Generate summary totals                               │
│     - Display multi-store view                              │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Description |
|---------------|-------------|
| `do=show` | Generate movement analysis |
| `productId` | Product ID (may include size/color variants) |
| `from` / `to` | Date range filter |

---

## 🧮 Calculation Methods

### Final Balance Calculation
```php
$final = ($buydif + $productafter + $settleFinal) - $selldif;

// Where:
// $buydif = total_purchases - total_purchase_returns
// $productafter = current_balance_from_last_movement
// $settleFinal = settlement_additions - settlement_subtractions  
// $selldif = total_sales - total_sales_returns
```

### Settlement Processing
```php
$settlementAdd = R::getCell('select if(sum(productquantity) > 0,sum(productquantity),0) 
    from storereport 
    where storereporttype = 0 
    AND (tablename ="settlementstoreController.php" OR tablename ="inventoryController.php")' 
    . $queryString);

$settlementSub = R::getCell('select if(sum(productquantity) > 0,sum(productquantity),0) 
    from storereport 
    where storereporttype = 1 
    AND (tablename ="settlementstoreController.php" OR tablename ="inventoryController.php")' 
    . $queryString);
```

### Discount Application
```php
// Bill-level discount distribution
$thirdStep = ($totalPrice / $sellbillTotalBill) * $sellbillDiscount;

// Final price after all discounts
$sellPriceForOneProduct = $totalPriceBeforeDiscount - (($discountValue * $quantity) + $sellbillDiscount);
```

---

## 🔒 Security & Permissions

### Authentication
```php
include_once("../public/authentication.php");
```

### Input Validation
- Parameter extraction with type checking
- Date range validation
- Product ID sanitization

---

## 📊 Performance Considerations

### Optimizations
- Store-specific query batching
- Efficient unit conversion handling
- Proper SQL aggregation functions
- Minimal template variable assignment

### Performance Notes
- Processes all stores sequentially
- Multiple database queries per store
- Complex calculation chains
- Large datasets may impact performance

---

## 🐛 Common Issues & Troubleshooting

### 1. **Balance Calculation Discrepancies**
**Issue**: Final balances don't match expected values
**Cause**: Missing transaction types or incorrect settlement handling

**Debug**:
```php
// Add debugging output
error_log("Store $storeId: Buy=$totalbuy, Sell=$totalsell, Balance=$productafter, Final=$final");
```

### 2. **Unit Conversion Errors**
**Issue**: Quantities not properly converted to base units
**Cause**: Missing or incorrect productnumber values

**Fix**: Ensure all products have proper unit conversion factors

---

## 🧪 Testing Scenarios

### Test Case 1: Multi-Store Movement
```
1. Select product with transactions in multiple stores
2. Set date range covering known movements
3. Verify calculations for each store
4. Check final balance accuracy
```

### Test Case 2: Discount Calculations
```
1. Test products with various discount types
2. Verify bill-level discount distribution
3. Check item-level discount application
4. Validate final pricing calculations
```

---

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