'httpOnly' => true, | 'httpOnly' => true, | ||||
], | ], | ||||
], | ], | ||||
'request' => [ | |||||
'parsers' => [ | |||||
'application/json' => 'yii\web\JsonParser', | |||||
] | |||||
], | |||||
'cache' => [ | 'cache' => [ | ||||
'class' => 'yii\caching\FileCache', | 'class' => 'yii\caching\FileCache', | ||||
], | ], |
<?php | |||||
/** | |||||
Copyright La boîte à pain (2018) | |||||
contact@laboiteapain.net | |||||
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. | |||||
*/ | |||||
namespace producer\assets; | |||||
use yii\web\AssetBundle; | |||||
use yii ; | |||||
/** | |||||
* @author Qiang Xue <qiang.xue@gmail.com> | |||||
* @since 2.0 | |||||
*/ | |||||
class VuejsOrderOrderAsset extends \common\components\MyAssetBundle | |||||
{ | |||||
public $basePath = '@webroot'; | |||||
public $baseUrl = '@web'; | |||||
public $css = []; | |||||
public $js = []; | |||||
public $depends = [ | |||||
'common\assets\CommonAsset' | |||||
]; | |||||
public function __construct() | |||||
{ | |||||
parent::__construct() ; | |||||
$this->addAsset('js','js/vuejs/order-order.js') ; | |||||
} | |||||
} |
namespace producer\controllers; | namespace producer\controllers; | ||||
use common\models\ProductDistribution ; | use common\models\ProductDistribution ; | ||||
use common\models\User ; | |||||
use common\models\Producer ; | |||||
use common\models\Order ; | |||||
use DateTime; | |||||
class OrderController extends ProducerBaseController | class OrderController extends ProducerBaseController | ||||
{ | { | ||||
var $enableCsrfValidation = false; | |||||
public function behaviors() | public function behaviors() | ||||
{ | { | ||||
], | ], | ||||
]; | ]; | ||||
} | } | ||||
public function actionOrder() | |||||
{ | |||||
return $this->render('order') ; | |||||
} | |||||
/** | /** | ||||
* Retourne au format JSON toutes les informations relatives à une | * Retourne au format JSON toutes les informations relatives à une | ||||
$deadline = 20; | $deadline = 20; | ||||
$date = date('Y-m-d'); | $date = date('Y-m-d'); | ||||
if (isset($producer)) { | if (isset($producer)) { | ||||
$deadline = $producer->order_deadline; | |||||
if($producer->order_deadline) { | |||||
$deadline = $producer->order_deadline; | |||||
} | |||||
if (date('H') >= $deadline) { | if (date('H') >= $deadline) { | ||||
$date = date('Y-m-d', strtotime(date('Y-m-d')) + ($producer->order_delay) * (24 * 60 * 60)); | $date = date('Y-m-d', strtotime(date('Y-m-d')) + ($producer->order_delay) * (24 * 60 * 60)); | ||||
} else { | } else { | ||||
* | * | ||||
* @return mixed | * @return mixed | ||||
*/ | */ | ||||
public function actionCreate() | |||||
public function actionAjaxProcess() | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||||
$order = new Order ; | |||||
$idProducer = $this->getProducer()->id ; | $idProducer = $this->getProducer()->id ; | ||||
$order = new Order; | |||||
$posts = Yii::$app->request->post(); | $posts = Yii::$app->request->post(); | ||||
if ($idProducer) { | if ($idProducer) { | ||||
$this->_verifyProducerActive($idProducer); | $this->_verifyProducerActive($idProducer); | ||||
} | } | ||||
if ($order->load($posts)) { | if ($order->load($posts)) { | ||||
$order = Order::find() | $order = Order::find() | ||||
->where('id_distribution = ' . $posts['Order']['id_distribution']) | |||||
->andWhere('id_user = ' . User::getCurrentId()) | |||||
->where('id_distribution = :id_distribution') | |||||
->andWhere('id_user = :id_user') | |||||
->params([ | |||||
':id_distribution' => $posts['Order']['id_distribution'], | |||||
':id_user' => User::getCurrentId() | |||||
]) | |||||
->one(); | ->one(); | ||||
if (!$order) { | if (!$order) { | ||||
$order->origin = Order::ORIGIN_USER; | $order->origin = Order::ORIGIN_USER; | ||||
} | } | ||||
$this->processForm($order); | |||||
$errors = $this->processForm($order); | |||||
if(count($errors)) { | |||||
return ['status' => 'error', 'errors' => $errors] ; | |||||
} | |||||
} | } | ||||
return $this->render('create', array_merge($this->initForm($order), [ | |||||
'model' => $order | |||||
])); | |||||
return ['status' => 'success'] ; | |||||
} | } | ||||
/** | /** | ||||
$totalQuantity = 0; | $totalQuantity = 0; | ||||
foreach ($posts['Product'] as $key => $quantity) { | |||||
$key = (int) str_replace('product_', '', $key); | |||||
$product = Product::find()->where(['id' => $key])->one(); | |||||
foreach ($posts['products'] as $key => $quantity) { | |||||
$product = Product::find()->where(['id' => (int) $key])->one(); | |||||
$totalQuantity += $quantity; | $totalQuantity += $quantity; | ||||
if ($product && $quantity) { | if ($product && $quantity) { | ||||
$productsArray[] = $product; | $productsArray[] = $product; | ||||
$pointSale = PointSale::findOne($posts['Order']['id_point_sale']); | $pointSale = PointSale::findOne($posts['Order']['id_point_sale']); | ||||
if ($pointSale) { | if ($pointSale) { | ||||
if (strlen($pointSale->code) && !$pointSale->validateCode($posts['code_point_sale_' . $pointSale->id])) { | |||||
if (strlen($pointSale->code) && !$pointSale->validateCode($posts['code_point_sale'])) { | |||||
$errorPointSale = true; | $errorPointSale = true; | ||||
} | } | ||||
} else { | } else { | ||||
} | } | ||||
} | } | ||||
$errors = [] ; | |||||
if ($order->validate() && count($productsArray) && !$errorDate && !$errorPointSale) { | if ($order->validate() && count($productsArray) && !$errorDate && !$errorPointSale) { | ||||
// gestion point de vente | // gestion point de vente | ||||
$productOrder->price = $product->price; | $productOrder->price = $product->price; | ||||
$quantity = (int) $posts['Product']['product_' . $product->id]; | |||||
$quantity = (int) $posts['products'][$product->id] ; | |||||
if ($availableProducts[$product->id]['quantity_max'] && $quantity > $availableProducts[$product->id]['quantity_remaining']) { | if ($availableProducts[$product->id]['quantity_max'] && $quantity > $availableProducts[$product->id]['quantity_remaining']) { | ||||
$quantity = $availableProducts[$product->id]['quantity_remaining']; | $quantity = $availableProducts[$product->id]['quantity_remaining']; | ||||
} | } | ||||
} | } | ||||
// credit | // credit | ||||
$credit = isset($posts['credit']) && $posts['credit']; | |||||
$credit = Producer::getConfig('credit'); | |||||
$order = Order::searchOne([ | $order = Order::searchOne([ | ||||
'id' => $order->id | 'id' => $order->id | ||||
]) ; | ]) ; | ||||
} | } | ||||
// redirection | // redirection | ||||
$this->redirect(Yii::$app->urlManager->createUrl(['order/history', 'orderOk' => true])); | |||||
//$this->redirect(Yii::$app->urlManager->createUrl(['order/history', 'orderOk' => true])); | |||||
} | } | ||||
else { | else { | ||||
if (!count($productsArray)) { | if (!count($productsArray)) { | ||||
Yii::$app->session->setFlash('error', "Vous n'avez choisi aucun produit"); | |||||
$errors[] = "Vous n'avez choisi aucun produit" ; | |||||
} | } | ||||
if ($errorDate) { | if ($errorDate) { | ||||
Yii::$app->session->setFlash('error', "Vous ne pouvez pas commander pour cette date."); | |||||
$errors[] = "Vous ne pouvez pas commander pour cette date." ; | |||||
} | } | ||||
if ($errorPointSale) { | if ($errorPointSale) { | ||||
Yii::$app->session->setFlash('error', "Point de vente invalide."); | |||||
$errors[] = "Point de vente invalide." ; | |||||
} | } | ||||
} | } | ||||
return $errors ; | |||||
} | } | ||||
/** | /** | ||||
* @param string $code | * @param string $code | ||||
* @return boolean | * @return boolean | ||||
*/ | */ | ||||
public function actionValidateCodePointSale($idPointSale, $code) | |||||
public function actionAjaxValidateCodePointSale($idPointSale, $code) | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||||
$pointSale = PointSale::findOne($idPointSale); | $pointSale = PointSale::findOne($idPointSale); | ||||
if ($pointSale) { | if ($pointSale) { | ||||
if ($pointSale->validateCode($code)) { | if ($pointSale->validateCode($code)) { | ||||
return true; | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
public function actionAjaxInfos($date = '') | |||||
{ | |||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||||
$json = [] ; | |||||
$format = 'Y-m-d' ; | |||||
$dateObject = DateTime::createFromFormat($format, $date); | |||||
// Producteur | |||||
$producer = Producer::searchOne([ | |||||
'id' => $this->getProducer()->id | |||||
]) ; | |||||
$json['producer'] = [ | |||||
'order_infos' => $producer->order_infos, | |||||
'credit' => $producer->credit | |||||
] ; | |||||
// Distributions | |||||
$deadline = 20; | |||||
$dateMini = date('Y-m-d'); | |||||
if (isset($producer)) { | |||||
if($producer->order_deadline) { | |||||
$deadline = $producer->order_deadline; | |||||
} | |||||
if (date('H') >= $deadline) { | |||||
$dateMini = date('Y-m-d', strtotime(date('Y-m-d')) + ($producer->order_delay) * (24 * 60 * 60)); | |||||
} else { | |||||
$dateMini = date('Y-m-d', strtotime(date('Y-m-d')) + ($producer->order_delay - 1) * (24 * 60 * 60)); | |||||
} | |||||
} | |||||
$distributionsArray = Distribution::searchAll([ | |||||
'active' => 1 | |||||
], [ | |||||
'conditions' => ['date > :date'], | |||||
'params' => [':date' => $dateMini], | |||||
]) ; | |||||
$json['distributions'] = $distributionsArray ; | |||||
// Commandes de l'utilisateur | |||||
$ordersUserArray = Order::searchAll([ | |||||
'id_user' => User::getCurrentId() | |||||
], [ | |||||
'conditions' => [ | |||||
'distribution.date > :date' | |||||
], | |||||
'params' => [ | |||||
':date' => $dateMini | |||||
] | |||||
]); | |||||
foreach($ordersUserArray as &$order) { | |||||
$order = array_merge($order->getAttributes(), [ | |||||
'amount_total' => $order->getAmount(Order::AMOUNT_TOTAL), | |||||
'date_distribution' => $order->distribution->date, | |||||
'pointSale' => $order->pointSale->getAttributes() | |||||
]) ; | |||||
} | |||||
$json['orders'] = $ordersUserArray; | |||||
// User | |||||
$userProducer = UserProducer::searchOne([ | |||||
'id_producer' => $producer->id, | |||||
'id_user' => User::getCurrentId() | |||||
]) ; | |||||
$json['credit'] = $userProducer->credit ; | |||||
if($dateObject && $dateObject->format($format) === $date) { | |||||
// Commande de l'utilisateur | |||||
$orderUser = Order::searchOne([ | |||||
'distribution.date' => $date, | |||||
'id_user' => User::getCurrentId(), | |||||
]); | |||||
if($orderUser) { | |||||
$json['order'] = array_merge($orderUser->getAttributes(), [ | |||||
'amount_total' => $orderUser->getAmount(Order::AMOUNT_TOTAL), | |||||
'amount_paid' => $orderUser->getAmount(Order::AMOUNT_PAID), | |||||
]) ; | |||||
} | } | ||||
// distribution | |||||
$distribution = Distribution::initDistribution($date) ; | |||||
$json['distribution'] = $distribution ; | |||||
$pointsSaleArray = PointSale::find() | |||||
->joinWith(['pointSaleDistribution' => function($query) use ($distribution) { | |||||
$query->where(['id_distribution' => $distribution->id]); | |||||
} | |||||
]) | |||||
->with(['userPointSale' => function($query) { | |||||
$query->onCondition(['id_user' => User::getCurrentId()]) ; | |||||
}]) | |||||
->where([ | |||||
'id_producer' => $distribution->id_producer, | |||||
]) | |||||
->all(); | |||||
foreach($pointsSaleArray as &$pointSale) { | |||||
$pointSale = array_merge($pointSale->getAttributes(),[ | |||||
'pointSaleDistribution' => [ | |||||
'id_distribution' => $pointSale->pointSaleDistribution[0]->id_distribution, | |||||
'id_point_sale' => $pointSale->pointSaleDistribution[0]->id_point_sale, | |||||
'delivery' => $pointSale->pointSaleDistribution[0]->delivery | |||||
], | |||||
'userPointSale' => ($pointSale->userPointSale ? $pointSale->userPointSale[0] : '') | |||||
]) ; | |||||
} | |||||
$json['points_sale'] = $pointsSaleArray; | |||||
// Commandes totales | |||||
$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($orderUser) { | |||||
$quantityOrderUser = Order::getProductQuantity($product['id'], [$orderUser]) ; | |||||
$product['quantity_ordered'] = $quantityOrder ; | |||||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder + $quantityOrderUser ; | |||||
$product['quantity_form'] = $quantityOrderUser ; | |||||
} | |||||
else { | |||||
$product['quantity_form'] = 0 ; | |||||
} | |||||
if($product['quantity_remaining'] < 0) $product['quantity_remaining'] = 0 ; | |||||
$product['index'] = $indexProduct ++ ; | |||||
} | |||||
$json['products'] = $productsArray; | |||||
} | } | ||||
return false; | |||||
return $json ; | |||||
} | } | ||||
} | } |
], | ], | ||||
[ | [ | ||||
'label' => '<span class="glyphicon glyphicon-plus"></span> Commander', | 'label' => '<span class="glyphicon glyphicon-plus"></span> Commander', | ||||
'url' => Yii::$app->urlManager->createUrl(['order/create']), | |||||
'url' => Yii::$app->urlManager->createUrl(['order/order']), | |||||
'visible' => !Yii::$app->user->isGuest, | 'visible' => !Yii::$app->user->isGuest, | ||||
'active' => $this->getControllerAction() == 'order/create' || $this->getControllerAction() == 'order/update', | |||||
'active' => $this->getControllerAction() == 'order/order', | |||||
], | ], | ||||
[ | [ | ||||
'label' => '<span class="glyphicon glyphicon-plus"></span> Commander', | 'label' => '<span class="glyphicon glyphicon-plus"></span> Commander', | ||||
'url' => Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/producer','id' => $this->context->getProducer()->id,'return_url' => Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/create','slug_producer' => $this->context->getProducer()->slug])]), | |||||
'url' => Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/producer','id' => $this->context->getProducer()->id,'return_url' => Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order','slug_producer' => $this->context->getProducer()->slug])]), | |||||
'visible' => Yii::$app->user->isGuest, | 'visible' => Yii::$app->user->isGuest, | ||||
'active' => $this->getControllerAction() == 'order/create' || $this->getControllerAction() == 'order/update', | |||||
'active' => $this->getControllerAction() == 'order/order', | |||||
], | ], | ||||
[ | [ | ||||
'label' => '<span class="glyphicon glyphicon-folder-open"></span> Historique', | 'label' => '<span class="glyphicon glyphicon-folder-open"></span> Historique', |
<?php | |||||
/** | |||||
Copyright La boîte à pain (2018) | |||||
contact@laboiteapain.net | |||||
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. | |||||
*/ | |||||
\producer\assets\VuejsOrderOrderAsset::register($this); | |||||
$this->setTitle('Commander') ; | |||||
?> | |||||
<div id="app-order-order" :class="{'loaded': !loadingInit}"> | |||||
<div v-if="orderSuccess" id="order-success"> | |||||
<div class="alert alert-success"> | |||||
<span class="glyphicon glyphicon-ok glyphicon-big"></span> | |||||
<div class="content"> | |||||
<h3>Votre commande a bien été prise en compte</h3> | |||||
<a href="<?= Yii::$app->urlManagerProducer->createUrl(['order/history']) ?>" class="btn btn-default"> | |||||
<span class="glyphicon glyphicon-chevron-right"></span> | |||||
Voir toutes mes commandes | |||||
</a> | |||||
</div> | |||||
<div class="clr"></div> | |||||
</div> | |||||
<div class="alert alert-info"> | |||||
<span class="glyphicon glyphicon-list-alt glyphicon-big"></span> | |||||
<div class="content"> | |||||
<h3>Récapitulatif de votre commande</h3> | |||||
<ul> | |||||
<li><span class="glyphicon glyphicon-time"></span> {{ dateFormat }}</li> | |||||
<li><span class="glyphicon glyphicon-map-marker"></span> {{ pointSaleActive.name }} <span class="locality" v-if="pointSaleActive.locality.length > 0">à {{ pointSaleActive.locality }}</span></li> | |||||
<li><span class="glyphicon glyphicon-th-list"></span> {{ countProductOrdered() }} produits</li> | |||||
<li><span class="glyphicon glyphicon-chevron-right"></span> {{ priceTotal(true) }}</li> | |||||
</ul> | |||||
</div> | |||||
<div class="clr"></div> | |||||
</div> | |||||
</div> | |||||
<div v-else> | |||||
<div :class="(producer != null && producer.order_infos.length) ? 'col-md-9' : 'col-md-12'"> | |||||
<div id="steps"> | |||||
<ul> | |||||
<li id="step-date" :class="'col-md-3 '+((step == 'date') ? 'active' : '')"> | |||||
<div class="info-step" v-if="dateFormat"> | |||||
{{ dateFormat }} | |||||
</div> | |||||
<button @click="changeStep('date')" :class="'btn '+ (step == 'date' ? 'btn-primary' : 'btn-default')"> | |||||
<span class="button-content"><span class="glyphicon glyphicon-time"></span> Date</span></span> | |||||
</button> | |||||
</li> | |||||
<li id="step-point-sale" :class="'col-md-3 '+((step == 'point-sale') ? 'active ' : '')"> | |||||
<div class="info-step" v-if="pointSaleActive"> | |||||
{{ pointSaleActive.name }} | |||||
</div> | |||||
<button @click="changeStep('point-sale')" :class="'btn '+ (step == 'point-sale' ? 'btn-primary' : 'btn-default')" :disabled="step == 'date'"> | |||||
<span class="button-content"><span class="glyphicon glyphicon-map-marker"></span> Points de vente</span> | |||||
</button> | |||||
</li> | |||||
<li id="step-products" :class="'col-md-3 '+((step == 'products') ? 'active ' : '')"> | |||||
<div class="info-step" v-if="oneProductOrdered()"> | |||||
{{ countProductOrdered() }} produit{{ (countProductOrdered() > 1) ? 's' : '' }} | |||||
</div> | |||||
<button @click="changeStep('products')" :class="'btn '+ (step == 'products' ? 'btn-primary' : 'btn-default')" :disabled="step == 'date' || step == 'point-sale'"> | |||||
<span class="button-content"><span class="glyphicon glyphicon-th-list"></span> Produits</span> | |||||
</button> | |||||
</li> | |||||
<li id="step-payment" :class="'col-md-3 '+((step == 'payment') ? 'active' : '')"> | |||||
<button @click="changeStep('payment')" :class="'btn '+ (step == 'payment' ? 'btn-primary' : 'btn-default')" :disabled="step == 'date' || step == 'point-sale' || step == 'products'"> | |||||
<span class="button-content"><span class="glyphicon glyphicon-ok"></span> Confirmation</span> | |||||
</button> | |||||
</li> | |||||
</ul> | |||||
<div class="clr"></div> | |||||
</div> | |||||
<div class="content"> | |||||
<transition name="slide"> | |||||
<div id="content-step-date" v-if="step == 'date'"> | |||||
<div id="legend"> | |||||
<div><span id="distribution-date-color"></span> Prochains jours de distribution</div> | |||||
<div><span id="order-date-color"></span> Vos commandes déjà enregistrées</div> | |||||
</div> | |||||
<div id="calendar"> | |||||
<v-calendar | |||||
is-inline | |||||
is-double-paned | |||||
is-expanded | |||||
v-model="date" | |||||
mode="single" | |||||
:formats="calendar.formats" | |||||
:theme-styles="calendar.themeStyles" | |||||
:attributes="calendar.attrs" | |||||
:available-dates="calendar.availableDates" | |||||
@dayclick='dayClick'> | |||||
></v-calendar> | |||||
</div> | |||||
</div> | |||||
</transition> | |||||
<transition name="slide"> | |||||
<div id="content-step-point-sale" v-if="step == 'point-sale'"> | |||||
<div v-if="loading"> | |||||
Chargement ... | |||||
</div> | |||||
<div v-else> | |||||
<table id="points-sale" class="table table-bordered" v-if="pointsSale.length"> | |||||
<thead> | |||||
<tr> | |||||
<th>Nom</th> | |||||
<th>Localité</th> | |||||
<th></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr v-for="pointSale in pointsSale" v-if="pointSale && pointSale.pointSaleDistribution.delivery" :class="(pointSaleActive && pointSale.id == pointSaleActive.id) ? 'selected' : ''"> | |||||
<td class="name"> | |||||
<span class="the-name">{{ pointSale.name }}</span> | |||||
<div class="comment" v-if="pointSale.userPointSale"> | |||||
{{ pointSale.userPointSale.comment }} | |||||
</div> | |||||
</td> | |||||
<td class="locality">{{ pointSale.locality }}</td> | |||||
<td class="actions"> | |||||
<div :class="'form-group' + (pointSale.invalid_code ? ' has-error' : '')"> | |||||
<div class="input-group" v-if="pointSale.code.length > 0"> | |||||
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span> | |||||
<input v-model="pointsSaleCodes[pointSale.id]" type="password" placeholder="Code" class="form-control input-code" /> | |||||
</div> | |||||
</div> | |||||
<button class="btn btn-primary" @click="pointSaleClick" :data-code="pointSale.code.length > 0" :data-id-point-sale="pointSale.id"> | |||||
<span class="glyphicon glyphicon-map-marker"></span> | |||||
Choisir | |||||
</button> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<div class="alert alert-warning" v-else> | |||||
Aucun point de vente disponible pour ce jour de distribution. | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</transition> | |||||
<transition name="slide"> | |||||
<div id="content-step-products" v-if="step == 'products'"> | |||||
<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_form == product.quantity_remaining && 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)" :disabled="product.quantity_form == 0"><span class="glyphicon glyphicon-minus"></span></button> | |||||
</span> | |||||
<input type="text" v-model="product.quantity_form" class="form-control quantity" readonly="readonly" /> | |||||
<span class="input-group-btn"> | |||||
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product, 1)" :disabled="product.quantity_form == product.quantity_remaining && product.quantity_max > 0"><span class="glyphicon glyphicon-plus"></span></button> | |||||
</span> | |||||
</div> | |||||
</td> | |||||
<td class="price-total"> | |||||
{{ formatPrice(product.price * product.quantity_form) }} | |||||
</td> | |||||
</tr> | |||||
<tr class="total"> | |||||
<td colspan="3"></td> | |||||
<td class="price-total">{{ priceTotal(true) }}</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> | |||||
</transition> | |||||
<transition name="slide"> | |||||
<div id="content-step-payment" v-if="step == 'payment'"> | |||||
<div class="comment"> | |||||
<label for="order-comment">Commentaire</label> | |||||
<textarea id="order-comment" v-model="comment" class="form-control"></textarea> | |||||
</div> | |||||
<div class="credit"> | |||||
<div v-if="producer.credit == 1 && pointSaleActive.credit == 1"> | |||||
<span class="glyphicon glyphicon-chevron-right"></span> La commande va être réglée via votre Crédit ({{ formatPrice(credit) }}). | |||||
<div class="info"> | |||||
<span v-if="order == null || order.amount_paid == 0">{{ priceTotal(true) }} seront débités</span> | |||||
<span v-else-if="order != null && order.amount_paid > 0 && order.amount_paid < priceTotal()">{{ formatPrice(priceTotal() - order.amount_paid) }} seront débités</span> | |||||
<span v-else-if="order != null && order.amount_paid > priceTotal()">{{ formatPrice(order.amount_paid - priceTotal()) }} seront remboursés</span> | |||||
</div> | |||||
</div> | |||||
<div v-else> | |||||
<span class="glyphicon glyphicon-chevron-right"></span> La commande sera à régler sur place. | |||||
</div> | |||||
</div> | |||||
<div class="block-actions"> | |||||
<button class="btn btn-primary" @click="confirmClick">Je confirme ma commande</button> | |||||
</div> | |||||
</div> | |||||
</transition> | |||||
</div> | |||||
</div> | |||||
<div id="infos" class="col-md-3" v-if="producer != null && producer.order_infos.length"> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
Informations | |||||
</div> | |||||
<div class="panel-body"> | |||||
{{ producer.order_infos }} | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> |
display: none; | display: none; | ||||
} | } | ||||
/* line 3, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order { | |||||
display: none; | |||||
} | |||||
/* line 7, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order.loaded { | |||||
display: block; | |||||
} | |||||
/* line 11, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order .slide-enter-active { | |||||
transition: all .2s ease; | |||||
} | |||||
/* line 15, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order .slide-leave-active { | |||||
transition: all 0s ease; | |||||
} | |||||
/* line 19, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order .slide-enter, .order-order #app-order-order .slide-leave-to { | |||||
transform: translateX(10px); | |||||
opacity: 0; | |||||
} | |||||
/* line 24, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps { | |||||
margin-bottom: 20px; | |||||
} | |||||
/* line 26, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul { | |||||
margin-top: 30px; | |||||
} | |||||
/* line 28, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li { | |||||
text-align: center; | |||||
padding-right: 8px; | |||||
padding-left: 8px; | |||||
position: relative; | |||||
} | |||||
/* line 34, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .info-step { | |||||
position: absolute; | |||||
top: -30px; | |||||
left: 0px; | |||||
width: 100%; | |||||
text-transform: normal; | |||||
} | |||||
/* line 42, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .glyphicon-chevron-right, .order-order #app-order-order #steps ul li.active .glyphicon-chevron-right { | |||||
float: right; | |||||
color: gray; | |||||
position: relative; | |||||
top: 10px; | |||||
} | |||||
/* line 50, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li#step-date { | |||||
padding-left: 0px; | |||||
} | |||||
/* line 54, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li#step-payment { | |||||
padding-right: 0px; | |||||
} | |||||
/* line 58, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li#step-payment .btn::after, .order-order #app-order-order #steps ul li#step-date .btn::before { | |||||
display: none; | |||||
} | |||||
/* line 63, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn { | |||||
color: #333; | |||||
text-transform: uppercase; | |||||
display: block; | |||||
width: 100%; | |||||
position: relative; | |||||
background-color: #e0e0e0; | |||||
-moz-border-radius: 0px; | |||||
-webkit-border-radius: 0px; | |||||
border-radius: 0px; | |||||
border: 0px none; | |||||
text-transform: uppercase; | |||||
} | |||||
/* line 74, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn .button-content { | |||||
position: relative; | |||||
left: 8px; | |||||
} | |||||
/* line 79, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn.btn-primary { | |||||
background-color: #BB8757; | |||||
} | |||||
/* line 83, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn::after, .order-order #app-order-order #steps ul li .btn::before { | |||||
content: ""; | |||||
position: absolute; | |||||
top: -1px; | |||||
} | |||||
/* line 89, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn::after { | |||||
right: -34px; | |||||
border: 17px solid transparent; | |||||
border-left: 17px solid #e0e0e0; | |||||
background-color: transparent; | |||||
} | |||||
/* line 96, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn::before { | |||||
left: 0px; | |||||
border: 17px solid transparent; | |||||
border-left: 17px solid white; | |||||
background-color: transparent; | |||||
} | |||||
/* line 103, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn.btn-primary::after { | |||||
border-left: 17px solid #BB8757; | |||||
} | |||||
/* line 117, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #steps ul li .btn-primary { | |||||
color: white; | |||||
} | |||||
/* line 125, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #legend #order-date-color, | |||||
.order-order #app-order-order #legend #distribution-date-color { | |||||
width: 13px; | |||||
height: 13px; | |||||
display: inline-block; | |||||
} | |||||
/* line 132, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #legend #order-date-color { | |||||
background-color: #018548; | |||||
} | |||||
/* line 135, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #legend #distribution-date-color { | |||||
background-color: #00A65A; | |||||
} | |||||
/* line 140, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #calendar { | |||||
margin-bottom: 15px; | |||||
} | |||||
/* line 142, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #calendar .c-header .c-title-layout .c-title-popover .c-title-anchor .c-title[data-v-2083cb72] { | |||||
font-size: 2rem; | |||||
} | |||||
/* line 145, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #calendar .c-day-background { | |||||
padding: 20px; | |||||
} | |||||
/* line 150, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #calendar .c-day:hover .c-day-background { | |||||
background-color: #F39C12 !important; | |||||
} | |||||
/* line 155, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #calendar .c-day-popover-content { | |||||
font-size: 1.3rem; | |||||
} | |||||
/* line 160, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order .block-actions { | |||||
text-align: right; | |||||
margin-top: 20px; | |||||
} | |||||
/* line 167, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#points-sale td.name .the-name { | |||||
text-transform: uppercase; | |||||
font-family: "myriadpro-regular"; | |||||
color: black; | |||||
font-size: 16px; | |||||
} | |||||
/* line 175, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#points-sale td.actions { | |||||
width: 150px; | |||||
} | |||||
/* line 177, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#points-sale td.actions button { | |||||
width: 100%; | |||||
} | |||||
/* line 183, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#points-sale tr.selected td { | |||||
background-color: #F8F1DD; | |||||
} | |||||
/* line 191, ../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 197, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#products td.name .other { | |||||
font-size: 14px; | |||||
color: #333; | |||||
} | |||||
/* line 201, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#products td.name .recipe { | |||||
color: gray; | |||||
} | |||||
/* line 205, ../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 209, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#products .td-quantity { | |||||
width: 150px; | |||||
} | |||||
/* line 211, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#products .td-quantity input.quantity { | |||||
text-align: center; | |||||
} | |||||
/* line 217, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order table#products tr.total .price-total { | |||||
font-size: 23px; | |||||
} | |||||
/* line 224, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #content-step-payment .credit { | |||||
margin-top: 20px; | |||||
} | |||||
/* line 227, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #content-step-payment .credit .info { | |||||
margin-left: 20px; | |||||
color: gray; | |||||
} | |||||
/* line 234, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #infos { | |||||
margin-top: 30px; | |||||
} | |||||
/* line 236, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #infos .panel-body { | |||||
padding-top: 0px; | |||||
white-space: pre-line; | |||||
} | |||||
/* line 244, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert.alert-success .glyphicon-big { | |||||
background-color: #00A65A; | |||||
} | |||||
/* line 250, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert.alert-info .glyphicon-big { | |||||
background-color: #0097BC; | |||||
padding: 55px 30px; | |||||
} | |||||
/* line 256, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert { | |||||
padding: 0px; | |||||
} | |||||
/* line 258, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert .glyphicon-big { | |||||
font-size: 90px; | |||||
color: white; | |||||
padding: 30px; | |||||
float: left; | |||||
} | |||||
/* line 265, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert div.content { | |||||
color: #333; | |||||
padding: 20px; | |||||
margin-left: 151px; | |||||
} | |||||
/* line 270, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert div.content h3 { | |||||
font-family: "myriadpro-light"; | |||||
text-transform: uppercase; | |||||
font-size: 30px; | |||||
color: #333; | |||||
margin-bottom: 20px; | |||||
margin-top: 0px; | |||||
margin-left: 0px; | |||||
text-align: left; | |||||
padding-left: 0px; | |||||
line-height: 35px; | |||||
} | |||||
/* line 283, ../sass/order/_order.scss */ | |||||
.order-order #app-order-order #order-success .alert div.content .locality { | |||||
color: gray; | |||||
} | |||||
/** | /** | ||||
Copyright La boîte à pain (2018) | Copyright La boîte à pain (2018) | ||||
width: 100%; | width: 100%; | ||||
} | } | ||||
/* line 145, ../sass/_responsive.scss */ | |||||
/* line 148, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order #steps ul li { | |||||
padding-left: 0px; | |||||
padding-right: 0px; | |||||
} | |||||
/* line 152, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order #steps ul li .info-step { | |||||
display: none; | |||||
} | |||||
/* line 156, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order #steps ul li .btn::after, | |||||
.order-order #app-order-order #steps ul li .btn::before { | |||||
display: none; | |||||
} | |||||
/* line 167, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order table#products td.name .recipe { | |||||
display: none; | |||||
} | |||||
/* line 173, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order table#products td.td-quantity .input-group-btn { | |||||
width: 100%; | |||||
display: block; | |||||
} | |||||
/* line 177, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order table#products td.td-quantity .input-group-btn button { | |||||
width: 100%; | |||||
display: block; | |||||
} | |||||
/* line 187, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order #order-success .alert .glyphicon-big { | |||||
font-size: 90px; | |||||
color: white; | |||||
padding: 30px; | |||||
display: block; | |||||
width: 100%; | |||||
text-align: center; | |||||
margin-bottom: 20px; | |||||
} | |||||
/* line 196, ../sass/_responsive.scss */ | |||||
.order-order #app-order-order #order-success .alert div.content { | |||||
margin-left: 0px; | |||||
text-align: center; | |||||
} | |||||
/* line 207, ../sass/_responsive.scss */ | |||||
#footer .content { | #footer .content { | ||||
text-align: center; | text-align: center; | ||||
} | } |
var app = new Vue({ | |||||
el: '#app-order-order', | |||||
data: { | |||||
loading: false, | |||||
loadingInit: true, | |||||
step: 'date', | |||||
producer: null, | |||||
date: null, | |||||
dateFormat: null, | |||||
distribution: null, | |||||
pointsSale: [], | |||||
pointSaleActive: null, | |||||
pointsSaleCodes: [], | |||||
products: [], | |||||
comment: '', | |||||
creditCheckbox: false, | |||||
credit: 0, | |||||
orderSuccess: false, | |||||
calendar: { | |||||
mode: 'single', | |||||
attrs: [], | |||||
availableDates: [], | |||||
themeStyles: { | |||||
wrapper: { | |||||
background: '#BB8757', | |||||
color: '#fafafa', | |||||
}, | |||||
header: { | |||||
padding: '10px 10px', | |||||
}, | |||||
headerHorizontalDivider: { | |||||
borderTop: 'solid rgba(255, 255, 255, 0.2) 1px', | |||||
width: '80%', | |||||
}, | |||||
weekdays: { | |||||
color: 'white', | |||||
fontWeight: '600', | |||||
padding: '10px 10px', | |||||
fontSize: '2rem' | |||||
}, | |||||
weeks: { | |||||
padding: '0 15px 15px 15px', | |||||
}, | |||||
dayContent: function(object) { | |||||
var style = { | |||||
fontSize: '1.5rem', | |||||
padding: '20px', | |||||
}; | |||||
return style ; | |||||
}, | |||||
}, | |||||
formats: { | |||||
dayPopover: 'DD/MM/YYYY' | |||||
} | |||||
}, | |||||
}, | |||||
mounted: function() { | |||||
if($('#distribution-date').size()) { | |||||
this.date = new Date($('#distribution-date').html()) ; | |||||
this.dateFormat = ('0' + this.date.getDate()).slice(-2)+ '/' | |||||
+ ('0' + (this.date.getMonth() +1)).slice(-2) + '/' | |||||
+ this.date.getFullYear() ; | |||||
} | |||||
this.init() ; | |||||
this.loadingInit = false ; | |||||
}, | |||||
methods: { | |||||
getDate: function() { | |||||
return this.formatDate(this.date) ; | |||||
}, | |||||
formatDate: function(date) { | |||||
if(date) { | |||||
return date.getFullYear() + '-' | |||||
+ ('0' + (date.getMonth() +1)).slice(-2) + '-' | |||||
+ ('0' + date.getDate()).slice(-2) ; | |||||
} | |||||
return false ; | |||||
}, | |||||
formatPrice: function(price) { | |||||
var isNumberRegExp = new RegExp(/^[-+]?[0-9]+(\.[0-9]+)*$/); | |||||
if(isNumberRegExp.test(price) && price > 0) { | |||||
return Number(price).toFixed(2).replace('.',',')+' €' ; | |||||
} | |||||
return '--' ; | |||||
}, | |||||
getPointSale: function(idPointSale) { | |||||
for(var key in this.pointsSale) { | |||||
if(this.pointsSale[key].id == idPointSale) { | |||||
return this.pointsSale[key] ; | |||||
} | |||||
} | |||||
}, | |||||
init: function() { | |||||
this.loading = true ; | |||||
axios.get("ajax-infos",{params: {date : this.getDate()}}) | |||||
.then(response => { | |||||
this.producer = response.data.producer ; | |||||
this.credit = response.data.credit ; | |||||
this.calendar.attrs = [] ; | |||||
this.calendar.availableDates = [] ; | |||||
var distributions = response.data.distributions ; | |||||
if(distributions.length) { | |||||
var arrayDate ; | |||||
for(var i= 0; i < distributions.length; i++) { | |||||
this.calendar.attrs.push({ | |||||
highlight: { | |||||
backgroundColor: '#00A65A' | |||||
}, | |||||
dates: distributions[i].date, | |||||
}) ; | |||||
arrayDate = distributions[i].date.split('-') ; | |||||
this.calendar.availableDates.push({ | |||||
start: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]), | |||||
end: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]) | |||||
}) ; | |||||
} | |||||
} | |||||
var orders = response.data.orders ; | |||||
if(orders.length) { | |||||
for(var i= 0; i < orders.length; i++) { | |||||
this.calendar.attrs.push({ | |||||
highlight: { | |||||
backgroundColor: '#018548', | |||||
}, | |||||
popover: { | |||||
label: orders[i].pointSale.name + ' / '+this.formatPrice(orders[i].amount_total), | |||||
hideIndicator: true | |||||
}, | |||||
dates: orders[i].date_distribution, | |||||
}) ; | |||||
} | |||||
} | |||||
if(response.data.distribution) { | |||||
this.distribution = response.data.distribution ; | |||||
} | |||||
if(response.data.points_sale) { | |||||
this.pointsSale = [] ; | |||||
for(var key in response.data.points_sale) { | |||||
this.pointsSale[response.data.points_sale[key].id] = response.data.points_sale[key] ; | |||||
this.pointsSaleCodes[response.data.points_sale[key].id] = '' ; | |||||
Vue.set(this.pointsSaleCodes, response.data.points_sale[key].id, ''); | |||||
} | |||||
} | |||||
if(response.data.products) { | |||||
this.products = response.data.products ; | |||||
} | |||||
this.order = null ; | |||||
if(response.data.order) { | |||||
this.order = response.data.order ; | |||||
this.pointSaleActive = this.getPointSale(response.data.order.id_point_sale) ; | |||||
} | |||||
else { | |||||
this.pointSaleActive = null ; | |||||
} | |||||
this.loading = false ; | |||||
}); | |||||
}, | |||||
changeStep: function(step) { | |||||
var oldStep = this.step ; | |||||
this.step = step ; | |||||
window.scroll(0, $('#page-title').position().top - 25) ; | |||||
if(oldStep == 'date' && step == 'point-sale') { | |||||
this.init() ; | |||||
} | |||||
}, | |||||
dayClick: function(day) { | |||||
if(this.isAvailableDate(day.date)) { | |||||
this.date = day.date ; | |||||
this.dateFormat = ('0' + this.date.getDate()).slice(-2)+ '/' | |||||
+ ('0' + (this.date.getMonth() +1)).slice(-2) + '/' | |||||
+ this.date.getFullYear() ; | |||||
this.init() ; | |||||
this.changeStep('point-sale') ; | |||||
} | |||||
}, | |||||
isAvailableDate: function(date) { | |||||
for(var key in this.calendar.availableDates) { | |||||
if(date.getTime() == this.calendar.availableDates[key].start.getTime()) { | |||||
return true ; | |||||
} | |||||
} | |||||
return false ; | |||||
}, | |||||
pointSaleClick: function(event) { | |||||
var idPointSale = event.currentTarget.getAttribute('data-id-point-sale') ; | |||||
var hasCode = event.currentTarget.getAttribute('data-code') ; | |||||
if(hasCode) { | |||||
axios.get('ajax-validate-code-point-sale',{params: { | |||||
idPointSale: idPointSale, | |||||
code: this.pointsSaleCodes[idPointSale] | |||||
}}).then(response => { | |||||
if(response.data) { | |||||
this.pointsSale[idPointSale].invalid_code = false ; | |||||
this.validatePointSale(idPointSale) ; | |||||
} | |||||
else { | |||||
this.pointsSale[idPointSale].invalid_code = true ; | |||||
Vue.set(this.pointsSaleCodes, idPointSale, ''); | |||||
} | |||||
}) ; | |||||
} | |||||
else { | |||||
this.validatePointSale(idPointSale) ; | |||||
} | |||||
}, | |||||
validatePointSale: function(idPointSale) { | |||||
this.pointSaleActive = this.getPointSale(idPointSale) ; | |||||
this.changeStep('products') ; | |||||
}, | |||||
productQuantityClick: function(product, quantity) { | |||||
if( this.products[product.index].quantity_form + quantity >= 0 && | |||||
(this.products[product.index].quantity_form + quantity <= this.products[product.index].quantity_remaining || | |||||
!this.products[product.index].quantity_max) | |||||
) { | |||||
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 ; | |||||
}, | |||||
countProductOrdered: function() { | |||||
var count = 0 ; | |||||
for(var key in this.products) { | |||||
if(this.products[key].quantity_form > 0) { | |||||
count += this.products[key].quantity_form ; | |||||
} | |||||
} | |||||
return count ; | |||||
}, | |||||
priceTotal: function(format) { | |||||
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 ; | |||||
} | |||||
} | |||||
if(format) { | |||||
return this.formatPrice(price) ; | |||||
} | |||||
else { | |||||
return price ; | |||||
} | |||||
}, | |||||
confirmClick: function() { | |||||
var productsArray = {} ; | |||||
for(var key in this.products) { | |||||
if( this.products[key].quantity_form != null && | |||||
this.products[key].quantity_form > 0) { | |||||
productsArray[this.products[key].id] = this.products[key].quantity_form ; | |||||
} | |||||
} | |||||
axios.post('ajax-process', { | |||||
Order: { | |||||
id_distribution : this.distribution.id, | |||||
id_point_sale: this.pointSaleActive.id, | |||||
comment: this.comment | |||||
}, | |||||
code_point_sale: this.pointsSaleCodes[this.pointSaleActive.id], | |||||
products: productsArray | |||||
}).then(response => { | |||||
if(response.data.status == 'success') { | |||||
this.orderSuccess = true ; | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
}); |
width: 100% ; | width: 100% ; | ||||
} | } | ||||
.order-order { | |||||
#app-order-order { | |||||
#steps { | |||||
ul { | |||||
li { | |||||
padding-left: 0px ; | |||||
padding-right: 0px ; | |||||
.info-step { | |||||
display: none ; | |||||
} | |||||
.btn::after, | |||||
.btn::before { | |||||
display: none ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
table#products { | |||||
td.name { | |||||
.recipe { | |||||
display: none ; | |||||
} | |||||
} | |||||
td.td-quantity { | |||||
.input-group-btn { | |||||
width: 100% ; | |||||
display: block ; | |||||
button { | |||||
width: 100% ; | |||||
display: block ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#order-success { | |||||
.alert { | |||||
.glyphicon-big { | |||||
font-size: 90px ; | |||||
color: white ; | |||||
padding: 30px ; | |||||
display: block ; | |||||
width: 100% ; | |||||
text-align: center ; | |||||
margin-bottom: 20px ; | |||||
} | |||||
div.content { | |||||
margin-left: 0px ; | |||||
text-align: center ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#footer { | #footer { | ||||
.content { | .content { | ||||
text-align: center ; | text-align: center ; |
.order-order { | |||||
#app-order-order { | |||||
display: none ; | |||||
&.loaded { | |||||
display: block ; | |||||
} | |||||
.slide-enter-active { | |||||
transition: all .2s ease; | |||||
} | |||||
.slide-leave-active { | |||||
//transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0); | |||||
transition: all 0s ease; | |||||
} | |||||
.slide-enter, .slide-leave-to { | |||||
transform: translateX(10px); | |||||
opacity: 0; | |||||
} | |||||
#steps { | |||||
margin-bottom: 20px ; | |||||
ul { | |||||
margin-top: 30px ; | |||||
li { | |||||
text-align: center ; | |||||
padding-right: 8px ; | |||||
padding-left: 8px ; | |||||
position: relative ; | |||||
.info-step { | |||||
position: absolute ; | |||||
top: -30px ; | |||||
left: 0px ; | |||||
width: 100% ; | |||||
text-transform: normal ; | |||||
} | |||||
.glyphicon-chevron-right, | |||||
&.active .glyphicon-chevron-right { | |||||
float: right ; | |||||
color: gray ; | |||||
position: relative ; | |||||
top: 10px ; | |||||
} | |||||
&#step-date { | |||||
padding-left: 0px ; | |||||
} | |||||
&#step-payment { | |||||
padding-right: 0px ; | |||||
} | |||||
&#step-payment .btn::after, | |||||
&#step-date .btn::before { | |||||
display: none ; | |||||
} | |||||
.btn { | |||||
color: #333 ; | |||||
text-transform: uppercase ; | |||||
display: block ; | |||||
width: 100% ; | |||||
position: relative ; | |||||
background-color: #e0e0e0 ; | |||||
@include border-radius(0px) ; | |||||
border: 0px none ; | |||||
text-transform: uppercase ; | |||||
.button-content { | |||||
position: relative; | |||||
left: 8px ; | |||||
} | |||||
&.btn-primary { | |||||
background-color: $color1 ; | |||||
} | |||||
&::after, &::before { | |||||
content: '' ; | |||||
position: absolute ; | |||||
top: -1px ; | |||||
} | |||||
&::after { | |||||
right: -34px ; | |||||
border:17px solid transparent; | |||||
border-left:17px solid #e0e0e0; | |||||
background-color: transparent ; | |||||
} | |||||
&::before { | |||||
left: 0px ; | |||||
border:17px solid transparent; | |||||
border-left:17px solid white; | |||||
background-color: transparent ; | |||||
} | |||||
&.btn-primary::after { | |||||
border-left:17px solid $color1; | |||||
} | |||||
&:hover { | |||||
//background-color: lighten($color1, 5) ; | |||||
} | |||||
&:hover::after { | |||||
//border:17px solid transparent; | |||||
//border-left:17px solid #fefefe; | |||||
} | |||||
} | |||||
.btn-primary { | |||||
color: white ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#legend { | |||||
#order-date-color, | |||||
#distribution-date-color { | |||||
width: 13px ; | |||||
height: 13px ; | |||||
display: inline-block ; | |||||
} | |||||
#order-date-color { | |||||
background-color: #018548 ; | |||||
} | |||||
#distribution-date-color { | |||||
background-color: #00A65A ; | |||||
} | |||||
} | |||||
#calendar { | |||||
margin-bottom: 15px ; | |||||
.c-header .c-title-layout .c-title-popover .c-title-anchor .c-title[data-v-2083cb72] { | |||||
font-size: 2rem ; | |||||
} | |||||
.c-day-background { | |||||
padding: 20px ; | |||||
} | |||||
.c-day:hover { | |||||
.c-day-background { | |||||
background-color: #F39C12 !important ; | |||||
} | |||||
} | |||||
.c-day-popover-content { | |||||
font-size: 1.3rem ; | |||||
} | |||||
} | |||||
.block-actions { | |||||
text-align: right ; | |||||
margin-top: 20px ; | |||||
} | |||||
table#points-sale { | |||||
td.name { | |||||
.the-name { | |||||
text-transform: uppercase ; | |||||
font-family: 'myriadpro-regular' ; | |||||
color: black ; | |||||
font-size: 16px ; | |||||
} | |||||
} | |||||
td.actions { | |||||
width: 150px ; | |||||
button { | |||||
width: 100% ; | |||||
} | |||||
} | |||||
tr.selected { | |||||
td { | |||||
background-color: $color2 ; | |||||
} | |||||
} | |||||
} | |||||
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 ; | |||||
} | |||||
} | |||||
tr.total { | |||||
.price-total { | |||||
font-size: 23px ; | |||||
} | |||||
} | |||||
} | |||||
#content-step-payment { | |||||
.credit { | |||||
margin-top: 20px ; | |||||
.info { | |||||
margin-left: 20px ; | |||||
color: gray ; | |||||
} | |||||
} | |||||
} | |||||
#infos { | |||||
margin-top: 30px ; | |||||
.panel-body { | |||||
padding-top: 0px ; | |||||
white-space: pre-line ; | |||||
} | |||||
} | |||||
#order-success { | |||||
.alert.alert-success { | |||||
.glyphicon-big { | |||||
background-color: #00A65A ; | |||||
} | |||||
} | |||||
.alert.alert-info { | |||||
.glyphicon-big { | |||||
background-color: #0097BC ; | |||||
padding: 55px 30px ; | |||||
} | |||||
} | |||||
.alert { | |||||
padding: 0px ; | |||||
.glyphicon-big { | |||||
font-size: 90px ; | |||||
color: white ; | |||||
padding: 30px ; | |||||
float: left ; | |||||
} | |||||
div.content { | |||||
color: #333 ; | |||||
padding: 20px ; | |||||
margin-left: 151px ; | |||||
h3 { | |||||
font-family: 'myriadpro-light' ; | |||||
text-transform: uppercase ; | |||||
font-size: 30px ; | |||||
color: #333 ; | |||||
margin-bottom: 20px ; | |||||
margin-top: 0px ; | |||||
margin-left: 0px ; | |||||
text-align: left ; | |||||
padding-left: 0px ; | |||||
line-height: 35px ; | |||||
} | |||||
.locality { | |||||
color: gray ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@import "site/_credit_history.scss"; | @import "site/_credit_history.scss"; | ||||
@import "order/_form.scss"; | @import "order/_form.scss"; | ||||
@import "order/_history.scss"; | @import "order/_history.scss"; | ||||
@import "order/_order.scss"; | |||||
@import "_responsive.scss"; | @import "_responsive.scss"; |