[ 'class' => AccessControl::className(), 'rules' => [ [ 'actions' => ['report-cron', 'report-terredepains'], 'allow' => true, 'roles' => ['?'] ], [ 'allow' => true, 'roles' => ['@'], 'matchCallback' => function ($rule, $action) { return User::getCurrentStatus() == USER::STATUS_ADMIN || User::getCurrentStatus() == USER::STATUS_PRODUCER; } ] ], ], ]; } public function actionIndex($date = '') { $this->checkProductsPointsSale() ; $format = 'Y-m-d' ; $theDate = '' ; $dateObject = DateTime::createFromFormat($format, $date); if($dateObject && $dateObject->format($format) === $date) { $theDate = $date ; } return $this->render('index', [ 'date' => $theDate ]) ; } public function actionAjaxInfos($date = '') { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $json = [ 'distribution' => [], 'products' => [] ] ; $format = 'Y-m-d' ; $dateObject = DateTime::createFromFormat($format, $date); $producer = Producer::getCurrent() ; $json['producer'] = [ 'credit' => $producer->credit ]; $distributionsArray = Distribution::searchAll([ 'active' => 1 ], [ 'conditions' => ['date > :date_begin','date < :date_end'], 'params' => [':date_begin' => date('Y-m-d', strtotime('-1 month')), ':date_end' => date('Y-m-d', strtotime('+3 month')), ], ]) ; $json['distributions'] = $distributionsArray ; if($dateObject && $dateObject->format($format) === $date) { // distribution $distribution = Distribution::initDistribution($date) ; $json['distribution'] = [ 'id' => $distribution->id, 'active' => $distribution->active, 'url_report' => Yii::$app->urlManagerBackend->createUrl(['distribution/report','date' => $distribution->date]) ] ; // commandes $ordersArray = Order::searchAll([ 'distribution.id' => $distribution->id, ],[ 'orderby' => 'user.lastname ASC, user.name ASC' ]); // montant et poids des commandes $revenues = 0; $weight = 0 ; if($ordersArray) { foreach ($ordersArray as $order) { if(is_null($order->date_delete)) { $revenues += $order->amount; $weight += $order->weight; } } } $json['distribution']['revenues'] = Price::format($revenues); $json['distribution']['weight'] = number_format($weight, 2); // products $productsArray = Product::find() ->orWhere(['id_producer' => Producer::getId(),]) ->joinWith(['productDistribution' => function($query) use($distribution) { $query->andOnCondition('product_distribution.id_distribution = '.$distribution->id) ; }]) ->orderBy('product_distribution.active DESC, order ASC') ->asArray() ->all(); $potentialRevenues = 0; $potentialWeight = 0; foreach($productsArray as &$theProduct) { $quantityOrder = Order::getProductQuantity($theProduct['id'], $ordersArray) ; $theProduct['quantity_ordered'] = $quantityOrder ; if(!isset($theProduct['productDistribution'][0])) { $theProductObject = (object) $theProduct ; $theProduct['productDistribution'][0] = $distribution->linkProduct($theProductObject) ; } if(!is_numeric($theProduct['productDistribution'][0]['quantity_max'])) { $theProduct['quantity_remaining'] = null ; } else { $theProduct['quantity_remaining'] = $theProduct['productDistribution'][0]['quantity_max'] - $quantityOrder ; } $theProduct['quantity_form'] = 0 ; if($theProduct['productDistribution'][0]['active'] && $theProduct['productDistribution'][0]['quantity_max']) { $potentialRevenues += $theProduct['productDistribution'][0]['quantity_max'] * $theProduct['price']; $potentialWeight += $theProduct['productDistribution'][0]['quantity_max'] * $theProduct['weight'] / 1000; } } $json['distribution']['potential_revenues'] = Price::format($potentialRevenues) ; $json['distribution']['potential_weight'] = number_format($potentialWeight, 2) ; $json['products'] = $productsArray ; // orders as array if($ordersArray) { foreach($ordersArray as &$order) { $productOrderArray = [] ; foreach($order->productOrder as $productOrder) { $productOrderArray[$productOrder->id_product] = [ 'quantity' => $productOrder->quantity * Product::$unitsArray[$productOrder->unit]['coefficient'], 'unit' => $productOrder->unit, ] ; } foreach($productsArray as $product) { if(!isset($productOrderArray[$product['id']])) { $productOrderArray[$product['id']] = [ 'quantity' => 0, 'unit' => $product['unit'] ] ; } } $creditHistoryArray = [] ; foreach($order->creditHistory as $creditHistory) { $creditHistoryArray[] = [ 'date' => date('d/m/Y H:i:s', strtotime($creditHistory->date)), 'user_action' => $creditHistory->strUserAction(), 'wording' => $creditHistory->getStrWording(), 'debit' => ($creditHistory->isTypeDebit() ? '- '.$creditHistory->getAmount(Order::AMOUNT_TOTAL,true) : ''), 'credit' => ($creditHistory->isTypeCredit() ? '+ '.$creditHistory->getAmount(Order::AMOUNT_TOTAL,true) : '') ] ; } $arrayCreditUser = [] ; if(isset($order->user) && isset($order->user->userProducer)) { $arrayCreditUser['credit'] = $order->user->userProducer[0]->credit ; } $oneProductUnactivated = false ; foreach($order->productOrder as $productOrder) { foreach($productsArray as $product) { if($productOrder->id_product == $product['id'] && !$product['productDistribution'][0]['active']) { $oneProductUnactivated = true ; } } } $order = array_merge($order->getAttributes(), [ 'amount' => $order->getAmount(Order::AMOUNT_TOTAL), 'amount_paid' => $order->getAmount(Order::AMOUNT_PAID), 'amount_remaining' => $order->getAmount(Order::AMOUNT_REMAINING), 'amount_surplus' => $order->getAmount(Order::AMOUNT_SURPLUS), 'user' => (isset($order->user)) ? array_merge($order->user->getAttributes(), $arrayCreditUser) : null, 'pointSale' => ['id' => $order->pointSale->id, 'name' => $order->pointSale->name], 'productOrder' => $productOrderArray, 'creditHistory' => $creditHistoryArray, 'oneProductUnactivated' => $oneProductUnactivated ]) ; } } $json['orders'] = $ordersArray ; // points de vente $pointsSaleArray = PointSale::find() ->joinWith(['pointSaleDistribution' => function($q) use ($distribution) { $q->where(['id_distribution' => $distribution->id]); }]) ->where([ 'id_producer' => Producer::getId(), ]) ->asArray() ->all(); $idPointSaleDefault = 0 ; foreach($pointsSaleArray as $pointSale) { if($pointSale['default']) { $idPointSaleDefault = $pointSale['id'] ; } } $json['points_sale'] = $pointsSaleArray ; // order create $productOrderArray = [] ; foreach($productsArray as $product) { $productOrderArray[$product['id']] = [ 'quantity' => 0, 'unit' => $product['unit'] ] ; } $json['order_create'] = [ 'id_point_sale' => $idPointSaleDefault, 'id_user' => 0, 'username' => '', 'comment' => '', 'productOrder' => $productOrderArray ] ; // utilisateurs $usersArray = User::findBy()->all() ; $json['users'] = $usersArray ; // une production de la semaine activée ou non $oneDistributionWeekActive = false ; $week = sprintf('%02d',date('W',strtotime($date))); $start = strtotime(date('Y',strtotime($date)).'W'.$week); $dateMonday = date('Y-m-d',strtotime('Monday',$start)) ; $dateTuesday = date('Y-m-d',strtotime('Tuesday',$start)) ; $dateWednesday = date('Y-m-d',strtotime('Wednesday',$start)) ; $dateThursday = date('Y-m-d',strtotime('Thursday',$start)) ; $dateFriday = date('Y-m-d',strtotime('Friday',$start)) ; $dateSaturday = date('Y-m-d',strtotime('Saturday',$start)) ; $dateSunday = date('Y-m-d',strtotime('Sunday',$start)) ; $weekDistribution = Distribution::find() ->andWhere([ 'id_producer' => Producer::getId(), 'active' => 1, ]) ->andWhere(['or', ['date' => $dateMonday], ['date' => $dateTuesday], ['date' => $dateWednesday], ['date' => $dateThursday], ['date' => $dateFriday], ['date' => $dateSaturday], ['date' => $dateSunday], ]) ->one(); if($weekDistribution) { $oneDistributionWeekActive = true ; } $json['one_distribution_week_active'] = $oneDistributionWeekActive ; } return $json ; } public function actionAjaxPointSaleFavorite($idUser) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $user = User::findOne(['id' => $idUser]) ; $favoritePointSale = $user->getFavoritePointSale() ; $idFavoritePointSale = 0 ; if($favoritePointSale) { $idFavoritePointSale = $favoritePointSale->id ; } return [ 'id_favorite_point_sale' => $idFavoritePointSale ] ; } /** * Génére un PDF récapitulatif des des commandes d'un producteur pour une * date donnée (Méthode appelable via CRON) * * @param string $date * @param boolean $save * @param integer $idProducer * @param string $key * @return PDF|null */ public function actionReportCron($date = '', $save = false, $idProducer = 0, $key = '') { if($key == '64ac0bdab7e9f5e48c4d991ec5201d57') { $this->actionReport($date, $save, $idProducer) ; } } /** * Génére un PDF récapitulatif des commandes d'un producteur pour une * date donnée. * * @param string $date * @param boolean $save * @param integer $idProducer * @return PDF|null */ public function actionReport($date = '', $save = false, $idProducer = 0, $type = "pdf") { if (!Yii::$app->user->isGuest) { $idProducer = Producer::getId() ; } $ordersArray = Order::searchAll([ 'distribution.date' => $date, ], [ 'orderby' => 'comment_point_sale ASC, user.name ASC', 'conditions' => 'date_delete IS NULL' ]) ; $distribution = Distribution::searchOne([],[ 'conditions' => 'date LIKE :date', 'params' => [':date' => $date] ]) ; if ($distribution) { $selectedProductsArray = ProductDistribution::searchByDistribution($distribution->id) ; $pointsSaleArray = PointSale::searchAll() ; foreach ($pointsSaleArray as $pointSale) { $pointSale->initOrders($ordersArray) ; } // produits $productsArray = Product::find() ->joinWith(['productDistribution' => function($q) use ($distribution) { $q->where(['id_distribution' => $distribution->id]); }]) ->where([ 'id_producer' => Producer::getId(), ]) ->orderBy('order ASC') ->all(); if($type == 'pdf') { // get your HTML raw content without any layouts or scripts $content = $this->renderPartial('report', [ 'date' => $date, 'distribution' => $distribution, 'selectedProductsArray' => $selectedProductsArray, 'pointsSaleArray' => $pointsSaleArray, 'productsArray' => $productsArray, 'ordersArray' => $ordersArray ]); $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' => Pdf::ORIENT_PORTRAIT, // 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; } 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 = []; // produits en colonne $productsNameArray = [''] ; $productsIndexArray = [] ; $productsHasQuantity = [] ; $cpt = 1 ; foreach ($productsArray as $product) { $productsHasQuantity[$product->id] = 0 ; foreach(Product::$unitsArray as $unit => $dataUnit) { $quantity = Order::getProductQuantity($product->id, $ordersArray, true, $unit); if($quantity) { $productsHasQuantity[$product->id] += $quantity ; } } if($productsHasQuantity[$product->id] > 0) { $productsNameArray[] = $product->name .' ('.Product::strUnit($product->unit, 'wording_short', true).')' ; $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 = [$order->getStrUser()] ; 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]] .= Product::strUnit($productOrder->unit, 'wording_short', true) ; } } $datas[] = $this->_lineOrderReportCSV($orderLine, $cpt) ; } // total point de vente $totalsPointSaleArray = $this->_totalReportCSV( 'Total', $pointSale->orders, $productsArray, $productsIndexArray ) ; $datas[] = $this->_lineOrderReportCSV($totalsPointSaleArray, $cpt) ; $datas[] = [] ; } } // global $totalsGlobalArray = $this->_totalReportCSV( '> Totaux', $ordersArray, $productsArray, $productsIndexArray ) ; $datas[] = $this->_lineOrderReportCSV($totalsGlobalArray, $cpt) ; CSV::downloadSendHeaders('Commandes_'.$date.'.csv'); echo CSV::array2csv($datas); die(); } } return null ; } /** * Génère un export des commandes au format CSV à destination du Google Drive * de Terre de pains. * * @param type $date * @return CSV */ public function actionReportTerredepains($date, $key) { if($key == 'ef572cc148c001f0180c4a624189ed30') { $producer = Producer::searchOne([ 'producer.slug' => 'terredepains' ]) ; $idProducer = $producer->id ; $ordersArray = Order::searchAll([ 'distribution.date' => $date, 'distribution.id_producer' => $idProducer ], [ 'orderby' => 'comment_point_sale ASC, user.name ASC', 'conditions' => 'date_delete IS NULL' ]) ; $distribution = Distribution::searchOne([ 'distribution.id_producer' => $idProducer ],[ 'conditions' => 'date LIKE :date', 'params' => [ ':date' => $date, ] ]) ; if ($distribution) { $selectedProductsArray = ProductDistribution::searchByDistribution($distribution->id) ; $pointsSaleArray = PointSale::searchAll([ 'point_sale.id_producer' => $idProducer ]) ; foreach($pointsSaleArray as $pointSale) { $pointSale->initOrders($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 = Product::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)) { // listing commandes $datas[] = ['> '.$pointSale->name] ; foreach($pointSale->orders as $order) { $orderLine = [$order->getStrUser()] ; 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]] .= Product::strUnit($productOrder->unit, 'wording_short', true) ; } } $datas[] = $this->_lineOrderReportCSV($orderLine, $cpt - 1, true) ; } // total point de vente $totalsPointSaleArray = $this->_totalReportCSV( 'Total point de vente', $pointSale->orders, $productsArray, $productsIndexArray ) ; $datas[] = $this->_lineOrderReportCSV($totalsPointSaleArray, $cpt - 1, true) ; $datas[] = [] ; } } CSV::downloadSendHeaders('Commandes_'.$date.'.csv'); echo CSV::array2csv($datas); die(); } return null ; } } public function _totalReportCSV($label, $ordersArray, $productsArray, $productsIndexArray) { $totalsPointSaleArray = [$label] ; foreach ($productsArray as $product) { foreach(Product::$unitsArray as $unit => $dataUnit) { $quantity = Order::getProductQuantity($product->id, $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] .= ''.Product::strUnit($unit, 'wording_short', true) ; } } } } 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] ; $cptTotal += $orderLine[$i] ; } else { $line[] = '' ; } } if($cptTotal > 0 && $showTotal) { $line[] = $cptTotal ; } return $line ; } public function actionAjaxProcessProductQuantityMax($idDistribution, $idProduct, $quantityMax) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $productDistribution = ProductDistribution::searchOne([ 'id_distribution' => $idDistribution, 'id_product' => $idProduct, ]) ; $productDistribution->quantity_max = (!$quantityMax) ? null : (int) $quantityMax ; $productDistribution->save() ; return ['success'] ; } public function actionAjaxProcessActiveProduct($idDistribution, $idProduct, $active) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $productDistribution = ProductDistribution::searchOne([ 'id_distribution' => $idDistribution, 'id_product' => $idProduct, ]) ; $productDistribution->active = $active ; $productDistribution->save() ; return ['success'] ; } public function actionAjaxProcessActivePointSale($idDistribution, $idPointSale, $delivery) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $pointSaleDistribution = PointSaleDistribution::searchOne([ 'id_distribution' => $idDistribution, 'id_point_sale' => $idPointSale, ]) ; $pointSaleDistribution->delivery = $delivery ; $pointSaleDistribution->save() ; return ['success'] ; } /** * Active/désactive un jour de distribution. * * @param integer $idDistribution * @param string $date * @param boolean $active * @return array */ public function actionAjaxProcessActiveDistribution($idDistribution = 0, $date = '', $active) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; if($idDistribution) { $distribution = Distribution::searchOne([ 'id' => $idDistribution ]) ; } $format = 'Y-m-d' ; $dateObject = DateTime::createFromFormat($format, $date); if($dateObject && $dateObject->format($format) === $date) { $distribution = Distribution::initDistribution($date) ; } if($distribution) { $distribution->active($active) ; return ['success'] ; } return ['error'] ; } /** * Change l'état d'une semaine de production (activé, désactivé). * * @param string $date * @param integer $active */ public function actionAjaxProcessActiveWeekDistribution($date, $active) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $week = sprintf('%02d',date('W',strtotime($date))); $start = strtotime(date('Y',strtotime($date)).'W'.$week); $dateMonday = date('Y-m-d',strtotime('Monday',$start)) ; $dateTuesday = date('Y-m-d',strtotime('Tuesday',$start)) ; $dateWednesday = date('Y-m-d',strtotime('Wednesday',$start)) ; $dateThursday = date('Y-m-d',strtotime('Thursday',$start)) ; $dateFriday = date('Y-m-d',strtotime('Friday',$start)) ; $dateSaturday = date('Y-m-d',strtotime('Saturday',$start)) ; $dateSunday = date('Y-m-d',strtotime('Sunday',$start)) ; $pointsSaleArray = PointSale::searchAll() ; $activeMonday = false ; $activeTuesday = false ; $activeWednesday = false ; $activeThursday = false ; $activeFriday = false ; $activeSaturday = false ; $activeSunday = false ; foreach($pointsSaleArray as $pointSale) { if($pointSale->delivery_monday) $activeMonday = true ; if($pointSale->delivery_tuesday) $activeTuesday = true ; if($pointSale->delivery_wednesday) $activeWednesday = true ; if($pointSale->delivery_thursday) $activeThursday = true ; if($pointSale->delivery_friday) $activeFriday = true ; if($pointSale->delivery_saturday) $activeSaturday = true ; if($pointSale->delivery_sunday) $activeSunday = true ; } if($activeMonday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateMonday, $active) ; } if($activeTuesday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateTuesday, $active) ; } if($activeWednesday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateWednesday, $active) ; } if($activeThursday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateThursday, $active) ; } if($activeFriday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateFriday, $active) ; } if($activeSaturday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateSaturday, $active) ; } if($activeSunday || !$active) { $this->actionAjaxProcessActiveDistribution(0, $dateSunday, $active) ; } return ['success'] ; } /** * Ajoute les commandes récurrentes pour une date donnée. * * @param string $date */ public function actionAjaxProcessAddSubscriptions($date) { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; Subscription::addAll($date, true); return ['success'] ; } }