You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

820 lines
62KB

  1. <?php
  2. /**
  3. Copyright Souke (2018)
  4. contact@souke.fr
  5. Ce logiciel est un programme informatique servant à aider les producteurs
  6. à distribuer leur production en circuits courts.
  7. Ce logiciel est régi par la licence CeCILL soumise au droit français et
  8. respectant les principes de diffusion des logiciels libres. Vous pouvez
  9. utiliser, modifier et/ou redistribuer ce programme sous les conditions
  10. de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  11. sur le site "http://www.cecill.info".
  12. En contrepartie de l'accessibilité au code source et des droits de copie,
  13. de modification et de redistribution accordés par cette licence, il n'est
  14. offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  15. seule une responsabilité restreinte pèse sur l'auteur du programme, le
  16. titulaire des de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  17. droits patrimoniaux et les concédants successifs.
  18. A cet égard l'attention de l'utilisateur est attirée sur les risques
  19. associés au chargement, à l'utilisation, à la modification et/ou au
  20. développement et à la reproduction du logiciel par l'utilisateur étant
  21. donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  22. manipuler et qui le réserve donc à des développeurs et des professionnels
  23. avertis possédant des connaissances informatiques approfondies. Les
  24. utilisateurs sont donc invités à charger et tester l'adéquation du
  25. logiciel à leurs besoins dans des conditions permettant d'assurer la
  26. sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  27. à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  28. Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  29. pris connaissance de la licence CeCILL, et que vous en avez accepté les
  30. termes.
  31. */
  32. $this->setTitle('Distributions') ;
  33. $this->setPageTitle('Distributions') ;
  34. ?>
  35. <?php if($orderUpdate):
  36. $orderUpdateDistributionTimestamp = strtotime($orderUpdate->distribution->date);
  37. ?>
  38. <script>
  39. window.vueValues = {
  40. date: new Date(<?= date('Y', $orderUpdateDistributionTimestamp) ?>, <?= date('m', $orderUpdateDistributionTimestamp) - 1 ?>, <?= date('d', $orderUpdateDistributionTimestamp) ?>),
  41. dateFormat: '<?= date('d/m/Y', $orderUpdateDistributionTimestamp) ?>',
  42. showModalFormOrderUpdate: true,
  43. idOrderUpdate: <?= $orderUpdate->id ?>
  44. };
  45. </script>
  46. <?php endif; ?>
  47. <div id="app-distribution-index" class="app-vuejs">
  48. <?php if(strlen($date)): ?>
  49. <span id="distribution-date"><?= $date; ?></span>
  50. <?php endif; ?>
  51. <div id="loading" v-if="showLoading">
  52. <img src="<?= Yii::$app->urlManagerBackend->getBaseUrl(); ?>/img/loader.gif" alt="Chargement ..." />
  53. </div>
  54. <div id="wrapper-app-distribution-index" :class="'wrapper-app-vuejs '+(loading ? '' : 'loaded')">
  55. <div class="col-md-4">
  56. <div id="calendar">
  57. <v-calendar
  58. is-inline
  59. is-expanded
  60. v-model="date"
  61. popover-visibility="hidden"
  62. color="green"
  63. :mode="calendar.mode"
  64. :formats="calendar.formats"
  65. :theme-styles="calendar.themeStyles"
  66. :attributes="calendar.attrs"
  67. @dayclick='dayClicked'>
  68. ></v-calendar>
  69. </div>
  70. <div class="clr"></div>
  71. </div>
  72. <div class="col-md-8">
  73. <div v-if="date">
  74. <div id="infos-top">
  75. <div class="col-md-12">
  76. <div class="info-box" id="info-box-distribution">
  77. <span :class="'info-box-icon '+(distribution.active ? 'bg-green' : 'bg-red')"><i :class="'fa '+(distribution.active ? 'fa-check' : 'fa-remove')"></i></span>
  78. <div class="info-box-content">
  79. <span class="info-box-text">
  80. <h4>
  81. Distribution du <strong>{{ dateFormat }}</strong>
  82. <a v-if="distribution.active" class="btn btn-default" :href="distribution.url_order" @click="copyLinkOrder($event, distribution.url_order)"><span class="glyphicon glyphicon-link"></span></a>
  83. <span v-if="distribution.is_leave_period" class="label label-default">
  84. <span class="glyphicon glyphicon-info-sign"></span>
  85. Congés
  86. </span>
  87. </h4>
  88. <a @click="activeWeekDistribution" data-active="0" class="btn btn-default btn-active-week" v-if="oneDistributionWeekActive">Désactiver cette semaine</a>
  89. <a @click="activeWeekDistribution" data-active="1" class="btn btn-default btn-active-week" v-else>Activer cette semaine</a>
  90. <a @click="activeDistribution" data-active="0" class="btn btn-default" v-if="distribution.active">Désactiver ce jour</a>
  91. <a @click="activeDistribution" data-active="1" class="btn btn-default" v-else>Activer ce jour</a>
  92. </span>
  93. </div>
  94. </div>
  95. </div>
  96. <!-- produits -->
  97. <div class="col-md-6">
  98. <div class="info-box col-md-4">
  99. <span class="info-box-icon bg-yellow"><i class="fa fa-clone"></i></span>
  100. <div class="info-box-content">
  101. <span class="info-box-text">
  102. {{ countActiveProducts }} Produits<br />
  103. <template v-if="isOneProductMaximumQuantityExceeded()"><span class="glyphicon glyphicon-alert"></span> Quantités max dépassées<br /></template>
  104. <br />
  105. <button class="btn btn-default" @click="showModalProducts = true">Configurer</button>
  106. </span>
  107. </div>
  108. </div>
  109. </div>
  110. <modal v-if="showModalProducts" id="modal-products" @close="showModalProducts = false">
  111. <h3 slot="header">Produits</h3>
  112. <div slot="body">
  113. <table class="table table-condensed table-bordered table-hover">
  114. <thead>
  115. <tr>
  116. <td>Actif</td>
  117. <td>Nom</td>
  118. <td class="quantity-ordered">Commandé</td>
  119. <td class="quantity-remaining">Reste</td>
  120. <td class="quantity-max">Maximum</td>
  121. </tr>
  122. </thead>
  123. <tbody>
  124. <tr v-for="product in products" v-if="getProductDistribution(product)">
  125. <td>
  126. <button class="btn btn-success" v-if="getProductDistribution(product).active == 1"><span class="glyphicon glyphicon-ok"></span></button>
  127. <button class="btn btn-default" v-else data-active-product="1" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-ok"></span></button>
  128. <button class="btn btn-danger" v-if="getProductDistribution(product).active == 0"><span class="glyphicon glyphicon-remove"></span></button>
  129. <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>
  130. </td>
  131. <td>{{ product.name }}</td>
  132. <td class="quantity-ordered">
  133. {{ product.quantity_ordered ? product.quantity_ordered + ' '+ ((product.unit == 'piece') ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') : '&empty;' }}
  134. </td>
  135. <td class="quantity-remaining">
  136. <span class="infinite" v-if="(getProductQuantityRemainingGlobal(product) === null)">&infin;</span>
  137. <span class="negative" v-else-if="getProductQuantityRemainingGlobal(product) <= 0">
  138. {{ getProductQuantityRemainingGlobal(product) }} {{ product.unit == 'piece' ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)' }}
  139. <span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemainingGlobal(product) < 0"></span>
  140. </span>
  141. <span class="has-quantity" v-else>{{ getProductQuantityRemainingGlobal(product) }} {{ product.unit == 'piece' ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)' }}</span>
  142. </td>
  143. <td class="quantity-max">
  144. <div class="input-group">
  145. <input type="text" class="form-control quantity-max" placeholder="&infin;" :data-id-product="product.id" v-model="getProductDistribution(product).quantity_max" @keyup="productQuantityMaxChange" />
  146. <span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span>
  147. </div>
  148. <div class="limit-quantity-accessories" v-if="getProductDistribution(product).quantity_max != product.quantity_max && product.quantity_max">
  149. <span class="glyphicon glyphicon-warning-sign"></span> Limitation accessoires :
  150. <strong>{{ product.quantity_max }} {{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</strong>
  151. </div>
  152. </td>
  153. </tr>
  154. </tbody>
  155. </table>
  156. </div>
  157. <div slot="footer">
  158. <div class="actions-form">
  159. <button class="modal-default-button btn btn-default" @click="closeModalProducts">Fermer</button>
  160. </div>
  161. </div>
  162. </modal>
  163. <div class="col-md-6">
  164. <div class="info-box col-md-4">
  165. <span class="info-box-icon bg-yellow"><i class="fa fa-map-marker"></i></span>
  166. <div class="info-box-content">
  167. <span class="info-box-text">
  168. {{ countActivePointsSale }} Points de vente<br /><br />
  169. <button class="btn btn-default" @click="showModalPointsSale = true">Configurer</button>
  170. </span>
  171. </div>
  172. </div>
  173. </div>
  174. <modal v-if="showModalPointsSale" id="modal-points-sale" @close="showModalPointsSale = false">
  175. <h3 slot="header">Points de vente</h3>
  176. <div slot="body">
  177. <table class="table table-condensed table-bordered table-hover">
  178. <thead>
  179. <tr>
  180. <td>Actif</td>
  181. <td>Nom</td>
  182. </tr>
  183. </thead>
  184. <tbody>
  185. <tr v-for="pointSale in pointsSale" v-if="pointSale.status == 1">
  186. <td>
  187. <button class="btn btn-success" v-if="pointSale.pointSaleDistribution[0].delivery == 1"><span class="glyphicon glyphicon-ok"></span></button>
  188. <button class="btn btn-default" v-else data-delivery-point-sale="1" :data-id-point-sale="pointSale.id" @click="pointSaleActiveClick"><span class="glyphicon glyphicon-ok"></span></button>
  189. <button class="btn btn-danger" v-if="pointSale.pointSaleDistribution[0].delivery == 0"><span class="glyphicon glyphicon-remove"></span></button>
  190. <button class="btn btn-default" v-else data-delivery-point-sale="0" :data-id-point-sale="pointSale.id" @click="pointSaleActiveClick"><span class="glyphicon glyphicon-remove"></span></button>
  191. </td>
  192. <td>{{ pointSale.name }}</td>
  193. </tr>
  194. </tbody>
  195. </table>
  196. </div>
  197. </modal>
  198. <div class="col-md-6">
  199. <div id="summary-ca-weight" class="info-box col-md-4">
  200. <span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
  201. <div class="info-box-content">
  202. <span class="info-box-text">CA réel / potentiel (HT)</span>
  203. <span class="info-box-number">
  204. <span data-toggle="tooltip" data-placement="bottom" :data-original-title="distribution.revenues_with_tax+' TTC'">{{ distribution.revenues }}</span>
  205. <span class="normal" v-if="distribution.potential_revenues != '0,00 €'">/ <span data-toggle="tooltip" data-placement="bottom" :data-original-title="distribution.potential_revenues_with_tax+' TTC'">{{ distribution.potential_revenues }}</span></span>
  206. </span>
  207. <span class="info-box-text">Poids</span>
  208. <span class="info-box-number">{{ distribution.weight }} kg <span class="normal" v-if="distribution.potential_weight > 0">/ {{ distribution.potential_weight }} kg</span></span>
  209. </div>
  210. </div>
  211. </div>
  212. <div class="col-md-6">
  213. <div class="info-box col-md-4">
  214. <span class="info-box-icon bg-yellow"><i class="fa fa-download"></i></span>
  215. <div class="info-box-content">
  216. <span class="info-box-text">
  217. {{ countOrders }} Commande<span v-if="countOrders > 1">s</span><br />
  218. <template v-for="distributionExport in distribution.exports">
  219. <a v-if="countOrders > 0" :href="distributionExport.url" target="_blank" class="btn btn-xs btn-default">{{ distributionExport.label }}</a><br />
  220. </template>
  221. <!--<a :href="distribution.url_report+'&type=csv'" class="btn btn-xs btn-default" v-if="countOrders > 0">Tableau (CSV)</a>
  222. <a :href="distribution.url_report_csv2" class="btn btn-xs btn-default" v-if="countOrders > 0">Tableau 2 (CSV)</a>
  223. <br />
  224. <a :href="distribution.url_report_grid" class="btn btn-xs btn-default" v-if="producer && producer.option_distribution_export_orders_grid_pdf && countOrders > 0">Grille (PDF)</a>
  225. <a :href="distribution.url_export_shopping_cart_labels" class="btn btn-xs btn-default" v-if="countOrders > 0">Étiquettes (PDF)</a>
  226. <a :href="distribution.url_report_total_products" class="btn btn-xs btn-default" v-if="countOrders > 0">Total produits (CSV)</a>-->
  227. </span>
  228. </div>
  229. </div>
  230. </div>
  231. </div>
  232. </div>
  233. <div class="callout callout-info" v-else>
  234. <h4><i class="fa fa-info"></i> Pour commencer</h4>
  235. <p>Veuillez choisir une date de distribution.</p>
  236. </div>
  237. </div>
  238. <div class="clr"></div>
  239. <div id="orders" class="panel panel-default" v-if="date">
  240. <div class="panel-heading">
  241. <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>
  242. <div class="buttons">
  243. </div>
  244. </div>
  245. <div class="panel-body">
  246. <order-form
  247. v-if="showModalFormOrderCreate"
  248. create="1"
  249. :date="date"
  250. :distribution="distribution"
  251. :order="orderCreate"
  252. :points-sale="pointsSale"
  253. :id-active-point-sale="idActivePointSale"
  254. :means-payment="meansPayment"
  255. :users="users"
  256. :products="products"
  257. :producer="producer"
  258. :orders="ordersUpdate"
  259. :loading-update-product-order="loadingUpdateProductOrder"
  260. :units="units"
  261. @close="closeModalOrderForm(true)"
  262. @ordercreatedupdated="orderCreatedUpdated"
  263. @updateproductorders="updateProductOrders"
  264. ></order-form>
  265. <div id="wrapper-nav-points-sale">
  266. <ul id="nav-points-sale">
  267. <li data-id-point-sale="0" data-id-point-sale="0" v-if="countActivePointsSale > 1" @click="pointSaleClick">
  268. <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>
  269. <a class="btn btn-default" v-else>Tous <span class="label label-default">{{ orders.length }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
  270. </li>
  271. <li v-for="pointSale in pointsSale" :data-id-point-sale="pointSale.id" v-if="pointSale.pointSaleDistribution[0].delivery == 1 && (pointSale.status == 1 || countOrdersByPointSale[pointSale.id] > 0)" @click="pointSaleClick">
  272. <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>
  273. <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>
  274. </li>
  275. </ul>
  276. <div class="clr"></div>
  277. </div>
  278. <div id="buttons-top-orders">
  279. <div class="right">
  280. <div class="dropdown">
  281. <button class="btn btn-default btn-xs dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
  282. <span class="glyphicon glyphicon-file"></span> Documents
  283. <span class="caret"></span>
  284. </button>
  285. <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  286. <li><a v-if="idActivePointSale > 0 && pointSaleActive.button_generate_delivery_note_point_sale == 1" @click="generateDeliveryNotePointSale" href="javascript:void(0);" >Générer un bon de livraison pour ce point de vente</a></li>
  287. <li><a v-if="idActivePointSale > 0 && pointSaleActive.button_generate_delivery_note_each_user == 1" @click="generateDeliveryNoteEachUser" href="javascript:void(0);">Générer un bon de livraison pour chaque client</a></li>
  288. <li><a @click="validateDeliveryNotes" href="javascript:void(0);">Valider les bons de livraisons</a></li>
  289. </ul>
  290. </div>
  291. <button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
  292. <template v-if="producer && producer.tiller == true">
  293. <template v-if="tillerIsAuthenticated">
  294. <button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-success btn-xs" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
  295. <template v-else-if="!isDistributionToday()">
  296. <span data-toggle="tooltip" data-placement="top" data-original-title="Synchronisation possible uniquement le jour de la distribution">
  297. <button id="btn-tiller" class="btn btn-xs btn-default" disabled><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
  298. </span>
  299. </template>
  300. <button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
  301. </template>
  302. <template v-else>
  303. <a :href="tillerUrlAuthorizeCode" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span> Connexion Tiller</a>
  304. </template>
  305. </template>
  306. <button v-if="producer && producer.credit" id="btn-pay-orders" class="btn btn-default btn-xs" @click="payOrders"><span class="glyphicon glyphicon-euro"></span> Débiter les commandes</button>
  307. <button id="btn-add-order" @click="openModalFormOrderCreate" class="btn btn-xs btn-primary"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button>
  308. </div>
  309. <div class="left">
  310. <a v-if="false && deliveryNoteExist(idActivePointSale)" :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>
  311. </div>
  312. <div class="clr"></div>
  313. </div>
  314. <div class="alert alert-info" v-if="missingSubscriptions && missingSubscriptions.length > 0">
  315. <span class="glyphicon glyphicon-info-sign"></span>
  316. {{ missingSubscriptions.length }} abonnement<template v-if="missingSubscriptions.length > 1">s</template> manquant<template v-if="missingSubscriptions.length > 1">s</template> :
  317. <span v-for="(subscription, index) in missingSubscriptions">
  318. {{ subscription.username }}<template v-if="index != missingSubscriptions.length - 1">, </template><template v-else>.</template>
  319. </span>
  320. </div>
  321. <div class="alert alert-danger" v-if="distribution && !distribution.active && orders && orders.length > 0">
  322. Attention, ce jour de distribution n'est pas activé et vous avez quand même des commandes enregistrées.
  323. </div>
  324. <div v-if="idActivePointSale > 0 && (totalActivePointSale() > 0 || weightActivePointSale() > 0 || pointSaleActive.producers_sharing_point_sale_as_string)" class="point-sale-totals">
  325. <div v-if="totalActivePointSale() > 0 || weightActivePointSale() > 0">
  326. <span class="title">Totaux</span>
  327. CA TTC : <strong>{{ totalActivePointSale() }} €</strong> / Poids : <strong>{{ weightActivePointSale() }} kg</strong>
  328. </div>
  329. <div v-if="producer.credit && pointSaleActive">
  330. <span class="title">Cagnotte</span>
  331. <template v-if="pointSaleActive.payment_method_credit && pointSaleActive.payment_method_credit == 1">
  332. <template v-if="pointSaleActive.credit_functioning == 'mandatory'">Obligatoire</template>
  333. <template v-else-if="pointSaleActive.credit_functioning == 'user'">Basé sur l'utilisateur</template>
  334. <template v-else-if="pointSaleActive.credit_functioning == 'optional'">Optionnel</template>
  335. </template>
  336. <template v-else>Désactivé</template>
  337. </div>
  338. <div v-if="pointSaleActive.producers_sharing_point_sale_as_string">
  339. <span class="title">Point de vente partagé</span>
  340. <i class="fa fa-share-alt"></i> {{ pointSaleActive.producers_sharing_point_sale_as_string }}
  341. </div>
  342. </div>
  343. <table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)">
  344. <thead>
  345. <tr>
  346. <th class="column-checkbox" v-if="idActivePointSale > 0">
  347. <input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrdersEvent" />
  348. </th>
  349. <th class="column-state">Statut</th>
  350. <th class="column-origin">Origine</th>
  351. <th class="column-user">Utilisateur</th>
  352. <th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th>
  353. <th class="column-amount">Montant</th>
  354. <th class="column-state-payment">Paiement</th>
  355. <th class="column-credit" v-if="!idActivePointSale || (pointSaleActive && pointSaleActive.payment_method_credit == 1)">Cagnotte</th>
  356. <th class="column-actions">Actions</th>
  357. <th class="column-tiller" v-if="producer && producer.tiller">Tiller</th>
  358. </tr>
  359. </thead>
  360. <tbody>
  361. <template v-for="(order, key, index) in orders" v-if="idActivePointSale == 0 || idActivePointSale == order.id_point_sale">
  362. <tr>
  363. <td class="column-checkbox" v-if="idActivePointSale > 0">
  364. <input type="checkbox" v-model="order.selected" />
  365. </td>
  366. <td class="column-state">
  367. <span v-if="order.order_status_alias == 'canceled'" class="label label-danger" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-trash"></span></span>
  368. <span v-if="order.order_status_alias == 'updated'" class="label label-warning" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-pencil"></span></span>
  369. <span v-if="order.order_status_alias == 'ordered'" class="label label-success" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-check"></span></span>
  370. </td>
  371. <td class="column-origin" v-html="order.labelOrigin"></td>
  372. <td class="column-user">
  373. <a v-if="order.user" :href="baseUrl+'/user/view?id='+order.id_user" target="_blank" :class="order.user.trust_alert ? 'user-trust-alert' : ''" :title="order.user.trust_alert ? order.user.trust_alert_comment : ''">
  374. {{ order.username_user }}
  375. </a>
  376. <span v-else class="user-without-account">{{ order.username }}</span>
  377. <span v-if="order.comment && order.comment.length > 0" class="glyphicon glyphicon-comment"></span>
  378. <span v-if="order.delivery_home && order.delivery_address && order.delivery_address.length > 0" class="glyphicon glyphicon-home"></span>
  379. </td>
  380. <td class="column-point-sale" v-if="idActivePointSale == 0">
  381. <template v-if="order.pointSale">
  382. {{ order.pointSale.name }}
  383. </template>
  384. </td>
  385. <td class="column-amount">
  386. {{ order.amount.toFixed(2)+'&nbsp;€' }}
  387. <div class="state-payment-mobile">
  388. <order-state-payment :order="order" :producer="producer"></order-state-payment>
  389. </div>
  390. </td>
  391. <td class="column-state-payment">
  392. <template v-if="order.order_status_alias == 'ordered' || order.order_status_alias == 'updated'">
  393. <a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
  394. <order-state-payment :order="order" :producer="producer"></order-state-payment>
  395. </a>
  396. <span class="glyphicon glyphicon-time" title="Débit automatique de la cagnotte la veille de la distribution" v-if="order.amount != 0 && order.isCreditAutoPayment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
  397. </template>
  398. </td>
  399. <td class="column-credit" v-if="!idActivePointSale || (pointSaleActive && pointSaleActive.payment_method_credit == 1)">
  400. <template v-if="order.isCreditContext">
  401. <a :href="baseUrl+'/user/credit?id='+order.id_user" target="_blank" :class="order.user.credit >= 0 ? 'positive' : 'negative'">
  402. {{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}
  403. </a>
  404. </template>
  405. </td>
  406. <td class="column-actions">
  407. <span v-if="false && order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>
  408. <a href="javascript:void(0);" class="btn btn-default btn-xs" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span></a>
  409. <a href="javascript:void(0);" class="btn btn-default btn-xs" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span></a>
  410. <div class="wrapper-button-dropdown">
  411. <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  412. € <span class="caret"></span>
  413. </button>
  414. <ul class="dropdown-menu">
  415. <template v-if="!order.isPaidViaInvoice">
  416. <li v-if="order.isCreditContext">
  417. <a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit">
  418. <span class="glyphicon glyphicon-piggy-bank"></span> {{ getLabelPaymentRefund(order, 'Débiter', 'Recréditer', 'la cagnotte') }}
  419. </a>
  420. </li>
  421. <template v-if="(!order.isCreditFunctioningMandatory && !order.isCreditFunctioningUser) || !order.id_user">
  422. <li>
  423. <a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="money">
  424. <span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'en espèce') }}
  425. </a>
  426. </li>
  427. <li>
  428. <a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="cheque">
  429. <span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par chèque') }}
  430. </a>
  431. </li>
  432. <li>
  433. <a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="transfer">
  434. <span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par virement') }}
  435. </a>
  436. </li>
  437. <li>
  438. <a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit-card">
  439. <span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par carte bancaire') }}
  440. </a>
  441. </li>
  442. </template>
  443. </template>
  444. <li>
  445. <a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
  446. <span class="glyphicon glyphicon-th-list"></span> Historique
  447. </a>
  448. </li>
  449. </ul>
  450. </div>
  451. <div class="wrapper-button-dropdown">
  452. <button type="button" :class="'btn btn-xs dropdown-toggle ' + (countDocuments(order) ? 'btn-success' : 'btn-default')" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  453. <span class="glyphicon glyphicon-file"></span> <template v-if="countDocuments(order)">{{ countDocuments(order) }}</template> <span class="caret"></span>
  454. </button>
  455. <ul class="dropdown-menu">
  456. <li v-if="!order.id_delivery_note">
  457. <a href="javascript:void(0);" :data-id-order="order.id" @click="generateDeliveryNote">
  458. <span class="glyphicon glyphicon-plus"></span> Générer un bon de livraison
  459. </a>
  460. </li>
  461. <li v-if="order.id_quotation">
  462. <a :href="UrlManager.getBaseUrl()+'quotation/update?id='+order.id_quotation">
  463. <span class="glyphicon glyphicon-file"></span> Modifier le devis
  464. </a>
  465. </li>
  466. <li v-if="order.id_delivery_note && order.deliveryNote">
  467. <a :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note">
  468. <span class="glyphicon glyphicon-file"></span> Modifier le bon de livraison
  469. </a>
  470. <template v-if="order.deliveryNote.status == 'valid'">
  471. <a v-if="!order.deliveryNote.is_sent" href="javascript:void(0);" :data-id-order="order.id" @click="sendDeliveryNote">
  472. <span class="glyphicon glyphicon-send"></span> Envoyer le bon de livraison
  473. </a>
  474. <a v-else class="text-success disable" href="#">
  475. <span class="glyphicon glyphicon-ok"></span> Bon de livraison envoyé
  476. </a>
  477. </template>
  478. </li>
  479. <li v-if="order.id_invoice">
  480. <a :href="UrlManager.getBaseUrl()+'invoice/update?id='+order.id_invoice">
  481. <span class="glyphicon glyphicon-file"></span> Modifier la facture
  482. </a>
  483. </li>
  484. </ul>
  485. </div>
  486. <div class="wrapper-button-dropdown">
  487. <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  488. <span class="caret"></span>
  489. </button>
  490. <ul class="dropdown-menu">
  491. <li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span> {{ order.labelDeleteAction }}</a></li>
  492. <li v-if="producer && producer.tiller"><a href="javascript:void(0);" @click="forceSynchronizeOrderTiller(order.id)"><span class="glyphicon glyphicon-transfer"></span> Synchroniser avec Tiller</a></li>
  493. <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 lié</a></li>
  494. <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</a></li>
  495. </ul>
  496. </div>
  497. <order-form
  498. v-if="showModalFormOrderUpdate && idOrderUpdate == order.id"
  499. create="0"
  500. :distribution="distribution"
  501. :date="date"
  502. :date-format="dateFormat"
  503. :points-sale="pointsSale"
  504. :id-active-point-sale="idActivePointSale"
  505. :means-payment="meansPayment"
  506. :users="users"
  507. :products="products"
  508. :order="ordersUpdate[key]"
  509. :orders="ordersUpdate"
  510. :producer="producer"
  511. :loading-update-product-order="loadingUpdateProductOrder"
  512. :units="units"
  513. @close="closeModalOrderForm(false)"
  514. @ordercreatedupdated="orderCreatedUpdated"
  515. @updateproductorders="updateProductOrders"
  516. @updateinvoiceprices="updateInvoicePrices"
  517. ></order-form>
  518. <modal v-if="showModalPayment && idOrderPayment == order.id" class="modal-payment" @close="showModalPayment = false">
  519. <h3 slot="header">
  520. Commande du <strong>{{ dateFormat }}</strong> &gt;
  521. <strong><span v-if="order.user">{{ order.username_user }}</span>
  522. <span v-else>{{ order.username }}</span></strong>
  523. </h3>
  524. <div slot="body">
  525. <div class="row">
  526. <div class="col-md-6">
  527. <div class="info-box">
  528. <span :class="'info-box-icon ' +((order.isPaid) ? 'bg-green' : 'bg-red')"><i class="fa fa-check"></i></span>
  529. <div class="info-box-content">
  530. <span class="info-box-text">Montant</span>
  531. <span class="info-box-number">
  532. {{ order.amount.toFixed(2)+' €' }}
  533. </span>
  534. </div>
  535. </div>
  536. </div>
  537. <div class="col-md-6" v-if="order.isCreditContext">
  538. <div class="info-box">
  539. <span :class="'info-box-icon ' +((order.user.credit > 0) ? 'bg-green' : 'bg-red')"><i class="fa fa-user"></i></span>
  540. <div class="info-box-content">
  541. <span class="info-box-text">Cagnotte</span>
  542. <span class="info-box-number">
  543. {{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
  544. </span>
  545. </div>
  546. </div>
  547. </div>
  548. </div>
  549. <div class="row">
  550. <div class="col-md-12">
  551. <h4>Historique paiements</h4>
  552. <table class="table table-condensed table-bordered table-hover" v-if="order.paymentsArray && order.paymentsArray.length > 0">
  553. <thead>
  554. <tr>
  555. <td>Date</td>
  556. <td>Origine action</td>
  557. <td>Type</td>
  558. <td>Moyen</td>
  559. <td>Montant</td>
  560. </tr>
  561. </thead>
  562. <tbody>
  563. <tr v-for="payment in order.paymentsArray">
  564. <td>{{ payment.date }}</td>
  565. <td>{{ payment.user_action }}</td>
  566. <td>{{ payment.wording_type }}</td>
  567. <td>{{ payment.wording_mean_payment }}</td>
  568. <td v-html="payment.amount"></td>
  569. </tr>
  570. </tbody>
  571. </table>
  572. <div class="alert alert-info" v-else>
  573. Aucun paiement rattaché à commande.
  574. </div>
  575. <div class="alert alert-success" v-if="order.isPaidViaInvoice">
  576. La commande est payée via la <a :href="UrlManager.getBaseUrl()+'invoice/update?id='+order.id_invoice">facture</a> à laquelle elle est rattachée.
  577. </div>
  578. </div>
  579. </div>
  580. </div>
  581. </modal>
  582. </td>
  583. <td v-if="producer && producer.tiller" class="tiller column-tiller">
  584. <input v-if="order.tiller_synchronization == true" type="checkbox" checked="checked" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
  585. <input v-else type="checkbox" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
  586. <label :for="'checkbox-tiller-synchronization-'+order.id">Tiller</label>
  587. </td>
  588. </tr>
  589. <tr class="view" v-if="showViewProduct && idOrderView == order.id">
  590. <td colspan="6">
  591. <strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong>
  592. <ul>
  593. <li v-for="product in products" v-if="getProductDistribution(product) && order.productOrder[product.id].quantity > 0">
  594. {{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="getProductDistribution(product).active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
  595. </li>
  596. </ul>
  597. <div v-if="order.comment && order.comment.length > 0" class="comment">
  598. <strong><span class="glyphicon glyphicon-menu-right"></span> Commentaire</strong><br />
  599. {{ order.comment }}
  600. </div>
  601. <div v-if="order.delivery_home && order.delivery_address && order.delivery_address.length > 0" class="delivery">
  602. <strong><span class="glyphicon glyphicon-menu-right"></span> Livraison à domicile</strong><br />
  603. {{ order.delivery_address }}
  604. </div>
  605. </td>
  606. </tr>
  607. </template>
  608. </tbody>
  609. </table>
  610. <div class="alert alert-warning" v-else>
  611. Aucune commande
  612. </div>
  613. </div>
  614. </div>
  615. </div>
  616. </div>
  617. <script type="text/x-template" id="order-state-payment">
  618. <span v-html="order.paymentLabelShort"></span>
  619. </script>
  620. <!-- template for the order-form component -->
  621. <script type="text/x-template" id="order-form-template">
  622. <modal class="modal-form-order" @close="$emit('close')">
  623. <h3 v-if="order.id" slot="header">
  624. <template v-if="order.id">Modifier</template>
  625. <template v-else>Ajouter</template>
  626. une commande - {{ dateFormat }}
  627. </h3>
  628. <div slot="body">
  629. <div class="callout callout-warning" v-if="errors.length">
  630. <ul>
  631. <li v-for="error in errors">{{ error }}</li>
  632. </ul>
  633. </div>
  634. <div class="col-md-4">
  635. <div class="form-group">
  636. <a v-if="producer && producer.credit && order.id_user > 0 && user.id_user == order.id_user" class="btn btn-xs btn-primary btn-credit" :href="baseUrl+'/user/credit?id='+user.id_user" v-for="user in users">{{ parseFloat(user.credit).toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}</a>
  637. <label class="control-label" for="select-id-user">
  638. Utilisateur
  639. <a v-if="!order.id_user || order.id_user == 0" class="btn btn-default btn-xs" :href="distribution.user_create_href">
  640. <span class="glyphicon glyphicon-plus"></span>
  641. Créer un utilisateur
  642. </a>
  643. </label>
  644. <select class="form-control select2-order-form" v-model="order.id_user" @change="userChange">
  645. <option value="0">--</option>
  646. <option v-for="user in users" :value="user.id_user">
  647. {{ user.username }}
  648. </option>
  649. </select>
  650. <input v-model="order.username" type="text" class="form-control" placeholder="Ou saisissez ici le nom de l'utilisateur" />
  651. </div>
  652. <div class="form-group">
  653. <label class="control-label" for="select-id-point-sale">Point de vente</label>
  654. <select class="form-control" id="select-id-point-sale" v-model="order.id_point_sale" @change="pointSaleChange">
  655. <option value="0">--</option>
  656. <option v-for="pointSale in pointsSale" v-if="pointSale.pointSaleDistribution[0].delivery == 1" :value="pointSale.id"">{{ pointSale.name }}</option>
  657. </select>
  658. </div>
  659. <div class="form-group">
  660. <label class="control-label" for="textarea-comment">Commentaire</label>
  661. <textarea class="form-control" id="textarea-comment" v-model="order.comment"></textarea>
  662. </div>
  663. <div class="form-group" v-if="isPointSaleCreditFunctioningOptional(order.id_point_sale)">
  664. <input type="checkbox" id="debit-credit" v-model="order.debitCredit" />
  665. <label class="control-label" for="debit-credit">Débiter la cagnotte</label>
  666. </div>
  667. </div>
  668. <div class="col-md-8">
  669. <label class="control-label">Produits</label>
  670. <table class="table table-condensed table-bordered table-hover table-products">
  671. <thead>
  672. <tr>
  673. <th></th>
  674. <th>Nom</th>
  675. <th>Prix unitaire</th>
  676. <th>Quantité</th>
  677. <th>Reste</th>
  678. </tr>
  679. </thead>
  680. <tbody>
  681. <tr v-for="product in products" v-if="product.status >= 0 || order.productOrder[product.id].quantity > 0" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''">
  682. <td>
  683. <span class="label label-success" v-if="order.productOrder[product.id].active">Actif</span>
  684. <span class="label label-danger" v-else>Inactif</span>
  685. </td>
  686. <td>
  687. {{ product.name }}
  688. </td>
  689. <td class="price">
  690. <div v-show="vatMode == 'all'" class="input-group">
  691. <input type="text" v-model="order.productOrder[product.id].price" class="form-control input-sm" @change="productPriceChange" :data-with-tax="false" :data-id-product="product.id" />
  692. <span class="input-group-addon" id="basic-addon2">€ HT&nbsp;&nbsp;</span>
  693. </div>
  694. <div class="input-group">
  695. <input type="text" v-model="order.productOrder[product.id].price_with_tax" class="form-control input-sm" @change="productPriceChange" :data-with-tax="true" :data-id-product="product.id" />
  696. <span class="input-group-addon" id="basic-addon2">€ TTC</span>
  697. </div>
  698. <div class="invoice-price" v-show="vatMode == 'all'" v-if="(order.id_invoice || order.id_delivery_note || order.id_quotation) && order.productOrder[product.id].quantity > 0">
  699. <span class="label-invoice-price">Prix facturé</span><br />
  700. <div class="input-group">
  701. <input v-if="order.isLinkedToValidInvoice" type="text" v-model="order.productOrder[product.id].invoice_price" class="form-control input-sm" :data-id-product="product.id" disabled="disabled" title="La commande est liée à une facture validée, le prix facturé n'est donc plus modifiable" />
  702. <input v-else type="text" v-model="order.productOrder[product.id].invoice_price" class="form-control input-sm" :data-id-product="product.id" />
  703. <span class="input-group-addon" id="basic-addon2">€ HT</span>
  704. </div>
  705. </div>
  706. </td>
  707. <td class="quantity">
  708. <div class="input-group">
  709. <span class="input-group-btn">
  710. <button class="btn btn-default btn-moins" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? -1 : -parseFloat(product.step))"><span class="glyphicon glyphicon-minus"></span></button>
  711. </span>
  712. <input type="text" v-model="order.productOrder[product.id].quantity" class="form-control input-quantity" />
  713. <span class="input-group-addon">{{ order.productOrder[product.id].unit == 'piece' ? 'p.' : order.productOrder[product.id].unit }}</span>
  714. <span class="input-group-btn">
  715. <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>
  716. </span>
  717. </div>
  718. </td>
  719. <td class="quantity-remaining">
  720. <span class="infinite" v-if="(getProductQuantityRemaining(order, product) === null) || order.productOrder[product.id].unit != product.unit">&infin;</span>
  721. <span class="negative" v-else-if="getProductQuantityRemaining(order, product) <= 0">
  722. {{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}
  723. <span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(order, product) < 0"></span>
  724. </span>
  725. <span class="has-quantity" v-else>{{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</span>
  726. </td>
  727. </tr>
  728. </tbody>
  729. </table>
  730. </div>
  731. </div>
  732. <div slot="footer">
  733. <div class="actions-form">
  734. <button class="modal-default-button btn btn-danger" @click="$emit('close')">Fermer</button>
  735. <button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button>
  736. <button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id">Créer</button>
  737. <div class="right">
  738. <button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrders(true)">Recharger les prix</button>
  739. <button v-if="order.id" class="modal-default-button btn btn-info btn-update-prices" @click="updateInvoicePrices(true)">
  740. Réinitialiser les prix facturés
  741. </button>
  742. <button class="modal-default-button btn btn-info btn-display-prices-without-tax" @click="toggleVatMode()">
  743. <template v-if="vatMode == 'all'">Cacher</template>
  744. <template v-else>Afficher</template>
  745. les prix HT
  746. </button>
  747. </div>
  748. </div>
  749. </div>
  750. </modal>
  751. </script>
  752. <!-- template for the modal component -->
  753. <script type="text/x-template" id="modal-template">
  754. <transition name="modal">
  755. <div class="modal-mask">
  756. <div class="modal-wrapper">
  757. <div class="modal-container">
  758. <div class="modal-header">
  759. <slot name="header"></slot>
  760. </div>
  761. <div class="modal-body">
  762. <slot name="body"></slot>
  763. </div>
  764. <div class="modal-footer">
  765. <slot name="footer">
  766. <button class="modal-default-button btn btn-default" @click="$emit('close')">Fermer</button>
  767. </slot>
  768. </div>
  769. </div>
  770. </div>
  771. </div>
  772. </transition>
  773. </script>