Browse Source

Step produits

dev
Guillaume Bourgeois 5 years ago
parent
commit
f28f7003dd
5 changed files with 229 additions and 9 deletions
  1. +31
    -2
      producer/controllers/OrderController.php
  2. +71
    -4
      producer/views/order/order.php
  3. +43
    -0
      producer/web/css/screen.css
  4. +37
    -3
      producer/web/js/vuejs/order-order.js
  5. +47
    -0
      producer/web/sass/order/_order.scss

+ 31
- 2
producer/controllers/OrderController.php View File

@@ -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 ;

+ 71
- 4
producer/views/order/order.php View File

@@ -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>

+ 43
- 0
producer/web/css/screen.css View File

@@ -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)

+ 37
- 3
producer/web/js/vuejs/order-order.js View File

@@ -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) ;
}
}
});

+ 47
- 0
producer/web/sass/order/_order.scss View File

@@ -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 ;
}
}
}
}
}

Loading…
Cancel
Save