/** | /** | ||||
* Génére un PDF récapitulatif des commandes d'un producteur pour une | * Génére un PDF récapitulatif des commandes d'un producteur pour une | ||||
* date donnée. | * date donnée. | ||||
* | |||||
* @param string $date | |||||
* @param boolean $save | |||||
* @param integer $idProducer | |||||
* @return Pdf|null|string | |||||
*/ | */ | ||||
public function actionReport($date = '', $save = false, $idProducer = 0, $type = "pdf") | |||||
public function actionReport(string $date = '', bool $save = false, int $idProducer = 0, string $type = "pdf") | |||||
{ | { | ||||
$productDistributionManager = $this->getProductDistributionManager(); | |||||
$producerManager = $this->getProducerManager(); | |||||
$orderManager = $this->getOrderManager(); | |||||
$productManager = $this->getProductManager(); | |||||
$pointSaleManager = $this->getPointSaleManager(); | |||||
if (!\Yii::$app->user->isGuest) { | |||||
$idProducer = GlobalParam::getCurrentProducerId(); | |||||
if (!$idProducer) { | |||||
$idProducer = $this->getProducerCurrent()->id; | |||||
} | } | ||||
$ordersArray = Order::searchAll( | |||||
[ | |||||
'distribution.date' => $date, | |||||
'distribution.id_producer' => $idProducer | |||||
], | |||||
[ | |||||
'orderby' => 'user.lastname ASC, user.name ASC, comment_point_sale ASC', | |||||
'conditions' => 'date_delete IS NULL' | |||||
] | |||||
); | |||||
$distribution = Distribution::searchOne([ | |||||
'id_producer' => $idProducer | |||||
], [ | |||||
'conditions' => 'date LIKE :date', | |||||
'params' => [':date' => $date] | |||||
]); | |||||
$distributionManager = $this->getDistributionManager(); | |||||
$producerManager = $this->getProducerManager(); | |||||
$producerCurrent = $producerManager->findOneProducerById($idProducer); | |||||
$this->getLogic()->setProducerContext($producerCurrent); | |||||
$distribution = $distributionManager->findOneDistribution($date); | |||||
if ($distribution) { | if ($distribution) { | ||||
$selectedProductsArray = $productDistributionManager->findProductDistributionsByDistribution($distribution); | |||||
$pointsSaleArray = PointSale::searchAll([ | |||||
'point_sale.id_producer' => $idProducer | |||||
]); | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
$orderManager->initPointSaleOrders($pointSale, $ordersArray); | |||||
} | |||||
// produits | |||||
$productsArray = Product::find() | |||||
->joinWith([ | |||||
'productDistribution' => function ($q) use ($distribution) { | |||||
$q->where(['id_distribution' => $distribution->id]); | |||||
} | |||||
]) | |||||
->where([ | |||||
'id_producer' => $idProducer, | |||||
]) | |||||
->orderBy('order ASC') | |||||
->all(); | |||||
if ($type == 'pdf') { | if ($type == 'pdf') { | ||||
$viewPdf = 'report'; | |||||
$orientationPdf = Pdf::ORIENT_PORTRAIT; | |||||
$producer = GlobalParam::getCurrentProducer(); | |||||
if ($producer->slug == 'bourlinguepacotille') { | |||||
$viewPdf = 'report-bourlingue'; | |||||
$orientationPdf = Pdf::ORIENT_LANDSCAPE; | |||||
} | |||||
// get your HTML raw content without any layouts or scripts | |||||
$content = $this->renderPartial($viewPdf, [ | |||||
'date' => $date, | |||||
'distribution' => $distribution, | |||||
'selectedProductsArray' => $selectedProductsArray, | |||||
'pointsSaleArray' => $pointsSaleArray, | |||||
'productsArray' => $productsArray, | |||||
'ordersArray' => $ordersArray, | |||||
'producer' => $producerManager->findOneProducerById($idProducer) | |||||
]); | |||||
$dateStr = date('d/m/Y', strtotime($date)); | |||||
if ($save) { | |||||
$destination = Pdf::DEST_FILE; | |||||
} else { | |||||
$destination = Pdf::DEST_BROWSER; | |||||
} | |||||
$pdf = new Pdf([ | |||||
// set to use core fonts only | |||||
'mode' => Pdf::MODE_UTF8, | |||||
// A4 paper format | |||||
'format' => Pdf::FORMAT_A4, | |||||
// portrait orientation | |||||
'orientation' => $orientationPdf, | |||||
// stream to browser inline | |||||
'destination' => $destination, | |||||
'filename' => \Yii::getAlias( | |||||
'@app/web/pdf/Commandes-' . $date . '-' . $idProducer . '.pdf' | |||||
), | |||||
// your html content input | |||||
'content' => $content, | |||||
// format content from your own css file if needed or use the | |||||
// enhanced bootstrap css built by Krajee for mPDF formatting | |||||
//'cssFile' => Yii::getAlias('@web/css/distribution/report.css'), | |||||
// any css to be embedded if required | |||||
'cssInline' => ' | |||||
table { | |||||
border-spacing : 0px ; | |||||
border-collapse : collapse ; | |||||
width: 100% ; | |||||
} | |||||
table tr th, | |||||
table tr td { | |||||
padding: 0px ; | |||||
margin: 0px ; | |||||
border: solid 1px #e0e0e0 ; | |||||
padding: 3px 8px ; | |||||
vertical-align : top; | |||||
page-break-inside: avoid !important; | |||||
color: black; | |||||
} | |||||
table tr th { | |||||
font-size: 13px ; | |||||
} | |||||
table tr td { | |||||
font-size: 13px ; | |||||
} | |||||
', | |||||
// set mPDF properties on the fly | |||||
//'options' => ['title' => 'Krajee Report Title'], | |||||
// call mPDF methods on the fly | |||||
'methods' => [ | |||||
'SetHeader' => ['Commandes du ' . $dateStr], | |||||
'SetFooter' => ['{PAGENO}'], | |||||
] | |||||
]); | |||||
// return the pdf output as per the destination setting | |||||
return $pdf->render(); | |||||
} elseif ($type == 'csv') { | |||||
$datas = []; | |||||
$optionCsvExportAllProducts = $producerManager->getConfig('option_csv_export_all_products'); | |||||
$optionCsvExportByPiece = $producerManager->getConfig('option_csv_export_by_piece'); | |||||
// produits en colonne | |||||
$productsNameArray = ['', 'Commentaire']; | |||||
$productsIndexArray = []; | |||||
$productsHasQuantity = []; | |||||
$cpt = 2; | |||||
foreach ($productsArray as $product) { | |||||
$productsHasQuantity[$product->id] = 0; | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantity = $orderManager->getProductQuantity($product, $ordersArray, true, $unit); | |||||
if ($quantity) { | |||||
$productsHasQuantity[$product->id] += $quantity; | |||||
} | |||||
} | |||||
if ($productsHasQuantity[$product->id] > 0 || $optionCsvExportAllProducts) { | |||||
$productName = $productManager->getNameExport($product); | |||||
if ($optionCsvExportByPiece) { | |||||
$productUnit = 'piece'; | |||||
} else { | |||||
$productUnit = $product->unit; | |||||
} | |||||
$productName .= ' (' . $productManager->strUnit($productUnit, 'wording_short', true) . ')'; | |||||
$productsNameArray[] = $productName; | |||||
$productsIndexArray[$product->id] = $cpt++; | |||||
} | |||||
} | |||||
$datas[] = $productsNameArray; | |||||
// points de vente | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
if (count($pointSale->orders)) { | |||||
// listing commandes | |||||
$datas[] = ['> ' . $pointSale->name]; | |||||
foreach ($pointSale->orders as $order) { | |||||
$orderLine = [$orderManager->getOrderUsername($order), $orderManager->getCommentReport($order)]; | |||||
if ($optionCsvExportByPiece) { | |||||
foreach ($order->productOrder as $productOrder) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] = $orderManager->getProductQuantityPieces( | |||||
$productOrder->product, | |||||
[$order] | |||||
); | |||||
} | |||||
} else { | |||||
foreach ($productsIndexArray as $idProduct => $indexProduct) { | |||||
$orderLine[$indexProduct] = ''; | |||||
} | |||||
foreach ($order->productOrder as $productOrder) { | |||||
if (strlen($orderLine[$productsIndexArray[$productOrder->id_product]])) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= ' + '; | |||||
} | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productOrder->quantity; | |||||
if ($productOrder->product->unit != $productOrder->unit) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productManager->strUnit( | |||||
$productOrder->unit, | |||||
'wording_short', | |||||
true | |||||
); | |||||
} | |||||
} | |||||
} | |||||
$datas[] = $this->_lineOrderReportCSV($orderLine, $cpt); | |||||
} | |||||
// total point de vente | |||||
if ($optionCsvExportByPiece) { | |||||
$totalsPointSaleArray = $this->_totalReportPiecesCSV( | |||||
'Total', | |||||
$pointSale->orders, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} else { | |||||
$totalsPointSaleArray = $this->_totalReportCSV( | |||||
'Total', | |||||
$pointSale->orders, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} | |||||
$datas[] = $this->_lineOrderReportCSV($totalsPointSaleArray, $cpt); | |||||
$datas[] = []; | |||||
} | |||||
} | |||||
// global | |||||
if ($optionCsvExportByPiece) { | |||||
$totalsGlobalArray = $this->_totalReportPiecesCSV( | |||||
'> Totaux', | |||||
$ordersArray, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} else { | |||||
$totalsGlobalArray = $this->_totalReportCSV( | |||||
'> Totaux', | |||||
$ordersArray, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} | |||||
$datas[] = $this->_lineOrderReportCSV($totalsGlobalArray, $cpt); | |||||
CSV::downloadSendHeaders('Commandes_' . $date . '.csv'); | |||||
echo CSV::array2csv($datas); | |||||
die(); | |||||
return $distributionManager->generateDistributionReportPdf($distribution, $save); | |||||
} | |||||
elseif ($type == 'csv') { | |||||
$distributionManager->generateDistributionReportCsv($distribution); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Génère un export des commandes au format CSV à destination du Google Drive | |||||
* de Terre de pains. | |||||
*/ | |||||
public function actionReportTerredepains($date, $key) | |||||
{ | |||||
$producerManager = $this->getProducerManager(); | |||||
$orderManager = $this->getOrderManager(); | |||||
$productManager = $this->getProductManager(); | |||||
if ($key == 'ef572cc148c001f0180c4a624189ed30') { | |||||
$producer = $producerManager->findOneProducerBySlug('terredepains'); | |||||
$idProducer = $producer->id; | |||||
$ordersArray = Order::searchAll( | |||||
[ | |||||
'distribution.date' => $date, | |||||
'distribution.id_producer' => $idProducer | |||||
], | |||||
[ | |||||
'orderby' => 'user.lastname ASC, user.name ASC, comment_point_sale ASC', | |||||
'conditions' => 'date_delete IS NULL' | |||||
] | |||||
); | |||||
$distribution = Distribution::searchOne([ | |||||
'distribution.id_producer' => $idProducer | |||||
], [ | |||||
'conditions' => 'date LIKE :date', | |||||
'params' => [ | |||||
':date' => $date, | |||||
] | |||||
]); | |||||
if ($distribution) { | |||||
$pointsSaleArray = PointSale::searchAll([ | |||||
'point_sale.id_producer' => $idProducer | |||||
]); | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
$orderManager->initPointSaleOrders($pointSale, $ordersArray); | |||||
} | |||||
// produits | |||||
$productsArray = Product::find() | |||||
->joinWith([ | |||||
'productDistribution' => function ($q) use ($distribution) { | |||||
$q->where(['id_distribution' => $distribution->id]); | |||||
} | |||||
]) | |||||
->where([ | |||||
'id_producer' => $idProducer, | |||||
]) | |||||
->orderBy('order ASC') | |||||
->all(); | |||||
$datas = []; | |||||
// produits en colonne | |||||
$productsNameArray = ['']; | |||||
$productsIndexArray = []; | |||||
$productsHasQuantity = []; | |||||
$cpt = 1; | |||||
foreach ($productsArray as $product) { | |||||
$theUnit = $productManager->strUnit($product->unit, 'wording_short', true); | |||||
$theUnit = ($theUnit == 'p.') ? '' : ' (' . $theUnit . ')'; | |||||
$productsNameArray[] = $product->name . $theUnit; | |||||
$productsIndexArray[$product->id] = $cpt++; | |||||
} | |||||
$productsNameArray[] = 'Total'; | |||||
$datas[] = $productsNameArray; | |||||
// global | |||||
$totalsGlobalArray = $this->_totalReportCSV( | |||||
'> Totaux', | |||||
$ordersArray, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
$datas[] = $this->_lineOrderReportCSV($totalsGlobalArray, $cpt - 1, true); | |||||
$datas[] = []; | |||||
// points de vente | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
if (count($pointSale->orders)) { | |||||
// total point de vente | |||||
$totalsPointSaleArray = $this->_totalReportCSV( | |||||
'> ' . $pointSale->name, | |||||
$pointSale->orders, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
$datas[] = $this->_lineOrderReportCSV($totalsPointSaleArray, $cpt - 1, true); | |||||
} | |||||
} | |||||
CSV::downloadSendHeaders('Commandes_' . $date . '.csv'); | |||||
echo CSV::array2csv($datas); | |||||
die(); | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
public function _totalReportCSV($label, $ordersArray, $productsArray, $productsIndexArray) | |||||
{ | |||||
$orderManager = $this->getOrderManager(); | |||||
$productManager = $this->getProductManager(); | |||||
$totalsPointSaleArray = [$label]; | |||||
foreach ($productsArray as $product) { | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantity = $orderManager->getProductQuantity($product, $ordersArray, false, $unit); | |||||
if ($quantity) { | |||||
$index = $productsIndexArray[$product->id]; | |||||
if (!isset($totalsPointSaleArray[$index])) { | |||||
$totalsPointSaleArray[$index] = ''; | |||||
} | |||||
if (strlen($totalsPointSaleArray[$index])) { | |||||
$totalsPointSaleArray[$index] .= ' + '; | |||||
} | |||||
$totalsPointSaleArray[$index] .= $quantity; | |||||
if ($product->unit != $unit) { | |||||
$totalsPointSaleArray[$index] .= '' . $productManager->strUnit($unit, 'wording_short', true); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return $totalsPointSaleArray; | |||||
} | |||||
public function _totalReportPiecesCSV($label, $ordersArray, $productsArray, $productsIndexArray) | |||||
{ | |||||
$orderManager = $this->getOrderManager(); | |||||
$totalsPointSaleArray = [$label]; | |||||
foreach ($productsArray as $product) { | |||||
$quantity = 0; | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantityProduct = $orderManager->getProductQuantity($product, $ordersArray, false, $unit); | |||||
if ($unit == 'piece') { | |||||
$quantity += $quantityProduct; | |||||
} else { | |||||
if ($product->weight > 0) { | |||||
$quantity += ($quantityProduct * $dataUnit['coefficient']) / $product->weight; | |||||
} | |||||
} | |||||
} | |||||
if ($quantity) { | |||||
$index = $productsIndexArray[$product->id]; | |||||
$totalsPointSaleArray[$index] = $quantity; | |||||
} | |||||
} | |||||
return $totalsPointSaleArray; | |||||
} | |||||
public function _lineOrderReportCSV($orderLine, $cptMax, $showTotal = false) | |||||
{ | |||||
$line = []; | |||||
$cptTotal = 0; | |||||
for ($i = 0; $i <= $cptMax; $i++) { | |||||
if (isset($orderLine[$i]) && $orderLine[$i]) { | |||||
$line[] = $orderLine[$i]; | |||||
if (is_numeric($orderLine[$i])) { | |||||
$cptTotal += $orderLine[$i]; | |||||
} | |||||
} else { | |||||
$line[] = ''; | |||||
} | |||||
} | |||||
if ($cptTotal > 0 && $showTotal) { | |||||
$line[] = $cptTotal; | |||||
} | |||||
return $line; | |||||
} | |||||
public function actionAjaxProcessProductQuantityMax($idDistribution, $idProduct, $quantityMax) | public function actionAjaxProcessProductQuantityMax($idDistribution, $idProduct, $quantityMax) | ||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
$productDistribution = $this->getProductDistribution($idProduct, $idDistribution); | $productDistribution = $this->getProductDistribution($idProduct, $idDistribution); | ||||
$productDistribution->quantity_max = ($quantityMax == -1) ? null : (float) abs($quantityMax); | $productDistribution->quantity_max = ($quantityMax == -1) ? null : (float) abs($quantityMax); | ||||
$productDistributionManager->saveUpdate($productDistribution); | |||||
$productDistributionManager->update($productDistribution); | |||||
return ['success']; | return ['success']; | ||||
} | } | ||||
$productDistribution = $this->getProductDistribution($idProduct, $idDistribution); | $productDistribution = $this->getProductDistribution($idProduct, $idDistribution); | ||||
$productDistribution->active = $active; | $productDistribution->active = $active; | ||||
$productDistributionManager->saveUpdate($productDistribution); | |||||
$productDistributionManager->update($productDistribution); | |||||
return ['success']; | return ['success']; | ||||
} | } | ||||
$pointSaleManager->findOnePointSaleById($idPointSale) | $pointSaleManager->findOnePointSaleById($idPointSale) | ||||
); | ); | ||||
$pointSaleDistribution->delivery = $delivery; | $pointSaleDistribution->delivery = $delivery; | ||||
$pointSaleDistributionManager->saveUpdate($pointSaleDistribution); | |||||
$pointSaleDistributionManager->update($pointSaleDistribution); | |||||
return ['success']; | return ['success']; | ||||
} | } |
<?php | |||||
namespace common\logic\Distribution\Distribution\Service; | |||||
use common\helpers\CSV; | |||||
use common\logic\AbstractGenerator; | |||||
use common\logic\Distribution\Distribution\Model\Distribution; | |||||
use common\logic\Order\Order\Repository\OrderRepository; | |||||
use common\logic\Order\Order\Service\OrderBuilder; | |||||
use common\logic\Order\Order\Service\OrderSolver; | |||||
use common\logic\PointSale\PointSale\Repository\PointSaleRepository; | |||||
use common\logic\Producer\Producer\Repository\ProducerRepository; | |||||
use common\logic\Product\Product\Model\Product; | |||||
use common\logic\Product\Product\Repository\ProductRepository; | |||||
use common\logic\Product\Product\Service\ProductSolver; | |||||
class DistributionReportCsvGenerator extends AbstractGenerator | |||||
{ | |||||
protected ProducerRepository $producerRepository; | |||||
protected ProductRepository $productRepository; | |||||
protected ProductSolver $productSolver; | |||||
protected OrderRepository $orderRepository; | |||||
protected OrderSolver $orderSolver; | |||||
protected PointSaleRepository $pointSaleRepository; | |||||
protected OrderBuilder $orderBuilder; | |||||
public function loadDependencies(): void | |||||
{ | |||||
$this->producerRepository = $this->loadService(ProducerRepository::class); | |||||
$this->productRepository = $this->loadService(ProductRepository::class); | |||||
$this->productSolver = $this->loadService(ProductSolver::class); | |||||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||||
$this->orderSolver = $this->loadService(OrderSolver::class); | |||||
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); | |||||
$this->orderBuilder = $this->loadService(OrderBuilder::class); | |||||
} | |||||
public function generateDistributionReportCsv(Distribution $distribution) | |||||
{ | |||||
$datas = []; | |||||
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution); | |||||
$productsArray = $this->productRepository->findProductsByDistribution($distribution); | |||||
$optionCsvExportAllProducts = $this->producerRepository->getConfig('option_csv_export_all_products'); | |||||
$optionCsvExportByPiece = $this->producerRepository->getConfig('option_csv_export_by_piece'); | |||||
$pointsSaleArray = $this->pointSaleRepository->findPointSales(); | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
$this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray); | |||||
} | |||||
// produits en colonne | |||||
$productsNameArray = ['', 'Commentaire']; | |||||
$productsIndexArray = []; | |||||
$productsHasQuantity = []; | |||||
$cpt = 2; | |||||
foreach ($productsArray as $product) { | |||||
$productsHasQuantity[$product->id] = 0; | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantity = $this->orderSolver->getProductQuantity($product, $ordersArray, true, $unit); | |||||
if ($quantity) { | |||||
$productsHasQuantity[$product->id] += $quantity; | |||||
} | |||||
} | |||||
if ($productsHasQuantity[$product->id] > 0 || $optionCsvExportAllProducts) { | |||||
$productName = $this->productSolver->getNameExport($product); | |||||
if ($optionCsvExportByPiece) { | |||||
$productUnit = 'piece'; | |||||
} else { | |||||
$productUnit = $product->unit; | |||||
} | |||||
$productName .= ' (' . $this->productSolver->strUnit($productUnit, 'wording_short', true) . ')'; | |||||
$productsNameArray[] = $productName; | |||||
$productsIndexArray[$product->id] = $cpt++; | |||||
} | |||||
} | |||||
$datas[] = $productsNameArray; | |||||
// points de vente | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
if (count($pointSale->orders)) { | |||||
// listing commandes | |||||
$datas[] = ['> ' . $pointSale->name]; | |||||
foreach ($pointSale->orders as $order) { | |||||
$orderLine = [$this->orderSolver->getOrderUsername($order), $this->orderSolver->getCommentReport($order)]; | |||||
if ($optionCsvExportByPiece) { | |||||
foreach ($order->productOrder as $productOrder) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] = $this->orderSolver->getProductQuantityPieces( | |||||
$productOrder->product, | |||||
[$order] | |||||
); | |||||
} | |||||
} else { | |||||
foreach ($productsIndexArray as $idProduct => $indexProduct) { | |||||
$orderLine[$indexProduct] = ''; | |||||
} | |||||
foreach ($order->productOrder as $productOrder) { | |||||
if (strlen($orderLine[$productsIndexArray[$productOrder->id_product]])) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= ' + '; | |||||
} | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productOrder->quantity; | |||||
if ($productOrder->product->unit != $productOrder->unit) { | |||||
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productManager->strUnit( | |||||
$productOrder->unit, | |||||
'wording_short', | |||||
true | |||||
); | |||||
} | |||||
} | |||||
} | |||||
$datas[] = $this->lineOrderReport($orderLine, $cpt); | |||||
} | |||||
// total point de vente | |||||
if ($optionCsvExportByPiece) { | |||||
$totalsPointSaleArray = $this->totalReportPieces( | |||||
'Total', | |||||
$pointSale->orders, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} else { | |||||
$totalsPointSaleArray = $this->totalReport( | |||||
'Total', | |||||
$pointSale->orders, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} | |||||
$datas[] = $this->lineOrderReport($totalsPointSaleArray, $cpt); | |||||
$datas[] = []; | |||||
} | |||||
} | |||||
// global | |||||
if ($optionCsvExportByPiece) { | |||||
$totalsGlobalArray = $this->totalReportPieces( | |||||
'> Totaux', | |||||
$ordersArray, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} else { | |||||
$totalsGlobalArray = $this->totalReport( | |||||
'> Totaux', | |||||
$ordersArray, | |||||
$productsArray, | |||||
$productsIndexArray | |||||
); | |||||
} | |||||
$datas[] = $this->lineOrderReport($totalsGlobalArray, $cpt); | |||||
CSV::send('Commandes_' . $distribution->date . '.csv', $datas); | |||||
} | |||||
private function totalReport($label, $ordersArray, $productsArray, $productsIndexArray) | |||||
{ | |||||
$totalsPointSaleArray = [$label]; | |||||
foreach ($productsArray as $product) { | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantity = $this->orderSolver->getProductQuantity($product, $ordersArray, false, $unit); | |||||
if ($quantity) { | |||||
$index = $productsIndexArray[$product->id]; | |||||
if (!isset($totalsPointSaleArray[$index])) { | |||||
$totalsPointSaleArray[$index] = ''; | |||||
} | |||||
if (strlen($totalsPointSaleArray[$index])) { | |||||
$totalsPointSaleArray[$index] .= ' + '; | |||||
} | |||||
$totalsPointSaleArray[$index] .= $quantity; | |||||
if ($product->unit != $unit) { | |||||
$totalsPointSaleArray[$index] .= '' . $this->productSolver->strUnit($unit, 'wording_short', true); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return $totalsPointSaleArray; | |||||
} | |||||
private function totalReportPieces($label, $ordersArray, $productsArray, $productsIndexArray) | |||||
{ | |||||
$totalsPointSaleArray = [$label]; | |||||
foreach ($productsArray as $product) { | |||||
$quantity = 0; | |||||
foreach (Product::$unitsArray as $unit => $dataUnit) { | |||||
$quantityProduct = $this->orderSolver->getProductQuantity($product, $ordersArray, false, $unit); | |||||
if ($unit == 'piece') { | |||||
$quantity += $quantityProduct; | |||||
} else { | |||||
if ($product->weight > 0) { | |||||
$quantity += ($quantityProduct * $dataUnit['coefficient']) / $product->weight; | |||||
} | |||||
} | |||||
} | |||||
if ($quantity) { | |||||
$index = $productsIndexArray[$product->id]; | |||||
$totalsPointSaleArray[$index] = $quantity; | |||||
} | |||||
} | |||||
return $totalsPointSaleArray; | |||||
} | |||||
private function lineOrderReport($orderLine, $cptMax, $showTotal = false) | |||||
{ | |||||
$line = []; | |||||
$cptTotal = 0; | |||||
for ($i = 0; $i <= $cptMax; $i++) { | |||||
if (isset($orderLine[$i]) && $orderLine[$i]) { | |||||
$line[] = $orderLine[$i]; | |||||
if (is_numeric($orderLine[$i])) { | |||||
$cptTotal += $orderLine[$i]; | |||||
} | |||||
} else { | |||||
$line[] = ''; | |||||
} | |||||
} | |||||
if ($cptTotal > 0 && $showTotal) { | |||||
$line[] = $cptTotal; | |||||
} | |||||
return $line; | |||||
} | |||||
} |
<?php | |||||
namespace common\logic\Distribution\Distribution\Service; | |||||
use common\logic\AbstractGenerator; | |||||
class DistributionReportGridCsvGenerator extends AbstractGenerator | |||||
{ | |||||
} |
<?php | |||||
namespace common\logic\Distribution\Distribution\Service; | |||||
use common\logic\AbstractGenerator; | |||||
use common\logic\Distribution\Distribution\Model\Distribution; | |||||
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; | |||||
use common\logic\Order\Order\Repository\OrderRepository; | |||||
use common\logic\Order\Order\Service\OrderBuilder; | |||||
use common\logic\PointSale\PointSale\Repository\PointSaleRepository; | |||||
use common\logic\Product\Product\Repository\ProductRepository; | |||||
use kartik\mpdf\Pdf; | |||||
class DistributionReportPdfGenerator extends AbstractGenerator | |||||
{ | |||||
protected OrderRepository $orderRepository; | |||||
protected OrderBuilder $orderBuilder; | |||||
protected ProductRepository $productRepository; | |||||
protected ProductDistributionRepository $productDistributionRepository; | |||||
protected PointSaleRepository $pointSaleRepository; | |||||
public function loadDependencies(): void | |||||
{ | |||||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||||
$this->orderBuilder = $this->loadService(OrderBuilder::class); | |||||
$this->productRepository = $this->loadService(ProductRepository::class); | |||||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | |||||
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); | |||||
} | |||||
public function generateDistributionReportPdf(Distribution $distribution, bool $save = false) | |||||
{ | |||||
$producer = $this->getProducerContext(); | |||||
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution); | |||||
$productsArray = $this->productRepository->findProductsByDistribution($distribution); | |||||
$selectedProductsArray = $this->productDistributionRepository->findProductDistributionsByDistribution($distribution); | |||||
$pointsSaleArray = $this->pointSaleRepository->findPointSales(); | |||||
foreach ($pointsSaleArray as $pointSale) { | |||||
$this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray); | |||||
} | |||||
$viewPdf = '@backend/views/distribution/report'; | |||||
$orientationPdf = Pdf::ORIENT_PORTRAIT; | |||||
if ($producer->slug == 'bourlinguepacotille') { | |||||
$viewPdf = '@backend/views/distribution/report-bourlingue'; | |||||
$orientationPdf = Pdf::ORIENT_LANDSCAPE; | |||||
} | |||||
// get your HTML raw content without any layouts or scripts | |||||
$content = \Yii::$app->getView()->render($viewPdf, [ | |||||
'date' => $distribution->date, | |||||
'distribution' => $distribution, | |||||
'selectedProductsArray' => $selectedProductsArray, | |||||
'pointsSaleArray' => $pointsSaleArray, | |||||
'productsArray' => $productsArray, | |||||
'ordersArray' => $ordersArray, | |||||
'producer' => $producer | |||||
]); | |||||
$dateStr = date('d/m/Y', strtotime($distribution->date)); | |||||
if ($save) { | |||||
$destination = Pdf::DEST_FILE; | |||||
} else { | |||||
$destination = Pdf::DEST_BROWSER; | |||||
} | |||||
$pdf = new Pdf([ | |||||
// set to use core fonts only | |||||
'mode' => Pdf::MODE_UTF8, | |||||
// A4 paper format | |||||
'format' => Pdf::FORMAT_A4, | |||||
// portrait orientation | |||||
'orientation' => $orientationPdf, | |||||
// stream to browser inline | |||||
'destination' => $destination, | |||||
'filename' => \Yii::getAlias( | |||||
'@app/web/pdf/Commandes-' . $distribution->date . '-' . $this->getProducerContextId() . '.pdf' | |||||
), | |||||
// your html content input | |||||
'content' => $content, | |||||
// format content from your own css file if needed or use the | |||||
// enhanced bootstrap css built by Krajee for mPDF formatting | |||||
//'cssFile' => Yii::getAlias('@web/css/distribution/report.css'), | |||||
// any css to be embedded if required | |||||
'cssInline' => ' | |||||
table { | |||||
border-spacing : 0px ; | |||||
border-collapse : collapse ; | |||||
width: 100% ; | |||||
} | |||||
table tr th, | |||||
table tr td { | |||||
padding: 0px ; | |||||
margin: 0px ; | |||||
border: solid 1px #e0e0e0 ; | |||||
padding: 3px 8px ; | |||||
vertical-align : top; | |||||
page-break-inside: avoid !important; | |||||
color: black; | |||||
} | |||||
table tr th { | |||||
font-size: 13px ; | |||||
} | |||||
table tr td { | |||||
font-size: 13px ; | |||||
} | |||||
', | |||||
// set mPDF properties on the fly | |||||
//'options' => ['title' => 'Krajee Report Title'], | |||||
// call mPDF methods on the fly | |||||
'methods' => [ | |||||
'SetHeader' => ['Commandes du ' . $dateStr], | |||||
'SetFooter' => ['{PAGENO}'], | |||||
] | |||||
]); | |||||
// return the pdf output as per the destination setting | |||||
return $pdf->render(); | |||||
} | |||||
} |
use common\logic\Distribution\Distribution\Repository\DistributionRepository; | use common\logic\Distribution\Distribution\Repository\DistributionRepository; | ||||
use common\logic\Distribution\Distribution\Service\DistributionBuilder; | use common\logic\Distribution\Distribution\Service\DistributionBuilder; | ||||
use common\logic\Distribution\Distribution\Service\DistributionDefinition; | use common\logic\Distribution\Distribution\Service\DistributionDefinition; | ||||
use common\logic\Distribution\Distribution\Service\DistributionReportCsvGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionReportGridCsvGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionReportPdfGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionSolver; | use common\logic\Distribution\Distribution\Service\DistributionSolver; | ||||
class DistributionContainer extends AbstractContainer | class DistributionContainer extends AbstractContainer | ||||
DistributionDefinition::class, | DistributionDefinition::class, | ||||
DistributionSolver::class, | DistributionSolver::class, | ||||
DistributionRepository::class, | DistributionRepository::class, | ||||
DistributionBuilder::class | |||||
DistributionBuilder::class, | |||||
DistributionReportCsvGenerator::class, | |||||
DistributionReportGridCsvGenerator::class, | |||||
DistributionReportPdfGenerator::class, | |||||
]; | ]; | ||||
} | } | ||||
{ | { | ||||
return DistributionDefinition::getInstance(); | return DistributionDefinition::getInstance(); | ||||
} | } | ||||
public function getSolver(): DistributionSolver | |||||
{ | |||||
return DistributionSolver::getInstance(); | |||||
} | |||||
public function getRepository(): DistributionRepository | |||||
{ | |||||
return DistributionRepository::getInstance(); | |||||
} | |||||
public function getBuilder(): DistributionBuilder | |||||
{ | |||||
return DistributionBuilder::getInstance(); | |||||
} | |||||
} | } |
use common\logic\Distribution\Distribution\Repository\DistributionRepository; | use common\logic\Distribution\Distribution\Repository\DistributionRepository; | ||||
use common\logic\Distribution\Distribution\Service\DistributionBuilder; | use common\logic\Distribution\Distribution\Service\DistributionBuilder; | ||||
use common\logic\Distribution\Distribution\Service\DistributionDefinition; | use common\logic\Distribution\Distribution\Service\DistributionDefinition; | ||||
use common\logic\Distribution\Distribution\Service\DistributionReportCsvGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionReportGridCsvGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionReportPdfGenerator; | |||||
use common\logic\Distribution\Distribution\Service\DistributionSolver; | use common\logic\Distribution\Distribution\Service\DistributionSolver; | ||||
/** | /** | ||||
* @mixin DistributionSolver | * @mixin DistributionSolver | ||||
* @mixin DistributionRepository | * @mixin DistributionRepository | ||||
* @mixin DistributionBuilder | * @mixin DistributionBuilder | ||||
* @mixin DistributionReportCsvGenerator | |||||
* @mixin DistributionReportGridCsvGenerator | |||||
* @mixin DistributionReportPdfGenerator | |||||
*/ | */ | ||||
class DistributionManager extends AbstractManager | class DistributionManager extends AbstractManager | ||||
{ | { |
->filterByDistributionDate($distribution->date) | ->filterByDistributionDate($distribution->date) | ||||
->filterIsValid() | ->filterIsValid() | ||||
->filterByCondition($conditionAppend) | ->filterByCondition($conditionAppend) | ||||
->orderBy('user.lastname ASC, user.name ASC') | |||||
->orderBy('user.lastname ASC, user.name ASC, comment_point_sale ASC') | |||||
->find(); | ->find(); | ||||
} | } | ||||
public function queryProductsByDistribution(Distribution $distribution) | public function queryProductsByDistribution(Distribution $distribution) | ||||
{ | { | ||||
return $this->createDefaultQuery() | return $this->createDefaultQuery() | ||||
//->leftJoin('product_distribution', 'product.id = product_distribution.id_product') | |||||
->joinWith([ | ->joinWith([ | ||||
//'taxRate', | |||||
'productDistribution' => function ($query) use ($distribution) { | 'productDistribution' => function ($query) use ($distribution) { | ||||
$query->andOnCondition( | $query->andOnCondition( | ||||
'product_distribution.id_distribution = ' . $distribution->id | 'product_distribution.id_distribution = ' . $distribution->id | ||||
); | ); | ||||
} | } | ||||
]) | ]) | ||||
//->filterByDistribution($distribution) | |||||
->orderBy('product_distribution.active DESC, product.order ASC'); | ->orderBy('product_distribution.active DESC, product.order ASC'); | ||||
/*$productsQuery = Product::find() | |||||
->orWhere(['id_producer' => GlobalParam::getCurrentProducerId(),]) | |||||
->joinWith([ | |||||
'taxRate', | |||||
'productDistribution' => function ($query) use ($distribution) { | |||||
$query->andOnCondition( | |||||
'product_distribution.id_distribution = ' . $distribution->id | |||||
); | |||||
} | |||||
]) | |||||
->orderBy('product_distribution.active DESC, order ASC');*/ | |||||
} | } | ||||
/** | /** |