@@ -593,8 +593,8 @@ class OrderController extends ProducerBaseController | |||
$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')), ], | |||
'conditions' => ['date > :date_today'], | |||
'params' => [':date_today' => date('Y-m-d')], | |||
]) ; | |||
$json['distributions'] = $distributionsArray ; | |||
@@ -627,6 +627,35 @@ class OrderController extends ProducerBaseController | |||
} | |||
$json['points_sale'] = $pointsSaleArray; | |||
// Commandes | |||
$ordersArray = Order::searchAll([ | |||
'distribution.date' => $date, | |||
]); | |||
// Produits | |||
$productsArray = Product::find() | |||
->where([ | |||
'id_producer' => $this->getProducer()->id, | |||
]) | |||
->joinWith(['productDistribution' => function($query) use($distribution) { | |||
$query->andOnCondition('product_distribution.id_distribution = '.$distribution->id) ; | |||
}]) | |||
->orderBy('product_distribution.active DESC, order ASC') | |||
->asArray() | |||
->all(); | |||
$indexProduct = 0 ; | |||
foreach($productsArray as &$product) { | |||
$quantityOrder = Order::getProductQuantity($product['id'], $ordersArray) ; | |||
$product['quantity_ordered'] = $quantityOrder ; | |||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder ; | |||
if($product['quantity_remaining'] < 0) $product['quantity_remaining'] = 0 ; | |||
$product['quantity_form'] = 0 ; | |||
$product['index'] = $indexProduct ++ ; | |||
} | |||
$json['products'] = $productsArray; | |||
} | |||
return $json ; |
@@ -43,7 +43,7 @@ $this->setTitle('Commander') ; | |||
?> | |||
<div id="app-order-order"> | |||
<div class="col-md-8"> | |||
<div class="col-md-9"> | |||
<div id="steps"> | |||
<ul> | |||
<li id="step-date" :class="'col-md-3 '+((step == 'date') ? 'active' : '')"> | |||
@@ -57,7 +57,8 @@ $this->setTitle('Commander') ; | |||
<span class="glyphicon glyphicon-chevron-right"></span> | |||
</li> | |||
<li id="step-products" :class="'col-md-3 '+((step == 'products') ? 'active' : '')"> | |||
Produits | |||
<a v-if="oneProductOrdered()" @click="changeStep('products')" href="javascript:void(0);">Produits</a> | |||
<span v-else>Produits</span> | |||
<span class="glyphicon glyphicon-chevron-right"></span> | |||
</li> | |||
<li id="step-payment" :class="'col-md-3 '+((step == 'payment') ? 'active' : '')"> | |||
@@ -113,14 +114,68 @@ $this->setTitle('Commander') ; | |||
</div> | |||
</div> | |||
<div id="content-step-products" v-if="step == 'products'"> | |||
Produits | |||
<div v-if="products.length"> | |||
<table id="products" class="table table-bordered" > | |||
<thead> | |||
<tr> | |||
<th>Nom</th> | |||
<th>Prix unitaire</th> | |||
<th>Quantité</th> | |||
<th>Total</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="product in products" v-if="product.productDistribution[0].active == 1"> | |||
<td class="name"> | |||
<span class="name">{{ product.name }}</span> | |||
<span class="other"> | |||
<span v-if="product.description.length">/</span> | |||
<span class="description">{{ product.description }}</span> | |||
<span v-if="product.weight">({{ product.weight }}g)</span> | |||
</span> | |||
<span v-if="product.quantity_remaining - product.quantity_form == 0 && product.quantity_max > 0" class="label label-danger"> | |||
Épuisé | |||
</span> | |||
<div class="recipe" v-if="product.recipe.length">{{ product.recipe }}</div> | |||
</td> | |||
<td class="price-unit"> | |||
{{ formatPrice(product.price) }} | |||
</td> | |||
<td class="td-quantity"> | |||
<div class="input-group"> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-moins" type="button" @click="productQuantityClick(product, -1)"><span class="glyphicon glyphicon-minus"></span></button> | |||
</span> | |||
<input type="text" v-model="product.quantity_form" class="form-control quantity" /> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product, 1)"><span class="glyphicon glyphicon-plus"></span></button> | |||
</span> | |||
</div> | |||
</td> | |||
<td class="price-total"> | |||
{{ formatPrice(product.price * product.quantity_form) }} | |||
</td> | |||
</tr> | |||
<tr> | |||
<td colspan="3"></td> | |||
<td>{{ priceTotal() }}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<div class="block-actions"> | |||
<button class="btn btn-primary" @click="changeStep('payment')">Valider</button> | |||
</div> | |||
</div> | |||
<div class="alert alert-warning" v-else> | |||
Aucun produit disponible | |||
</div> | |||
</div> | |||
<div id="content-step-payment" v-if="step == 'payment'"> | |||
Paiement | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-md-4" v-if="date"> | |||
<div id="summary" class="col-md-3" v-if="date"> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Résumé | |||
@@ -131,6 +186,18 @@ $this->setTitle('Commander') ; | |||
<span class="glyphicon glyphicon-map-marker"></span> | |||
{{ pointSaleActive.name }} | |||
</div> | |||
<div class="products" v-if="products.length && oneProductOrdered()"> | |||
<span class="glyphicon glyphicon-th-list"></span> | |||
<ul> | |||
<li v-for="product in products" v-if="product.quantity_form"> | |||
{{ product.quantity_form }} x {{ product.name }} | |||
</li> | |||
</ul> | |||
</div> | |||
<div class="products" v-if="products.length && oneProductOrdered()"> | |||
<span class="glyphicon glyphicon-euro"></span> | |||
{{ priceTotal() }} | |||
</div> | |||
</div> | |||
</div> | |||
</div> |
@@ -1208,6 +1208,49 @@ termes. | |||
.order-order #app-order-order #calendar .c-day-popover-content { | |||
font-size: 1.3rem; | |||
} | |||
/* line 39, ../sass/order/_order.scss */ | |||
.order-order #app-order-order .block-actions { | |||
text-align: right; | |||
} | |||
/* line 45, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products td.name .name { | |||
text-transform: uppercase; | |||
font-family: "myriadpro-regular"; | |||
color: black; | |||
font-size: 16px; | |||
} | |||
/* line 51, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products td.name .other { | |||
font-size: 14px; | |||
color: #333; | |||
} | |||
/* line 55, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products td.name .recipe { | |||
color: gray; | |||
} | |||
/* line 59, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products .price-unit, .order-order #app-order-order table#products .price-total { | |||
width: 100px; | |||
text-align: center; | |||
} | |||
/* line 63, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products .td-quantity { | |||
width: 150px; | |||
} | |||
/* line 65, ../sass/order/_order.scss */ | |||
.order-order #app-order-order table#products .td-quantity input.quantity { | |||
text-align: center; | |||
} | |||
/* line 72, ../sass/order/_order.scss */ | |||
.order-order #app-order-order #summary .glyphicon { | |||
margin-right: 11px; | |||
} | |||
/* line 76, ../sass/order/_order.scss */ | |||
.order-order #app-order-order #summary .products ul { | |||
padding-left: 30px; | |||
position: relative; | |||
top: -19px; | |||
} | |||
/** | |||
Copyright La boîte à pain (2018) |
@@ -7,6 +7,7 @@ var app = new Vue({ | |||
dateFormat: null, | |||
pointsSale: [], | |||
pointSaleActive: null, | |||
products: [], | |||
calendar: { | |||
mode: 'single', | |||
attrs: [], | |||
@@ -34,7 +35,6 @@ var app = new Vue({ | |||
dayContent: function(object) { | |||
var style = { | |||
fontSize: '2rem', | |||
//padding: '16px', | |||
padding: '20px', | |||
}; | |||
@@ -71,6 +71,13 @@ var app = new Vue({ | |||
} | |||
return false ; | |||
}, | |||
formatPrice: function(price) { | |||
var isNumberRegExp = new RegExp(/^[-+]?[0-9]+(\.[0-9]+)*$/); | |||
if(isNumberRegExp.test(price)) { | |||
return Number(price).toFixed(2).replace('.',',')+' €' ; | |||
} | |||
return '' ; | |||
}, | |||
getPointSale: function(idPointSale) { | |||
for(var key in this.pointsSale) { | |||
if(this.pointsSale[key].id == idPointSale) { | |||
@@ -97,6 +104,10 @@ var app = new Vue({ | |||
if(response.data.points_sale) { | |||
this.pointsSale = response.data.points_sale ; | |||
} | |||
if(response.data.products) { | |||
this.products = response.data.products ; | |||
} | |||
}); | |||
}, | |||
changeStep: function(step) { | |||
@@ -115,9 +126,32 @@ var app = new Vue({ | |||
}, | |||
pointSaleClick: function(event) { | |||
this.pointSaleActive = this.getPointSale(event.currentTarget.getAttribute('data-id-point-sale')) ; | |||
console.log(event.currentTarget.getAttribute('data-id-point-sale')) ; | |||
console.log(this.getPointSale(10)) ; | |||
this.changeStep('products') ; | |||
}, | |||
productQuantityClick: function(product, quantity) { | |||
if( this.products[product.index].quantity_form + quantity >= 0 && | |||
( !this.products[product.index].quantity_remaining || | |||
this.products[product.index].quantity_form + quantity <= this.products[product.index].quantity_remaining | |||
)) { | |||
this.products[product.index].quantity_form += quantity ; | |||
} | |||
}, | |||
oneProductOrdered: function() { | |||
for(var key in this.products) { | |||
if(this.products[key].quantity_form > 0) { | |||
return true ; | |||
} | |||
} | |||
return false ; | |||
}, | |||
priceTotal: function() { | |||
var price = 0 ; | |||
for(var key in this.products) { | |||
if(this.products[key].quantity_form > 0) { | |||
price += this.products[key].quantity_form * this.products[key].price ; | |||
} | |||
} | |||
return this.formatPrice(price) ; | |||
} | |||
} | |||
}); |
@@ -35,5 +35,52 @@ | |||
font-size: 1.3rem ; | |||
} | |||
} | |||
.block-actions { | |||
text-align: right ; | |||
} | |||
table#products { | |||
td.name { | |||
.name { | |||
text-transform: uppercase ; | |||
font-family: 'myriadpro-regular' ; | |||
color: black ; | |||
font-size: 16px ; | |||
} | |||
.other { | |||
font-size: 14px ; | |||
color: #333 ; | |||
} | |||
.recipe { | |||
color: gray ; | |||
} | |||
} | |||
.price-unit, .price-total { | |||
width: 100px ; | |||
text-align: center ; | |||
} | |||
.td-quantity { | |||
width: 150px ; | |||
input.quantity { | |||
text-align: center ; | |||
} | |||
} | |||
} | |||
#summary { | |||
.glyphicon { | |||
margin-right: 11px ; | |||
} | |||
.products { | |||
ul { | |||
padding-left: 30px ; | |||
position: relative ; | |||
top: -19px ; | |||
} | |||
} | |||
} | |||
} | |||
} |