<?php
$PageSecurity = 11;
include('includes/session.inc');
include('includes/function_lib.php');

$invoiceId = isset($_REQUEST['invoice_id']) ? mysqli_real_escape_string($db, $_REQUEST['invoice_id']) : '';
$recAgainst = isset($_REQUEST['recAgainst']) ? trim($_REQUEST['recAgainst']) : '';
$poId = isset($_REQUEST['POID']) ? mysqli_real_escape_string($db, $_REQUEST['POID']) : '';

class InvoiceProcessor
{
    private $db;
    private $s;

    public function __construct($db, $s)
    {
        $this->db = $db;
        $this->s = $s;
    }

    /**
     * Process invoice details request
     */
    public function processInvoiceDetails($invoiceId)
    {
        if (empty($invoiceId)) {
            return false;
        }
        $sql = "SELECT * FROM invoice_details WHERE invoiceid = '$invoiceId'";
        $result = DB_query($sql, $this->db);
        if (DB_num_rows($result) == 0) {
            return false;
        }

        return $this->renderInvoiceDetailsTable($result);
    }

    /**
     * Render complete invoice details table
     */
    private function renderInvoiceDetailsTable($result)
    {
        $html = '<h3>Items Details ';
        $html .= '<input type="button" value="Delete" onclick="deleteItems()" class="search" /></h3>';
        $html .= '<table width="100%" cellpadding="1" cellspacing="0" border="0" class="thborder">';
        $html .= $this->getInvoiceTableHeader();

        $counter = 1;
        while ($data = DB_fetch_array($result)) {
            $html .= $this->getInvoiceTableRow($data, $counter);
            $counter++;
        }

        $html .= $this->getInvoiceTableFooter($counter);
        $html .= '</table>';
        $html .= '<input type="hidden" value="' . $counter . '" id="count3" name="hiditemcount">';

        return $html;
    }

    private function getInvoiceTableHeader()
    {
        return '<tr>
               <th width="4%">S. No.</th>
               <th width="10%">Item Code</th>
               <th>Item Name</th>
               <th width="8%">PO Qty.</th>
               <th width="8%">Free Qty.</th>
               <th width="8%">Pending Qty.</th>
               <th width="10%">Batch No.</th>
               <th width="7%">Date of Mfg.</th>
               <th width="7%">Date of Exp.</th>
               <th width="8%">Bill Qty.</th>
               <th style="text-align:center;" colspan="5">Rec. Qty.</th>
               <th colspan="5" class="text-right">Short/Excess Qty</th>
           </tr>';
    }

    private function getInvoiceTableRow($data, $counter)
    {
        $itemCode = $this->s->GetFieldValue("item_master", "id='{$data['ItemCode']}'", "StockID");
        $itemName = $this->s->GetFieldValue("item_master", "id='{$data['ItemCode']}'", "item_name");
        $unit = $this->s->GetFieldValue("item_master", "id='{$data['ItemCode']}'", "mst_unitid");
        $unitName = $this->s->GetFieldValue("unitsofmeasure", "unitid='$unit'", "unitname");
        $convUnit = $this->s->GetFieldValue("item_master", "id='{$data['ItemCode']}'", "conv_unit");
        $secUnitName = $this->s->GetFieldValue("unitsofmeasure", "unitid='$convUnit'", "unitname");
        $convFactor = $this->s->GetFieldValue("item_master", "id='{$data['ItemCode']}'", "conv_factor");

        $html = '<tr>';
        $html .= '<td>' . $counter;
        $html .= '<input type="hidden" value="' . htmlspecialchars($data['ItemCode']) . '" id="itemid" name="mst_itemid[]">';
        $html .= '<input type="hidden" value="" size="15" name="tolrancees[]" id="tolerances_' . $counter . '" readonly>' . '</td>';
        $html .= '<td><input type="text" value="' . htmlspecialchars($itemCode) . '" readonly></td>';
        $html .= '<td><input type="text" value="' . htmlspecialchars($itemName) . '" readonly></td>';
        $html .= '<td><input type="text" value="' . $data['Quantity'] . '" id="poqty_' . $counter . '" name="poqty[]" readonly></td>';
        $html .= '<td><input type="text" value="' . $data['free_qty'] . '" id="freeqty_' . $counter . '" name="freeqty[]" readonly></td>';
        $html .= '<td><input type="text" value="' . $data['Quantity'] . '" id="pending_' . $counter . '" name="pending_qty[]" readonly></td>';
        $html .= '<td><input type="text" value="' . htmlspecialchars($data['batch_no']) . '" id="batchNo_' . $counter . '" name="batchNo[]"></td>';
        $html .= '<td><input type="text" readonly id="mfg_' . $counter . '" value="' . ConvertSQLDate($data['date_of_mfg']) . '" name="mfg[]"></td>';
        $html .= '<td><input type="text" readonly id="expiry_' . $counter . '" value="' . ConvertSQLDate($data['ExpireDate']) . '" name="expiry[]"></td>';
        $html .= '<td align="right"><input type="text" value="' . $data['Quantity'] . '" onkeyup="calTotalQty1Direct(this.value,this.id,this);" autocomplete="off" id="qtyasperbill_' . $counter . '" onkeypress="return isNumberKey(event)" name="qtyasperbill[]"></td>';
        $html .= '<td align="right"><input type="text" onkeyup="calTotalQtyDirect(this.value,this.id,this);" autocomplete="off" id="reciveqty_' . $counter . '" onkeypress="return isNumberKey(event)" name="reciveqty[]"></td>';
        $html .= '<td align="right"><input type="text" onkeyup="calTotalQtyDirect(this.value,this.id,this);" autocomplete="off" id="rfreeqty_' . $counter . '" onkeypress="return isNumberKey(event)" name="rfreeqty[]"  placeholder="Free Qty" ></td>';
        $html .= '<td align="right">';
        $html .= '<select name="unit[]"><option value="' . $unit . '">' . htmlspecialchars($unitName) . '</option></select>';
        $html .= '<input type="hidden" value="' . $convFactor . '" autocomplete="off" id="convfac_' . $counter . '" name="conv_fac[]">';
        $html .= '</td>';
        $html .= '<td align="right"><input type="text" autocomplete="off" id="reciveqty2_' . $counter . '" readonly name="reciveqty2[]"></td>';
        $html .= '<td align="right"><select name="unit2[]"><option value="' . $convUnit . '">' . htmlspecialchars($secUnitName) . '</option></select></td>';
        $html .= '<td align="right"><div style="float:left; width:20px;"><input type="text" id="minSign_' . $counter . '" name="minSign[]" readonly style="width:20px;"></div></td>';
        $html .= '<td align="right">';
        $html .= '<div style="float:left; width:100%;">';
        $html .= '<input type="text" onfocus="calculate_poshort(1);" readonly="true" value="" id="shortaccessid_' . $counter . '" name="shortaccessid[]">';
        $html .= '</div>';
        $html .= '<input type="hidden" name="qtytype[]" id="qtytype_' . $counter . '" value="P">';
        $html .= '</td>';
        $html .= '</tr>';

        return $html;
    }

    private function getInvoiceTableFooter($counter)
    {
        return '<tr>
               <td style="text-align:right;" colspan="9"><strong>Total Quantity</strong></td>
               <td><input type="text" size="8" id="shortDirect" readonly name="totalBillQty"></td>
               <td><input type="text" size="8" id="short1Direct" readonly name="totalRecQty"></td>
               <td colspan="7">&nbsp;</td>
           </tr>';
    }

    /**
     * Process PO reception
     */
    public function processPOReception($poId)
    {
        if (empty($poId)) {
            return false;
        }

        $poData = $this->getPurchaseOrderData($poId);
        if (!$poData) {
            return false;
        }

        $poTypeDisplay = $this->getPOTypeDisplay($poData['purchase_ord_Type']);
        $poCategoryDisplay = $this->getPOCategoryDisplay($poData['po_category']);
        $dutyType = ($poData['itemwise_check'] == 'Y') ? 'itemwise' : 'Consolidated';

        $poInfo = $this->renderPOInfo($poTypeDisplay, $poData['purchase_ord_Type'], $dutyType);
        $categoryInfo = $this->renderPOCategoryInfo($poCategoryDisplay, $poData['po_category']);
        $itemsTable = $this->renderPOItemsTable($poId, $poData);

        return $poInfo . '__' . $itemsTable . '__' . $categoryInfo;
    }

    private function getPurchaseOrderData($poId)
    {
        $sql = "SELECT * FROM purchorders WHERE id = '$poId'";
        $result = DB_query($sql, $this->db);
        return DB_fetch_array($result);
    }

    private function getPOTypeDisplay($poType)
    {
        $typeMap = [
            'IO' => 'Import Order',
            'DO' => 'Domestic Order'
        ];
        return isset($typeMap[$poType]) ? $typeMap[$poType] : '';
    }

    private function getPOCategoryDisplay($poCategory)
    {
        $categoryMap = [
            'AT' => 'Asset',
            'MT' => 'Material',
            'SV' => 'Service'
        ];
        return isset($categoryMap[$poCategory]) ? $categoryMap[$poCategory] : '';
    }

    private function renderPOInfo($poTypeDisplay, $poType, $dutyType)
    {
        return '<input type="text" name="" id="" readonly value="' . htmlspecialchars($poTypeDisplay) . '" style="width:100%;"/>
                   <input type="hidden" name="poType" id="poType" value="' . htmlspecialchars($poType) . '" />
                   <input type="hidden" name="dutytype" id="dutytype" value="' . htmlspecialchars($dutyType) . '" />';
    }

    private function renderPOCategoryInfo($poCategoryDisplay, $poCategory)
    {
        return '<input type="text" name="" id="purch_ord_category" readonly value="' . htmlspecialchars($poCategoryDisplay) . '" style="width:100%;"/>
                   <input type="hidden" name="purch_ord_category" value="' . htmlspecialchars($poCategory) . '" />';
       }
       
       private function renderPOItemsTable($poId, $poData) {
           $html = '<h3>Items Details ';
           $html .= '<input type="button" value="Delete" class="search" onclick="deleteItems()"/></h3>';
           $html .= '<table width="100%" cellpadding="3" cellspacing="0" border="0" class="thborder" id="tableDataProduction">';
           $html .= $this->getPOItemsTableHeader();
           
           $counter = 1;
           $itemDetailsSql = "SELECT * FROM purchorderdetails WHERE parantId = '$poId' AND status = 'Pending' GROUP BY mst_itemid";
           $itemResult = DB_query($itemDetailsSql, $this->db);
           
           while ($itemRow = DB_fetch_array($itemResult)) {
               $itemSummary = $this->getItemQuantitySummary($poId, $itemRow['mst_itemid']);
               $itemRow['Quantity'] = $itemSummary['qty'];
               $itemRow['free_qty'] = $itemSummary['free_qty'];
               
               if ($this->shouldDisplayItem($itemRow, $poId)) {
                   $html .= $this->getPOItemTableRow($itemRow, $poId, $counter, $poData);
                   $counter++;
               }
           }
           
           $html .= $this->getPOItemsTableFooter($counter);
           $html .= '</table>';
           $html .= '<input type="hidden" name="hiditemcount" id="count3" value="' . $counter . '"/>';
		   
		   $query_edit = "SELECT *, discount_amt*100/total_amount AS dis_per from purchorders where id = '$poId'";
           $query_edit_res = DB_query($query_edit,$this->db) or die(DB_error());
           $query_edit_result = DB_fetch_assoc($query_edit_res);
				
   	       $data2 = '';
   		   $data2 .= '<table width="100%" border="0" cellspacing="0" cellpadding="3">';
   		   $data2 .= '<tr class="row1">';
   		   $data2 .= '<td width="36%" align="right">Basic Amount</td>';
   		   $data2 .= '<td><input type="text" name="basic_amt" readonly id="total_item_amount" class="text-right" value="" data-val="' . $query_edit_result['total_amount'] . '" /></td>';
   		   $data2 .= '</tr>';
   			
   		   $data2 .= '<tr class="row1">';
   		   $data2 .= '<td align="right">Freight And P&amp;S</td>';
   		   $data2 .= '<td><input type="text" name="Freight" id="TotalCharge" onkeyup="calTotalQtyDirect(this.value,this.id,this);" class="text-right" value="' . $query_edit_result['Freight'] . '"  data-val="' . $query_edit_result['Freight'] . '" /></td>';
   		   $data2 .= '</tr>';
   			
   		   $data2 .= '<tr class="row1">';
   		   $data2 .= '<td align="right">GST</td>';
   		   $data2 .= '<td><div id="taxval"><input type="text" class="text-right" value="" data-val="' . $query_edit_result['vat_amt'] . '" ';
   		   $data2 .= 'name="tax_amt" id="taxvalue" readonly="true" /></div></td>';
   		   $data2 .= '</tr>';
   			
   		   $data2 .= '<tr class="row1">';
   		   $data2 .= '<td align="right">Insurance</td>';
   		   $data2 .= '<td><input name="insr_amt" class="text-right" value="" data-val="' . $query_edit_result['insurancecharges_amt'] . '" ';
   		   $data2 .= 'id="insurance" type="text" readonly /></td>';
   		   $data2 .= '</tr>';
   			
   		   $data2 .= '<tr class="row1">';
   		   $data2 .= '<td align="right">Miscellaneous</td>';
   		   $data2 .= '<td><input type="text" class="text-right" value="" data-val="' . $query_edit_result['other_amt'] . '" ';
   		   $data2 .= 'name="other_amt" id="miscellaneous" readonly /></td>';
   		   $data2 .= '</tr>';
   			
   			$data2 .= '<tr class="row1">';
   			$data2 .= '<td align="right">Round Off</td>';
   			$data2 .= '<td>';
   			$data2 .= '<input type="text" name="pluMin" readonly id="pluMin" style="width:23%;" ';
   			$data2 .= ' value="" data-val="' . $query_edit_result['pluMin'] . '" />';
   			$data2 .= '<input type="text" name="roundVal" readonly id="roundVal" class="text-right" style="width:74%;" ';
   			$data2 .= ' value="" data-val="' . $query_edit_result['roundVal'] . '" />';
   			$data2 .= '</td></tr>';
   			
   			$data2 .= '<tr class="row1">';
   			$data2 .= '<td align="right">Grand Total</td>';
   			$data2 .= '<td><input type="text" name="GrandTotal" class="text-right" readonly id="GrandTotal" ';
   			$data2 .= ' value="" data-val="' . $query_edit_result['GrandTotal'] . '" /></td>';
   			$data2 .= '</tr>';
   			$data2 .= '</table>';
   			
   		    $html .= '<table border="0" width="100%" cellpadding="2" cellspacing="0">
   			<tr>
   				<td valign="top" colspan="6">&nbsp;</td>
   				<td width="36%" valign="top">
   					<div id="basicamtdetails">' . $data2 . '</div>
   				</td>
   			</tr>
   		</table>';


        return $html;
    }

    private function getPOItemsTableHeader()
    {
        return '<tr>
               <th width="4%">Select</th>
               <th width="8%">Item Code</th>
               <th width="15%">Item Name</th>
               <th width="5%">PO Qty.</th>
               <th width="5%">Free Qty.</th>
               <th width="5%">Pending Qty.</th>
               <th width="5.5%">Batch No.</th>
               <th width="6%">Date of MFG.</th>
               <th width="6%">Date of Exp.</th>
               <th width="4.5%">Bill Qty.</th>
               <th style="text-align:center;" colspan="5">Rec. Qty.</th>
               <th colspan="2">Short/Excess Qty.</th>
               <th width="1"></th>
               <th width="4%">MRP</th>
           </tr>';
       }
       
       private function getItemQuantitySummary($poId, $itemId) {
           $sql = "SELECT SUM(Quantity) as qty, SUM(free_qty) as free_qty FROM purchorderdetails WHERE parantId = '$poId' AND status = 'Pending' AND mst_itemid = '$itemId'";
           $result = DB_query($sql, $this->db);
           return DB_fetch_array($result);
       }
       
       private function shouldDisplayItem($itemRow, $poId) {
           $pendingQty = $this->calculatePendingQuantity($itemRow, $poId);
           $secondaryQty = $this->calculateSecondaryQuantity($itemRow, $poId);
           return ($pendingQty != 0 || $secondaryQty != 0);
       }
       
       private function calculatePendingQuantity($itemRow, $poId) {
           $totQty = $itemRow['Quantity'] + $itemRow['free_qty'];
           $unitId = $itemRow['mst_unitid'];
           if ($unitId == '0') {
               $unitId = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'mst_unitid');
           }
           
           $stockQtySql = "SELECT SUM(reciveqty) as stockqty, SUM(stock_qty2) as stockqty2 FROM addmrnqty INNER JOIN addmrn ON addmrn.id = addmrnqty.issue_id WHERE addmrn.order_no = '$poId' AND addmrnqty.mst_itemid = '{$itemRow['mst_itemid']}' AND mst_unitid = '$unitId' AND ReceivedAgainst = 'PO'";
           
           $stockResult = DB_query($stockQtySql, $this->db);
           $stockData = DB_fetch_array($stockResult);
           
           $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');
           $secondaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_unit');
           $qtyType = ($unitId == $primaryUnit) ? 'P' : 'S';
           
           if ($qtyType == 'P') {
               return ($totQty >= $stockData['stockqty']) ? $totQty - $stockData['stockqty'] : $totQty;
           } else {
               return ($totQty >= $stockData['stockqty2']) ? $totQty - $stockData['stockqty2'] : $totQty;
           }
       }
       
       private function calculateSecondaryQuantity($itemRow, $poId) {
           $pendingQty = $this->calculatePendingQuantity($itemRow, $poId);
           $convFactor = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_factor');
           $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');
           $unitId = $itemRow['mst_unitid'];
           if ($unitId == $primaryUnit) {
               return round($pendingQty * $convFactor, 2);
           } else {
               return round($pendingQty / $convFactor, 2);
           }
       }
       
       private function getPOItemTableRow($itemRow, $poId, $counter, $poData) {
           $itemCode = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'StockID');
           $itemName = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'item_name');
           $unitId = $itemRow['mst_unitid'];
           if ($unitId == '0') {
               $unitId = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'mst_unitid');
           }
           $unitName = $this->s->GetFieldValue('unitsofmeasure', "unitid='$unitId'", 'unitname');
           $secondaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_unit');
           $secUnitName = $this->s->GetFieldValue('unitsofmeasure', "unitid='$secondaryUnit'", 'unitname');
           $convFactor = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_factor');
           $tolerance = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'item_mst_form_rate');
           $pendingQty = $this->calculatePendingQuantity($itemRow, $poId);
   		
           if (!empty($tolerance)) {
               $tolr = round(($pendingQty * $tolerance) / 100, 2);
               $pendingQty = round(($pendingQty + $tolr), 2);
           }
           
           $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');
           $qtyType = ($unitId == $primaryUnit) ? 'P' : 'S';
		   
		   $taxrate = $this->s->getField('sales_tax_master', 'salestax_id', $itemRow['vat_id'], 'taxrate');
           
           $html = '<tr>';
           $html .= '<td>';
           $html .= '<input type="checkbox" name="rec[]" id="rec_' . $counter . '"> ';
           $html .= '&nbsp;<input type="button" value="+" id="add_' . $counter . '" onclick="javascript:addBatch(this,this.id);">';
           $html .= '<input type="hidden" id="tolerances_' . $counter . '" name="tolrancees[]" size="15" value="' . $tolerance . '" />';
           $html .= '<input type="hidden" name="mst_itemid[]" id="itemid" value="' . $itemRow['mst_itemid'] . '" />';
   		   $html .= '</td>';
           $html .= '<td width="8%">' . htmlspecialchars($itemCode) . '</td>';
           $html .= '<td width="15%">' . htmlspecialchars($itemName) . '</td>';
           $html .= '<td class="text-center">' . $itemRow['Quantity'] . '<input type="hidden" name="poqty[]" id="poqty_' . $counter . '" value="' . $itemRow['Quantity'] . '" /></td>';
           $html .= '<td class="text-center">' . $itemRow['free_qty'] . '<input type="hidden" name="freeqty[]" id="freeqty_' . $counter . '" value="' . $itemRow['free_qty'] . '" /></td>';
           $html .= '<td class="text-center">' . $pendingQty;
           $html .= '<input type="hidden" name="pending_qty[]" class="text-right" id="pending_' . $counter . '" value="' . $pendingQty . '" data-rate="'.$itemRow['Rate'].'" data-tax="'.$taxrate.'"/>';
           $html .= '<input type="hidden" name="count_item" id="count_item" value="' . $counter . '" /></td>';
           $html .= '<td><input type="text" name="batchNo[]" id="batchNo_' . $counter . '" size="8"/></td>';
           $html .= '<td><input type="text" name="mfg[]" id="mfg_' . $counter . '" class="datepicker" readonly onchange="checkfuturedate(this.value);" /></td>';
           $html .= '<td><input type="text" name="expiry[]" id="expiry_' . $counter . '" class="datepicker" readonly onchange="checkitemdate(this);" /></td>';
           $html .= '<td width="4%"><input name="qtyasperbill[]" onkeypress="return isNumberKey(event)" type="text" id="qtyasperbill_' . $counter . '" class="sum_bill_quantity_' . $counter . ' text-right" autocomplete="off" onkeyup="calTotalQty1Direct(this.value,this.id,this);" size="8" /></td>';
           $html .= '<td width="4%"><input name="reciveqty[]" onkeypress="return isNumberKey(event)" type="text" id="reciveqty_' . $counter . '" autocomplete="off" onkeyup="calTotalQtyDirect(this.value,this.id,this);" size="8" class="text-right" /></td>';
   		   $html .= '<td width="3.5%"><input name="rfreeqty[]" onkeypress="return isNumberKey(event)" type="text" id="rfreeqty_' . $counter . '" autocomplete="off" onkeyup="calTotalQtyDirect(this.value,this.id,this);" placeholder="Free Qty" class="text-right" size="8" /></td>';
           $html .= '<td width="6%"><select name="unit[]"><option value="' . $unitId . '">' . htmlspecialchars($unitName) . '</option></select>';
           $html .= '<input name="conv_fac[]" type="hidden" id="convfac_' . $counter . '" autocomplete="off" size="8" value="' . $convFactor . '" /></td>';
           $html .= '<td width="4%"><input name="reciveqty2[]" readonly type="text" id="reciveqty2_' . $counter . '" autocomplete="off" size="8" class="text-right" /></td>';
           $html .= '<td width="6%"><select name="unit2[]"><option value="' . $secondaryUnit . '">' . htmlspecialchars($secUnitName) . '</option></select></td>';
           $html .= '<td width="4.5%"><div style="float:left; width:100%;"><input type="text" readonly name="minSign[]" id="minSign_' . $counter . '" /></div></td>';
           $html .= '<td width="4.5%"><div style="float:left; width:100%;">';
           $html .= '<input name="shortaccessid[]" type="text" id="shortaccessid_' . $counter . '" value="" readonly="true" onfocus="calculate_poshort(' . $counter . ');" /></div></td>';
           $html .= '<td><input id="confac1_' . $counter . '" type="hidden" value="' . $convFactor . '" />';
           $html .= '<input type="hidden" name="qtytype[]" id="qtytype_' . $counter . '" value="' . $qtyType . '" /></td>';
           $html .= '<td><input type="text" name="mrprate[]" class="text-right" onkeyup="calTotalQtyDirect(this.value,this.id,this);" id="mrprate_' . $counter . '" value="' . $itemRow['mrp'] . '"  size="8"/></td>';
           $html .= '</tr>';
           
           return $html;
       }
       
       private function getPOItemsTableFooter($counter) {
           return '<tr>
               <td colspan="9" style="text-align:right;"><strong>Total Quantity</strong></td>
               <td><input name="totalBillQty" readonly type="text" id="shortDirect" size="8" /></td>
               <td><input name="totalRecQty" readonly type="text" id="short1Direct" size="8" /></td>
               <td colspan="9">&nbsp;</td>
           </tr>';
    }

    /**
     * Process Indent reception
     */
    public function processIndentReception($indentId)
    {
        if (empty($indentId)) {
            return false;
        }

        $html = '<h3><strong>Items Details</strong></h3>';
        $html .= '<table width="140%" cellpadding="3" cellspacing="0" border="0" class="thborder">';
        $html .= $this->getIndentTableHeader();

        $counter = 1;
        $itemDetailsSql = "SELECT * FROM requisitionorderdetails WHERE requsitionno = '$indentId'";
        $itemResult = DB_query($itemDetailsSql, $this->db);

        while ($itemRow = DB_fetch_array($itemResult)) {
            if ($this->shouldDisplayIndentItem($itemRow, $indentId)) {
                $html .= $this->getIndentTableRow($itemRow, $indentId, $counter);
                $counter++;
            }
        }

        $html .= $this->getIndentTableFooter($counter);
        $html .= '</table>';
        $html .= '<input type="hidden" name="hiditemcount" id="count3" value="' . $counter . '"/>';

        return $html;
    }

    private function getIndentTableHeader()
    {
        return '<tr>
               <th width="3%">S. No.</th>
               <th width="8%">Item Code</th>
               <th>Item Name</th>
               <th width="4%">Unit</th>
               <th width="4%">Indent Qty.</th>
               <th width="4%">Pending Qty.</th>
               <th width="8%">Batch No.</th>
               <th width="4%">Bill Qty.</th>
               <th style="text-align:center;" colspan="5">Rec. Qty.</th>
               <th colspan="3" class="text-right">Short/Excess Qty.</th>
           </tr>';
    }

    private function shouldDisplayIndentItem($itemRow, $indentId)
    {
        $pendingQty = $this->calculateIndentPendingQuantity($itemRow, $indentId);
        $secondaryQty = $this->calculateIndentSecondaryQuantity($itemRow, $indentId);
        return ($pendingQty != 0 || $secondaryQty != 0);
    }

    private function calculateIndentPendingQuantity($itemRow, $indentId)
    {
        $unitId = $itemRow['uom'];
        $stockQtySql = "SELECT SUM(reciveqty) as stockqty, SUM(stock_qty2) as stockqty2 
                          FROM addmrnqty 
                          INNER JOIN addmrn ON addmrn.id = addmrnqty.issue_id
                          WHERE addmrn.order_no = '$indentId' 
                          AND addmrnqty.mst_itemid = '{$itemRow['mst_itemid']}' 
                          AND ReceivedAgainst = 'Indent'";

        $stockResult = DB_query($stockQtySql, $this->db);
        $stockData = DB_fetch_array($stockResult);

        $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');
        $secondaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_unit');
        $qtyType = ($unitId == $primaryUnit) ? 'P' : 'S';

        if ($qtyType == 'P') {
            return ($itemRow['requisition_qty'] >= $stockData['stockqty']) ?
                $itemRow['requisition_qty'] - $stockData['stockqty'] : $itemRow['requisition_qty'];
        } else {
            return ($itemRow['requisition_qty'] >= $stockData['stockqty2']) ?
                $itemRow['requisition_qty'] - $stockData['stockqty2'] : $itemRow['requisition_qty'];
        }
    }

    private function calculateIndentSecondaryQuantity($itemRow, $indentId)
    {
        $pendingQty = $this->calculateIndentPendingQuantity($itemRow, $indentId);
        $convFactor = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_factor');
        $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');

        if ($itemRow['uom'] == $primaryUnit) {
            return round($pendingQty * $convFactor, 2);
        } else {
            return round($pendingQty / $convFactor, 2);
        }
    }

    private function getIndentTableRow($itemRow, $indentId, $counter)
    {
        $itemCode = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'StockID');
        $itemName = $this->s->GetFieldValue('item_master', "id='{$itemRow['mst_itemid']}'", 'item_name');
        $unitId = $itemRow['uom'];
        $unitName = $this->s->GetFieldValue('unitsofmeasure', "unitid='$unitId'", 'unitname');
        $convFactor = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'conv_factor');
        $tolerance = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'item_mst_form_rate');
        $pendingQty = $this->calculateIndentPendingQuantity($itemRow, $indentId);

        $primaryUnit = $this->s->getField('item_master', 'id', $itemRow['mst_itemid'], 'mst_unitid');
        $qtyType = ($unitId == $primaryUnit) ? 'P' : 'S';

        $html = '<input type="hidden" name="mst_itemid[]" id="itemid" value="' . $itemRow['mst_itemid'] . '" />';
        $html .= '<input type="hidden" id="tolerances_' . $counter . '" name="tolrancees[]" size="15" value="' . $tolerance . '" />';
        $html .= '<tr>';
        $html .= '<td>' . $counter . '.</td>';
        $html .= '<td>' . htmlspecialchars($itemCode) . '</td>';
        $html .= '<td>' . htmlspecialchars($itemName) . '</td>';
        $html .= '<td>' . htmlspecialchars($unitName) . '<input type="hidden" name="unitid[]" value="' . $unitId . '"></td>';
        $html .= '<td>' . $itemRow['requisition_qty'] . '<input type="hidden" name="poqty[]" id="poqty_' . $counter . '" value="' . $itemRow['requisition_qty'] . '" /></td>';
        $html .= '<td>' . $pendingQty . '<input type="hidden" name="pending_qty[]" id="pending_' . $counter . '" value="' . $pendingQty . '" /></td>';
        $html .= '<td width="4%"><input type="text" autocomplete="off" name="batchNo[]" id="batchNo_' . $counter . '" size="8"/></td>';
        $html .= '<td width="4%"><input name="qtyasperbill[]" type="text" id="qtyasperbill_' . $counter . '" autocomplete="off" onkeyup="calTotalQty1Direct(this.value,this.id);" size="8"/></td>';
        $html .= '<td width="4%"><input name="reciveqty[]" type="text" id="reciveqty_' . $counter . '" autocomplete="off" onkeyup="calTotalQtyDirect(this.value,this.id);" size="8"/></td>';
        $html .= '<td width="4%"><input name="rfreeqty[]" type="text" id="rfreeqty_' . $counter . '" autocomplete="off" onkeyup="calTotalQtyDirect(this.value,this.id);" placeholder="Free Qty" size="8"/></td>';
        $html .= '<td width="1"><input name="conv_fac[]" type="hidden" id="convfac_' . $counter . '" autocomplete="off" value="' . $convFactor . '" size="8" /></td>';
        $html .= '<td width="4%"><input name="reciveqty2[]" type="text" id="reciveqty2_' . $counter . '" autocomplete="off" size="8" /></td>';
        $html .= '<td width="4%"><div style="float:left; width:100%;"><input type="text" name="minSign[]" id="minSign_' . $counter . '" /></div></td>';
        $html .= '<td width="4%"><div style="float:left; width:100%;">';
        $html .= '<input name="shortaccessid[]" type="text" id="shortaccessid_' . $counter . '" value="" readonly="true" onfocus="calculate_poshort(' . $counter . ');" /></div></td>';
        $html .= '<td width="1">';
        $html .= '<input id="confac1_' . $counter . '" type="hidden" value="' . $convFactor . '" />';
        $html .= '<input type="hidden" name="qtytype[]" id="qtytype_' . $counter . '" value="' . $qtyType . '" />';
        $html .= '</td>';
        $html .= '</tr>';

        return $html;
    }

    private function getIndentTableFooter($counter)
    {
        return '<tr class="row1">
               <td colspan="7" style="text-align:right;"><strong>Total Quantity</strong></td>
               <td><input name="totalBillQty" type="text" id="shortDirect" size="8" /></td>
               <td colspan="2"><input name="totalRecQty" type="text" id="short1Direct" size="8" /></td>
           </tr>';
    }
}

$processor = new InvoiceProcessor($db, $s);

if (isset($_REQUEST['invoice_details']) && !empty($invoiceId)) {
    $result = $processor->processInvoiceDetails($invoiceId);
    if ($result) {
        echo $result;
    }
    exit;
}

if ($recAgainst == 'PO' && !empty($poId)) {
    $result = $processor->processPOReception($poId);
    if ($result) {
        echo $result;
    }
    exit;
}

if ($recAgainst == 'Indent' && !empty($poId)) {
    $result = $processor->processIndentReception($poId);
    if ($result) {
        echo $result;
    }
    exit;
}
