@@ -227,8 +227,18 @@ class DistributionController extends BackendController | |||
} | |||
$jsonProduct['quantity_max'] = $orderModule->getResolver()->getProductQuantityMax($product, $distribution); | |||
$jsonProduct['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($product, $distribution); | |||
$jsonProduct['quantity_form'] = 0; | |||
$jsonProduct['accessories'] = []; | |||
foreach($product->getProductAccessories() as $productAccessory) { | |||
$jsonProduct['accessories'][] = [ | |||
'id_accessory' => $productAccessory->getAccessory()->getId(), | |||
'quantity' => $productAccessory->getQuantity(), | |||
]; | |||
} | |||
if ($product->taxRate) { | |||
$jsonProduct['taxRate'] = $product->taxRate->getAttributes(); | |||
} | |||
@@ -530,11 +540,14 @@ class DistributionController extends BackendController | |||
$idDistribution, | |||
$idUser = false, | |||
$idPointSale = false, | |||
$idOrder = false | |||
$idOrder = false, | |||
$productOrderFormArray = [] | |||
) | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
$productOrderFormArray = json_decode($productOrderFormArray, true); | |||
$distributionModule = $this-> getDistributionModule(); | |||
$orderModule = $this->getOrderModule(); | |||
$userModule = $this->getUserModule(); | |||
@@ -565,7 +578,7 @@ class DistributionController extends BackendController | |||
if (isset($order->productOrder)) { | |||
foreach ($order->productOrder as $productOrder) { | |||
if ($productOrder->id_product == $product['id']) { | |||
if ($productOrder->id_product == $product->id) { | |||
if ($productOrder->invoice_price) { | |||
$invoicePrice = number_format($productOrder->invoice_price, 5); | |||
} else { | |||
@@ -576,16 +589,48 @@ class DistributionController extends BackendController | |||
} | |||
} | |||
$productOrderArray[$product['id']] = [ | |||
// Quantité définie dans le formulaire | |||
if(isset($productOrderFormArray[$product->id]['quantity'])) { | |||
$quantity = $productOrderFormArray[$product->id]['quantity'] / $productModule->getSolver()->getUnitCoefficient($product); | |||
} | |||
$productOrderArray[$product->id] = [ | |||
'quantity' => $quantity, | |||
'unit' => $product->unit, | |||
'prices' => $priceArray, | |||
'active' => $product->productDistribution[0]->active | |||
&& (!$pointSale || $productModule->isAvailableOnPointSale($product, $pointSale)), | |||
'invoice_price' => $invoicePrice | |||
'invoice_price' => $invoicePrice, | |||
//'quantity_remaining' => $orderModule->getResolver()->getProductQuantityRemaining($product, $distribution, $order, $quantityForm), | |||
]; | |||
} | |||
// construction de $orderOverride | |||
$orderOverride = $order; | |||
if(!$orderOverride) { | |||
$orderOverride = new Order(); | |||
} | |||
$productOrderModule = $this->getProductOrderModule(); | |||
$productOrderObjectArray = []; | |||
foreach($productOrderArray as $idProduct => $productOrder) { | |||
if($productOrder['quantity']) { | |||
$product = $productModule->getRepository()->findOneProductById($idProduct); | |||
$productOrderObject = $productOrderModule->getBuilder()->instanciateProductOrder( | |||
$orderOverride, | |||
$product, | |||
$productOrder['quantity'], | |||
0 | |||
); | |||
$productOrderObjectArray[] = $productOrderObject; | |||
} | |||
} | |||
$orderOverride->populateRelation('productOrder', $productOrderObjectArray); | |||
foreach($productOrderArray as $idProduct => $productOrder) { | |||
$product = $productModule->getRepository()->findOneProductById($idProduct); | |||
$productOrderArray[$idProduct]['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($product, $distribution, $orderOverride); | |||
} | |||
return $productOrderArray; | |||
} | |||
@@ -66,10 +66,22 @@ $this->setMetaRefresh(true); | |||
) ?> | |||
</div> | |||
<div class="col-lg-6 col-xs-6"> | |||
<?php | |||
$colorBoxTicket = 'blue'; | |||
if($countTicketsAdminOpen == 0) { | |||
$colorBoxTicket = 'green'; | |||
} | |||
elseif($countTicketsAdminUnread == 0) { | |||
$colorBoxTicket = 'blue'; | |||
} | |||
elseif($countTicketsAdminUnread > 0) { | |||
$colorBoxTicket = 'red'; | |||
} | |||
?> | |||
<?= AdminLTE::smallBox( | |||
$countTicketsAdminOpen, | |||
'Tickets', | |||
$countTicketsAdminUnread ? 'red' : 'blue', | |||
$colorBoxTicket, | |||
'comments', | |||
Yii::$app->urlManager->createUrl('support-admin/index') | |||
) ?> |
@@ -151,9 +151,9 @@ $this->setPageTitle('Distributions') ; | |||
<input type="text" class="form-control quantity-max" placeholder="∞" :data-id-product="product.id" v-model="getProductDistribution(product).quantity_max" @keyup="productQuantityMaxChange" /> | |||
<span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span> | |||
</div> | |||
<div v-if=" false && getProductDistribution(product).quantity_max != product.quantity_max"> | |||
Limitation accessoires : <br /> | |||
{{ product.quantity_max }} | |||
<div class="limit-quantity-accessories" v-if="getProductDistribution(product).quantity_max != product.quantity_max && product.quantity_max"> | |||
<span class="glyphicon glyphicon-warning-sign"></span> Limitation accessoires : | |||
<strong>{{ product.quantity_max }} {{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</strong> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -272,7 +272,7 @@ $this->setPageTitle('Distributions') ; | |||
:units="units" | |||
@close="closeModalOrderForm(true)" | |||
@ordercreatedupdated="orderCreatedUpdated" | |||
@updateproductorderprices="updateProductOrderPrices" | |||
@updateproductorders="updateProductOrders" | |||
></order-form> | |||
<div id="wrapper-nav-points-sale"> | |||
@@ -535,7 +535,7 @@ $this->setPageTitle('Distributions') ; | |||
:units="units" | |||
@close="closeModalOrderForm(false)" | |||
@ordercreatedupdated="orderCreatedUpdated" | |||
@updateproductorderprices="updateProductOrderPrices" | |||
@updateproductorders="updateProductOrders" | |||
@updateinvoiceprices="updateInvoicePrices" | |||
></order-form> | |||
@@ -745,12 +745,12 @@ $this->setPageTitle('Distributions') ; | |||
</span> | |||
</div> | |||
</td> | |||
<td class="quantity-remaining infinite" v-if="(getProductQuantityRemaining(product) === null) || order.productOrder[product.id].unit != product.unit">∞</td> | |||
<td class="quantity-remaining negative" v-else-if="getProductQuantityRemaining(product) <= 0"> | |||
{{ getProductQuantityRemaining(product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }} | |||
<span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(product) < 0"></span> | |||
<td class="quantity-remaining infinite" v-if="(getProductQuantityRemaining(order, product) === null) || order.productOrder[product.id].unit != product.unit">∞</td> | |||
<td class="quantity-remaining negative" v-else-if="getProductQuantityRemaining(order, product) <= 0"> | |||
{{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }} | |||
<span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(order, product) < 0"></span> | |||
</td> | |||
<td class="quantity-remaining has-quantity" v-else>{{ getProductQuantityRemaining(product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
<td class="quantity-remaining has-quantity" v-else>{{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
@@ -764,7 +764,7 @@ $this->setPageTitle('Distributions') ; | |||
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id">Créer</button> | |||
<div class="right"> | |||
<button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrderPrices(true)">Recharger les prix</button> | |||
<button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrders(true)">Recharger les prix</button> | |||
<button v-if="order.id" class="modal-default-button btn btn-info btn-update-prices" @click="updateInvoicePrices(true)"> | |||
Réinitialiser les prix facturés | |||
</button> |
@@ -2477,34 +2477,43 @@ termes. | |||
text-align: center; | |||
min-width: 50px; | |||
} | |||
/* line 191, ../sass/distribution/_index.scss */ | |||
/* line 188, ../sass/distribution/_index.scss */ | |||
.distribution-index #modal-products table.table td.quantity-max .limit-quantity-accessories { | |||
margin-top: 7px; | |||
font-size: 12px; | |||
} | |||
/* line 192, ../sass/distribution/_index.scss */ | |||
.distribution-index #modal-products table.table td.quantity-max .limit-quantity-accessories .quantity { | |||
font-weight: bold; | |||
} | |||
/* line 200, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders { | |||
position: relative; | |||
} | |||
/* line 196, ../sass/distribution/_index.scss */ | |||
/* line 205, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders .panel-heading .buttons .btn { | |||
position: relative; | |||
top: -19px; | |||
float: right; | |||
margin-left: 10px; | |||
} | |||
/* line 205, ../sass/distribution/_index.scss */ | |||
/* line 214, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #wrapper-nav-points-sale { | |||
margin-bottom: 10px; | |||
} | |||
/* line 208, ../sass/distribution/_index.scss */ | |||
/* line 217, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #wrapper-nav-points-sale ul#nav-points-sale { | |||
margin: 0px; | |||
padding: 0px; | |||
list-style-type: none; | |||
} | |||
/* line 213, ../sass/distribution/_index.scss */ | |||
/* line 222, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #wrapper-nav-points-sale ul#nav-points-sale li { | |||
float: left; | |||
margin-right: 10px; | |||
margin-bottom: 10px; | |||
} | |||
/* line 219, ../sass/distribution/_index.scss */ | |||
/* line 228, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #wrapper-nav-points-sale ul#nav-points-sale li a .label { | |||
background-color: white; | |||
border: solid 1px #e0e0e0; | |||
@@ -2512,7 +2521,7 @@ termes. | |||
-webkit-border-radius: 10px; | |||
border-radius: 10px; | |||
} | |||
/* line 230, ../sass/distribution/_index.scss */ | |||
/* line 239, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #buttons-top-orders { | |||
background-color: #F5F5F5; | |||
padding: 10px 20px; | |||
@@ -2522,15 +2531,15 @@ termes. | |||
border-radius: 5px; | |||
margin-bottom: 20px; | |||
} | |||
/* line 241, ../sass/distribution/_index.scss */ | |||
/* line 250, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #buttons-top-orders .right { | |||
float: right; | |||
} | |||
/* line 245, ../sass/distribution/_index.scss */ | |||
/* line 254, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders #buttons-top-orders .dropdown { | |||
display: inline-block; | |||
} | |||
/* line 250, ../sass/distribution/_index.scss */ | |||
/* line 259, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders .point-sale-totals { | |||
background-color: white; | |||
padding: 10px 20px; | |||
@@ -2540,30 +2549,30 @@ termes. | |||
border-radius: 5px; | |||
margin-bottom: 20px; | |||
} | |||
/* line 257, ../sass/distribution/_index.scss */ | |||
/* line 266, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders .point-sale-totals .title { | |||
color: gray; | |||
font-size: 13px; | |||
margin-right: 13px; | |||
text-transform: uppercase; | |||
} | |||
/* line 267, ../sass/distribution/_index.scss */ | |||
/* line 276, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user { | |||
position: relative; | |||
} | |||
/* line 270, ../sass/distribution/_index.scss */ | |||
/* line 279, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user:hover .shortcuts { | |||
display: block; | |||
} | |||
/* line 274, ../sass/distribution/_index.scss */ | |||
/* line 283, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user a { | |||
color: #333; | |||
} | |||
/* line 277, ../sass/distribution/_index.scss */ | |||
/* line 286, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user a:hover { | |||
text-decoration: underline; | |||
} | |||
/* line 282, ../sass/distribution/_index.scss */ | |||
/* line 291, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user .shortcuts { | |||
display: none; | |||
float: right; | |||
@@ -2571,19 +2580,19 @@ termes. | |||
top: 1px; | |||
right: 1px; | |||
} | |||
/* line 290, ../sass/distribution/_index.scss */ | |||
/* line 299, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-user .user-trust-alert { | |||
color: red; | |||
} | |||
/* line 295, ../sass/distribution/_index.scss */ | |||
/* line 304, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-delivery-note { | |||
position: relative; | |||
} | |||
/* line 299, ../sass/distribution/_index.scss */ | |||
/* line 308, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.tiller { | |||
width: 60px; | |||
} | |||
/* line 302, ../sass/distribution/_index.scss */ | |||
/* line 311, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.tiller label { | |||
font-size: 12px; | |||
cursor: pointer; | |||
@@ -2591,88 +2600,88 @@ termes. | |||
top: -2px; | |||
font-weight: normal; | |||
} | |||
/* line 311, ../sass/distribution/_index.scss */ | |||
/* line 320, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions { | |||
position: relative; | |||
text-align: right; | |||
} | |||
/* line 315, ../sass/distribution/_index.scss */ | |||
/* line 324, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .wrapper-button-dropdown { | |||
display: inline-block; | |||
} | |||
/* line 319, ../sass/distribution/_index.scss */ | |||
/* line 328, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .dropdown-menu { | |||
left: -70px; | |||
width: 227px; | |||
} | |||
/* line 324, ../sass/distribution/_index.scss */ | |||
/* line 333, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .modal-form-order, | |||
.distribution-index #orders table td.column-actions .modal-payment { | |||
text-align: left; | |||
} | |||
/* line 329, ../sass/distribution/_index.scss */ | |||
/* line 338, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .add-subscription { | |||
position: relative; | |||
} | |||
/* line 332, ../sass/distribution/_index.scss */ | |||
/* line 341, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .add-subscription .glyphicon-plus { | |||
position: absolute; | |||
top: 4px; | |||
right: 4px; | |||
font-size: 7px; | |||
} | |||
/* line 341, ../sass/distribution/_index.scss */ | |||
/* line 350, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-state-payment { | |||
width: 133px; | |||
} | |||
/* line 347, ../sass/distribution/_index.scss */ | |||
/* line 356, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-credit a.positive { | |||
color: green; | |||
} | |||
/* line 350, ../sass/distribution/_index.scss */ | |||
/* line 359, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-credit a.negative { | |||
color: red; | |||
} | |||
/* line 356, ../sass/distribution/_index.scss */ | |||
/* line 365, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table .state-payment-mobile { | |||
display: none; | |||
} | |||
/* line 360, ../sass/distribution/_index.scss */ | |||
/* line 369, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-payment { | |||
position: relative; | |||
} | |||
/* line 363, ../sass/distribution/_index.scss */ | |||
/* line 372, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-payment div.btn-group { | |||
width: 125px; | |||
} | |||
/* line 369, ../sass/distribution/_index.scss */ | |||
/* line 378, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view ul { | |||
list-style-type: none; | |||
margin-left: 0px; | |||
padding-left: 15px; | |||
} | |||
/* line 379, ../sass/distribution/_index.scss */ | |||
/* line 388, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view .comment { | |||
margin-top: 20px; | |||
} | |||
/* line 383, ../sass/distribution/_index.scss */ | |||
/* line 392, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view .delivery { | |||
margin-top: 20px; | |||
} | |||
/* line 392, ../sass/distribution/_index.scss */ | |||
/* line 401, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container { | |||
width: 100%; | |||
padding: 0px; | |||
} | |||
/* line 396, ../sass/distribution/_index.scss */ | |||
/* line 405, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-body { | |||
padding-right: 15px; | |||
} | |||
/* line 399, ../sass/distribution/_index.scss */ | |||
/* line 408, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-body table { | |||
margin-bottom: 150px; | |||
} | |||
/* line 404, ../sass/distribution/_index.scss */ | |||
/* line 413, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer { | |||
border-top-color: #f4f4f4; | |||
position: fixed; | |||
@@ -2684,64 +2693,64 @@ termes. | |||
text-align: center; | |||
border-top: solid 1px #e0e0e0; | |||
} | |||
/* line 416, ../sass/distribution/_index.scss */ | |||
/* line 425, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form button { | |||
float: none; | |||
} | |||
/* line 420, ../sass/distribution/_index.scss */ | |||
/* line 429, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form div.right { | |||
float: right; | |||
} | |||
/* line 427, ../sass/distribution/_index.scss */ | |||
/* line 436, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .btn-credit { | |||
float: right; | |||
} | |||
/* line 433, ../sass/distribution/_index.scss */ | |||
/* line 442, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered td { | |||
background-color: #e9e9e9; | |||
} | |||
/* line 437, ../sass/distribution/_index.scss */ | |||
/* line 446, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered input.input-quantity { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} | |||
/* line 443, ../sass/distribution/_index.scss */ | |||
/* line 452, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price { | |||
width: 150px; | |||
} | |||
/* line 446, ../sass/distribution/_index.scss */ | |||
/* line 455, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price input { | |||
text-align: center; | |||
} | |||
/* line 450, ../sass/distribution/_index.scss */ | |||
/* line 459, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price .input-group-addon { | |||
background-color: #eee; | |||
} | |||
/* line 454, ../sass/distribution/_index.scss */ | |||
/* line 463, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price .invoice-price { | |||
margin-top: 8px; | |||
} | |||
/* line 456, ../sass/distribution/_index.scss */ | |||
/* line 465, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price .invoice-price .label-invoice-price { | |||
font-size: 11px; | |||
font-weight: bold; | |||
color: gray; | |||
} | |||
/* line 464, ../sass/distribution/_index.scss */ | |||
/* line 473, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity { | |||
width: 165px; | |||
} | |||
/* line 467, ../sass/distribution/_index.scss */ | |||
/* line 476, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity input { | |||
text-align: center; | |||
color: black; | |||
} | |||
/* line 472, ../sass/distribution/_index.scss */ | |||
/* line 481, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity .form-control { | |||
border-right: 0px none; | |||
padding-right: 4px; | |||
} | |||
/* line 477, ../sass/distribution/_index.scss */ | |||
/* line 486, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity .input-group-addon { | |||
padding: 5px; | |||
padding-left: 0px; | |||
@@ -2749,35 +2758,35 @@ termes. | |||
border-left: 0px none; | |||
border-right: 0px none; | |||
} | |||
/* line 486, ../sass/distribution/_index.scss */ | |||
/* line 495, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining { | |||
text-align: right; | |||
} | |||
/* line 489, ../sass/distribution/_index.scss */ | |||
/* line 498, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.quantity-remaining, .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite { | |||
color: #00A65A; | |||
} | |||
/* line 493, ../sass/distribution/_index.scss */ | |||
/* line 502, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.negative { | |||
color: #DD4B39; | |||
} | |||
/* line 497, ../sass/distribution/_index.scss */ | |||
/* line 506, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite, .distribution-index .modal-form-order table.table-products td.quantity-remaining.empty { | |||
font-size: 18px; | |||
} | |||
/* line 504, ../sass/distribution/_index.scss */ | |||
/* line 513, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .actions-form button { | |||
margin-left: 15px; | |||
} | |||
/* line 512, ../sass/distribution/_index.scss */ | |||
/* line 521, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-icon { | |||
width: 50px; | |||
} | |||
/* line 515, ../sass/distribution/_index.scss */ | |||
/* line 524, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-icon i { | |||
font-size: 30px; | |||
} | |||
/* line 520, ../sass/distribution/_index.scss */ | |||
/* line 529, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-content { | |||
margin-left: 50px; | |||
} |
@@ -493,19 +493,19 @@ if($(selector).length) { | |||
}, | |||
updateOrderFromUrl: function () { | |||
this.initModalFormOrder(); | |||
this.updateProductOrderPrices(false); | |||
this.updateProductOrders(false); | |||
}, | |||
updateOrderClick: function (event) { | |||
var idOrder = event.currentTarget.getAttribute('data-id-order'); | |||
this.idOrderUpdate = idOrder; | |||
this.showModalFormOrderUpdate = true; | |||
this.initModalFormOrder(); | |||
this.updateProductOrderPrices(false); | |||
this.updateProductOrders(false); | |||
}, | |||
openModalFormOrderCreate: function () { | |||
this.showModalFormOrderCreate = true; | |||
this.initModalFormOrder(); | |||
this.updateProductOrderPrices(false); | |||
this.updateProductOrders(false); | |||
}, | |||
initModalFormOrder: function () { | |||
var app = this; | |||
@@ -829,8 +829,19 @@ if($(selector).length) { | |||
app.init(app.idActivePointSale); | |||
}); | |||
}, | |||
updateProductOrderPrices: function (updatePricesOnUpdateOrder) { | |||
getProductOrderArrayRequest: function (order) { | |||
var productOrderArrayRequest = {}; | |||
for (var key in order.productOrder) { | |||
productOrderArrayRequest[key] = { | |||
quantity: order.productOrder[key].quantity, | |||
unit: order.productOrder[key].unit, | |||
price: order.productOrder[key].price, | |||
invoice_price: order.productOrder[key].invoice_price | |||
}; | |||
} | |||
return JSON.stringify(productOrderArrayRequest); | |||
}, | |||
updateProductOrders: function (updatePricesOnUpdateOrder) { | |||
var app = this; | |||
app.loadingUpdateProductOrder = true; | |||
var order = null; | |||
@@ -853,7 +864,8 @@ if($(selector).length) { | |||
idDistribution: app.distribution.id, | |||
idUser: order.id_user, | |||
idPointSale: order.id_point_sale, | |||
idOrder: order.id | |||
idOrder: order.id, | |||
productOrderFormArray: app.getProductOrderArrayRequest(order) | |||
} | |||
}) | |||
.then(function (response) { | |||
@@ -861,6 +873,7 @@ if($(selector).length) { | |||
for (idProduct in response.data) { | |||
if (app.showModalFormOrderCreate) { | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'quantity_remaining', response.data[idProduct].quantity_remaining); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'active', response.data[idProduct].active); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity, false)); | |||
@@ -870,6 +883,7 @@ if($(selector).length) { | |||
if (app.showModalFormOrderUpdate && app.idOrderUpdate) { | |||
for (keyOrderUpdate in app.ordersUpdate) { | |||
if (order.id == app.idOrderUpdate) { | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'quantity_remaining', response.data[idProduct].quantity_remaining); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'active', response.data[idProduct].active); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'invoice_price', response.data[idProduct].invoice_price); | |||
@@ -916,7 +930,7 @@ if($(selector).length) { | |||
} | |||
}) | |||
.then(function (response) { | |||
app.updateProductOrderPrices(false); | |||
app.updateProductOrders(false); | |||
appAlerts.alert('info', 'Prix facturés réinitialisés.'); | |||
}); | |||
} | |||
@@ -1157,6 +1171,8 @@ if($(selector).length) { | |||
Vue.set(this.order.productOrder[id_product], 'price', app.getBestProductPrice(this.order, id_product, theQuantity, false)); | |||
Vue.set(this.order.productOrder[id_product], 'price_with_tax', app.getBestProductPrice(this.order, id_product, theQuantity, true)); | |||
} | |||
this.updateProductOrders(false); | |||
}, | |||
getProduct: function (idProduct) { | |||
for (var i = 0; i < this.products.length; i++) { | |||
@@ -1215,14 +1231,14 @@ if($(selector).length) { | |||
if (app.idActivePointSale == 0) { | |||
app.order.id_point_sale = response.data.id_favorite_point_sale; | |||
} | |||
app.updateProductOrderPrices(true); | |||
app.updateProductOrders(true); | |||
}); | |||
}, | |||
pointSaleChange: function (event) { | |||
this.updateProductOrderPrices(true); | |||
this.updateProductOrders(true); | |||
}, | |||
updateProductOrderPrices: function (updateProductOrderPrices) { | |||
this.$emit('updateproductorderprices', updateProductOrderPrices); | |||
updateProductOrders: function (updateProductOrders) { | |||
this.$emit('updateproductorders', updateProductOrders); | |||
}, | |||
updateInvoicePrices: function () { | |||
this.$emit('updateinvoiceprices'); | |||
@@ -1247,14 +1263,8 @@ if($(selector).length) { | |||
} | |||
return productQuantityOrder; | |||
}, | |||
getProductQuantityRemaining: function (product) { | |||
var productQuantityRemaining = null; | |||
var productQuantityMax = this.getProductQuantityMax(product); | |||
var productQuantityOrder = this.getProductQuantityOrder(product); | |||
if(productQuantityMax) { | |||
productQuantityRemaining = productQuantityMax - productQuantityOrder; | |||
} | |||
getProductQuantityRemaining: function (order, product) { | |||
var productQuantityRemaining = order.productOrder[product.id].quantity_remaining; | |||
// format | |||
if (productQuantityRemaining && product.unit != 'piece') { |
@@ -184,6 +184,15 @@ termes. | |||
text-align: center; | |||
min-width: 50px; | |||
} | |||
.limit-quantity-accessories { | |||
margin-top: 7px; | |||
font-size: 12px; | |||
.quantity { | |||
font-weight: bold; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -10,7 +10,7 @@ version( | |||
"[Administration] Utilisateur > Créer (en arrivant de la création d'une commande) : retour automatique à la création de la commande", | |||
], | |||
[ | |||
"[Administration] Tableau de bord : corectif affichage des commandes modifiées issues des abonnements" | |||
"[Administration] Tableau de bord : correctif affichage des commandes modifiées issues des abonnements" | |||
] | |||
], | |||
[ |
@@ -9,27 +9,62 @@ use domain\Feature\Feature\Feature; | |||
use domain\Feature\Feature\FeatureChecker; | |||
use domain\Product\Accessory\Accessory; | |||
use domain\Product\Product\Product; | |||
use domain\Product\Product\ProductSolver; | |||
use yii\base\ErrorException; | |||
class OrderResolver extends AbstractResolver | |||
{ | |||
protected ProductSolver $productSolver; | |||
protected OrderSolver $orderSolver; | |||
protected OrderRepository $orderRepository; | |||
protected ProductDistributionRepository $productDistributionRepository; | |||
protected FeatureChecker $featureChecker; | |||
protected array $ordersArrayCachedByDistribution = []; | |||
public function loadDependencies(): void | |||
{ | |||
$this->productSolver = $this->loadService(ProductSolver::class); | |||
$this->orderSolver = $this->loadService(OrderSolver::class); | |||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | |||
$this->featureChecker = $this->loadService(FeatureChecker::class); | |||
} | |||
public function getProductQuantityByDistribution(Product $product, Distribution $distribution): float | |||
public function getProductQuantityByDistribution( | |||
Product $product, | |||
Distribution $distribution, | |||
bool $inNumberOfPieces = false, | |||
Order $orderOverride = null | |||
): float | |||
{ | |||
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution); | |||
return $this->orderSolver->getProductQuantity($product, $ordersArray); | |||
if(!isset($this->ordersArrayCachedByDistribution[$distribution->id])) { | |||
$this->ordersArrayCachedByDistribution[$distribution->id] = $this->orderRepository->findOrdersByDistribution($distribution); | |||
} | |||
$ordersArray = $this->ordersArrayCachedByDistribution[$distribution->id]; | |||
// @TODO : sortir cette logique de la méthode (refactoring) | |||
if($orderOverride) { | |||
$override = false; | |||
foreach($ordersArray as $key => $order) { | |||
if($order->id == $orderOverride->id) { | |||
$ordersArray[$key] = $orderOverride; | |||
$override = true; | |||
} | |||
} | |||
if(!$override) { | |||
$ordersArray[] = $orderOverride; | |||
} | |||
} | |||
$productQuantity = $this->orderSolver->getProductQuantity($product, $ordersArray); | |||
if($inNumberOfPieces) { | |||
$productQuantity = $this->productSolver->getNumberOfPieces($productQuantity, $product); | |||
} | |||
return $productQuantity; | |||
} | |||
public function getSmallestQuantityAccessory(Product $product): ?int | |||
@@ -48,7 +83,6 @@ class OrderResolver extends AbstractResolver | |||
public function getProductQuantityMax(Product $product, Distribution $distribution): ?float | |||
{ | |||
$productDistribution = $this->productDistributionRepository->findOneProductDistribution($distribution, $product); | |||
// @TODO : gérer via une exception | |||
if(!$productDistribution) { | |||
return null; | |||
} | |||
@@ -58,25 +92,40 @@ class OrderResolver extends AbstractResolver | |||
if($this->featureChecker->isEnabled(Feature::ALIAS_PRODUCT_ACCESSORY)) { | |||
$smallestQuantityAccessory = $this->getSmallestQuantityAccessory($product); | |||
if (!is_null($smallestQuantityAccessory)) { | |||
$quantityMax = is_null($quantityMax) ? $smallestQuantityAccessory : min($quantityMax, $smallestQuantityAccessory); | |||
$smallestQuantityAccessory = $this->productSolver->getWeightOrNumberOfPieces($smallestQuantityAccessory, $product); | |||
$quantityMax = is_null($quantityMax) ? $smallestQuantityAccessory | |||
: min($quantityMax, $smallestQuantityAccessory); | |||
} | |||
} | |||
return $quantityMax; | |||
} | |||
public function getQuantityOfAccessoryAvailableInDistribution(Accessory $accessory, Distribution $distribution): int | |||
public function getQuantityOfAccessoryAvailableInDistribution( | |||
Accessory $accessory, | |||
Distribution $distribution, | |||
Order $orderOverride = null | |||
): int | |||
{ | |||
$quantityOfAccessoryUsed = 0; | |||
foreach($accessory->getProductAccessories() as $productAccessory) { | |||
$quantityOfAccessoryUsed += $this->getProductQuantityByDistribution($productAccessory->getProduct(), $distribution); | |||
$quantityOfAccessoryUsed += $this->getProductQuantityByDistribution( | |||
$productAccessory->getProduct(), | |||
$distribution, | |||
true, | |||
$orderOverride | |||
); | |||
} | |||
return $accessory->getQuantity() - $quantityOfAccessoryUsed; | |||
} | |||
public function getSmallestQuantityAccessoryAvailable(Product $product, Distribution $distribution): ?int | |||
public function getSmallestQuantityAccessoryAvailable( | |||
Product $product, | |||
Distribution $distribution, | |||
Order $orderOverride = null | |||
): ?int | |||
{ | |||
$smallestQuantity = null; | |||
@@ -84,7 +133,8 @@ class OrderResolver extends AbstractResolver | |||
foreach ($product->getProductAccessories() as $productAccessory) { | |||
$quantityAccessoryAvailableInDistribution = $this->getQuantityOfAccessoryAvailableInDistribution( | |||
$productAccessory->getAccessory(), | |||
$distribution | |||
$distribution, | |||
$orderOverride | |||
); | |||
$smallestQuantity = is_null($smallestQuantity) ? $quantityAccessoryAvailableInDistribution | |||
: min($smallestQuantity, $quantityAccessoryAvailableInDistribution); | |||
@@ -94,21 +144,35 @@ class OrderResolver extends AbstractResolver | |||
return $smallestQuantity; | |||
} | |||
public function getProductQuantityRemaining(Product $product, Distribution $distribution): ?float | |||
public function getProductQuantityRemaining( | |||
Product $product, | |||
Distribution $distribution, | |||
Order $orderOverride = null | |||
): ?float | |||
{ | |||
$productDistribution = $this->productDistributionRepository->findOneProductDistribution($distribution, $product); | |||
if(!$productDistribution) { | |||
return null; | |||
} | |||
$quantityOrder = $this->getProductQuantityByDistribution($product, $distribution); | |||
$quantityOrder = $this->getProductQuantityByDistribution( | |||
$product, | |||
$distribution, | |||
false, | |||
$orderOverride | |||
); | |||
$quantityRemaining = is_null($productDistribution->quantity_max) ? null | |||
: ($productDistribution->quantity_max - $quantityOrder); | |||
// Limitation par nombre d'accessoires disponibles | |||
if($this->featureChecker->isEnabled(Feature::ALIAS_PRODUCT_ACCESSORY)) { | |||
$smallestQuantityAccessoryAvailable = $this->getSmallestQuantityAccessoryAvailable($product, $distribution); | |||
$smallestQuantityAccessoryAvailable = $this->getSmallestQuantityAccessoryAvailable( | |||
$product, | |||
$distribution, | |||
$orderOverride | |||
); | |||
if (!is_null($smallestQuantityAccessoryAvailable)) { | |||
$smallestQuantityAccessoryAvailable = $this->productSolver->getWeightOrNumberOfPieces($smallestQuantityAccessoryAvailable, $product); | |||
$quantityRemaining = is_null($quantityRemaining) ? $smallestQuantityAccessoryAvailable | |||
: min($quantityRemaining, $smallestQuantityAccessoryAvailable); | |||
} |
@@ -25,6 +25,25 @@ class ProductSolver extends AbstractService implements SolverInterface | |||
$this->pointSaleSolver = $this->loadService(PointSaleSolver::class); | |||
} | |||
public function getWeightOrNumberOfPieces(float $quantity, Product $product): float | |||
{ | |||
// Poids total | |||
if($product->unit != 'piece') { | |||
$quantity = ($quantity * $product->weight) / $this->getUnitCoefficient($product); | |||
} | |||
return $quantity; | |||
} | |||
public function getNumberOfPieces(float $quantity, Product $product): int | |||
{ | |||
if($product->unit != 'piece') { | |||
$quantity = ($quantity * $this->getUnitCoefficient($product)) / $product->weight; | |||
} | |||
return $quantity; | |||
} | |||
public function getUnitCoefficient(Product $product): int | |||
{ | |||
return $this->unitSolver->getUnitCoefficient($product->unit); |
@@ -984,15 +984,16 @@ class OrderController extends ProducerBaseController | |||
$product['photo'] = Image::getThumbnailSmall($product['photo']); | |||
} | |||
$product['quantity_max'] = (isset($product['productDistribution']) && isset($product['productDistribution'][0])) ? $product['productDistribution'][0]['quantity_max'] : null; | |||
$quantityOrder = $orderModule->getProductQuantity($productObject, $ordersArray); | |||
//$product['quantity_max'] = (isset($product['productDistribution']) && isset($product['productDistribution'][0])) ? $product['productDistribution'][0]['quantity_max'] : null; | |||
$product['quantity_max'] = $orderModule->getResolver()->getProductQuantityMax($productObject, $distribution); | |||
$quantityOrder = $orderModule->getSolver()->getProductQuantity($productObject, $ordersArray); | |||
$product['quantity_ordered'] = $quantityOrder; | |||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder; | |||
$product['wording_unit'] = $unitModule->getSolver()->strUnit($product['unit'], UnitDefinition::WORDING_UNIT, true); | |||
$product['wording_unit_ref'] = $unitModule->getSolver()->strUnit($product['unit'], UnitDefinition::WORDING_SHORT, true); | |||
if ($order) { | |||
$quantityOrderUser = $orderModule->getProductQuantity($productObject, [$order], true); | |||
$quantityOrderUser = $orderModule->getSolver()->getProductQuantity($productObject, [$order], true); | |||
$product['quantity_ordered'] = $quantityOrder; | |||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder + $quantityOrderUser; | |||
$product['quantity_form'] = $quantityOrderUser * $coefficient_unit; |
@@ -1,341 +0,0 @@ | |||
<?php | |||
/** | |||
Copyright Souke (2018) | |||
contact@souke.fr | |||
Ce logiciel est un programme informatique servant à aider les producteurs | |||
à distribuer leur production en circuits courts. | |||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||
sur le site "http://www.cecill.info". | |||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||
de modification et de redistribution accordés par cette licence, il n'est | |||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||
titulaire des droits patrimoniaux et les concédants successifs. | |||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||
associés au chargement, à l'utilisation, à la modification et/ou au | |||
développement et à la reproduction du logiciel par l'utilisateur étant | |||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||
avertis possédant des connaissances informatiques approfondies. Les | |||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||
termes. | |||
*/ | |||
use common\helpers\GlobalParam; | |||
use common\helpers\Price; | |||
use domain\Order\Order\OrderModule; | |||
use domain\Producer\Producer\Producer; | |||
use domain\Producer\Producer\ProducerModule; | |||
use yii\helpers\Html; | |||
use yii\widgets\ActiveForm; | |||
$producerModule = ProducerModule::getInstance(); | |||
$orderModule = OrderModule::getInstance(); | |||
?> | |||
<div class="order-form"> | |||
<?php | |||
$form = ActiveForm::begin([ | |||
'enableClientScript' => false | |||
]); | |||
?> | |||
<?php | |||
if(count($distributionDaysArray) <= 1) : | |||
?> | |||
<div class="alert alert-warning">Aucun jour de production n'a été programmé par le producteur.</div> | |||
<?php endif; ?> | |||
<?php if($idProducer && count($distributionDaysArray) > 1): ?> | |||
<div id="step-date" class="col-md-6"> | |||
<?= $form->field($model, 'id_distribution')->label('')->hiddenInput(); ?> | |||
<?php if (isset($model->id)): ?> | |||
<div class="date-order"><span><?php echo date('d/m/Y', strtotime($distribution->date)); ?></span></div> | |||
<?= Html::hiddenInput('id_order', $model->id,['id'=>'id-order']); ?> | |||
<?= Html::hiddenInput('paid_amount', $orderModule->getOrderAmount($model, Order::AMOUNT_PAID),['id'=>'paid-amount']); ?> | |||
<?php endif; ?> | |||
<div id="datepicker-distribution" <?php if (isset($model->id)): ?>style="display:none"<?php endif; ?>> | |||
</div> | |||
<?php if (!isset($model->id)): ?> | |||
<br /> | |||
<?php endif; ?> | |||
<div id="dates" style="display:none;"> | |||
<?php | |||
foreach ($distributionDaysArray as $idDistribution => $day) { | |||
if ($day != '--') { | |||
echo '<div><span class="date">' . $day . '</span><span class="id_distribution">' . $idDistribution. '</span></div>'; | |||
} | |||
} | |||
?> | |||
</div> | |||
<div class="clr"></div> | |||
<div id="orders-in-progress" style="display:none;"> | |||
<?php foreach ($ordersArray as $order): ?> | |||
<?php echo '<div class="order" data-iddistribution="' . $order->id_distribution. '" data-id="' . $order->id . '" data-href="' . \Yii::$app->urlManager->createUrl(['order/update', 'id' => $order->id, 'id_producer' => $order->distribution->id_producer]) . '"></div>'; ?> | |||
<?php endforeach; ?> | |||
</div> | |||
<div id="has-order-in-progress" style="display:none;" class="alert alert-danger">Vous avez déjà une commande en cours pour cette date. <a href="#">Cliquez ici</a> pour la modifier.</div> | |||
</div> | |||
<div class="col-md-6"> | |||
<?php if(strlen($producer->order_infos)): ?> | |||
<div id="order-infos"> | |||
<?= nl2br(Html::encode($producer->order_infos)) ?> | |||
</div> | |||
<?php endif; ?> | |||
</div> | |||
<div class="clr"></div> | |||
<div id="block-points-sale"> | |||
<h3 id="step-point-sale"><span><?= $producerModule->getPointSaleWording($producer); ?></span></h3> | |||
<?= | |||
$form->field($model, 'id_point_sale') | |||
->label('') | |||
->hiddenInput(); | |||
?> | |||
<input type="hidden" id="livraison" value="<?php if (!is_null($distribution) && $distribution->delivery): ?>1<?php else: ?>0<?php endif; ?>" /> | |||
<ul id="points-sale" class="blocks"> | |||
<?php | |||
foreach ($pointsSaleArray as $pointSale) { | |||
$comment = '' ; | |||
if(isset($pointSale->userPointSale) && is_array($pointSale->userPointSale) && count($pointSale->userPointSale)) | |||
{ | |||
foreach($pointSale->userPointSale as $userPointSale) | |||
{ | |||
if($userPointSale->id_user == GlobalParam::getCurrentUserId() && strlen($userPointSale->comment)) | |||
{ | |||
$comment = '<div class="comment"><span>'.Html::encode($userPointSale->comment).'</span></div>' ; | |||
} | |||
} | |||
} | |||
$htmlCode = '' ; | |||
$dataCode = '0' ; | |||
$code = '' ; | |||
if(strlen($pointSale->code)) | |||
{ | |||
if(!isset($model->id_point_sale) || $model->id_point_sale != $pointSale->id) | |||
{ | |||
$htmlCode .= '<span class="glyphicon glyphicon-lock"></span> ' ; | |||
$dataCode = '1' ; | |||
} | |||
else { | |||
$code = $pointSale->code ; | |||
} | |||
} | |||
echo '<li class="block point-sale point-sale-' . $pointSale->id . '" data-code="'.$dataCode.'" data-credit="'.(int) $pointSale->payment_method_credit.'"><div class="contenu">' . | |||
'<span style="display:none;" class="id">' . $pointSale->id . '</span>' . | |||
'<div class="name">' .$htmlCode. Html::encode($pointSale->name) . '</div>' . | |||
'<div class="address">à ' . Html::encode($pointSale->locality) . '</div>' . | |||
$comment . | |||
'<input type="hidden" name="code_point_sale_'.$pointSale->id.'" value="'.$code.'" />'. | |||
'</div></li>'; | |||
} | |||
?> | |||
</ul> | |||
<div class="clr"></div> | |||
<div id="step-infos-point-sale"> | |||
<?php | |||
foreach ($pointsSaleArray as $pointSale) { | |||
echo '<div class="alert alert-warning infos-point-sale infos-point-sale-'.$pointSale->id.'"><h4>Infos : <span>'.Html::encode($pointSale->name).'</span></h4>' . | |||
'<div class="jour jour-1">' . $pointSale->getStrInfos('monday') . '</div>' . | |||
'<div class="jour jour-2">' . $pointSale->getStrInfos('tuesday') . '</div>' . | |||
'<div class="jour jour-3">' . $pointSale->getStrInfos('wednesday') . '</div>' . | |||
'<div class="jour jour-4">' . $pointSale->getStrInfos('thursday') . '</div>' . | |||
'<div class="jour jour-5">' . $pointSale->getStrInfos('friday') . '</div>' . | |||
'<div class="jour jour-6">' . $pointSale->getStrInfos('saturday') . '</div>' . | |||
'<div class="jour jour-0">' . $pointSale->getStrInfos('sunday') . '</div>' . | |||
'</div>' ; | |||
} | |||
?> | |||
</div> | |||
<div class="clr"></div> | |||
</div> | |||
<div id="products"> | |||
<h3 id="step-products"><span>Produits</span></h3> | |||
<?php // erreur ?> | |||
<?php if (Yii::$app->session->getFlash('error')): ?> | |||
<div class="alert alert-danger"><div class="icon"></div><?= \Yii::$app->session->getFlash('error'); ?></div> | |||
<?php endif; ?> | |||
<div id=""> | |||
<div class="alert alert-warning unavailable">Produit indisponible pour ce point de vente</div> | |||
<table class="table table-bordered" id="table-products"> | |||
<thead> | |||
<tr> | |||
<th class="th-photo">Photo</th> | |||
<th class="product">Produit</th> | |||
<th class="price-unit">Prix unitaire</th> | |||
<th class="column-quantity">Quantité</th> | |||
<th class="total">Total</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<?php foreach ($productsArray as $product): ?> | |||
<?php | |||
$quantity = 0; | |||
if (isset($selectedProducts[$product->id])) { | |||
$quantity = $selectedProducts[$product->id]; | |||
} | |||
?> | |||
<tr class="product-<?php echo $product->id; ?>" data-no-limit="<?php if(!$product->quantity_max): ?>1<?php else: ?>0<?php endif; ?>" data-quantity-max="<?= $quantity ?>" <?php if (count($availableProducts) && !$availableProducts[$product->id]['active']): ?>style="display:none;"<?php endif; ?>> | |||
<td class="td-photo"> | |||
<?php if (strlen($product->photo) && file_exists(dirname(__FILE__).'/../../web/uploads/' . $product->photo)): ?><a href="<?= \Yii::$app->urlManager->getBaseUrl() . '/uploads/' . $product->photo ?>" data-lightbox="product-<?php echo $product->id; ?>"><img class="photo img-rounded" src="<?= \Yii::$app->urlManager->getBaseUrl() . '/uploads/' . $product->photo ?>" alt="Photo <?= Html::encode($product->name); ?>" /></a><?php endif; ?> | |||
</td> | |||
<td class="produit"> | |||
<span class="name"><?= Html::encode($product->name); ?></span> - <span class="description"><?= Html::encode($product->getDescription()); ?></span><br /> | |||
<span class="recipe"><?= Html::encode($product->recipe); ?></span> | |||
</td> | |||
<td class="price-unit"> | |||
<span class="price"><?= Price::format($product->price); ?></span> € | |||
</td> | |||
<td class="column-quantity"> | |||
<div class="input-group" <?php if (isset($availableProducts[$product->id]) && $availableProducts[$product->id]['quantity_remaining'] == 0 && $quantity == 0): ?>style="display:none;"<?php endif; ?>> | |||
<span class="input-group-btn"> | |||
<button type="button" class="btn btn-default move-quantity minus">-</button> | |||
</span> | |||
<input type="text" value="<?php if (isset($selectedProducts[$product->id])): echo $selectedProducts[$product->id]; | |||
else: ?>0<?php endif; ?>" readonly name="Product[product_<?php echo $product->id; ?>]" class="quantity form-control"> | |||
<span class="input-group-btn"> | |||
<button type="button" class="btn btn-default move-quantity plus">+</button> | |||
</span> | |||
</div> | |||
<div class="quantity-remaining">Reste <span class="nb"><?php if (isset($availableProducts[$product->id])): echo $availableProducts[$product->id]['quantity_remaining'] + $quantity; | |||
endif; ?></span> <?php echo Html::encode(strtolower($product->name)); ?>(s) | |||
</div> | |||
<div class="unavailable">Épuisé</div> | |||
</td> | |||
<td class="total"><strong></strong></td> | |||
</tr> | |||
<?php endforeach; ?> | |||
</tbody> | |||
<tfoot> | |||
<tr> | |||
<td></td> | |||
<td></td> | |||
<td></td> | |||
<td id="total-order"><strong></strong></td> | |||
</tr> | |||
</tfoot> | |||
</table> | |||
</div> | |||
</div> | |||
<?php if($idProducer): ?> | |||
<?php | |||
$producer = Producer::findOne($idProducer); | |||
?> | |||
<div id="bar-fixed" class="<?php if($producer->credit): ?>credit<?php else: ?>no-credit<?php endif; ?>"> | |||
<div class="container"> | |||
<?php if (isset($model->id) && $orderModule->getSolver()->isOrderStatusValid($model)): ?> | |||
<a href="<?php echo \Yii::$app->urlManager->createUrl(['order/cancel', 'id' => $model->id]); ?>" class="btn btn-danger cancel-order">Annuler ma commande</a> | |||
<?php endif; ?> | |||
<span id="total-order-bottom"><span></span> €</span> | |||
<?= Html::submitButton('<span class="glyphicon glyphicon-comment"></span> Commentaire', ['class' => 'btn btn-default btn-comment', 'data-placement' => 'top', 'data-toggle' => 'tooltip', 'data-original-title' => 'Ajouter un commentaire']) ?> | |||
<?php | |||
if($producer->credit): | |||
$linkCredit = '<a class="info-credit" href="'.Yii::$app->urlManager->createUrl(['site/credit']) .'" data-toggle="tooltip" data-placement="bottom" title="En savoir plus sur le Crédit"><span class="glyphicon glyphicon-info-sign"></span></a>' ; ; | |||
?> | |||
<div id="checkbox-credit" > | |||
<?php if($credit || $orderModule->getAmount($order, Order::AMOUNT_PAID)): ?> | |||
<?= Html::checkbox('credit', true, ['label' => 'Utiliser mon Crédit <span class="the-credit" data-toggle="tooltip" data-placement="top" data-original-title="Vous avez actuellement '.number_format($credit,2).' € sur votre compte Crédit">'.number_format($credit,2).' €</span><br /><span class="info"></span>']) ?> | |||
<?= Html::hiddenInput('amount_credit', $credit, ['id' => 'amount-credit']) ?> | |||
<?= Html::hiddenInput('str_amount_credit', number_format($credit,2).' €', ['id' => 'str-amount-credit']) ?> | |||
<?php else: ?> | |||
<div id="info-credit-empty"> | |||
Votre compte Crédit est vide <?= $linkCredit ?> | |||
</div> | |||
<?php endif; ?> | |||
<div id="credit-disabled">Le Crédit est désactivé<br /> pour ce point de vente <?= $linkCredit ?></div> | |||
</div> | |||
<div class="clr"></div> | |||
<?php endif; ?> | |||
<?= $form->field($model, 'comment')->textarea(['rows' => 3, 'placeholder' => 'Un commentaire ?'])->label(''); ?> | |||
<div id="block-confirm-order"> | |||
<?php if($model->date_delete): $strButtonConfirmOrder = 'Réactiver ma commande' ; else: $strButtonConfirmOrder = 'Valider ma commande' ; endif; ?> | |||
<?= Html::submitButton('<span class="glyphicon glyphicon-ok"></span> '.$strButtonConfirmOrder, ['class' => 'btn btn-primary confirm-order']) ?> | |||
</div> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<?php | |||
// id_etablissement | |||
endif; ?> | |||
<?php ActiveForm::end(); ?> | |||
<!-- modal code point de vente --> | |||
<div class="modal fade" id="modal-code" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |||
<div class="modal-dialog modal-lg" role="document"> | |||
<div class="modal-content"> | |||
<div class="modal-header"> | |||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |||
<h4 class="modal-title" id="myModalLabel">Code d'accès</h4> | |||
</div> | |||
<div class="modal-body"> | |||
<div class="alert alert-warning"> | |||
Ce point de vente nécessite un code d'accès. | |||
</div> | |||
<form action="index.php?r=order/validate-code-point-sale" method="post"> | |||
<input type="hidden" value="" name="idPointSale" id="id-point-sale" /> | |||
<div class="form-group field-code required"> | |||
<label class="control-label" for="code">Code d'accès :</label> | |||
<input type="password" class="form-control" id="code" name="code" /> | |||
<p class="help-block help-block-error" style="display:none;">Code incorrect</p> | |||
</div> | |||
<div class="form-group"> | |||
<button type="submit" class="btn btn-primary">Valider</button> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div><!-- commande-form --> |
@@ -1,59 +0,0 @@ | |||
<?php | |||
/** | |||
Copyright Souke (2018) | |||
contact@souke.fr | |||
Ce logiciel est un programme informatique servant à aider les producteurs | |||
à distribuer leur production en circuits courts. | |||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||
sur le site "http://www.cecill.info". | |||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||
de modification et de redistribution accordés par cette licence, il n'est | |||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||
titulaire des droits patrimoniaux et les concédants successifs. | |||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||
associés au chargement, à l'utilisation, à la modification et/ou au | |||
développement et à la reproduction du logiciel par l'utilisateur étant | |||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||
avertis possédant des connaissances informatiques approfondies. Les | |||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||
termes. | |||
*/ | |||
$this->setTitle('Passer une commande') ; | |||
?> | |||
<div class="order-create"> | |||
<?= $this->render('_form', [ | |||
'model' => $model, | |||
'pointsSaleArray' => $pointsSaleArray, | |||
'distributionDaysArray' => $distributionDaysArray, | |||
'productsArray' => $productsArray, | |||
'selectedProducts' => $selectedProducts, | |||
'availableProducts' => $availableProducts, | |||
'distribution' => $distribution, | |||
'ordersArray' => $ordersArray, | |||
'producersArray' => $producersArray, | |||
'idProducer' => $idProducer, | |||
'producer' => $producer, | |||
'credit' => $credit | |||
]) ?> | |||
</div> |
@@ -412,7 +412,7 @@ $this->setMeta('description', $producerModule->getSeoGenerator()->generateMetaDe | |||
<button class="btn btn-secondary btn-plus" | |||
type="button" | |||
@click="productQuantityClick(product, product.unit == 'piece' ? 1 : parseFloat(product.step))" | |||
:disabled="product.quantity_form == product.quantity_remaining && product.quantity_max > 0"> | |||
:disabled="(product.quantity_form / product.coefficient_unit) == product.quantity_remaining && product.quantity_max > 0"> | |||
<i class="bi bi-plus-lg"></i></button> | |||
</span> | |||
</div> |
@@ -1,66 +0,0 @@ | |||
<?php | |||
/** | |||
Copyright Souke (2018) | |||
contact@souke.fr | |||
Ce logiciel est un programme informatique servant à aider les producteurs | |||
à distribuer leur production en circuits courts. | |||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||
sur le site "http://www.cecill.info". | |||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||
de modification et de redistribution accordés par cette licence, il n'est | |||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||
titulaire des droits patrimoniaux et les concédants successifs. | |||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||
associés au chargement, à l'utilisation, à la modification et/ou au | |||
développement et à la reproduction du logiciel par l'utilisateur étant | |||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||
avertis possédant des connaissances informatiques approfondies. Les | |||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||
termes. | |||
*/ | |||
$this->setTitle('Modifier une commande') ; | |||
?> | |||
<div class="order-update"> | |||
<?php if($orderNotfound): ?> | |||
<div class="alert alert-danger">Cette commande est introuvable</div><br /> | |||
<a class="btn btn-default" href="<?php echo \Yii::$app->urlManager->createUrl(['order/index']); ?>">Retour</a> | |||
<?php else: ?> | |||
<?= $this->render('_form', [ | |||
'model' => $model, | |||
'pointsSaleArray' => $pointsSaleArray, | |||
'distributionDaysArray' => $distributionDaysArray, | |||
'productsArray' => $productsArray, | |||
'selectedProducts' => $selectedProducts, | |||
'availableProducts' => $availableProducts, | |||
'distribution' => $distribution, | |||
'ordersArray' => $ordersArray, | |||
'producersArray' => $producersArray, | |||
'idProducer' => $idProducer, | |||
'producer' => $producer, | |||
'credit' => $credit | |||
]) ?> | |||
<?php endif; ?> | |||
</div> |