Browse Source

Génération des BL sur la page des distributions #179

refactoring
Guillaume Bourgeois 5 years ago
parent
commit
53ad58a756
13 changed files with 1333 additions and 1030 deletions
  1. +2
    -1
      backend/assets/VuejsDistributionIndexAsset.php
  2. +1001
    -907
      backend/controllers/DistributionController.php
  3. +65
    -8
      backend/controllers/DocumentController.php
  4. +1
    -0
      backend/controllers/OrderController.php
  5. +129
    -75
      backend/views/distribution/index.php
  6. +1
    -1
      backend/views/document/_form.php
  7. +46
    -27
      backend/web/css/screen.css
  8. +5
    -0
      backend/web/js/vuejs/alerts.js
  9. +53
    -3
      backend/web/js/vuejs/distribution-index.js
  10. +3
    -2
      backend/web/js/vuejs/document-form.js
  11. +1
    -1
      backend/web/sass/_alerts.scss
  12. +23
    -3
      backend/web/sass/distribution/_index.scss
  13. +3
    -2
      common/models/Subscription.php

+ 2
- 1
backend/assets/VuejsDistributionIndexAsset.php View File

@@ -51,7 +51,8 @@ class VuejsDistributionIndexAsset extends \common\components\MyAssetBundle
public $css = [];
public $js = [];
public $depends = [
'common\assets\CommonAsset'
'common\assets\CommonAsset',
'backend\assets\AppAsset',
];
public function __construct()

+ 1001
- 907
backend/controllers/DistributionController.php
File diff suppressed because it is too large
View File


+ 65
- 8
backend/controllers/DocumentController.php View File

@@ -126,6 +126,26 @@ class DocumentController extends BackendController
]);
}

public function actionDelete($id)
{
$model = $this->findModel($id);

if ($model->isStatusValid()) {
throw new UserException('Vous ne pouvez pas supprimer un document validé.');
}

$model->delete() ;

Order::updateAll([
'order.id_delivery_note' => null
],[
'order.id_delivery_note' => $id
]) ;

Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('delete', $model));
$this->redirect(['delivery-note/index']) ;
}

public function actionAjaxAddressUser($idUser)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
@@ -159,11 +179,23 @@ class DocumentController extends BackendController
if ($document) {
$document->changeStatus(Document::STATUS_VALID);
$document->save();
return ['return' => 'success'];
return [
'return' => 'success',
'alert' => [
'type' => 'success',
'message' => 'Document validé'
]
];
}
}

return ['return' => 'error'];
return [
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la validation du document.'
]
];
}

public function actionAjaxInit($idDocument, $classDocument)
@@ -262,7 +294,11 @@ class DocumentController extends BackendController
$productOrder->save();

return [
'return' => 'success',
'return' => 'error',
'alert' => [
'type' => 'success',
'message' => 'Produit ajouté'
]
];
}
}
@@ -270,7 +306,11 @@ class DocumentController extends BackendController
}

return [
'return' => 'error'
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la suppression du produit.'
]
];
}

@@ -284,13 +324,22 @@ class DocumentController extends BackendController

if ($productOrder) {
$productOrder->delete();

return [
'return' => 'success'
'return' => 'success',
'alert' => [
'type' => 'danger',
'message' => 'Produit supprimé'
]
];
}

return [
'return' => 'error'
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la suppression du produit.'
]
];
}

@@ -330,9 +379,13 @@ class DocumentController extends BackendController

if ($type == 'create') {
$message .= 'ajouté';
} elseif ($type == 'update') {
}
elseif ($type == 'update') {
$message .= 'modifié';
}
elseif ($type == 'delete') {
$message .= 'supprimé';
}

if ($class == 'Invoice') {
$message .= 'e';
@@ -371,7 +424,11 @@ class DocumentController extends BackendController
{
$class = $this->getClass();

if (($model = $class::findOne($id)) !== null) {
$model = $class::searchOne([
'id' => $id
]) ;

if ($model) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');

+ 1
- 0
backend/controllers/OrderController.php View File

@@ -831,6 +831,7 @@ class OrderController extends BackendController
$order->id_distribution = $distribution->id;
$order->origin = Order::ORIGIN_ADMIN;
$order->comment = $comment;
$order->status = 'tmp-order';

if ($idUser) {
$order->id_user = $idUser;

+ 129
- 75
backend/views/distribution/index.php View File

@@ -1,38 +1,38 @@
<?php

/**
Copyright distrib (2018)
/**
Copyright distrib (2018)

contact@opendistrib.net

Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.
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
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 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
titulaire des de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
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 à
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é.
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
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.
*/
@@ -45,7 +45,7 @@ $this->setPageTitle('Distributions') ;
?>
<div id="app-distribution-index" class="app-vuejs">
<?php if(strlen($date)): ?>
<span id="distribution-date"><?= $date; ?></span>
<span id="distribution-date"><?= $date; ?></span>
<?php endif; ?>
<div id="loading" v-if="showLoading">
<img src="<?= Yii::$app->urlManagerBackend->getBaseUrl(); ?>/img/loader.gif" alt="Chargement ..." />
@@ -64,7 +64,7 @@ $this->setPageTitle('Distributions') ;
:theme-styles="calendar.themeStyles"
:attributes="calendar.attrs"
@dayclick='dayClicked'>
></v-date-picker>
></v-date-picker>
</div>
<div class="clr"></div>
</div>
@@ -86,7 +86,7 @@ $this->setPageTitle('Distributions') ;
</div>
</div>
</div>
<!-- produits -->
<div class="col-md-6">
<div class="info-box col-md-4">
@@ -120,13 +120,13 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button>
</td>
<td>{{ product.name }}</td>
<td class="quantity-ordered">{{ product.quantity_ordered ? product.quantity_ordered + ' '+ ((product.unit == 'piece') ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') : '&empty;' }}</td>
<td class="quantity-ordered">{{ product.quantity_ordered ? product.quantity_ordered + ' '+ ((product.unit == 'piece') ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') : '&empty;' }}</td>
<td class="quantity-max">
<div class="input-group">
<input type="text" class="form-control quantity-max" placeholder="&infin;" :data-id-product="product.id" v-model="product.productDistribution[0].quantity_max" @keyup="productQuantityMaxChange" />
<span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span>
</div>
</td>
</tr>
</tbody>
@@ -138,7 +138,7 @@ $this->setPageTitle('Distributions') ;
</div>
</div>
</modal>
<div class="col-md-6">
<div class="info-box col-md-4">
<span class="info-box-icon bg-yellow"><i class="fa fa-map-marker"></i></span>
@@ -174,7 +174,7 @@ $this->setPageTitle('Distributions') ;
</table>
</div>
</modal>
<div class="col-md-6">
<div id="summary-ca-weight" class="info-box col-md-4">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
@@ -217,45 +217,83 @@ $this->setPageTitle('Distributions') ;
<div class="panel-heading">
<h3 class="panel-title">Commandes <label class="label label-success" v-if="orders.length">{{ orders.length }}</label><label class="label label-danger" v-else>0</label></h3>
<div class="buttons">
<button id="btn-add-order" @click="showModalFormOrderCreate = true" class="btn btn-primary btn-xs"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button>
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
<template v-if="producer.tiller == true">
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-xs btn-success" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</template>
</div>
</div>
<div class="panel-body">
<order-form
<order-form
v-if="showModalFormOrderCreate"
:date="date"
:order="orderCreate"
:points-sale="pointsSale"
:means-payment="meansPayment"
:users="users"
:users="users"
:products="products"
:producer="producer"
@close="showModalFormOrderCreate = false"
@ordercreatedupdated="orderCreatedUpdated"
></order-form>
<div id="wrapper-nav-points-sale">
<ul id="nav-points-sale">
<li data-id-point-sale="0" data-id-point-sale="0" v-if="countActivePointsSale > 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == 0">Tous <span class="label label-default">{{ orders.length }}</span> <span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>Tous <span class="label label-default">{{ orders.length }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
<li v-for="pointSale in pointsSale" :data-id-point-sale="pointSale.id" v-if="pointSale.pointSaleDistribution[0].delivery == 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == pointSale.id">{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
</ul>
<ul id="nav-points-sale">
<li data-id-point-sale="0" data-id-point-sale="0" v-if="countActivePointsSale > 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == 0">Tous <span class="label label-default">{{ orders.length }}</span> <span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>Tous <span class="label label-default">{{ orders.length }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
<li v-for="pointSale in pointsSale" :data-id-point-sale="pointSale.id" v-if="pointSale.pointSaleDistribution[0].delivery == 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == pointSale.id">{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
</ul>
<div class="clr"></div>
</div>

<div id="buttons-top-orders">
<div class="right">
<a v-if="typeof deliveryNotes[idActivePointSale] != 'undefined'" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+deliveryNotes[idActivePointSale].id" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-file"></span> Bon de livraison</a>
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
<template v-if="producer.tiller == true">
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-success btn-xs" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</template>
<button id="btn-add-order" @click="showModalFormOrderCreate = true" class="btn btn-xs btn-primary"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button>
</div>
<div class="left">
<div v-if="idActivePointSale > 0 && oneOrderSelected()" class="btn-group">
<button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action groupée <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a @click="generateDeliveryNote" href="javascript:void(0);">Générer un bon de livraison</a></li>
</ul>
</div>
</div>
<div class="clr"></div>
</div>

<table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)">
<thead>
<tr>
<th v-if="idActivePointSale > 0">
<input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrders" />
</th>
<th>Origine</th>
<th>État</th>
<th>Utilisateur</th>
<th v-if="idActivePointSale == 0">Point de vente</th>
<th>Montant</th>
<th>Paiement</th>
<th></th>
<th v-if="producer.tiller">Tiller</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<template v-for="(order, key, index) in orders" v-if="idActivePointSale == 0 || idActivePointSale == order.id_point_sale">
<tr>
<td v-if="idActivePointSale > 0">
<input type="checkbox" v-model="order.selected" />
</td>
<td>
<label class="label label-success" v-if="order.origin == 'user'">client</label>
<label class="label label-default" v-else-if="order.origin == 'auto'">auto</label>
@@ -276,12 +314,12 @@ $this->setPageTitle('Distributions') ;
</td>
<td>{{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}</td>
<td class="column-state-payment">
<div class="input-group">
<div class="input-group">
<span class="label label-success input-group-addon" v-if="order.amount_paid == order.amount">payé</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non réglé</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à payer</span>
<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
</td>
@@ -299,7 +337,7 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-xs btn-default" v-else-if="order.amount_paid > order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount_surplus">
<span class="glyphicon glyphicon-euro"></span> Rembourser
</button>
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
@@ -316,26 +354,32 @@ $this->setPageTitle('Distributions') ;
</td>
<td class="column-actions">
<span v-if="order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>
<button class="btn btn-default" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span></button>
<a class="btn btn-default" :href="baseUrl+'/subscription/update?id='+order.id_subscription" v-if="order.id_subscription > 0"><span class="glyphicon glyphicon-repeat"></span></a>
<a class="btn btn-default add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id" v-else><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span></a>
<order-form

<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span> Voir</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span> Modifier</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li>
<li v-if="order.id_subscription > 0"><a class="" :href="baseUrl+'/subscription/update?id='+order.id_subscription"><span class="glyphicon glyphicon-repeat"></span> Modifier l'abonnement associé</a></li>
<li v-else><a class="add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id"><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span>Créer un abonnement sur cette base</a></li>
</ul>

<order-form
v-if="showModalFormOrderUpdate && idOrderUpdate == order.id"
:date="date"
:id-point-sale="idActivePointSale"
:points-sale="pointsSale"
:means-payment="meansPayment"
:users="users"
:users="users"
:products="products"
:order="ordersUpdate[key]"
:producer="producer"
@close="showModalFormOrderUpdate = false"
@ordercreatedupdated="orderCreatedUpdated"
></order-form>
<modal v-if="showModalPayment && idOrderPayment == order.id" class="modal-payment" @close="showModalPayment = false">
<h3 slot="header">
Commande du <strong>{{ dateFormat }}</strong> &gt;
@@ -354,11 +398,11 @@ $this->setPageTitle('Distributions') ;
<span class="label label-success" v-if="order.amount_paid == order.amount">payé</span>
<span class="label label-default" v-else-if="order.amount_paid == 0">non réglé</span>
<span class="label label-default" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning" v-else-if="order.amount_paid < order.amount">reste à payer</span>
<span class="label label-warning" v-else-if="order.amount_paid < order.amount">reste à payer</span>
</span>
</div>
</div>
<div class="info-box">
<span :class="'info-box-icon ' +((order.user.credit > 0) ? 'bg-green' : 'bg-red')"><i class="fa fa-user"></i></span>
<div class="info-box-content">
@@ -366,44 +410,44 @@ $this->setPageTitle('Distributions') ;
<span class="info-box-number">{{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</span>
</div>
</div>
<button v-if="order.amount_paid == order.amount"
class="btn btn-default"
:data-amount="order.amount"
<button v-if="order.amount_paid == order.amount"
class="btn btn-default"
:data-amount="order.amount"
data-type="refund"
@click="orderPaymentClick" >
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Rembourser {{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid == 0"
class="btn btn-default"
:data-amount="order.amount"
<button v-else-if="order.amount_paid == 0"
class="btn btn-default"
:data-amount="order.amount"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Payer {{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid > order.amount"
<button v-else-if="order.amount_paid > order.amount"
class="btn btn-default"
:data-amount="order.amount_surplus"
:data-amount="order.amount_surplus"
data-type="refund"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Rembourser {{ order.amount_surplus.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid < order.amount"
class="btn btn-default"
:data-amount="order.amount_remaining"
class="btn btn-default"
:data-amount="order.amount_remaining"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Payer le restant {{ order.amount_remaining.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
</div>
<div class="col-md-8">
<h4>Historique paiement</h4>
<table class="table table-condensed table-bordered table-hover">
@@ -427,10 +471,15 @@ $this->setPageTitle('Distributions') ;
</tbody>
</table>
</div>
</div>
</modal>

</td>
<td>
<a v-if="order.id_delivery_note" class="btn btn-default btn-xs" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note">
<span class="glyphicon glyphicon-file"></span> BL
</a>
</td>
</tr>
<tr class="view" v-if="showViewProduct && idOrderView == order.id">
@@ -438,7 +487,7 @@ $this->setPageTitle('Distributions') ;
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong>
<ul>
<li v-for="product in products" v-if="order.productOrder[product.id].quantity > 0">
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
</li>
</ul>
<div v-if="order.comment && order.comment.length > 0" class="comment">
@@ -448,6 +497,11 @@ $this->setPageTitle('Distributions') ;
</td>
</tr>
</template>
<tr v-if="idActivePointSale > 0">
<td colspan="4"><strong>Total (TTC)</strong></td>
<td><strong>{{ totalActivePointSale() }}</strong></td>
<td colspan="3"></td>
</tr>
</tbody>
</table>
<div class="alert alert-warning" v-else>
@@ -528,7 +582,7 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? 1 : parseFloat(product.step))"><span class="glyphicon glyphicon-plus"></span></button>
</span>
</div>
</td>
</td>
<td class="quantity-remaining infinite" v-if="product.quantity_remaining === null || order.productOrder[product.id].unit != product.unit">&infin;</td>
<td class="quantity-remaining negative" v-else-if="product.quantity_remaining <= 0">{{ product.quantity_remaining }} {{ 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>{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td>
@@ -541,7 +595,7 @@ $this->setPageTitle('Distributions') ;
<div class="actions-form">
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id && order.id_user > 0" data-process-credit="1">Créer et payer</button>
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id && order.id_user > 0" data-process-credit="1">Modifier et payer</button>
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button>
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-else>Créer</button>


+ 1
- 1
backend/views/document/_form.php View File

@@ -112,7 +112,7 @@ use common\models\Producer;
<div id="" class="info-box">
<span class="info-box-icon bg-red"><i class="fa fa-flash"></i></span>
<div class="info-box-content">
<a v-if="document.status == 'draft' && document.class == 'Invoice'" class="btn btn-default" @click="validateDocument">Valider le document</a>
<a v-if="document.status == 'draft'" class="btn btn-default" @click="validateDocument">Valider le document</a>
</div>
</div>
</div>

+ 46
- 27
backend/web/css/screen.css View File

@@ -1704,7 +1704,7 @@ body.login-page .login-box .login-box-body a:hover {
position: fixed;
bottom: 30px;
right: 15px;
width: 200px;
width: 300px;
height: auto;
}
/* line 9, ../sass/_alerts.scss */
@@ -2014,11 +2014,25 @@ termes.
-webkit-border-radius: 10px;
border-radius: 10px;
}
/* line 207, ../sass/distribution/_index.scss */
/* line 204, ../sass/distribution/_index.scss */
.distribution-index #orders #buttons-top-orders {
background-color: #F5F5F5;
padding: 10px 20px;
border: solid 1px #e0e0e0;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
margin-bottom: 20px;
}
/* line 215, ../sass/distribution/_index.scss */
.distribution-index #orders #buttons-top-orders .right {
float: right;
}
/* line 222, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller {
width: 60px;
}
/* line 210, ../sass/distribution/_index.scss */
/* line 225, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller label {
font-size: 12px;
cursor: pointer;
@@ -2026,73 +2040,78 @@ termes.
top: -2px;
font-weight: normal;
}
/* line 219, ../sass/distribution/_index.scss */
/* line 234, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions {
position: relative;
text-align: right;
width: 230px;
}
/* line 223, ../sass/distribution/_index.scss */
/* line 238, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .dropdown-menu {
top: 0px;
right: 0px;
}
/* line 243, ../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 228, ../sass/distribution/_index.scss */
/* line 248, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .add-subscription {
position: relative;
}
/* line 230, ../sass/distribution/_index.scss */
/* line 250, ../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 239, ../sass/distribution/_index.scss */
/* line 259, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-state-payment {
width: 120px;
}
/* line 244, ../sass/distribution/_index.scss */
/* line 264, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-payment div.btn-group {
width: 125px;
}
/* line 250, ../sass/distribution/_index.scss */
/* line 270, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view ul {
list-style-type: none;
margin-left: 0px;
padding-left: 15px;
}
/* line 259, ../sass/distribution/_index.scss */
/* line 279, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view .comment {
margin-top: 20px;
}
/* line 268, ../sass/distribution/_index.scss */
/* line 288, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .btn-credit {
float: right;
}
/* line 274, ../sass/distribution/_index.scss */
/* line 294, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered td {
background-color: #e9e9e9;
}
/* line 278, ../sass/distribution/_index.scss */
/* line 298, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered input {
font-size: 16px;
font-weight: bold;
}
/* line 284, ../sass/distribution/_index.scss */
/* line 304, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity {
width: 165px;
}
/* line 287, ../sass/distribution/_index.scss */
/* line 307, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity input {
text-align: center;
color: black;
}
/* line 291, ../sass/distribution/_index.scss */
/* line 311, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .form-control {
border-right: 0px none;
padding-right: 4px;
}
/* line 295, ../sass/distribution/_index.scss */
/* line 315, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .input-group-addon {
padding: 5px;
padding-left: 0px;
@@ -2100,35 +2119,35 @@ termes.
border-left: 0px none;
border-right: 0px none;
}
/* line 303, ../sass/distribution/_index.scss */
/* line 323, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining {
text-align: right;
}
/* line 306, ../sass/distribution/_index.scss */
/* line 326, ../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 310, ../sass/distribution/_index.scss */
/* line 330, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.negative {
color: #DD4B39;
}
/* line 314, ../sass/distribution/_index.scss */
/* line 334, ../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 321, ../sass/distribution/_index.scss */
/* line 341, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .actions-form button {
margin-left: 15px;
}
/* line 329, ../sass/distribution/_index.scss */
/* line 349, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon {
width: 50px;
}
/* line 331, ../sass/distribution/_index.scss */
/* line 351, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon i {
font-size: 30px;
}
/* line 335, ../sass/distribution/_index.scss */
/* line 355, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-content {
margin-left: 50px;
}

+ 5
- 0
backend/web/js/vuejs/alerts.js View File

@@ -9,6 +9,11 @@ var appAlerts = new Vue({

},
methods: {
alertResponse: function(response) {
if(response.data.alert) {
this.alert(response.data.alert.type, response.data.alert.message) ;
}
},
alert: function(type, message) {
var app = this ;
var index = this.alerts.length ;

+ 53
- 3
backend/web/js/vuejs/distribution-index.js View File

@@ -38,6 +38,7 @@ termes.
var app = new Vue({
el: '#app-distribution-index',
data: {
UrlManager: UrlManager,
baseUrl: $('meta[name=baseurl]').attr('content'),
date: null,
dateFormat: null,
@@ -59,6 +60,7 @@ var app = new Vue({
ordersUpdate: [],
countOrders: 0,
users: [],
deliveryNotes: [],
showModalProducts: false,
showModalPointsSale: false,
showModalFormOrderCreate: false,
@@ -71,6 +73,7 @@ var app = new Vue({
idOrderPayment: 0,
showLoading: false,
tillerIsSynchro: false,
checkboxSelectAllOrders: false,
calendar: {
mode: 'single',
attrs: [],
@@ -150,7 +153,6 @@ var app = new Vue({
app.products = response.data.products ;
app.initCountActiveProducts() ;
app.meansPayment = response.data.means_payment ;
app.oneDistributionWeekActive = response.data.one_distribution_week_active ;
app.countOrders = 0 ;
@@ -184,7 +186,11 @@ var app = new Vue({
if(response.data.users) {
app.users = response.data.users ;
}

if(response.data.delivery_notes) {
app.deliveryNotes = response.data.delivery_notes ;
}

app.tillerIsSynchro = response.data.tiller_is_synchro ;
app.calendar.attrs = [] ;
@@ -203,7 +209,8 @@ var app = new Vue({
}
}
app.showLoading = false ;
app.showLoading = false ;
app.checkboxSelectAllOrders = false ;
}) ;
},
initCountActiveProducts: function() {
@@ -413,6 +420,15 @@ var app = new Vue({
app.init(app.idActivePointSale) ;
}) ;
},
totalActivePointSale: function() {
var total = 0 ;
for(var i = 0; i < this.orders.length ; i++) {
if(this.orders[i].id_point_sale == this.idActivePointSale) {
total += this.orders[i].amount ;
}
}
return formatPrice(total) ;
},
changeSynchroTiller: function(event) {
var app = this ;
var idOrder = event.currentTarget.getAttribute('data-id-order') ;
@@ -424,6 +440,40 @@ var app = new Vue({
app.init() ;
}) ;
},
selectAllOrders: function(event) {
var bool = event.currentTarget.checked ;
for(var key in this.orders) {
if(this.orders[key].id_point_sale == this.idActivePointSale) {
this.orders[key].selected = bool ;
}
}
},
oneOrderSelected: function() {
for(var key in this.orders) {
if(this.orders[key].selected == true) {
return true ;
}
}
return false ;
},
generateDeliveryNote: function() {
var app = this ;
var idOrders = {} ;
for(var key in this.orders) {
if(this.orders[key].selected == true) {
idOrders[key] = this.orders[key].id ;
}
}
axios.get(UrlManager.getBaseUrlAbsolute()+"distribution/ajax-generate-delivery-note",{params: {
idOrders: JSON.stringify(idOrders)
}})
.then(function(response) {
if(response.data.alert && response.data.alert.length) {
appAlerts.alert(response.data.return, response.data.alert) ;
}
app.init(app.idActivePointSale) ;
}) ;
}
},
});


+ 3
- 2
backend/web/js/vuejs/document-form.js View File

@@ -101,6 +101,7 @@ var app = new Vue({
classDocument: app.classDocument,
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.init() ;
}) ;
},
@@ -131,9 +132,9 @@ var app = new Vue({
price: app.productAddPrice,
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.productAddId = 0 ;
app.init() ;
appAlerts.alert('success','Produit ajouté') ;
}) ;
},
deleteProductOrder: function(idProductOrder) {
@@ -142,8 +143,8 @@ var app = new Vue({
idProductOrder: idProductOrder
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.init() ;
appAlerts.alert('danger','Produit supprimé') ;
}) ;
},
formatProductAddPrice: function() {

+ 1
- 1
backend/web/sass/_alerts.scss View File

@@ -3,7 +3,7 @@
position: fixed ;
bottom: 30px ;
right: 15px ;
width: 200px ;
width: 300px ;
height: auto ;

.slide-fade-enter-active {

+ 23
- 3
backend/web/sass/distribution/_index.scss View File

@@ -200,7 +200,22 @@ termes.
}
}
}

#buttons-top-orders {
background-color: #F5F5F5 ;
padding: 10px 20px ;
border: solid 1px #e0e0e0 ;
@include border-radius(5px) ;
margin-bottom: 20px ;

.left {

}

.right {
float: right ;
}
}
table {
@@ -217,9 +232,14 @@ termes.
}
td.column-actions {
position: relative ;
text-align: right ;
width: 230px ;

.dropdown-menu {
top: 0px ;
right: 0px ;
}

.modal-form-order,
.modal-payment {
text-align: left ;

+ 3
- 2
common/models/Subscription.php View File

@@ -192,6 +192,7 @@ class Subscription extends ActiveRecordCommon
$order->id_point_sale = $this->id_point_sale;
$order->id_distribution = $distribution->id;
$order->id_subscription = $this->id;
$order->status = 'tmp-order' ;
if (strlen($this->comment)) {
$order->comment = $this->comment;
}
@@ -243,8 +244,8 @@ class Subscription extends ActiveRecordCommon
$productOrder->id_product = $productSubscription->product->id;
$productOrder->quantity = $productSubscription->quantity;
$productOrder->price = $productSubscription->product->price;
$productOrder->unit = $productSubscription->unit;
$productOrder->step = $productSubscription->step;
$productOrder->unit = $productSubscription->product->unit;
$productOrder->step = $productSubscription->product->step;
$productOrder->save();
$productsAdd = true;
}

Loading…
Cancel
Save