HEX
Server: Apache
System: Linux server1.royalgt4.com 4.18.0-553.89.1.lve.el8.x86_64 #1 SMP Wed Dec 10 13:58:50 UTC 2025 x86_64
User: mostafedeg (1125)
PHP: 5.6.40
Disabled: mail,passthru,parse_ini_file,show_source,eval,assert,pcntl_exec,dl,putenv,proc_open,popen
Upload Files
File: /home/mostafedeg/public_html/erp/controllers/reCalcBillPricesFunctions.php
<?php

session_start();
ob_start();

// get the config file
include_once("../public/config.php");

//here the db files that include in the file
include("../public/include_dao.php");

//Lastbillidspricesupdated
require_once('../models/dao/LastbillidspricesupdatedDAO.class.php');
require_once('../models/dto/Lastbillidspricesupdated.class.php');
require_once('../models/mysql/LastbillidspricesupdatedMySqlDAO.class.php');
require_once('../models/mysql/ext/LastbillidspricesupdatedMySqlExtDAO.class.php');

//Buybill
require_once('../models/dao/BuybillDAO.class.php');
require_once('../models/dto/Buybill.class.php');
require_once('../models/mysql/BuybillMySqlDAO.class.php');
require_once('../models/mysql/ext/BuybillMySqlExtDAO.class.php');
//Buybilldetail
require_once('../models/dao/BuybilldetailDAO.class.php');
require_once('../models/dto/Buybilldetail.class.php');
require_once('../models/mysql/BuybilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/BuybilldetailMySqlExtDAO.class.php');
//Returnbuybill
require_once('../models/dao/ReturnbuybillDAO.class.php');
require_once('../models/dto/Returnbuybill.class.php');
require_once('../models/mysql/ReturnbuybillMySqlDAO.class.php');
require_once('../models/mysql/ext/ReturnbuybillMySqlExtDAO.class.php');
//Returnbuybilldetail
require_once('../models/dao/ReturnbuybilldetailDAO.class.php');
require_once('../models/dto/Returnbuybilldetail.class.php');
require_once('../models/mysql/ReturnbuybilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/ReturnbuybilldetailMySqlExtDAO.class.php');
//Buyandruternbill
require_once('../models/dao/BuyandruternbillDAO.class.php');
require_once('../models/dto/Buyandruternbill.class.php');
require_once('../models/mysql/BuyandruternbillMySqlDAO.class.php');
require_once('../models/mysql/ext/BuyandruternbillMySqlExtDAO.class.php');
//Buyandruternbilldetail
require_once('../models/dao/BuyandruternbilldetailDAO.class.php');
require_once('../models/dto/Buyandruternbilldetail.class.php');
require_once('../models/mysql/BuyandruternbilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/BuyandruternbilldetailMySqlExtDAO.class.php');


//Sellbilldetail
require_once('../models/dao/SellbilldetailDAO.class.php');
require_once('../models/dto/Sellbilldetail.class.php');
require_once('../models/mysql/SellbilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/SellbilldetailMySqlExtDAO.class.php');
//Returnsellbilldetail
require_once('../models/dao/ReturnsellbilldetailDAO.class.php');
require_once('../models/dto/Returnsellbilldetail.class.php');
require_once('../models/mysql/ReturnsellbilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/ReturnsellbilldetailMySqlExtDAO.class.php');
//Sellandruternbilldetail
require_once('../models/dao/SellandruternbilldetailDAO.class.php');
require_once('../models/dto/Sellandruternbilldetail.class.php');
require_once('../models/mysql/SellandruternbilldetailMySqlDAO.class.php');
require_once('../models/mysql/ext/SellandruternbilldetailMySqlExtDAO.class.php');

//Storereport
require_once('../models/dao/StorereportDAO.class.php');
require_once('../models/dto/Storereport.class.php');
require_once('../models/mysql/StorereportMySqlDAO.class.php');
require_once('../models/mysql/ext/StorereportMySqlExtDAO.class.php');
//Billsetting
require_once('../models/dao/BillsettingsDAO.class.php');
require_once('../models/dto/Billsetting.class.php');
require_once('../models/mysql/BillsettingsMySqlDAO.class.php');
require_once('../models/mysql/ext/BillsettingsMySqlExtDAO.class.php');

//Productunit
require_once('../models/dao/ProductunitDAO.class.php');
require_once('../models/dto/Productunit.class.php');
require_once('../models/mysql/ProductunitMySqlDAO.class.php');
require_once('../models/mysql/ext/ProductunitMySqlExtDAO.class.php');

/////////////////////product////////////////////////
require_once('../models/dao/ProductDAO.class.php');
require_once('../models/dto/Product.class.php');
require_once('../models/mysql/ProductMySqlDAO.class.php');
require_once('../models/mysql/ext/ProductMySqlExtDAO.class.php');
//Programsetting
require_once('../models/dao/ProgramsettingsDAO.class.php');
require_once('../models/dto/Programsetting.class.php');
require_once('../models/mysql/ProgramsettingsMySqlDAO.class.php');
require_once('../models/mysql/ext/ProgramsettingsMySqlExtDAO.class.php');

$do = $_GET['do'];

/* ======================

  Controller Name :- storedetailCTRL تقرير مخزون اول مدة

  OPERTATION in Controller

  1-load save data
  2-display show form

  ======================== */

//here the global templates
//$smarty->display("header.html");
//here goes the instances and general variables
//Lastbillidspricesupdated
$lastBillIdsPricesUpdated = new Lastbillidspricesupdated();
$lastBillIdsPricesUpdatedDAO = new LastbillidspricesupdatedMySqlDAO();

//Buybill
$buyBill = new Buybill();
$buyBillDAO = new BuybillMySqlDAO();
$buyBillExt = new BuybillMySqlExtDAO();
//Buybilldetail
$buyBillDetail = new Buybilldetail();
$buyBillDetailDAO = new BuybilldetailMySqlDAO();
$buyBillDetailExt = new BuybilldetailMySqlExtDAO();
//Returnbuybill
$returnBuyBill = new Returnbuybill();
$returnBuyBillDAO = new ReturnbuybillMySqlDAO();
$returnBuyBillExt = new ReturnbuybillMySqlExtDAO();
//Returnbuybilldetail
$returnBuyBillDetail = new Returnbuybilldetail();
$returnBuyBillDetailDAO = new ReturnbuybilldetailMySqlDAO();
$returnBuyBillDetailExt = new ReturnbuybilldetailMySqlExtDAO();
//Buyandruternbill
$buyAndReturnBill = new Buyandruternbill();
$buyAndReturnBillDAO = new BuyandruternbillMySqlDAO();
$buyAndReturnBillExt = new BuyandruternbillMySqlExtDAO();
//Buyandruternbilldetail
$buyAndReturnBillDetail = new Buyandruternbilldetail();
$buyAndReturnBillDetailDAO = new BuyandruternbilldetailMySqlDAO();
$buyAndReturnBillDetailExt = new BuyandruternbilldetailMySqlExtDAO();


//Sellbilldetail
$sellbilldetail = new Sellbilldetail();
$sellbilldetailDAO = new SellbilldetailMySqlDAO();
$sellbilldetailEX = new SellbilldetailMySqlExtDAO();
//Returnsellbilldetail
$returnSellBillDetail = new Returnsellbilldetail();
$returnSellBillDetailDAO = new ReturnsellbilldetailMySqlDAO();
$returnSellBillDetailEX = new ReturnsellbilldetailMySqlExtDAO();
//Sellandruternbilldetail
$sellAndRuternBillDetail = new Sellandruternbilldetail();
$sellAndRuternBillDetailDAO = new SellandruternbilldetailMySqlDAO();
$sellAndRuternBillDetailEX = new SellandruternbilldetailMySqlExtDAO();
##################################
//bill
$bills = new Bill();
$billsDAO = new BillsMySqlDAO();
$billsEX = new BillsMySqlExtDAO();
//billsproducts
$billsProducts = new Billsproduct();
$billsProductsDAO = new BillsproductsMySqlDAO();
$billsProductsEX = new BillsproductsMySqlExtDAO();

//bill
$billsReturn = new Billsreturn();
$billsReturnDAO = new BillsreturnMySqlDAO();
$billsReturnEX = new BillsreturnMySqlExtDAO();
//billsReturnproducts
$billsReturnProducts = new Billsreturnproduct();
$billsReturnProductsDAO = new BillsreturnproductsMySqlDAO();
$billsReturnProductsEX = new BillsreturnproductsMySqlExtDAO();

$storeReportEX = new StorereportMySqlExtDAO();
//Billsetting
$billSettingExt = new BillsettingsMySqlExtDAO();

///////////////product///////////////
$ProductDAO = new ProductMySqlDAO();
$Product = new Product();
$ProductEX = new ProductMySqlExtDAO();
//Productcat
$productCatDAO = new ProductcatMySqlDAO();
$productCatExt = new ProductcatMySqlExtDAO();

//Productunit
$ProductunitDAO = new ProductunitMySqlDAO();
$myProductunitEx = new ProductunitMySqlExtDAO();

//
$ProgramsettingDAO = new ProgramsettingsMySqlDAO();

$Programsettingdata = $ProgramsettingDAO->load(1);
$noOfDecimalPlaces = ($Programsettingdata->roundnumbers == 0) ? 0 : (int) $Programsettingdata->noOfDecimalPlaces;


$lastBillIdsPricesUpdated = $lastBillIdsPricesUpdatedDAO->load(1);
if (!isset($lastBillIdsPricesUpdated->id) || empty($lastBillIdsPricesUpdated->id)) {
    $lastBillIdsPricesUpdated->buybill = 0;
    $lastBillIdsPricesUpdated->buyandret = 0;
    $lastBillIdsPricesUpdated->retbuy = 0;
    $lastBillIdsPricesUpdated->sell = 0;
    $lastBillIdsPricesUpdated->sellandret = 0;
    $lastBillIdsPricesUpdated->retsell = 0;
    $lastBillIdsPricesUpdated->buyquantity = 0;
    $lastBillIdsPricesUpdated->buyandretquantity = 0;
    $lastBillIdsPricesUpdatedDAO->insert($lastBillIdsPricesUpdated);
}


if ($do == "updatePricesBuyBills") {
    $allbuyBills = $buyBillDetailExt->buyOnlyAllBills($lastBillIdsPricesUpdated->buybill, $lastBillIdsPricesUpdated->buyandret);
    $proArr = [];
    foreach ($allbuyBills as $billProduct) {
        $isFirstBill = 0;
        $firstBillDetailId = R::getCell('select min(buybilldetailid) from buybilldetail join buybill on buybill.buybillid = buybilldetail.buybillid where buybill.conditions = 0 and buybilldetailproductid = ' . $billProduct->buybilldetailproductid);
        //for first bill get quantity before "which added with product"
        if ($firstBillDetailId == $billProduct->buybilldetailid) {
            $isFirstBill = 1;
            $firstQuantityAtAddPro = (float) R::getCell('select sum(productquantity) from storereport where tablename="productController.php" and productid=' . $billProduct->buybilldetailproductid);
            $totalcreditorAtAddPro = (float) R::getCell('select totalcreditor from dailyentry where operationDetailLink="productController.php?do=edit&id=' . $billProduct->buybilldetailproductid . '" order by id asc limit 1');
            $firstPriceAtAddPro = (float) ($totalcreditorAtAddPro / $firstQuantityAtAddPro);
            $proArr[] = $billProduct->buybilldetailproductid;
        } else {
            $firstQuantityAtAddPro = $isFirstBill = $firstPriceAtAddPro = 0;
        }
        fixPricesBuyBills($billProduct, $firstQuantityAtAddPro, $firstPriceAtAddPro, $isFirstBill);
    }
    header("location:profitreportController.php");
} elseif ($do == "updatePricesSellBills") {
    $sell = $sellbilldetailEX->queryAllNotDel(" and sellbilldetailid > $lastBillIdsPricesUpdated->sell order by sellbilldetailid asc");
    foreach ($sell as $value) {
        $prices = getLastPrices($value->sellbilldetailproductid, $value->sellbilldate);
        $sellbilldetailEX->updatePrices_f("sellbilldetail", $prices->buybilldetailprice, $prices->lastbuyprice, $prices->meanbuyprice, $prices->lastbuyprice_withDiscount, $prices->meanbuyprice_withDiscount, "sellbilldetailid", $value->sellbilldetailid);
        $lastBillIdsPricesUpdated->sell = $value->sellbilldetailid;
        $lastBillIdsPricesUpdatedDAO->update($lastBillIdsPricesUpdated);
    }
    $sellAndRet = $sellAndRuternBillDetailEX->queryAllNotDel(" and sellbilldetailid > $lastBillIdsPricesUpdated->sellandret order by sellbilldetailid asc");
    foreach ($sellAndRet as $value) {
        $prices = getLastPrices($value->sellbilldetailproductid, $value->sellbilldate);
        $sellbilldetailEX->updatePrices_f("sellandruternbilldetail", $prices->buybilldetailprice, $prices->lastbuyprice, $prices->meanbuyprice, $prices->lastbuyprice_withDiscount, $prices->meanbuyprice_withDiscount, "sellbilldetailid", $value->sellbilldetailid);
        $lastBillIdsPricesUpdated->sellandret = $value->sellbilldetailid;
        $lastBillIdsPricesUpdatedDAO->update($lastBillIdsPricesUpdated);
    }
    $retSell = $returnSellBillDetailEX->queryAllNotDel(" and returnsellbilldetailid > $lastBillIdsPricesUpdated->retsell order by returnsellbilldetailid asc");
    foreach ($retSell as $value) {
        $prices = getLastPrices($value->returnsellbilldetailproductid, $value->returnsellbilldate);
        $sellbilldetailEX->updatePrices_f("returnsellbilldetail", $prices->buybilldetailprice, $prices->lastbuyprice, $prices->meanbuyprice, $prices->lastbuyprice_withDiscount, $prices->meanbuyprice_withDiscount, "returnsellbilldetailid", $value->returnsellbilldetailid);
        $lastBillIdsPricesUpdated->retsell = $value->returnsellbilldetailid;
        $lastBillIdsPricesUpdatedDAO->update($lastBillIdsPricesUpdated);
    }
    header("location:profitreportController.php");
} elseif ($do == "updateQuantityBeforeBuyBills") {
    $allbuyBills = $buyBillDetailExt->buyOnlyAllBills($lastBillIdsPricesUpdated->buyquantity, $lastBillIdsPricesUpdated->buyandretquantity, ' where quantitybefore is null');
    foreach ($allbuyBills as $billProduct) {
        fixPricesBuyBillsQuantityBefore($billProduct);
    }
    header("location:profitreportController.php");
} elseif ($do == "updatePricesBuyBillsAllProducts") {
    $productsOverAllAverage = $buyBillDetailExt->getOverallAverage();
    $sql = '';
    foreach ($productsOverAllAverage as $value) {
        $sql .= "UPDATE product SET overAllAveragePrice = $value->overallAverage WHERE productId = $value->buybilldetailproductid;
";
    }

    if ($sql != '') {
        $ProductEX->updateBulk($sql);
    }
    header("location:profitreportController.php");
}
/* ===============================
  function in this CONTROLLER
  ================================ */

function fixPricesBuyBills($billProduct, $firstQuantityAtAddPro = 0, $firstPriceAtAddPro = 0, $isFirstBill = 0)
{
    global $buyBillDetailExt;
    global $lastBillIdsPricesUpdated;
    global $lastBillIdsPricesUpdatedDAO;
    //get all buy bills for the product and before it
    $previousProductBills = $buyBillDetailExt->buyOnlyAllBills(0, 0, " where buybilldetailproductid = $billProduct->buybilldetailproductid and buybillsysdate < '" . $billProduct->buybillsysdate . "' ");

    $totalQuantity = $firstQuantityAtAddPro;
    $TotalPriceTimesQuantity = $firstQuantityAtAddPro * $firstPriceAtAddPro;
    $TotalPriceWithDiscountTimesQuantity = $firstQuantityAtAddPro * $firstPriceAtAddPro;
    $lastBuyPriceLastBillBefore = $firstPriceAtAddPro;
    foreach ($previousProductBills as $data) {
        $prototal = $data->buybilldetailtotalprice;
        $rowDiscount = $data->discountvalue; //of buy bill details "of product"
        $gendis = $data->buybilldiscount; //of bill "for all products at end of bill"
        $discount_type = $data->buybilldiscountrype; //of bill also
        $billTotalBeforeDiscount = $data->buybilltotalbill; //of bill also
        ##get $billDiscountVal
        $billDiscountVal = $gendis;
        if ($discount_type == "1") {
            $billDiscountVal = ($gendis / 100) * $billTotalBeforeDiscount;
            $billDiscountVal = round($billDiscountVal, 2);
        }

        $finalquantity = $data->buybilldetailquantity * $data->productnumber;
        $price = ($prototal + $rowDiscount);
        $priceWithDiscount = $prototal - ($billDiscountVal * ($prototal / $billTotalBeforeDiscount));


        $totalQuantity += $finalquantity;
        $TotalPriceTimesQuantity += $price;
        $TotalPriceWithDiscountTimesQuantity += $priceWithDiscount;
        $lastBuyPriceLastBillBefore = $data->buybilldetailprice;
    }

    $finalquantity = $billProduct->buybilldetailquantity * $billProduct->productnumber;

    $billid = $billProduct->buybillid;
    $lastBuyPriceOnePiece = $billProduct->buybilldetailprice / $billProduct->productnumber;
    $colName = "buybilldetailid";
    $detailId = $billProduct->buybilldetailid;
    $productId = $billProduct->buybilldetailproductid;
    $sizeId = $billProduct->sizeid;
    $colorId = $billProduct->colorid;
    if ($billProduct->typeOfBill == "1") {
        $tableName = "buybill";
    } elseif ($billProduct->typeOfBill == "2") {
        $tableName = "buyandruternbill";
    }
    $productquantityBefore = $totalQuantity;
    $productquantityAfter = $productquantityBefore + $finalquantity;
    $productChangeAmount = $finalquantity;
    $operation = "add";
    $billnameId = $billProduct->billnameid;
    $prototal = $billProduct->buybilldetailtotalprice;
    $rowDiscount = $billProduct->discountvalue;
    //billDiscountVal
    $gendis = $billProduct->buybilldiscount; //of bill "for all products at end of bill"
    $discount_type = $billProduct->buybilldiscountrype; //of bill also
    $billTotalBeforeDiscount = $billProduct->buybilltotalbill; //of bill also
    ##get $billDiscountVal
    $billDiscountVal = $gendis;
    if ($discount_type == "1") {
        $billDiscountVal = ($gendis / 100) * $billTotalBeforeDiscount;
        $billDiscountVal = round($billDiscountVal, 2);
    }
    /////
    $rowtaxval = $billProduct->rowtaxval;
    $billPayedTaxPer = $billProduct->payedtax;
    $cFactor = 1;
    if ($billProduct->currencyId != 1) {
        $cFactor = (float) R::getCell('select conversionFactor from buybillcurr where buybillid = ' . $billProduct->buybillid);
    }

    $probuyDiscountPer = $billProduct->probuyDiscountPer;
    lastAndMeanBuyPrice($billid, $firstPriceAtAddPro, $isFirstBill, $lastBuyPriceOnePiece, $colName, $detailId, $productId, $sizeId, $colorId, $tableName, $productquantityBefore, $productquantityAfter, $productChangeAmount, $operation, $billnameId, $prototal, $rowDiscount, $billDiscountVal, $billTotalBeforeDiscount, $rowtaxval, $billPayedTaxPer, $cFactor, $probuyDiscountPer);


    //update bill
    if ($billProduct->typeOfBill == 1) { //buy
        $lastBillIdsPricesUpdated->buybill = $detailId;
    } else { //buy and ret
        $lastBillIdsPricesUpdated->buyandret = $detailId;
    }
    ##update this too
    $lastBillIdsPricesUpdatedDAO->update($lastBillIdsPricesUpdated);
}

function fixPricesBuyBillsQuantityBefore($billProduct)
{
    global $storeReportEX;
    global $buyAndReturnBillDetailExt;
    global $buyBillDetailExt;
    global $lastBillIdsPricesUpdated;
    global $lastBillIdsPricesUpdatedDAO;


    $productId = $billProduct->buybilldetailproductid;
    $billId = $billProduct->buybillid;
    if ($billProduct->typeOfBill == 1) { //buy
        $tablename = 'buyBillController.php';
    } else { //buy and ret
        $tablename = 'buyAndReturnBillController.php';
    }
    $buybilldetailid = $billProduct->buybilldetailid;

    $storeReport = $storeReportEX->getProductQuantityBeforeConditions($productId, $billId, $tablename);
    $productOrder = $buyBillDetailExt->getProductOrderInBillDetails($billId, $buybilldetailid, $productId);
    $quantityBefore = $storeReport[$productOrder]->productbefore;

    if (isset($quantityBefore)) {
        //update bill
        if ($billProduct->typeOfBill == 1) { //buy
            $lastBillIdsPricesUpdated->buyquantity = $buybilldetailid;
            $buyBillDetailExt->updatequantityBefore($quantityBefore, $buybilldetailid);
        } else { //buy and ret
            $lastBillIdsPricesUpdated->buyandretquantity = $buybilldetailid;
            $buyAndReturnBillDetailExt->updatequantityBefore($quantityBefore, $buybilldetailid);
        }
        ##update this too
        $lastBillIdsPricesUpdatedDAO->update($lastBillIdsPricesUpdated);
    }
}

function getLastPrices($productId, $date)
{
    global $buyBillDetailExt;
    global $ProductDAO;
    $priceData = $buyBillDetailExt->buyOnlyAllBillsLatPricesBefore(" where buybilldetailproductid = $productId and buybilldate < '" . $date . "' order by buybilldate desc limit 1");
    $prices = new stdClass();
    if (isset($priceData->buybilldetailid) && $priceData->buybilldetailid > 0) {
        $prices->buybilldetailprice = (float) $priceData->buybilldetailprice;
        $prices->lastbuyprice = (float) $priceData->lastbuyprice;
        $prices->meanbuyprice = (float) $priceData->meanbuyprice;
        $prices->lastbuyprice_withDiscount = (float) $priceData->lastbuyprice_withDiscount;
        $prices->meanbuyprice_withDiscount = (float) $priceData->meanbuyprice_withDiscount;
    } else {
        $priceData = $ProductDAO->load($productId);
        $prices->buybilldetailprice = (float) $priceData->productBuyPrice;
        $prices->lastbuyprice = (float) $priceData->lastbuyprice;
        $prices->meanbuyprice = (float) $priceData->meanbuyprice;
        $prices->lastbuyprice_withDiscount = (float) $priceData->lastbuyprice_withDiscount;
        $prices->meanbuyprice_withDiscount = (float) $priceData->meanbuyprice_withDiscount;
    }
    return $prices;
}

function lastAndMeanBuyPrice($billId, $firstPriceAtAddPro = 0, $isFirstBill = 0, $lastBuyPriceOnePiece, $colName, $detailId, $productId, $sizeId, $colorId, $tableName, $productquantityBefore, $productquantityAfter, $productChangeAmount, $operation = "add", $billnameId, $prototal, $rowDiscount, $billDiscountVal, $billTotalBeforeDiscount, $rowtaxval, $billPayedTaxPer, $cFactor, $probuyDiscountPer)
{

    global $ProductDAO;
    global $buyBillDetailExt;
    global $ProductunitDAO;
    global $billSettingExt;
    global $myProductunitEx;
    global $Programsettingdata;
    global $noOfDecimalPlaces;

    ##currency convert to main currency
    $cFactor = (isset($cFactor) && !empty($cFactor)) ? $cFactor : 1;
    $billDiscountVal = $billDiscountVal / $cFactor;
    $billTotalBeforeDiscount = $billTotalBeforeDiscount / $cFactor;
    $rowtaxval = $rowtaxval / $cFactor;


    ##use quantity @allstores
    ##we has affected db but transaction isnot commited yet so now we have the before quantity
    $productquantityBeforeAllStores = 0;
    if ($sizeId > 0 && $colorId > 0) {
        //$productquantityBeforeAllStores = (float) R::getCell("select sum(quantity) from sizecolorstoredetail where productid = $productId and sizeid = $sizeId and colorid = $colorId");
    } else {
        $tblNm = "buyBillController.php";
        $detailTbl = "buybilldetail";
        if ($tableName == "buyandruternbilldetail") {
            $tblNm = "buyAndReturnBillController.php";
            $detailTbl = "buyandruternbilldetail";
        }
        if ($isFirstBill == 1) {
            $productquantityBeforeAllStores = $productquantityBefore;
        } else {
            $lastStores = R::getCol('SELECT DISTINCT storeid FROM `storereport` WHERE `productid` = ' . $productId . ' and storereportid <
            (select storereportid from storereport where `productid` = ' . $productId . ' and `storereportmodelid` = ' . $billId . ' and `tablename` = "' . $tblNm . '" order by `storereportid` desc limit 1)
            order by `storereportid` desc');
            $laststorereportId = R::getCell('select storereportid from storereport where `productid` = ' . $productId . ' and `storereportmodelid` = ' . $billId . ' and `tablename` = "' . $tblNm . '" order by `storereportid` desc limit 1');
            foreach ($lastStores as $storeId) {
                $productquantityBeforeAllStores += R::getCell('SELECT productafter FROM `storereport` WHERE `productid` = ' . $productId . ' and storereportid <' . $laststorereportId . '
                and storeid = ' . $storeId . ' order by `storereportid` desc limit 1');
            }
        }
    }
    //
    if ($productquantityAfter < $productquantityBefore) {
        $productquantityAfter = $productquantityBeforeAllStores - $productChangeAmount;
    } else {
        $productquantityAfter = $productquantityBeforeAllStores + $productChangeAmount;
    }
    $productquantityBefore = $productquantityBeforeAllStores;
    ###################################
    $buyProduct = new Product();
    //# load billSettingData
    $billpropertyid = 67; //# هذا الرقم يدل على تطبيق نسب الخصم فى فاتورة الشراء فى الداتا بيز

    $billSettingData = $billSettingExt->queryByBillidAndBillpropertyid($billnameId, $billpropertyid);

    ##1- get mean
    $buyProduct = $ProductDAO->load($productId);
    if ($firstPriceAtAddPro > 0) {
        $buyProduct->meanbuyprice = $buyProduct->meanbuyprice_withDiscount = $buyProduct->meanbuyprice_withTax = $firstPriceAtAddPro;
    }

    if ($buyProduct->meanbuyprice == NULL || $buyProduct->meanbuyprice == 0) {
        $buyProduct->meanbuyprice = $buyProduct->productBuyPrice;
    }
    if ($buyProduct->meanbuyprice_withDiscount == NULL || $buyProduct->meanbuyprice_withDiscount == 0) {
        $buyProduct->meanbuyprice_withDiscount = $buyProduct->productBuyPrice;
    }
    if ($buyProduct->meanbuyprice_withTax == NULL || $buyProduct->meanbuyprice_withTax == 0) {
        $buyProduct->meanbuyprice_withTax = $buyProduct->productBuyPrice;
    }

    //# عند تطبيق تطبيق نسب الخصم
    if ($billSettingData[0]->billsettingsvalue == 0) {
        //# $prototal الاجمالى
        if ($productquantityAfter < $productquantityBefore) { // $operation == "delete")
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) - ($prototal + $rowDiscount - $rowtaxval);
            // $billTaxShareForRow = ($prototal + $rowDiscount) * ($billPayedTaxPer / 100);
            $billTaxShareForRow = $prototal * ($billPayedTaxPer / 100);
            $BastWithTax = ($productquantityBefore * $buyProduct->meanbuyprice_withTax) - ($prototal + $billTaxShareForRow);
        } else {
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) + ($prototal + $rowDiscount - $rowtaxval);
            // $billTaxShareForRow = ($prototal + $rowDiscount) * ($billPayedTaxPer / 100);
            $billTaxShareForRow = $prototal * ($billPayedTaxPer / 100);
            $BastWithTax = ($productquantityBefore * $buyProduct->meanbuyprice_withTax) + ($prototal + $billTaxShareForRow);
        }

        $makam = $productquantityAfter;
        $meanBuyPrice = round(($Bast / $makam), $noOfDecimalPlaces);
        $meanBuyPriceWithTax = round(($BastWithTax / $makam), $noOfDecimalPlaces);
        ##with discount ##decrease pro total with its share of general discount
        $prototalWithDiscount = $prototal - ($billDiscountVal * ($prototal / $billTotalBeforeDiscount));
        if ($productquantityAfter < $productquantityBefore) { // $operation == "delete")
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice_withDiscount) - $prototalWithDiscount;
            $BastWithTaxAndDiscount = ($productquantityBefore * $buyProduct->meanbuyprice_withTax) + $prototalWithDiscount + $billTaxShareForRow;
        } else {
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice_withDiscount) + $prototalWithDiscount;
            $BastWithTaxAndDiscount = ($productquantityBefore * $buyProduct->meanbuyprice_withTax) + $prototalWithDiscount + $billTaxShareForRow;
        }

        $makam = $productquantityAfter;
        $meanBuyPrice_withDiscount = round(($Bast / $makam), $noOfDecimalPlaces);
        $meanBuyPriceWithTax = round(($BastWithTaxAndDiscount / $makam), $noOfDecimalPlaces);
    } else {
        $realPrice_precentage = $buyProduct->buypricereal_precentage; //#   نسبة سعر الشراء الفعلى
        $total_precntage = ($realPrice_precentage / 100) * ($prototal + $rowDiscount - $rowtaxval); //# نسبة شعر الشراء على 100 * الاجمالى
        if ($productquantityAfter < $productquantityBefore) { // $operation == "delete")
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) - ($prototal - $total_precntage);
        } else {
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) + ($prototal - $total_precntage);
        }

        $makam = $productquantityAfter;
        $meanBuyPrice = round(($Bast / $makam), $noOfDecimalPlaces);
        ##with discount ##decrease pro total with its share of general discount
        $prototalWithDiscount = $prototal - ($billDiscountVal * ($prototal / $billTotalBeforeDiscount));
        $realPrice_precentage = $buyProduct->buypricereal_precentage; //#   نسبة سعر الشراء الفعلى
        $total_precntage = ($realPrice_precentage / 100) * $prototalWithDiscount; //# نسبة شعر الشراء على 100 * الاجمالى
        if ($productquantityAfter < $productquantityBefore) { // $operation == "delete")
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) - ($prototalWithDiscount - $total_precntage);
        } else {
            $Bast = ($productquantityBefore * $buyProduct->meanbuyprice) + ($prototalWithDiscount - $total_precntage);
        }

        $makam = $productquantityAfter;
        $meanBuyPrice_withDiscount = round(($Bast / $makam), $noOfDecimalPlaces);
    }

    ##
    $lastBuyPriceOnePiece = $lastBuyPriceOnePiece - $probuyDiscountPer;
    $lastBuyPriceOnePiece_WithRowTax = $lastBuyPriceOnePiece + ($rowtaxval / $productChangeAmount);
    $lastBuyPriceOnePiece_WithTax = $lastBuyPriceOnePiece_WithRowTax + ($lastBuyPriceOnePiece_WithRowTax * ($billPayedTaxPer / 100)); //$billTaxPer is like 0.14 is bill tax percentage
    //
    ##2-save them
    $buyProduct->meanbuyprice = abs($meanBuyPrice);
    $buyProduct->meanbuyprice_withDiscount = abs($meanBuyPrice_withDiscount);
    $buyProduct->lastbuyprice = $lastBuyPriceOnePiece;
    $buyProduct->lastbuyprice_withTax = abs($lastBuyPriceOnePiece_WithTax);
    $buyProduct->meanbuyprice_withTax = abs($meanBuyPriceWithTax);

    //calc $rowDiscountPer============
    $rowDiscountPer = (($rowDiscount + $probuyDiscountPer) / ($prototal + $rowDiscount + $probuyDiscountPer - $rowtaxval)) * 100;
    if ($productquantityAfter < $productquantityBefore) { // $operation == "delete")
        if ($operation == "add") {
            $lastBuyPriceOnePiece_withDiscount = ($prototalWithDiscount / $productChangeAmount);
            $lastBuyPriceOnePiece_withDiscountAndTax = $lastBuyPriceOnePiece_withDiscount + ($rowtaxval / $productChangeAmount);
        }
        $buyProduct->lastbuyprice_withDiscount = round($lastBuyPriceOnePiece_withDiscount, $noOfDecimalPlaces);
        $buyProduct->lastbuyprice_withDiscountAndTax = round($lastBuyPriceOnePiece_withDiscountAndTax, $noOfDecimalPlaces);
        $newWeightedDiscount = (($productquantityBefore * $buyProduct->weightedDiscount) - ($productChangeAmount * $rowDiscountPer)) / ($productquantityBefore - $productChangeAmount);
        $buyProduct->weightedDiscount = round($newWeightedDiscount, $noOfDecimalPlaces);
    } else {
        $buyProduct->lastbuyprice_withDiscount = round(($prototalWithDiscount / $productChangeAmount), $noOfDecimalPlaces);
        $buyProduct->lastbuyprice_withDiscountAndTax = round($buyProduct->lastbuyprice_withDiscount + ($buyProduct->lastbuyprice_withDiscount * ($billPayedTaxPer / 100)), $noOfDecimalPlaces);
        $newWeightedDiscount = (($productquantityBefore * $buyProduct->weightedDiscount) + ($productChangeAmount * $rowDiscountPer)) / ($productquantityBefore + $productChangeAmount);
        $buyProduct->weightedDiscount = round($newWeightedDiscount, $noOfDecimalPlaces);
    }

    //another check after calculation to stop zero value
    if ($buyProduct->meanbuyprice == NULL || $buyProduct->meanbuyprice == 0) {
        $buyProduct->meanbuyprice = $buyProduct->productBuyPrice;
    }
    if ($buyProduct->meanbuyprice_withDiscount == NULL || $buyProduct->meanbuyprice_withDiscount == 0) {
        $buyProduct->meanbuyprice_withDiscount = $buyProduct->productBuyPrice;
    }

    $ProductDAO->update($buyProduct);

    if ($operation != "delete") {
        if (isset($detailId) && !empty($detailId)) {
            $buyBillDetailExt->updatePrices_f($detailTbl, $buyProduct->lastbuyprice, $buyProduct->meanbuyprice, $buyProduct->lastbuyprice_withDiscount, $buyProduct->meanbuyprice_withDiscount, $buyProduct->lastbuyprice_withTax, $buyProduct->meanbuyprice_withTax, $buyProduct->lastbuyprice_withDiscountAndTax, $colName, $detailId);
        }
    }

    if ($Programsettingdata->updateProUnitPricesOnPriceUpdate == 0) {
        $myProductunitEx->updateQuery("UPDATE productunit SET proUnitBuyPrice = $buyProduct->lastbuyprice * productnumber WHERE productid = $productId");
    }
}