@@ -47,6 +47,7 @@ use common\models\PointSale; | |||
use common\models\Product; | |||
use common\models\Producer; | |||
use common\models\Order; | |||
use common\models\ProductCategory; | |||
use common\models\User; | |||
use common\models\Subscription; | |||
use common\helpers\Price; | |||
@@ -113,7 +114,8 @@ class DistributionController extends BackendController | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$json['producer'] = [ | |||
'credit' => $producer->credit, | |||
'tiller' => $producer->tiller | |||
'tiller' => $producer->tiller, | |||
'option_display_export_grid' => $producer->option_display_export_grid | |||
]; | |||
$json['means_payment'] = MeanPayment::getAll(); | |||
@@ -132,7 +134,8 @@ class DistributionController extends BackendController | |||
$json['distribution'] = [ | |||
'id' => $distribution->id, | |||
'active' => $distribution->active, | |||
'url_report' => Yii::$app->urlManagerBackend->createUrl(['distribution/report', 'date' => $distribution->date]) | |||
'url_report' => Yii::$app->urlManagerBackend->createUrl(['distribution/report', 'date' => $distribution->date]), | |||
'url_report_grid' => Yii::$app->urlManagerBackend->createUrl(['distribution/report-grid', 'date' => $distribution->date]), | |||
]; | |||
// commandes | |||
@@ -703,6 +706,178 @@ class DistributionController extends BackendController | |||
return null; | |||
} | |||
public function actionReportGrid($date = '', $save = false, $idProducer = 0, $type = "pdf") | |||
{ | |||
if (!Yii::$app->user->isGuest) { | |||
$idProducer = GlobalParam::getCurrentProducerId(); | |||
} | |||
$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' | |||
]); | |||
$ordersByPage = 12 ; | |||
$nbPages = ceil(count($ordersArray) / $ordersByPage) ; | |||
$ordersArrayPaged = [] ; | |||
$index = 0 ; | |||
$indexPage = 0 ; | |||
foreach($ordersArray as $order) { | |||
if(!isset($ordersArrayPaged[$indexPage])) { | |||
$ordersArrayPaged[$indexPage] = [] ; | |||
} | |||
$ordersArrayPaged[$indexPage][] = $order ; | |||
$index ++ ; | |||
if($index == $ordersByPage - 1) { | |||
$index = 0 ; | |||
$indexPage ++ ; | |||
} | |||
} | |||
$distribution = Distribution::searchOne([ | |||
'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); | |||
} | |||
// catégories | |||
$categoriesArray = ProductCategory::searchAll(['id_producer' => $idProducer], ['orderby' => 'product_category.position ASC']) ; | |||
array_unshift($categoriesArray, null) ; | |||
// produits | |||
$productsArray = Product::find() | |||
->joinWith(['productDistribution' => function ($q) use ($distribution) { | |||
$q->where(['id_distribution' => $distribution->id]); | |||
}]) | |||
->where([ | |||
'id_producer' => $idProducer, | |||
]) | |||
->orderBy('order ASC') | |||
->all(); | |||
$viewPdf = 'report-grid'; | |||
$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, | |||
'categoriesArray' => $categoriesArray, | |||
'productsArray' => $productsArray, | |||
'ordersArray' => $ordersArrayPaged, | |||
'producer' => Producer::searchOne(['id' => $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; | |||
} | |||
table tr th { | |||
font-size: 13px ; | |||
} | |||
table tr td { | |||
font-size: 11px ; | |||
} | |||
table thead tr { | |||
line-height: 220px; | |||
text-align:left; | |||
} | |||
.th-user, | |||
.td-nb-products { | |||
width: 35px ; | |||
text-align: center ; | |||
} | |||
.th-user { | |||
padding: 10px ; | |||
} | |||
.category-name { | |||
font-weight: bold ; | |||
} | |||
', | |||
// 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(); | |||
} | |||
} | |||
/** | |||
* Génère un export des commandes au format CSV à destination du Google Drive | |||
* de Terre de pains. |
@@ -193,11 +193,11 @@ $this->setPageTitle('Distributions') ; | |||
<span class="info-box-text"> | |||
{{ countOrders }} Commande<span v-if="countOrders > 1">s</span><br /> | |||
<a href="#" class="btn btn-xs btn-default" disabled="disabled" v-if="countOrders == 0">Télécharger (PDF)</a> | |||
<a :href="distribution.url_report" class="btn btn-default">Télécharger (PDF)</a><br /> | |||
<a href="#" class="btn btn-xs btn-default" disabled="disabled" v-if="countOrders == 0">Télécharger (CSV)</a> | |||
<a :href="distribution.url_report+'&type=csv'" class="btn btn-default">Télécharger (CSV)</a> | |||
<a :href="distribution.url_report" class="btn btn-xs btn-default" v-if="countOrders > 0">Liste (PDF)</a> | |||
<a :href="distribution.url_report+'&type=csv'" class="btn btn-xs btn-default" v-if="countOrders > 0">Tableau (CSV)</a> | |||
<br v-if="producer.option_display_export_grid && countOrders > 0" /> | |||
<a :href="distribution.url_report_grid" class="btn btn-xs btn-default" v-if="producer.option_display_export_grid && countOrders > 0">Grille (PDF)</a> | |||
</span> | |||
</div> | |||
</div> |
@@ -0,0 +1,100 @@ | |||
<?php | |||
$html = '' ; | |||
foreach($ordersArray as $indexPage => $orders) { | |||
$html .= '<table class="">' | |||
. '<thead>' | |||
. '<tr>' | |||
. '<th></th>' ; | |||
foreach($orders as $order) { | |||
$html .= '<th class="th-user" text-rotate="90">' | |||
.'<div class="user">'.$order->getStrUser().'</div>' | |||
//.'<div class="amount">'.number_format($order->amount_with_tax, 2) .' € </div>' | |||
.'</th>' ; | |||
} | |||
$html .= '</tr>' | |||
. '<thead>' | |||
. '<tbody>'; | |||
foreach($categoriesArray as $category) { | |||
if($category) { | |||
$html .= '<tr><td class="category-name">'.$category->name.'</td><td colspan="'.(count($orders)).'"></td></tr>' ; | |||
} | |||
foreach($productsArray as $product) { | |||
if(($category && $product->id_product_category == $category->id) || (!$category && !$product->id_product_category)) { | |||
$html .= line_product($product, $orders) ; | |||
} | |||
} | |||
} | |||
$html .= '</tbody>' | |||
.'</table>' ; | |||
$html .= '<pagebreak>' ; | |||
$html .= '<table class="">' | |||
. '<thead>' | |||
. '<tr>' | |||
. '<th>Client</th>' | |||
. '<th>Contact</th>' | |||
. '<th>Commentaire</th>' | |||
. '<th>Montant</th>' | |||
. '</thead>' | |||
. '<tbody>'; | |||
foreach($orders as $order) { | |||
$html .= '<tr>' ; | |||
$strUser = $order->getStrUser() ; | |||
if($producer->option_order_reference_type == Producer::ORDER_REFERENCE_TYPE_YEARLY && $order->reference && strlen($order->reference) > 0) { | |||
$strUser .= '<br />'.$order->reference ; | |||
} | |||
$html .= '<td>'.$strUser.'</td>' ; | |||
$contactUser = '' ; | |||
if($order->user) { | |||
$contactUser .= $order->user->phone.'<br />'.$order->user->email ; | |||
} | |||
$html .= '<td>'.$contactUser.'</td>' ; | |||
$html .= '<td>'.nl2br($order->comment).'</td>' ; | |||
$html .= '<td>'.number_format($order->amount_with_tax, 2) .' € </td>' ; | |||
$html .= '</tr>' ; | |||
} | |||
$html .= '</tbody></table>' ; | |||
$html .= '<pagebreak>' ; | |||
} | |||
echo($html) ; | |||
function line_product($product, $orders) { | |||
$html = '' ; | |||
$html .= '<tr>' ; | |||
$html .= '<td>'.$product->name.'</td>' ; | |||
foreach($orders as $order) { | |||
$quantity = '' ; | |||
foreach($order->productOrder as $productOrder) { | |||
if($product->id == $productOrder->id_product) { | |||
$unit = (Product::strUnit($productOrder->unit, 'wording_short', true) == 'p.') ? '' : ' '.Product::strUnit($productOrder->unit, 'wording_short', true) ; | |||
$quantity .= $productOrder->quantity .$unit ; | |||
if($productOrder->quantity > 1) { | |||
$quantity = '<strong>'.$quantity.'</strong>' ; | |||
} | |||
} | |||
} | |||
$html .= '<td class="td-nb-products">'.$quantity.'</td>' ; | |||
} | |||
$html .= '</tr>' ; | |||
return $html ; | |||
} |
@@ -272,6 +272,12 @@ $this->addBreadcrumb($this->getTitle()) ; | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_display_export_grid') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_order_reference_type') | |||
->dropDownList([ | |||
Producer::ORDER_REFERENCE_TYPE_NONE => '--', |
@@ -969,9 +969,10 @@ class Order extends ActiveRecordCommon | |||
public function initReference() | |||
{ | |||
$producer = GlobalParam::getCurrentProducer() ; | |||
$idProducer = GlobalParam::getCurrentProducerId() ; | |||
$producer = Producer::findOne($idProducer) ; | |||
if($producer->option_order_reference_type == Producer::ORDER_REFERENCE_TYPE_YEARLY) | |||
if(!$this->reference && $producer->option_order_reference_type == Producer::ORDER_REFERENCE_TYPE_YEARLY) | |||
{ | |||
$lastOrder = Order::find()->innerJoinWith('distribution', true) | |||
->where(['>=', 'distribution.date', date('Y').'-01-01']) | |||
@@ -979,7 +980,7 @@ class Order extends ActiveRecordCommon | |||
'distribution.id_producer' => $producer->id | |||
]) | |||
->andWhere(['not', ['order.reference' => null]]) | |||
->orderBy('order.id DESC') | |||
->orderBy('order.reference DESC') | |||
->one() ; | |||
if($lastOrder && $lastOrder->reference && strlen($lastOrder->reference) > 0) { |
@@ -140,7 +140,7 @@ class Producer extends ActiveRecordCommon | |||
}], | |||
[['description', 'mentions', 'gcs', 'order_infos', 'slug', 'secret_key_payplug', 'background_color_logo', 'option_behavior_cancel_order', 'tiller_provider_token', 'tiller_restaurant_token', 'status', | |||
'document_infos_bottom', 'document_infos_quotation', 'document_infos_invoice', 'document_infos_delivery_note', 'address', 'behavior_home_point_sale_day_list', 'behavior_order_select_distribution', 'option_payment_info', 'option_order_reference_type', 'option_order_entry_point'], 'string'], | |||
[['negative_balance', 'credit', 'active', 'online_payment', 'user_manage_subscription', 'option_allow_user_gift', 'use_credit_checked_default', 'tiller', 'document_display_orders_invoice', 'document_display_orders_delivery_note', 'document_display_prices_delivery_note', 'option_email_confirm', 'option_email_confirm_producer', 'option_csv_export_all_products', 'option_csv_export_by_piece', 'option_export_display_product_reference', 'option_allow_order_guest', 'option_delivery'], 'boolean'], | |||
[['negative_balance', 'credit', 'active', 'online_payment', 'user_manage_subscription', 'option_allow_user_gift', 'use_credit_checked_default', 'tiller', 'document_display_orders_invoice', 'document_display_orders_delivery_note', 'document_display_prices_delivery_note', 'option_email_confirm', 'option_email_confirm_producer', 'option_csv_export_all_products', 'option_csv_export_by_piece', 'option_export_display_product_reference', 'option_allow_order_guest', 'option_delivery', 'option_display_export_grid'], 'boolean'], | |||
[['name', 'siret', 'logo', 'photo', 'postcode', 'city', 'code', 'type', 'credit_functioning', 'option_behavior_cancel_order', 'document_quotation_prefix', 'document_quotation_first_reference', 'document_invoice_prefix', 'document_invoice_first_reference', 'document_delivery_note_prefix', 'document_delivery_note_first_reference'], 'string', 'max' => 255], | |||
[['free_price', 'credit_limit_reminder', 'credit_limit'], 'double'], | |||
['free_price', 'compare', 'compareValue' => 0, 'operator' => '>=', 'type' => 'number', 'message' => 'Prix libre doit être supérieur ou égal à 0'], | |||
@@ -233,7 +233,8 @@ class Producer extends ActiveRecordCommon | |||
'option_export_display_product_reference' => 'Afficher la référence des produits au moment de l\'export', | |||
'option_allow_order_guest' => 'Autoriser les visiteurs à passer commande (création de compte à la fin du tunnel)', | |||
'option_order_entry_point' => 'Point d\'entrée par point de vente ou par date', | |||
'option_delivery' => 'Proposer la livraison à domicile' | |||
'option_delivery' => 'Proposer la livraison à domicile', | |||
'option_display_export_grid' => 'Afficher l\'export grille dans les distributions' | |||
]; | |||
} | |||
@@ -0,0 +1,18 @@ | |||
<?php | |||
use yii\db\Migration; | |||
use yii\db\Schema; | |||
class m210419_100507_add_option_display_export_grid extends Migration | |||
{ | |||
public function safeUp() | |||
{ | |||
$this->addColumn('producer', 'option_display_export_grid', Schema::TYPE_BOOLEAN. ' DEFAULT 0'); | |||
} | |||
public function safeDown() | |||
{ | |||
$this->dropColumn('producer', 'option_display_export_grid'); | |||
} | |||
} |
@@ -117,7 +117,7 @@ $producer = GlobalParam::getCurrentProducer() ; | |||
<div class="clr"></div> | |||
</div> | |||
<div class="content"> | |||
<div v-if="errors.length" class="alert alert-danger"> | |||
<div v-if="errors && errors.length" class="alert alert-danger"> | |||
<ul> | |||
<li v-for="error in errors"> | |||
<div v-html="error"></div> |