Преглед на файлове

Merge branch 'develop'

master
Guillaume Bourgeois преди 1 година
родител
ревизия
ce572bf17f
променени са 45 файла, в които са добавени 1529 реда и са изтрити 879 реда
  1. +52
    -88
      backend/controllers/DocumentController.php
  2. +62
    -42
      backend/controllers/InvoiceController.php
  3. +8
    -4
      backend/views/distribution/index.php
  4. +306
    -230
      backend/views/document/_form.php
  5. +9
    -2
      backend/views/product/update/prices/_form.php
  6. +5
    -2
      backend/views/subscription/index.php
  7. +23
    -0
      backend/web/js/backend.js
  8. +11
    -1
      backend/web/js/vuejs/distribution-index.js
  9. +49
    -14
      backend/web/js/vuejs/document-form.js
  10. +25
    -0
      common/config/main.php
  11. +1
    -1
      common/config/params.php
  12. +2
    -5
      common/forms/SubscriptionForm.php
  13. +1
    -1
      common/logic/Document/DeliveryNote/Model/DeliveryNote.php
  14. +1
    -1
      common/logic/Document/Document/Model/Document.php
  15. +6
    -0
      common/logic/Document/Document/Service/DocumentBuilder.php
  16. +5
    -2
      common/logic/Document/Document/Service/DocumentUtils.php
  17. +1
    -0
      common/logic/Document/Invoice/Model/Invoice.php
  18. +11
    -0
      common/logic/Order/Order/Event/OrderDeleteEvent.php
  19. +4
    -1
      common/logic/Order/Order/Model/Order.php
  20. +56
    -1
      common/logic/Order/Order/Repository/OrderRepository.php
  21. +30
    -0
      common/logic/Order/Order/Repository/OrderRepositoryQuery.php
  22. +52
    -60
      common/logic/Order/Order/Service/OrderBuilder.php
  23. +8
    -5
      common/logic/Order/Order/Service/OrderSolver.php
  24. +1
    -1
      common/logic/Subscription/Subscription/Model/Subscription.php
  25. +28
    -0
      common/logic/User/CreditHistory/Event/OrderObserver.php
  26. +13
    -9
      common/logic/User/CreditHistory/Service/CreditUtils.php
  27. +26
    -0
      common/versions/23.9.C.php
  28. +2
    -2
      common/versions/_macros.php
  29. +2
    -1
      composer.json
  30. +244
    -84
      composer.lock
  31. +28
    -0
      console/migrations/m230912_070221_add_column_order_ignore_when_invoicing.php
  32. +1
    -1
      frontend/views/site/_prices_producer.php
  33. +4
    -4
      frontend/views/site/index.php
  34. +121
    -114
      frontend/views/site/service.php
  35. +163
    -140
      frontend/web/css/screen.css
  36. +71
    -0
      frontend/web/js/frontend.js
  37. +5
    -1
      frontend/web/sass/_responsive.scss
  38. +18
    -3
      frontend/web/sass/screen.scss
  39. +11
    -1
      producer/controllers/NewsletterController.php
  40. +2
    -1
      producer/controllers/SubscriptionController.php
  41. +3
    -1
      producer/views/order/order.php
  42. +20
    -3
      producer/views/subscription/_form.php
  43. +1
    -1
      producer/views/subscription/form.php
  44. +2
    -2
      producer/views/subscription/index.php
  45. +35
    -50
      producer/web/js/vuejs/order-order.js

+ 52
- 88
backend/controllers/DocumentController.php Целия файл

@@ -38,6 +38,7 @@

namespace backend\controllers;

use common\helpers\Ajax;
use common\helpers\CSV;
use common\helpers\GlobalParam;
use common\helpers\Price;
@@ -113,6 +114,7 @@ class DocumentController extends BackendController

if ($model->save()) {
$this->processInvoiceViaDeliveryNotes($model);
$this->processInvoiceViaOrders($model);

$this->setFlash('success', $this->getFlashMessage('create', $model));
return $this->redirect(['/' . $this->getControllerUrl() . '/update', 'id' => $model->id]);
@@ -130,27 +132,33 @@ class DocumentController extends BackendController

public function processInvoiceViaDeliveryNotes($model)
{
$orderManager = $this->getOrderManager();
$documentManager = $this->getDocumentManager();
$deliveryNoteManager = $this->getDeliveryNoteManager();
if ($documentManager->getClass($model) == 'Invoice') {
if ($model->deliveryNotes && is_array($model->deliveryNotes) && count($model->deliveryNotes)) {
foreach ($model->deliveryNotes as $key => $idDeliveryNote) {
Order::updateAll([
'id_invoice' => $model->id
], [
'id_delivery_note' => $idDeliveryNote
]);
$deliveryNote = $deliveryNoteManager->findOneDeliveryNoteById($idDeliveryNote);
$orderManager->assignAllOrdersInvoiceByDeliveryNote($model, $deliveryNote);
}
}
}
}

public function processInvoiceViaOrders($model)
{
$orderManager = $this->getOrderManager();
$documentManager = $this->getDocumentManager();
if ($documentManager->getClass($model) == 'Invoice') {
if ($model->ordersOnCreate && is_array($model->ordersOnCreate) && count($model->ordersOnCreate)) {
foreach ($model->ordersOnCreate as $key => $idOrder) {
$order = $orderManager->findOneOrderById($idOrder);
$orderManager->updateOrderInvoice($order, $model);
}
}
}
}

/**
* Modifie un modèle Produit existant.
* Si la modification réussit, le navigateur est redirigé vers la page 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
@@ -173,7 +181,6 @@ class DocumentController extends BackendController
public function actionDelete($id)
{
$documentManager = $this->getDocumentManager();

$model = $this->findModel($id);

if ($documentManager->isStatusValid($model)) {
@@ -339,6 +346,7 @@ class DocumentController extends BackendController
{
$documentManager = $this->getDocumentManager();
$document = $this->findModel($id);

return $documentManager->downloadPdf($document);
}

@@ -356,10 +364,7 @@ class DocumentController extends BackendController
{
$documentManager = $this->getDocumentManager();
$document = $this->findModel($id);
if ($documentManager->send($document)) {
$document->is_sent = true;
$document->save();

if ($documentManager->sendDocument($document)) {
$this->setFlash('success', $this->getFlashMessage('send', $document));
} else {
$this->setFlash('danger', $this->getFlashMessage('send', $document));
@@ -376,6 +381,7 @@ class DocumentController extends BackendController
{
$userManager = $this->getUserManager();
$documentManager = $this->getDocumentManager();
$orderManager = $this->getOrderManager();

\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

@@ -407,16 +413,19 @@ class DocumentController extends BackendController
$deliveryNotesCreateArray = DeliveryNote::searchAll([
'id_user' => $user->id,
'status' => Document::STATUS_VALID,
'ignore_when_billing' => null
'ignore_when_invoicing' => null
], $options);
$deliveryNotesUpdateArray = DeliveryNote::searchAll([
'id_user' => $user->id,
'status' => Document::STATUS_VALID,
'order.id_invoice' => $idDocument,
'ignore_when_billing' => null
'ignore_when_invoicing' => null
], $options);
$json['delivery_note_create_array'] = $this->initDeliveryNoteArray('create', $deliveryNotesCreateArray);
$json['delivery_note_update_array'] = $this->initDeliveryNoteArray('update', $deliveryNotesUpdateArray);

$json['orders_create_array'] = $this->initOrdersArray($orderManager->findOrdersByUserNotInvoiced($user));
$json['orders_update_array'] = $document ? $this->initOrdersArray($orderManager->findOrdersByUserAndInvoice($user, $document)) : [];
}

return $json;
@@ -426,6 +435,24 @@ class DocumentController extends BackendController
return ['return' => 'error'];
}

public function initOrdersArray(array $ordersArray)
{
$orderManager = $this->getOrderManager();
$ordersReturnArray = [];

foreach($ordersArray as &$order) {
$orderManager->initOrder($order);
$ordersReturnArray[] = [
'id' => $order->id,
'date' => $order->distribution->date,
'name' => date('d/m/Y', strtotime($order->distribution->date)),
'amount_with_tax' => $orderManager->getOrderAmountWithTax($order, Order::INVOICE_AMOUNT_TOTAL)
];
}

return $ordersReturnArray;
}

public function initDeliveryNoteArray($type, $deliveryNoteArrayResults)
{
$deliveryNoteArray = [];
@@ -474,10 +501,9 @@ class DocumentController extends BackendController
$document = $this->findModel($id);

if ($document) {
$documentManager->changeStatus($document,Document::STATUS_VALID);
$documentManager->saveUpdate($document);
$documentManager->validateDocument($document);

// génération PDF
// @TODO : gérer via un événement
$documentManager->generatePdf($document, Pdf::DEST_FILE);

$this->setFlash('success', $this->getFlashMessage('validate', $document));
@@ -495,40 +521,6 @@ class DocumentController extends BackendController
return $this->redirect([$this->getControllerUrl() . '/index']);
}

public function actionAjaxValidateDocument($idDocument, $classDocument)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$documentManager = $this->getDocumentManager();

if ($idDocument > 0 && $documentManager->isValidClass($classDocument)) {
$document = $classDocument::searchOne([
'id' => $idDocument
]);

if ($document) {
$documentManager->changeStatus($document,Document::STATUS_VALID);
$documentManager->saveUpdate($document);

return [
'return' => 'success',
'alert' => [
'type' => 'success',
'message' => 'Document validé'
]
];
}
}

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

public function actionAjaxInit($idDocument, $classDocument)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
@@ -617,8 +609,6 @@ class DocumentController extends BackendController

public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$documentManager = $this->getDocumentManager();
$productManager = $this->getProductManager();

@@ -655,30 +645,16 @@ class DocumentController extends BackendController
$productOrder->id_tax_rate = $product->taxRate->id;
$productOrder->save();

return [
'return' => 'success',
'alert' => [
'type' => 'success',
'message' => 'Produit ajouté'
]
];
return Ajax::responseSuccess('Produit ajouté');
}
}
}

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

public function actionAjaxDeleteProductOrder($idProductOrder)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$productOrderManager = $this->getProductOrderManager();

$productOrder = $productOrderManager->findOneProductOrderById($idProductOrder);
@@ -686,22 +662,10 @@ class DocumentController extends BackendController
if ($productOrder) {
$productOrderManager->delete($productOrder);

return [
'return' => 'success',
'alert' => [
'type' => 'danger',
'message' => 'Produit supprimé'
]
];
return Ajax::responseSuccess('Produit supprimé');
}

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

public function getClass()

+ 62
- 42
backend/controllers/InvoiceController.php Целия файл

@@ -38,6 +38,7 @@

namespace backend\controllers;

use common\helpers\Ajax;
use common\logic\Document\Invoice\Model\InvoiceSearch;
use common\logic\Order\Order\Model\Order;

@@ -59,39 +60,23 @@ class InvoiceController extends DocumentController

public function actionAjaxDeleteDeliveryNote($idInvoice, $idDeliveryNote)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$orderManager = $this->getOrderManager();
$invoiceManager = $this->getInvoiceManager();
$deliveryNoteManager = $this->getDeliveryNoteManager();
$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$deliveryNote = $deliveryNoteManager->findOneDeliveryNoteById($idDeliveryNote);

if ($invoice && $invoiceManager->isStatusDraft($invoice)) {
Order::updateAll([
'id_invoice' => null
], [
'id_delivery_note' => $idDeliveryNote
]);

return [
'alert' => [
'type' => 'success',
'message' => 'Bon de livraison supprimé de la facture.'
]
];
if ($invoice && $invoiceManager->isStatusDraft($invoice) && $deliveryNote) {
$orderManager->unassignAllOrdersInvoiceByDeliveryNote($deliveryNote);
return Ajax::responseSuccess('Bon de livraison supprimé de la facture.');
} else {
return [
'alert' => [
'type' => 'error',
'message' => 'Une erreur est survenue lors de la suppression du bon de livraison.'
]
];
return Ajax::responseError('Une erreur est survenue lors de la suppression du bon de livraison.');
}
}

public function actionAjaxAddDeliveryNote($idInvoice, $idDeliveryNote)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$orderManager = $this->getOrderManager();
$invoiceManager = $this->getInvoiceManager();
$deliveryNoteManager = $this->getDeliveryNoteManager();

@@ -99,26 +84,61 @@ class InvoiceController extends DocumentController
$deliveryNote = $deliveryNoteManager->findOneDeliveryNoteById($idDeliveryNote);

if ($invoice && $invoiceManager->isStatusDraft($invoice) && $deliveryNote) {
Order::updateAll([
'id_invoice' => $idInvoice
], [
'id_delivery_note' => $idDeliveryNote
]);

return [
'alert' => [
'type' => 'success',
'message' => 'Bon de livraison ajouté à la facture.'
]
];
$orderManager->assignAllOrdersInvoiceByDeliveryNote($invoice, $deliveryNote);
return Ajax::responseSuccess("Bon de livraison ajouté à la facture.");
} else {
return [
'alert' => [
'type' => 'error',
'message' => 'Une erreur est survenue lors de l\'ajout du bon de livraison.'
]
];
return Ajax::responseError("Une erreur est survenue lors de l'ajout du bon de livraison.");
}
}

public function actionAjaxAddOrder($idInvoice, $idOrder)
{
$invoiceManager = $this->getInvoiceManager();
$orderManager = $this->getOrderManager();

$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$order = $orderManager->findOneOrderById($idOrder);

if ($invoice && $invoiceManager->isStatusDraft($invoice) && $order) {
$orderManager->updateOrderInvoice($order, $invoice);
return Ajax::responseSuccess("Commande ajoutée à la facture.");
}
else {
return Ajax::responseError("Une erreur est survenue lors de l'ajout de la commande.");
}
}

public function actionAjaxDeleteOrder($idInvoice, $idOrder)
{
$invoiceManager = $this->getInvoiceManager();
$orderManager = $this->getOrderManager();

$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$order = $orderManager->findOneOrderById($idOrder);

if ($invoice && $invoiceManager->isStatusDraft($invoice)) {
$orderManager->updateOrderInvoice($order, null);
return Ajax::responseSuccess('Commande supprimée de la facture.');
}
else {
return Ajax::responseError('Une erreur est survenue lors de la suppression de la commande.');
}
}

public function actionAjaxIgnoreOrderWhenInvoicing($idInvoice, $idOrder)
{
$invoiceManager = $this->getInvoiceManager();
$orderManager = $this->getOrderManager();

$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$order = $orderManager->findOneOrderById($idOrder);

if ($invoice && $invoiceManager->isStatusDraft($invoice) && $order) {
$orderManager->updateOrderIgnoreWhenInvoicing($order, true);
return Ajax::responseSuccess("La commande sera maintenant ignorée au moment de la facturation.");
}
else {
return Ajax::responseError("Une erreur est survenue.");
}
}
}

+ 8
- 4
backend/views/distribution/index.php Целия файл

@@ -432,6 +432,7 @@ $this->setPageTitle('Distributions') ;
:users="users"
:products="products"
:order="ordersUpdate[key]"
:orders="ordersUpdate"
:producer="producer"
:loading-update-product-order="loadingUpdateProductOrder"
@close="showModalFormOrderUpdate = false"
@@ -586,7 +587,7 @@ $this->setPageTitle('Distributions') ;
<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 à débiter</span>

<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
</script>

@@ -691,8 +692,11 @@ $this->setPageTitle('Distributions') ;
</div>
</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>
<td class="quantity-remaining negative" v-else-if="getProductQuantityRemaining(product) <= 0">
{{ getProductQuantityRemaining(product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}
<span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(product) < 0"></span>
</td>
<td class="quantity-remaining has-quantity" v-else>{{ getProductQuantityRemaining(product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td>
</tr>
</tbody>
</table>
@@ -728,7 +732,7 @@ $this->setPageTitle('Distributions') ;
<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 à débiter</span>

<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
</script>


+ 306
- 230
backend/views/document/_form.php Целия файл

@@ -38,7 +38,6 @@

use common\logic\Document\Document\Wrapper\DocumentManager;
use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\logic\User\User\Model\User;
use common\logic\User\User\Wrapper\UserManager;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
@@ -96,25 +95,52 @@ $documentClass = $documentManager->getClass($model);

<?php if ($action == 'create' && $documentClass == 'Invoice'): ?>
<template v-if="idUser > 0">
<strong>Bons de livraison</strong>
<table v-if="deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0" class="table table-bordered">
<thead>
<tr>
<th></th>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
</tr>
</thead>
<tbody>
<tr v-for="deliveryNote in deliveryNoteCreateArray">
<td><input type="checkbox" name="Invoice[deliveryNotes][]" :value="deliveryNote.id"/></td>
<td>{{ deliveryNote.name }}</td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucun bon de livraison pour cet utilisateur.</div>

<template v-if="deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0">
<strong>Bons de livraison</strong>
<table v-if="deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0"
class="table table-bordered">
<thead>
<tr>
<th></th>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
</tr>
</thead>
<tbody>
<tr v-for="deliveryNote in deliveryNoteCreateArray">
<td><input type="checkbox" name="Invoice[deliveryNotes][]"
:value="deliveryNote.id"/></td>
<td>{{ deliveryNote.name }}</td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucun bon de livraison pour cet utilisateur.</div>
</template>
<template v-else-if="ordersCreateArray && ordersCreateArray.length > 0">
<strong>Commandes</strong>
<table v-if="ordersCreateArray && ordersCreateArray.length > 0"
class="table table-bordered">
<thead>
<tr>
<th></th>
<th>Date</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
</tr>
</thead>
<tbody>
<tr v-for="order in ordersCreateArray">
<td><input type="checkbox" name="Invoice[ordersOnCreate][]" :value="order.id"/></td>
<td>{{ order.name }}</td>
<td>{{ formatPrice(order.amount_with_tax) }}</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucune commande pour cet utilisateur.</div>
</template>
</template>
<?php endif; ?>

@@ -124,14 +150,98 @@ $documentClass = $documentManager->getClass($model);
<?php ActiveForm::end(); ?>
</div>
</div>
</div>

<?php if ($action == 'update'): ?>

<div class="col-md-6">
<div id="" class="info-box">
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span>
<div class="info-box-content">
<span class="info-box-text">
<?= $typeDocument ?>
<span v-html="document.html_label"></span>
<span v-if="document.is_sent" class="label label-success">Envoyé</span>
</span>
<span class="info-box-number">{{ document.reference }}</span>
<span class="info-box-text">Date</span>
<span class="info-box-number">{{ document.date }}</span>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
<div class="info-box-content">
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span>
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span>
<p v-if="invoiceUrl">
<a class="btn btn-sm btn-default" :href="invoiceUrl">
<span class="glyphicon glyphicon-eye-open"></span> Voir la facture
</a>
</p>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-calendar"></i></span>
<div class="info-box-content">
<span class="info-box-text">Commandes</span>
<?php foreach ($model->orders as $order): ?>
<?php if ($order->distribution): ?>
<a class="btn btn-sm btn-default"
href="<?= Yii::$app->urlManager->createUrl(['distribution/index', 'idOrderUpdate' => $order->id]); ?>">
<?= date('d/m/Y', strtotime($order->distribution->date)) ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span>
<div class="info-box-content">
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/download', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger
(PDF)</a>

<?php if ($documentManager->isStatusValid($model)): ?>
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/regenerate', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-repeat"></span> Regénérer
(PDF)</a>
<?php endif; ?>

<?php if ($documentClass == 'Invoice' && $producerManager->getConfig('option_export_evoliz')): ?>
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/export-csv-evoliz', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz
(CSV)</a>
<?php endif; ?>
</div>
</div>
<div v-if="document.status == 'draft' || !document.is_sent" 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'"
href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/validate', 'id' => $model->id, 'backUpdateForm' => 1]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document</a>

<?php if (isset($model->user) && strlen($model->user->email) > 0): ?>
<a v-if="!document.is_sent"
href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id, 'backUpdateForm' => 1]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le
document</a>
<?php endif; ?>
</div>
</div>
</div>
<div class="clr"></div>

<?php if ($action == 'update' && $documentClass == 'Invoice'): ?>
<?php if ($action == 'update' && $documentClass == 'Invoice'): ?>
<div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)">
<div class="panel panel-default">
<div class="panel-heading">
Bons de livraison
</div>
<div class="panel-body">
<table v-if="deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0" class="table table-bordered">
<table v-if="deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0"
class="table table-bordered">
<thead>
<tr>
<th>Libellé</th>
@@ -144,7 +254,10 @@ $documentClass = $documentManager->getClass($model);
<tr v-for="deliveryNote in deliveryNoteUpdateArray">
<td><a :href="deliveryNote.url">{{ deliveryNote.name }}</a></td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
<td v-if="document.status == 'draft'"><a class="btn btn-default" href="javascript:void(0);" @click="deleteDeliveryNoteOfInvoice" :data-id="deliveryNote.id"><span class="glyphicon glyphicon-trash"></span></a></td>
<td v-if="document.status == 'draft'"><a class="btn btn-default" href="javascript:void(0);"
@click="deleteDeliveryNoteFromInvoice"
:data-id="deliveryNote.id"><span
class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
@@ -160,236 +273,199 @@ $documentClass = $documentManager->getClass($model);
</select>
</div>
<div class="col-md-4">
<button class="btn btn-primary" value="Ajouter" @click="submitDeliveryNoteAddToInvoice">Ajouter</button>
<button class="btn btn-primary" value="Ajouter" @click="submitDeliveryNoteAddToInvoice">
Ajouter
</button>
</div>
</div>
</div>
</div>
<?php endif; ?>

</div>

<?php if ($action == 'update'): ?>

<div class="col-md-6">
<div id="" class="info-box">
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span>
<div class="info-box-content">
<span class="info-box-text">
<?= $typeDocument ?>
<span v-html="document.html_label"></span>
<span v-if="document.is_sent" class="label label-success">Envoyé</span>
</span>
<span class="info-box-number">{{ document.reference }}</span>
<span class="info-box-text">Date</span>
<span class="info-box-number">{{ document.date }}</span>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
<div class="info-box-content">
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span>
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span>
<p v-if="invoiceUrl">
<a class="btn btn-sm btn-default" :href="invoiceUrl">
<span class="glyphicon glyphicon-eye-open"></span> Voir la facture
</a>
</p>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-calendar"></i></span>
<div class="info-box-content">
<span class="info-box-text">Commandes</span>
<?php foreach($model->orders as $order): ?>
<?php if($order->distribution): ?>
<a class="btn btn-sm btn-default" href="<?= Yii::$app->urlManager->createUrl(['distribution/index', 'idOrderUpdate' => $order->id]); ?>">
<?= date('d/m/Y', strtotime($order->distribution->date)) ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span>
<div class="info-box-content">
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/download', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a>

<?php if($documentManager->isStatusValid($model)): ?>
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/regenerate', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-repeat"></span> Regénérer (PDF)</a>
<?php endif; ?>

<?php if ($documentClass == 'Invoice' && $producerManager->getConfig('option_export_evoliz')): ?>
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/export-csv-evoliz', 'id' => $model->id]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz
(CSV)</a>
<?php endif; ?>
</div>
<div v-else>
<div class="panel panel-default">
<div class="panel-heading">
Commandes
</div>
</div>
<div v-if="document.status == 'draft' || !document.is_sent" 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'" href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/validate', 'id' => $model->id, 'backUpdateForm' => 1]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document</a>
<div class="panel-body">
<table v-if="ordersUpdateArray && ordersUpdateArray.length > 0" class="table table-bordered">
<thead>
<tr>
<th>Date</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
<th v-if="document.status == 'draft'"></th>
</tr>
</thead>
<tbody>
<tr v-for="order in ordersUpdateArray">
<td>{{ order.name }}</td>
<td>{{ formatPrice(order.amount_with_tax) }}</td>
<td v-if="document.status == 'draft'">
<a class="btn btn-default" href="javascript:void(0);" @click="deleteOrderFromInvoice"
:data-id="order.id">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucune commande associée.</div>

<?php if (isset($model->user) && strlen($model->user->email) > 0): ?>
<a v-if="!document.is_sent" href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id, 'backUpdateForm' => 1]) ?>"
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le
document</a>
<?php endif; ?>
<div v-if="document.status == 'draft'" id="order-add">
<div class="col-md-8">
<select class="form-control" v-model="orderAddId">
<option value="0" selected="selected">--</option>
<option v-for="order in ordersCreateArray" :value="order.id">
{{ order.name }}
</option>
</select>
</div>
<div class="col-md-4">
<button class="btn btn-primary" value="Ajouter" @click="submitOrderAddToInvoice">Ajouter</button>
<button class="btn btn-danger" value="Ignorer" @click="submitOrderIgnoreWhenInvoicing">Ignorer</button>
</div>
</div>
</div>
</div>
</div>
<div class="clr"></div>
<?php endif; ?>

<div class="">
<div class="panel panel-default" id="block-add-product">
<div class="panel-heading">
Ajouter un produit
</div>
<div class="panel-body">
<div class="col-md-6">
<strong>Produit</strong>
<select class="form-control" v-model="productAddId"
@change="changeProductAdd">
<option value="0" selected="selected">--</option>
<option v-for="product in productsArray" :value="product.id">
{{ product.name }}
</option>
</select>
<div class="panel panel-default" id="block-add-product">
<div class="panel-heading">
Ajouter un produit
</div>
<div class="panel-body">
<div class="col-md-6">
<strong>Produit</strong>
<select class="form-control" v-model="productAddId"
@change="changeProductAdd">
<option value="0" selected="selected">--</option>
<option v-for="product in productsArray" :value="product.id">
{{ product.name }}
</option>
</select>
</div>
<template v-if="productAddId > 0">
<div class="col-md-3">
<strong>Prix unitaire</strong>
<div class="input-group">
<input type="text" class="form-control input-price"
v-model="productAddPrice" @change="formatProductAddPrice"/>
<span class="input-group-addon"><span
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span>
</div>
<template v-if="productAddId > 0">
<div class="col-md-3">
<strong>Prix unitaire</strong>
<div class="input-group">
<input type="text" class="form-control input-price"
v-model="productAddPrice" @change="formatProductAddPrice"/>
<span class="input-group-addon"><span
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span>
</div>
</div>
<div class="col-md-3 total">
<strong>Quantité</strong>
<div class="input-group input-group-quantity">
</div>
<div class="col-md-3 total">
<strong>Quantité</strong>
<div class="input-group input-group-quantity">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
@click="changeQuantityProductAdd(-1)">-</button>
</span>
<input type="text" class="form-control input-quantity"
v-model="productAddQuantity" @change="formatProductAddQuantity"/>
<span class="input-group-addon">{{ getProductById(productAddId).wording_unit }}</span>
<span class="input-group-btn">
<input type="text" class="form-control input-quantity"
v-model="productAddQuantity" @change="formatProductAddQuantity"/>
<span class="input-group-addon">{{ getProductById(productAddId).wording_unit }}</span>
<span class="input-group-btn">
<button class="btn btn-default"
type="button"
@click="changeQuantityProductAdd(1)">+</button>
</span>
</div>
<button class="btn btn-primary" value="Ajouter"
@click="submitProductAdd">Ajouter
</button>
<div class="clr"></div>
</div>
<!--<div class="col-md-3 total">
<strong>Total</strong>
<div class="input-group">
<input type="text" class="form-control input-price" readonly
:value="formatPrice(productAddPrice * productAddQuantity)"/>
<span class="input-group-addon"><span
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span>
</div>
</div>-->
</template>
</div>
<button class="btn btn-primary" value="Ajouter"
@click="submitProductAdd">Ajouter
</button>
<div class="clr"></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Produits
</div>
<div class="panel-body">
<div id="block-list-products">
<table class="table table-bordered" v-if="Object.keys(ordersArray).length > 0">
<thead>
<tr>
<th>Nom</th>
<th>Prix (unité)</th>
<th>Quantité</th>
<th v-if="taxRateProducer != 0">TVA</th>
<th v-if="taxRateProducer != 0">Total HT</th>
<th v-else>Total</th>
<th>Supprimer</th>
</tr>
</thead>
<tbody>
<template v-for="order in ordersArray">
<tr v-for="productOrder in order.productOrder">
<td class="col-md-4">
<div class="product-name">{{ getProductById(productOrder.id_product).name }}
</div>
<ul class="product-order-meta">
<li v-if="order.distribution_date">Commande : <a class="btn btn-sm btn-default" :href="productOrder.url_order">{{ order.distribution_date }}</a></li>
<li>Utilisateur : {{ order.username }}</li>
<li v-if="order.point_sale_name">Point de vente : {{ order.point_sale_name }}</li>
</ul>
</td>
<td class="col-md-2">
{{ formatPrice(getProductOrderPrice(productOrder)) }}
<template v-if="document.status == 'draft' && getProductOrderPrice(productOrder) != getBestProductPrice(productOrder.id_product, productOrder.quantity)">
<i class="fa fa-exclamation-triangle" title="Prix différent de celui défini au niveau du produit"></i>
</template>
</td>
<td class="col-md-2">{{ productOrder.quantity }}</td>
<td class="col-md-1" v-if="taxRateProducer != 0">
{{ getProductById(productOrder.id_product).tax_rate * 100 }} %
</td>
<td class="col-md-2">
{{ formatPrice(productOrder.quantity * getProductOrderPrice(productOrder)) }}
</td>
<td class="col-md-1">
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</template>
<template v-if="taxRateProducer != 0">
<tr>
<td colspan="4"><strong>Total HT</strong></td>
<td><strong>{{ formatPrice(total) }} HT</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Montant TVA</strong></td>
<td><strong>{{ formatPrice(total_with_tax - total) }}</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Total TTC</strong></td>
<td><strong>{{ formatPrice(total_with_tax) }} TTC</strong></td>
<td></td>
</tr>
</template>
<template v-else>
<tr>
<td colspan="3"><strong>Total</strong></td>
<td><strong>{{ formatPrice(total) }}</strong></td>
<td></td>
</tr>
</template>
</template>
<div class="clr"></div>
</div>
</div>

</tbody>
</table>
<div v-else class="alert alert-info">
Aucun produit.
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Produits
</div>
<div class="panel-body">
<div id="block-list-products">
<table class="table table-bordered" v-if="Object.keys(ordersArray).length > 0">
<thead>
<tr>
<th>Nom</th>
<th>Prix (unité)</th>
<th>Quantité</th>
<th v-if="taxRateProducer != 0">TVA</th>
<th v-if="taxRateProducer != 0">Total HT</th>
<th v-else>Total</th>
<th>Supprimer</th>
</tr>
</thead>
<tbody>
<template v-for="order in ordersArray">
<tr v-for="productOrder in order.productOrder">
<td class="col-md-4">
<div class="product-name">{{ getProductById(productOrder.id_product).name }}
</div>
<ul class="product-order-meta">
<li v-if="order.distribution_date">Commande : <a class="btn btn-sm btn-default"
:href="productOrder.url_order">{{
order.distribution_date }}</a></li>
<li>Utilisateur : {{ order.username }}</li>
<li v-if="order.point_sale_name">Point de vente : {{ order.point_sale_name }}</li>
</ul>
</td>
<td class="col-md-2">
{{ formatPrice(getProductOrderPrice(productOrder)) }}
<template
v-if="document.status == 'draft' && getProductOrderPrice(productOrder) != getBestProductPrice(productOrder.id_product, productOrder.quantity)">
<i class="fa fa-exclamation-triangle"
title="Prix différent de celui défini au niveau du produit"></i>
</template>
</td>
<td class="col-md-2">{{ productOrder.quantity }}</td>
<td class="col-md-1" v-if="taxRateProducer != 0">
{{ getProductById(productOrder.id_product).tax_rate * 100 }} %
</td>
<td class="col-md-2">
{{ formatPrice(productOrder.quantity * getProductOrderPrice(productOrder)) }}
</td>
<td class="col-md-1">
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</template>
<template v-if="taxRateProducer != 0">
<tr>
<td colspan="4"><strong>Total HT</strong></td>
<td><strong>{{ formatPrice(total) }} HT</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Montant TVA</strong></td>
<td><strong>{{ formatPrice(total_with_tax - total) }}</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Total TTC</strong></td>
<td><strong>{{ formatPrice(total_with_tax) }} TTC</strong></td>
<td></td>
</tr>
</template>
<template v-else>
<tr>
<td colspan="3"><strong>Total</strong></td>
<td><strong>{{ formatPrice(total) }}</strong></td>
<td></td>
</tr>
</template>
</tbody>
</table>
<div v-else class="alert alert-info">
Aucun produit.
</div>
</div>
</div>
<?php endif; ?>


</div>
</div>
<?php endif; ?>

+ 9
- 2
backend/views/product/update/prices/_form.php Целия файл

@@ -40,13 +40,20 @@ $productManager = $this->getProductManager();
<?= $form->field($model, 'price', [
'template' => '
<div class="row">
<div class="col-xs-6">
<div class="col-xs-4">
<label for="reduction-increase-percent" class="control-label">Réduction / augmentation</label>
<div class="input-group">
<input type="text" id="reduction-increase-percent" class="form-control" name="" value="" data-price-base="'.$productManager->getPrice($modelProduct).'">
<span class="input-group-addon">%</span>
</div>
</div>
<div class="col-xs-4">
<label for="product-price" class="control-label without-tax">Prix ('. $productManager->strUnit($productManager->getRefUnit($modelProduct->unit), 'wording_unit').') HT</label>
<div class="input-group">
{input} <span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div>
</div>
<div class="col-xs-6">
<div class="col-xs-4">
<label for="productprice-price-with-tax" class="control-label with-tax">Prix ('. $productManager->strUnit($productManager->getRefUnit($modelProduct->unit), 'wording_unit').') TTC</label>
<div class="input-group">
<input type="text" id="productprice-price-with-tax" class="form-control" name="" value="" data-tax-rate-value="'.$taxRateValue.'">

+ 5
- 2
backend/views/subscription/index.php Целия файл

@@ -214,13 +214,16 @@ $subscriptionsArray = Subscription::searchAll() ;
[
'attribute' => 'auto_payment',
'format' => 'raw',
'label' => 'Paiement automatique',
'label' => 'Débit automatique',
'headerOptions' => ['class' => 'column-auto-payment column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-auto-payment column-hide-on-mobile'],
'filter' => [0 => 'Non', 1 => 'Oui'],
'value' => function($model) {
if($model->auto_payment) {
if($model->auto_payment == Subscription::AUTO_PAYMENT_DEDUCTED) {
return '<span class="label label-success">Déduit</span>' ;
}
elseif($model->auto_payment == Subscription::AUTO_PAYMENT_YES) {
return '<span class="label label-success">Oui</span>' ;
}
else {

+ 23
- 0
backend/web/js/backend.js Целия файл

@@ -262,6 +262,9 @@ function opendistrib_product_prices() {
opendistrib_product_prices_event_price_with_tax();
$('#productprice-price').change(opendistrib_product_prices_event_price_with_tax);
$('#productprice-price-with-tax').change(opendistrib_product_prices_event_price);
$('#reduction-increase-percent').change(function() {
opendistrib_product_prices_event_reduction_increase();
});
}
}

@@ -272,6 +275,8 @@ function opendistrib_product_prices_event_price_with_tax() {
$('#productprice-price-with-tax').val(getPriceWithTax(price, taxRateValue));
// formattage
$('#productprice-price').val(parseFloat(price).toFixed(5));

opendistrib_product_prices_update_reduction_increase();
}
}

@@ -282,6 +287,24 @@ function opendistrib_product_prices_event_price() {
$('#productprice-price').val(getPrice(priceWithTax, taxRateValue));
// formattage
$('#productprice-price-with-tax').val(parseFloat(priceWithTax).toFixed(2));

opendistrib_product_prices_update_reduction_increase();
}
}
function opendistrib_product_prices_update_reduction_increase() {
var productPriceBase = $('#reduction-increase-percent').data('price-base');
var productPriceSpecific = $('#productprice-price').val().replace(',', '.');
var reductionIncreasePercent = (productPriceSpecific / productPriceBase) * 100 - 100;
$('#reduction-increase-percent').val(parseFloat(reductionIncreasePercent).toFixed(5));
}

function opendistrib_product_prices_event_reduction_increase() {
var productPriceBase = $('#reduction-increase-percent').data('price-base');
var reductionIncreasePercent = $('#reduction-increase-percent').val();
if(reductionIncreasePercent) {
var newPrice = productPriceBase + productPriceBase * (reductionIncreasePercent / 100);
$('#productprice-price').val(parseFloat(newPrice).toFixed(5));
opendistrib_product_prices_event_price_with_tax();
}
}


+ 11
- 1
backend/web/js/vuejs/distribution-index.js Целия файл

@@ -871,7 +871,7 @@ Vue.component('modal', {
});

Vue.component('order-form', {
props: ['date', 'dateFormat', 'pointsSale', 'idActivePointSale', 'meansPayment', 'users', 'products', 'order', 'producer', 'loadingUpdateProductOrder'],
props: ['date', 'dateFormat', 'pointsSale', 'idActivePointSale', 'meansPayment', 'users', 'products', 'order', 'orders', 'producer', 'loadingUpdateProductOrder'],
emits: ['updateProductPrice', 'updateInvoicePrices'],
data: function () {
return {
@@ -1078,6 +1078,16 @@ Vue.component('order-form', {
} else {
this.vatMode = 'all';
}
},
getProductQuantityRemaining: function(product) {
var app = this;
var productQuantityOrder = 0;

for(key in app.orders) {
var order = app.orders[key];
productQuantityOrder += order.productOrder[product.id].quantity;
}
return product.productDistribution[0].quantity_max - productQuantityOrder;
}
}
});

+ 49
- 14
backend/web/js/vuejs/document-form.js Целия файл

@@ -42,6 +42,9 @@ var app = new Vue({
deliveryNoteCreateArray: [],
deliveryNoteUpdateArray: [],
deliveryNoteAddId: 0,
ordersCreateArray: [],
ordersUpdateArray: [],
orderAddId: 0,
idDocument: 0,
typeDocument: '',
idUser: '',
@@ -143,25 +146,14 @@ var app = new Vue({
Vue.set(app.document, 'address', response.data.address);
app.deliveryNoteCreateArray = response.data.delivery_note_create_array;
app.deliveryNoteUpdateArray = response.data.delivery_note_update_array;
app.ordersCreateArray = response.data.orders_create_array;
app.ordersUpdateArray = response.data.orders_update_array;
} else {
app.document.address = '';
}
});
},
validateDocument: function () {
var app = this;
axios.get(UrlManager.getBaseUrlAbsolute() + "document/ajax-validate-document", {
params: {
idDocument: app.getDocumentId(),
classDocument: app.getDocumentClass(),
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.init();
});
},
deleteDeliveryNoteOfInvoice: function(event) {
deleteDeliveryNoteFromInvoice: function(event) {
var app = this;
var idDeliveryNote = event.currentTarget.getAttribute('data-id');

@@ -190,6 +182,49 @@ var app = new Vue({
app.init();
});
},
submitOrderAddToInvoice: function() {
var app = this;
axios.get(UrlManager.getBaseUrlAbsolute() + "invoice/ajax-add-order", {
params: {
idInvoice: this.getDocumentId(),
idOrder: app.orderAddId
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.orderAddId = 0;
app.init();
});
},
submitOrderIgnoreWhenInvoicing: function() {
var app = this;
axios.get(UrlManager.getBaseUrlAbsolute() + "invoice/ajax-ignore-order-when-invoicing", {
params: {
idInvoice: this.getDocumentId(),
idOrder: app.orderAddId
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.orderAddId = 0;
app.init();
});
},
deleteOrderFromInvoice: function() {
var app = this;
var idOrder = event.currentTarget.getAttribute('data-id');

axios.get(UrlManager.getBaseUrlAbsolute() + "invoice/ajax-delete-order", {
params: {
idInvoice: app.getDocumentId(),
idOrder: idOrder
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.init();
});
},
getStepProductAdd: function () {
var step = parseInt(this.getProductById(this.productAddId).step);
if(!step) {

+ 25
- 0
common/config/main.php Целия файл

@@ -40,6 +40,7 @@ use common\components\BusinessLogic;
use common\components\DolibarrApi;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Document\DeliveryNote\Model\DeliveryNote;
use common\logic\Order\Order\Model\Order;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\CreditHistory\Model\CreditHistory;

@@ -96,6 +97,22 @@ return [
'mailerService' => [
'class' => 'common\components\MailerService'
],
'view' => [
'class' => 'yii\web\View',
'renderers' => [
'twig' => [
'class' => 'yii\twig\ViewRenderer',
'cachePath' => '@runtime/Twig/cache',
'options' => [
'auto_reload' => true,
],
'globals' => [
'html' => ['class' => '\yii\helpers\Html'],
],
'uses' => ['yii\bootstrap'],
],
],
],
'urlManagerProducer' => [
'class' => 'producer\components\UrlManagerProducer',
'subDomain' => Yii::getAlias('@producerSubdomain'),
@@ -143,16 +160,24 @@ return [
'class' => \justcoded\yii2\eventlistener\components\EventListener::class,
'listeners' => [],
'observers' => [
Order::class => [
// CreditHistory : remboursement commande
common\logic\User\CreditHistory\Event\OrderObserver::class
],
CreditHistory::class => [
// UserProducer : mise à jour du crédit
common\logic\User\UserProducer\Event\CreditHistoryObserver::class
],
Distribution::class => [
// Subscription : génération des commandes sur base des abonnements
common\logic\Subscription\Subscription\Event\DistributionObserver::class
],
DeliveryNote::class => [
// Order : assignation du bon de livraison aux commandes
common\logic\Order\Order\Event\DeliveryNoteObserver::class
],
Ticket::class => [
// User : envoi email nouveau ticket à l'administrateur
common\logic\User\User\Event\TicketObserver::class,
],
],

+ 1
- 1
common/config/params.php Целия файл

@@ -37,7 +37,7 @@
*/

return [
'version' => '23.9.A',
'version' => '23.9.C',
'siteName' => 'Opendistrib',
'adminEmail' => 'contact@opendistrib.net',
'supportEmail' => 'contact@opendistrib.net',

+ 2
- 5
common/forms/SubscriptionForm.php Целия файл

@@ -44,9 +44,6 @@ use common\logic\Subscription\Subscription\Model\Subscription;
use Yii;
use yii\base\Model;

/**
* Login form
*/
class SubscriptionForm extends Model
{
public $isAdmin = false ;
@@ -106,7 +103,7 @@ class SubscriptionForm extends Model
'sunday' => 'Dimanche',
'week_frequency' => 'Périodicité (semaines)',
'username' => 'Nom d\'utilisateur',
'auto_payment' => 'Paiement automatique',
'auto_payment' => 'Débit automatique',
'comment' => 'Commentaire'
];
}
@@ -150,7 +147,7 @@ class SubscriptionForm extends Model
$subscription->saturday = $this->saturday;
$subscription->sunday = $this->sunday;
$subscription->week_frequency = $this->week_frequency;
$subscription->auto_payment = (int) $this->auto_payment;
$subscription->auto_payment = Subscription::AUTO_PAYMENT_DEDUCTED;
$subscription->comment = $this->comment;

$subscription->save();

+ 1
- 1
common/logic/Document/DeliveryNote/Model/DeliveryNote.php Целия файл

@@ -56,7 +56,7 @@ class DeliveryNote extends Document
{
$rules = parent::rules();

$rules[] = ['ignore_when_billing', 'boolean'];
$rules[] = ['ignore_when_invoicing', 'boolean'];

return $rules;
}

+ 1
- 1
common/logic/Document/Document/Model/Document.php Целия файл

@@ -70,7 +70,7 @@ class Document extends ActiveRecordCommon implements DocumentInterface
[['id_user', 'id_producer'], 'integer'],
[['is_sent'], 'boolean'],
[['name', 'reference', 'status'], 'string', 'max' => 255],
[['deliveryNotes'], 'safe']
[['deliveryNotes', 'ordersOnCreate'], 'safe']
];
}


+ 6
- 0
common/logic/Document/Document/Service/DocumentBuilder.php Целия файл

@@ -87,4 +87,10 @@ class DocumentBuilder extends AbstractBuilder
$document->tax_calculation_method = Document::TAX_CALCULATION_METHOD_DEFAULT;
}
}

public function updateDocumentIsSend(Document $document, bool $isSent)
{
$document->is_sent = $isSent;
$this->update($document);
}
}

+ 5
- 2
common/logic/Document/Document/Service/DocumentUtils.php Целия файл

@@ -100,10 +100,10 @@ class DocumentUtils extends AbstractService implements UtilsInterface
}
}

public function send(DocumentInterface $document): bool
public function sendDocument(DocumentInterface $document): bool
{
if (isset($document->user) && strlen($document->user->email) > 0) {
$producer = GlobalParam::getCurrentProducer();
$producer = $this->getProducerContext();

$subjectEmail = $this->documentSolver->getType($document);
if ($this->documentSolver->isStatusValid($document)) {
@@ -124,6 +124,9 @@ class DocumentUtils extends AbstractService implements UtilsInterface
$this->generatePdf($document, Pdf::DEST_FILE);
$email->attach($this->documentSolver->getFilenameComplete($document));

// @TODO : gérer via un événement
$this->documentBuilder->updateDocumentIsSend($document, true);

return $email->send();
}


+ 1
- 0
common/logic/Document/Invoice/Model/Invoice.php Целия файл

@@ -46,6 +46,7 @@ use common\logic\Document\Document\Model\Document;
class Invoice extends Document
{
public $deliveryNotes;
public $ordersOnCreate;

/**
* @inheritdoc

+ 11
- 0
common/logic/Order/Order/Event/OrderDeleteEvent.php Целия файл

@@ -0,0 +1,11 @@
<?php

namespace common\logic\Order\Order\Event;

use common\logic\Order\Order\Model\Order;
use yii\base\Event;

class OrderDeleteEvent extends Event
{
public Order $order;
}

+ 4
- 1
common/logic/Order/Order/Model/Order.php Целия файл

@@ -54,6 +54,8 @@ use common\components\ActiveRecordCommon;
*/
class Order extends ActiveRecordCommon
{
const EVENT_DELETE = 'order.event.delete';

var $amount = 0;
var $amount_with_tax = 0;
var $amount_vat = [];
@@ -108,7 +110,7 @@ class Order extends ActiveRecordCommon
],
'integer'
],
[['auto_payment', 'tiller_synchronization', 'delivery_home'], 'boolean'],
[['auto_payment', 'tiller_synchronization', 'delivery_home', 'ignore_when_invoicing'], 'boolean'],
[['status', 'reference', 'delivery_address', 'online_payment_url', 'tiller_external_id'], 'string'],
[['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment', 'tiller_external_id'], 'safe']
];
@@ -136,6 +138,7 @@ class Order extends ActiveRecordCommon
'delivery_address' => 'Adresse de livraison',
'online_payment_url' => 'URL de paiement',
'tiller_external_id' => 'Tiller : externalId',
'ignore_when_invoicing' => "Ignorer au moment de la facturation"
];
}


+ 56
- 1
common/logic/Order/Order/Repository/OrderRepository.php Целия файл

@@ -8,6 +8,7 @@ use common\logic\AbstractRepository;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Order\ProductOrder\Repository\ProductOrderRepository;
@@ -17,6 +18,7 @@ use common\logic\PointSale\UserPointSale\Repository\UserPointSaleRepository;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Repository\ProducerRepository;
use common\logic\Product\Product\Service\ProductSolver;
use common\logic\Subscription\Subscription\Model\Subscription;
use common\logic\User\User\Model\User;
use common\logic\User\UserProducer\Repository\UserProducerRepository;
use yii\helpers\Html;
@@ -56,7 +58,7 @@ class OrderRepository extends AbstractRepository
'productOrder.product',
'creditHistory',
'creditHistory.userAction',
'pointSale'
'pointSale',
],
self::JOIN_WITH => [
'distribution',
@@ -113,6 +115,29 @@ class OrderRepository extends AbstractRepository
->find();
}

public function findOrdersByUserAndInvoice(User $user, Invoice $invoice)
{
return $this
->createDefaultQuery()
->filterByUser($user)
->filterIsInvoiced($invoice)
->filterIsValid()
->find();
}

public function findOrdersByUserNotInvoiced(User $user)
{
return $this
->createDefaultQuery()
->filterByUser($user)
->filterIsNotInvoiced()
->filterIsPassed()
->filterIsValid()
->filterIsNotIgnoreWhenInvoicing()
->orderByDistributionDate('ASC')
->find();
}

public function queryOrdersHistory(Producer $producer, User $user)
{
$queryIncoming = clone $this->createDefaultQuery()
@@ -376,4 +401,34 @@ class OrderRepository extends AbstractRepository

return intval($total / 3);
}

public function findOrdersIncomingBySubscription(Subscription $subscription, bool $begin = true)
{
if($begin) {
$dateStart = $subscription->date_begin;
$comparatorDateStart = '>=';
}
else {
$dateStart = $subscription->date_end;
$comparatorDateStart = '>';
}

$params = [
':id_producer' => GlobalParam::getCurrentProducerId(),
':date_today' => date('Y-m-d'),
':date_start' => $dateStart,
':id_subscription' => $subscription->id
];

$orders = Order::find()
->joinWith('distribution')
->where('distribution.id_producer = :id_producer')
->andWhere('distribution.date >= :date_today')
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start')
->andWhere('order.id_subscription = :id_subscription');

$orders->params($params);

return $orders->all();
}
}

+ 30
- 0
common/logic/Order/Order/Repository/OrderRepositoryQuery.php Целия файл

@@ -3,6 +3,7 @@
namespace common\logic\Order\Order\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Service\OrderDefinition;
use common\logic\User\User\Model\User;

@@ -74,4 +75,33 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery

return $this;
}

public function filterIsInvoiced(Invoice $invoice): self
{
$this->andWhere('order.id_invoice IS NOT NULL AND order.id_invoice = :id_invoice')
->params([':id_invoice' => $invoice->id]);

return $this;
}

public function filterIsNotInvoiced(): self
{
$this->andWhere('order.id_invoice IS NULL');

return $this;
}

public function filterIsNotIgnoreWhenInvoicing(): self
{
$this->andWhere('order.ignore_when_invoicing IS NULL');

return $this;
}

public function orderByDistributionDate(string $order = 'ASC'): self
{
$this->orderBy(['distribution.date' => $order]);

return $this;
}
}

+ 52
- 60
common/logic/Order/Order/Service/OrderBuilder.php Целия файл

@@ -13,6 +13,8 @@ use common\logic\Distribution\Distribution\Service\DistributionSolver;
use common\logic\Document\DeliveryNote\Model\DeliveryNote;
use common\logic\Document\DeliveryNote\Service\DeliveryNoteBuilder;
use common\logic\Document\Document\Model\Document;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Event\OrderDeleteEvent;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\ProductOrder\Model\ProductOrder;
@@ -176,31 +178,8 @@ class OrderBuilder extends AbstractBuilder

public function deleteOrdersIncomingDistributionsFromSubscription(Subscription $subscription, bool $deleteAfterDateEnd = false): int
{
$dateStart = $subscription->date_begin;
$comparatorDateStart = '>=';
if ($deleteAfterDateEnd) {
$dateStart = $subscription->date_end;
$comparatorDateStart = '>';
}

$params = [
':id_producer' => GlobalParam::getCurrentProducerId(),
':date_today' => date('Y-m-d'),
':date_start' => $dateStart,
':id_subscription' => $subscription->id
];

$orders = Order::find()
->joinWith('distribution')
->where('distribution.id_producer = :id_producer')
->andWhere('distribution.date >= :date_today')
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start')
->andWhere('order.id_subscription = :id_subscription');
$ordersArray = $this->orderRepository->findOrdersIncomingBySubscription($subscription, !$deleteAfterDateEnd);

$orders->params($params);

$ordersArray = $orders->all();
$configCredit = $this->producerRepository->getConfig('credit');

$countOrdersDeleted = 0;
if ($ordersArray && count($ordersArray)) {
@@ -208,21 +187,7 @@ class OrderBuilder extends AbstractBuilder
if ($this->distributionSolver->isDistributionAvailable($order->distribution)) {
$theOrder = $this->orderRepository->findOneOrderById($order->id);
$this->initOrder($theOrder);

// remboursement de la commande
if ($theOrder->id_user && $this->orderSolver->getOrderAmount($theOrder, Order::AMOUNT_PAID) && $configCredit) {

$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$this->orderSolver->getOrderAmount($theOrder, Order::AMOUNT_PAID),
$theOrder->distribution->producer,
$theOrder->user,
GlobalParam::getCurrentUser()
);
}

$this->deleteOrder($order, true);

$countOrdersDeleted++;
}
}
@@ -337,9 +302,9 @@ class OrderBuilder extends AbstractBuilder
/**
* Initialise le montant total, le montant déjà payé et le poids de la commande.
*/
// init
public function initOrder(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void
public function initOrder(Order $order): void
{
$taxCalculationMethod = $this->getProducerContext()->option_tax_calculation_method;
$this->initOrderAmount($order, $taxCalculationMethod);
$this->initOrderPaidAmount($order);
}
@@ -347,7 +312,6 @@ class OrderBuilder extends AbstractBuilder
/**
* Initialise le montant de la commande.
*/
// initAmount
public function initOrderAmount(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void
{
$order->amount = 0;
@@ -437,23 +401,9 @@ class OrderBuilder extends AbstractBuilder

public function deleteOrder(Order $order, bool $force = false): bool
{
$return = false;
$this->initOrder($order);

// remboursement si l'utilisateur a payé pour cette commande
$amountPaid = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID);

if ($amountPaid >= 0.01) {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$amountPaid,
GlobalParam::getCurrentProducer(),
$order->user,
$this->userSolver->getCurrent(),
MeanPayment::CREDIT,
$order
);
}

// delete
if ($this->producerRepository->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
($this->producerRepository->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS && strlen($order->date_delete))
@@ -461,15 +411,21 @@ class OrderBuilder extends AbstractBuilder

$this->productOrderBuilder->deleteProductOrdersByOrder($order);

return $this->delete($order);
} // status 'delete'
$return = $this->delete($order);
}
// status 'delete'
elseif ($this->producerRepository->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
$order->date_delete = date('Y-m-d H:i:s');
$return = $this->update($order);
}

return $this->saveUpdate($order);
if($return) {
$orderDeleteEvent = new OrderDeleteEvent();
$orderDeleteEvent->order = $order;
$order->trigger(Order::EVENT_DELETE, $orderDeleteEvent);
}

return false;
return $return;
}

/**
@@ -654,4 +610,40 @@ class OrderBuilder extends AbstractBuilder
'id_delivery_note' => $deliveryNote->id
]);
}

public function unassignAllOrdersInvoiceByDeliveryNote(DeliveryNote $deliveryNote)
{
Order::updateAll([
'id_invoice' => null
], [
'id_delivery_note' => $deliveryNote->id
]);
}

public function assignAllOrdersInvoiceByDeliveryNote(Invoice $invoice, DeliveryNote $deliveryNote)
{
Order::updateAll([
'id_invoice' => $invoice->id
], [
'id_delivery_note' => $deliveryNote->id
]);
}

public function updateOrderIgnoreWhenInvoicing(Order $order, bool $ignoreWhenInvoicing)
{
$order->ignore_when_invoicing = $ignoreWhenInvoicing;
$this->update($order);
}

public function updateOrderInvoice(Order $order, Invoice $invoice = null)
{
if($invoice) {
$order->populateInvoice($invoice);
}
else {
$order->id_invoice = null;
}

$this->update($order);
}
}

+ 8
- 5
common/logic/Order/Order/Service/OrderSolver.php Целия файл

@@ -4,9 +4,10 @@ namespace common\logic\Order\Order\Service;

use common\helpers\Price;
use common\logic\AbstractService;
use common\logic\Document\Document\Model\Document;
use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Order\Order\Model\Order;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Service\ProducerSolver;
use common\logic\Product\Product\Model\Product;
use common\logic\SolverInterface;
use common\logic\User\CreditHistory\Model\CreditHistory;
@@ -20,12 +21,14 @@ class OrderSolver extends AbstractService implements SolverInterface
protected UserSolver $userSolver;
protected DocumentSolver $documentSolver;
protected CreditHistorySolver $creditHistorySolver;
protected ProducerSolver $producerSolver;

public function loadDependencies(): void
{
$this->documentSolver = $this->loadService(DocumentSolver::class);
$this->userSolver = $this->loadService(UserSolver::class);
$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::class);
}

public function getFieldNameAmount($typeTotal = Order::AMOUNT_TOTAL, string $typeField = ''): string
@@ -53,6 +56,10 @@ class OrderSolver extends AbstractService implements SolverInterface
$totalVat += $vat;
}

if($this->getProducerContext()->option_tax_calculation_method == Document::TAX_CALCULATION_METHOD_ROUNDING_OF_THE_SUM) {
$totalVat = Price::round($totalVat);
}

return $totalVat;
}

@@ -106,7 +113,6 @@ class OrderSolver extends AbstractService implements SolverInterface
/**
* Retourne une chaine de caractère décrivant l'utilisateur lié à la commande.
*/
// getStrUser
public function getOrderUsername(Order $order): string
{
if (isset($order->user)) {
@@ -169,7 +175,6 @@ class OrderSolver extends AbstractService implements SolverInterface
/**
* Retourne un bloc html présentant une date.
*/
// getBlockDate
public function getDateAsHtml(Order $order): string
{
return '<div class="block-date">
@@ -328,7 +333,6 @@ class OrderSolver extends AbstractService implements SolverInterface
/**
* Retourne le montant de la commande (total, payé, restant, ou en surplus).
*/
// getAmount
public function getOrderAmount(Order $order, string $type = Order::AMOUNT_TOTAL, bool $format = false)
{
$amount = $order->amount;
@@ -339,7 +343,6 @@ class OrderSolver extends AbstractService implements SolverInterface
return $this->_getAmountGeneric($order, $type, $amount, $format);
}

// getAmountWithTax
public function getOrderAmountWithTax(Order $order, string $type = Order::AMOUNT_TOTAL, bool $format = false)
{
$amount = $order->amount + $this->getOrderTotalVat($order, $type);

+ 1
- 1
common/logic/Subscription/Subscription/Model/Subscription.php Целия файл

@@ -94,7 +94,7 @@ class Subscription extends ActiveRecordCommon
'saturday' => 'Samedi',
'sunday' => 'Dimanche',
'week_frequency' => 'Périodicité',
'auto_payment' => 'Paiement automatique',
'auto_payment' => 'Débit automatique',
'comment' => 'Commentaire'
];
}

+ 28
- 0
common/logic/User/CreditHistory/Event/OrderObserver.php Целия файл

@@ -0,0 +1,28 @@
<?php

namespace common\logic\User\CreditHistory\Event;

use common\logic\Order\Order\Event\OrderDeleteEvent;
use common\logic\Order\Order\Model\Order;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\User\User\Wrapper\UserManager;
use justcoded\yii2\eventlistener\observers\Observer;

class OrderObserver extends Observer
{
public function events()
{
return [
Order::EVENT_DELETE => 'onOrderDelete'
];
}

public function onOrderDelete(OrderDeleteEvent $event)
{
$order = $event->order;
$creditHistoryManager = CreditHistoryManager::getInstance();
$userManager = UserManager::getInstance();

$creditHistoryManager->refundOrder($order, $userManager->getCurrent());
}
}

+ 13
- 9
common/logic/User/CreditHistory/Service/CreditUtils.php Целия файл

@@ -93,15 +93,19 @@ class CreditUtils extends AbstractService implements UtilsInterface

public function refundOrder(Order $order, User $userAction): void
{
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_PAID),
$this->getProducerContext(),
$order->user,
$userAction,
MeanPayment::CREDIT,
$order
);
$amountPaid = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID);

if ($amountPaid >= 0.01 && $order->id_user) {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID),
$this->getProducerContext(),
$order->user,
$userAction,
MeanPayment::CREDIT,
$order
);
}
}

public function refundSurplusOrder(Order $order, User $userAction): void

+ 26
- 0
common/versions/23.9.C.php Целия файл

@@ -0,0 +1,26 @@
<?php

require_once dirname(__FILE__).'/_macros.php';

version(
'18/09/2023',
[
[
"[Administration] Produits > Prix spécifiques : calcul des prix via un champs de remises en pourcentage",
"[Administration] Distributions : mise en avant des dépassements de quantités",
"[Administration] Documents > Factures : possibilité de génération sur base des commandes",
"[Espace producteur] Abonnements : mise en avant du fait que les commandes sont re-générées au moment de la modification d'un abonnement"
],
[
]
],
[
[
],
[
"[Technique] Mise en place Twig"
]
],
);

?>

+ 2
- 2
common/versions/_macros.php Целия файл

@@ -18,7 +18,7 @@ function release_date(string $date) {

function features(array $featuresArray, array $featuresAdminArray) {
$userManager = UserManager::getInstance();
if(count($featuresArray) > 0) {
if(count($featuresArray) > 0 || count($featuresAdminArray) > 0) {
$html = '<div class="block block-features">';
$html .= '<h4><span class="glyphicon glyphicon-flash"></span> Évolutions</h4>';
$html .= '<ul>';
@@ -38,7 +38,7 @@ function features(array $featuresArray, array $featuresAdminArray) {

function maintenance(array $maintenanceArray, array $maintenanceAdminArray) {
$userManager = UserManager::getInstance();
if(count($maintenanceArray) > 0) {
if(count($maintenanceArray) > 0 || count($maintenanceAdminArray) > 0) {
$html = '<div class="block block-maintenance">';
$html .= '<h4><span class="glyphicon glyphicon-wrench"></span> Maintenance</h4>';
$html .= '<ul>';

+ 2
- 1
composer.json Целия файл

@@ -36,7 +36,8 @@
"ext-pdo": "*",
"weluse/yii2-mailjet": "^0.2.0",
"ext-json": "*",
"ext-curl": "*"
"ext-curl": "*",
"yiisoft/yii2-twig": "^2.4"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",

+ 244
- 84
composer.lock Целия файл

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cf81ea895f037844a4e20f4780fd7e7e",
"content-hash": "1d287231533b2d1fef1047dd81b0e4d5",
"packages": [
{
"name": "2amigos/yii2-chartjs-widget",
@@ -2051,6 +2051,88 @@
"abandoned": "symfony/mailer",
"time": "2021-10-18T15:26:12+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.27.0",
@@ -2464,6 +2546,77 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "twig/twig",
"version": "v3.7.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Twig Team",
"role": "Contributors"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "https://twig.symfony.com",
"keywords": [
"templating"
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.7.1"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"time": "2023-08-28T11:09:02+00:00"
},
{
"name": "weluse/yii2-mailjet",
"version": "v0.2.0",
@@ -2973,6 +3126,93 @@
],
"time": "2021-12-30T08:48:48+00:00"
},
{
"name": "yiisoft/yii2-twig",
"version": "2.4.2",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-twig.git",
"reference": "8b33fe24960ed43e55820cd35df1740869876fa3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-twig/zipball/8b33fe24960ed43e55820cd35df1740869876fa3",
"reference": "8b33fe24960ed43e55820cd35df1740869876fa3",
"shasum": ""
},
"require": {
"php": "^7.2.5|^8.0|^8.1",
"twig/twig": "~3.0",
"yiisoft/yii2": "~2.0.4"
},
"require-dev": {
"cweagans/composer-patches": "^1.7",
"phpunit/phpunit": "4.8.34"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
},
"composer-exit-on-patch-failure": true,
"patches": {
"phpunit/phpunit-mock-objects": {
"Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
},
"phpunit/php-file-iterator": {
"Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_path_file_iterator.patch"
},
"phpunit/phpunit": {
"Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
"Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch",
"Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch"
}
}
},
"autoload": {
"psr-4": {
"yii\\twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Alexander Makarov",
"email": "sam@rmcreative.ru"
}
],
"description": "The Twig integration for the Yii framework",
"keywords": [
"renderer",
"twig",
"yii2"
],
"support": {
"forum": "http://www.yiiframework.com/forum/",
"irc": "irc://irc.freenode.net/yii",
"issues": "https://github.com/yiisoft/yii2-twig/issues",
"source": "https://github.com/yiisoft/yii2-twig",
"wiki": "http://www.yiiframework.com/wiki/"
},
"funding": [
{
"url": "https://github.com/yiisoft",
"type": "github"
},
{
"url": "https://opencollective.com/yiisoft",
"type": "open_collective"
},
{
"url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-twig",
"type": "tidelift"
}
],
"time": "2022-09-04T10:45:53+00:00"
},
{
"name": "yurkinx/yii2-image",
"version": "dev-master",
@@ -5651,88 +5891,6 @@
],
"time": "2022-07-29T07:35:46+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-php73",
"version": "v1.27.0",
@@ -6517,7 +6675,9 @@
"prefer-lowest": false,
"platform": {
"php": ">=7.4",
"ext-pdo": "*"
"ext-pdo": "*",
"ext-json": "*",
"ext-curl": "*"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"

+ 28
- 0
console/migrations/m230912_070221_add_column_order_ignore_when_invoicing.php Целия файл

@@ -0,0 +1,28 @@
<?php

use yii\db\Migration;
use yii\db\Schema;

/**
* Class m230912_070221_add_column_order_ignore_when_invoicing
*/
class m230912_070221_add_column_order_ignore_when_invoicing extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('order', 'ignore_when_invoicing', Schema::TYPE_BOOLEAN);
$this->renameColumn('delivery_note', 'ignore_when_billing', 'ignore_when_invoicing');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('order', 'ignore_when_invoicing');
$this->renameColumn('delivery_note', 'ignore_when_invoicing', 'ignore_when_billing');
}
}

+ 1
- 1
frontend/views/site/_prices_producer.php Целия файл

@@ -41,7 +41,7 @@ use yii\grid\GridView;
?>

<div class="alert alert-warning" role="alert">
Découvrez ci-dessous notre <strong>grille tarifaire</strong> pour l'hébergement de votre circuit court sur Opendistrib.
Découvrez ci-dessous la <strong>grille tarifaire</strong> pour l'hébergement de votre circuit court sur Opendistrib.
Le montant qui vous est facturé mensuellement dépend de votre chiffre d’affaire hors taxe réalisé sur le logiciel.
Il est donc adapté chaque mois en fonction de l’évolution de votre activité.<br>
Le service est <strong>sans engagement</strong>, vous arrêtez quand vous voulez sur simple désactivation de votre compte.

+ 4
- 4
frontend/views/site/index.php Целия файл

@@ -54,8 +54,8 @@ $this->setMeta('description', 'Simplifiez la distribution de vos produits en cir
</div>
<div class="panel-body">
<div class="hook">
Simplifiez la distribution de vos produits<br>
en circuit court avec des outils adaptés.
Profitez d'un logiciel simple et intuitif pour :<br />
<div class="word-animate"><span class="functionality"></span></div>
</div>
<div class="links">
<?php if (Yii::$app->user->isGuest): ?>
@@ -92,8 +92,8 @@ $this->setMeta('description', 'Simplifiez la distribution de vos produits en cir
</div>
<div class="panel-body">
<div class="hook">
Réservez facilement vos produits en ligne<br>
auprès de producteurs locaux.
Réservez facilement vos produits<br>
auprès de producteurs locaux.<br><br>
</div>
<div class="links">
<?php if (Yii::$app->user->isGuest): ?>

+ 121
- 114
frontend/views/site/service.php Целия файл

@@ -42,141 +42,148 @@ $this->setIcon('console');
//$this->setMeta('description', '');

?>
<div class="site-service">
<div class="content-text">
<div id="row-functionalities-rates">
<div class="panel panel-primary" id="block-functionnalities">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-cog"></span>
<span class="the-title">Fonctionnalités</span>
</h2>
</div>
<div class="panel-body">
<?= block_feature('grain', "Un espace producteur dédié accessible aux clients avec un système de prise de commandes, la présentation de l'activité, la liste des produits et des points de vente, un formulaire de contact"); ?>
<?= block_feature("cog", "Une administration complète et intuitive pour configurer finement l'ensemble des aspects de l'activité de producteur"); ?>
<div class="clr"></div>
<?= block_feature("calendar", "Planification des jours de distributions"); ?>
<?= block_feature("download-alt", "Accès à un récapitulatif des commandes par jour de distribution"); ?>
<?= block_feature("cutlery", "Gestion des produits, catégories et prix spécifiques"); ?>
<?= block_feature("map-marker", "Gestion des points de vente avec possibilité d'accès restreint à certains utilisateurs"); ?>
<?= block_feature("repeat", "Gestion des abonnements pour les commandes récurrentes"); ?>
<?= block_feature("user", "Gestion des clients"); ?>
<?= block_feature("euro", "Système de crédit (ou cagnotte) permettant la comptabilisation des paiements"); ?>
<?= block_feature("bullhorn", "Communication facilitée avec les clients via l'envoi d'emails en masse"); ?>
<?= block_feature("folder-open", "Génération de bons de livraison, factures & devis"); ?>
<?= block_feature("stats", "Statistiques et rapports de vente"); ?>
<div class="site-service">
<div class="content-text">
<div id="row-functionalities-rates">
<div class="panel panel-primary" id="block-functionnalities">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-cog"></span>
<span class="the-title">Fonctionnalités</span>
</h2>
</div>
<div class="panel-body">
<?= block_feature('grain', "Un espace producteur dédié accessible à vos clients pour leur présenter votre activité et gérer vos prises de commandes."); ?>
<?= block_feature("cog", "Une administration complète et intuitive pour gérer votre activité de producteur."); ?>
<div class="clr"></div>
<?= block_feature("calendar", "Planification des jours de distributions."); ?>
<?= block_feature("download-alt", "Accès à un récapitulatif des commandes par jour de distribution."); ?>
<?= block_feature("cutlery", "Gestion des produits, catégories et prix spécifiques."); ?>
<?= block_feature("map-marker", "Gestion des points de vente."); ?>
<?= block_feature("repeat", "Gestion des abonnements pour les commandes récurrentes."); ?>
<?= block_feature("user", "Gestion des clients."); ?>
<?= block_feature("euro", "Système de crédit (ou cagnotte) permettant la comptabilisation des paiements."); ?>
<?= block_feature("credit-card", "Paiement en ligne possible via la plateforme <strong>Stripe</strong> pour que les clients puissent alimenter leur crédit de manière autonome."); ?>
<?= block_feature("bullhorn", "Communication facilitée avec les clients via l'envoi d'emails en masse."); ?>
<?= block_feature("folder-open", "Génération de bons de livraison, factures & devis."); ?>
<?= block_feature("stats", "Statistiques et rapports de vente."); ?>
<?= block_feature("transfer", "Exports vers les logiciels <strong>Evoliz</strong> (comptabilité) et <strong>Tiller</strong> (caisse)."); ?>
</div>
</div>
</div>

<div class="panel panel-primary" id="block-services">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-wrench"></span>
<span class="the-title">Services</span>
</h2>
</div>
<div class="panel-body">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-body">
<h3>Évolutions régulières</h3>
<p>Les évolutions sont développées en fonction des retours de tous les producteurs
et le
logiciel est régulièrement mis à jour.<br>
Si vous avez un besoin spécifique à votre activité, nous pouvons réaliser des
développements sur-mesure <a
href="<?= \Yii::$app->urlManager->createUrl(['site/contact']) ?>">sur
devis</a>.
</p>
<div class="panel panel-primary" id="block-services">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-wrench"></span>
<span class="the-title">Services</span>
</h2>
</div>
<div class="panel-body">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-body">
<h3>Évolutions régulières</h3>
<p>Les évolutions sont développées en fonction des retours de tous les producteurs
et le
logiciel est régulièrement mis à jour.<br>
Si vous avez un besoin spécifique à votre activité, je peux réaliser des
développements sur-mesure <a
href="<?= \Yii::$app->urlManager->createUrl(['site/contact']) ?>">sur
devis</a>.
</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<h3>Formation & accompagnement</h3>
<p>Au moment du lancement de votre circuit court sur Opendistrib, ainsi que tout au
long de
votre projet,
nous assurons la formation et l'accompagnement dans l'utilisation du
logiciel.</p>
<div class="panel panel-default">
<div class="panel-body">
<h3>Formation & accompagnement</h3>
<p>Au moment du lancement de votre circuit court sur Opendistrib, ainsi que tout au
long de
votre projet,
j'assure la formation et l'accompagnement dans l'utilisation du
logiciel.</p>
</div>
</div>
</div>
</div>

<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-body">
<h3>Support</h3>
<p>Nous sommes disponibles pour répondre rapidement à toutes vos questions par email
ou par
téléphone.</p>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-body">
<h3>Support</h3>
<p>Je suis disponible pour répondre rapidement à toutes vos questions par email
ou par
téléphone.</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<h3>Maintenance</h3>
<p>Nous travaillons contamment sur la qualité/sécurité du logiciel et
intervenons au plus vite en cas de bug.</p>
<div class="panel panel-default">
<div class="panel-body">
<h3>Maintenance</h3>
<p>Je travaille contamment sur la qualité/sécurité du logiciel et
interviens au plus vite en cas de bug.</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<h3>Hébergement</h3>
<p>La plateforme est hébergée en France par la société <a
href="https://www.alwaysdata.com/">Alwaysdata</a>.</p>
<div class="panel panel-default">
<div class="panel-body">
<h3>Hébergement</h3>
<p>La plateforme est hébergée en France par la société <a
href="https://www.alwaysdata.com/">Alwaysdata</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>

<div class="panel panel-primary" id="block-rates">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-euro"></span>
<span class="the-title">Tarifs</span>
</h2>
</div>
<div class="panel-body">
<?= $this->render('_prices_producer', ['dataProviderPrices' => $dataProviderPrices]); ?>
<div class="panel panel-primary" id="block-rates">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-euro"></span>
<span class="the-title">Tarifs</span>
</h2>
</div>
<div class="panel-body">
<?= $this->render('_prices_producer', ['dataProviderPrices' => $dataProviderPrices]); ?>
</div>
</div>
</div>

<div class="panel panel-primary" id="panel-go-further">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-plus"></span>
<span class="the-title">Pour aller plus loin</span>
</h2>
</div>
<div class="panel-body">
<p class="text-center">
<?php if (Yii::$app->user->isGuest): ?>
<div class="panel panel-primary" id="panel-go-further">
<div class="panel-heading">
<h2 class="panel-title">
<span class="glyphicon glyphicon-plus"></span>
<span class="the-title">Pour aller plus loin</span>
</h2>
</div>
<div class="panel-body">
<p class="text-center">
<?php if (Yii::$app->user->isGuest): ?>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/signup']); ?>">
<span class="glyphicon glyphicon-user"></span> Je crée un espace producteur
</a>
<?php endif; ?>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/producer', 'id' => 32]); ?>">
<span class="glyphicon glyphicon-check"></span> Je teste le logiciel
</a>
<a class="btn btn-default" href="<?= \Yii::$app->parameterBag->get('appointmentUrl'); ?>"
target="_blank">
<span class="glyphicon glyphicon-education"></span> Je demande une démo
</a>
<br><br>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/about']); ?>">
<span class="glyphicon glyphicon-info-sign"></span> À propos
</a>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/signup']); ?>">
<span class="glyphicon glyphicon-user"></span> Je crée un espace producteur
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/contact']); ?>">
<span class="glyphicon glyphicon-envelope"></span> Contact
</a>
<?php endif; ?>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/producer', 'id' => 32]); ?>">
<span class="glyphicon glyphicon-check"></span> Je teste le logiciel
</a>
<a class="btn btn-default" href="<?= \Yii::$app->parameterBag->get('appointmentUrl'); ?>"
target="_blank">
<span class="glyphicon glyphicon-education"></span> Je demande une démo
</a>
<a class="btn btn-default"
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/contact']); ?>">
<span class="glyphicon glyphicon-envelope"></span> Je contacte le développeur
</a>
</p>
</p>
</div>
</div>
</div>

</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>
</div>

<?php


+ 163
- 140
frontend/web/css/screen.css Целия файл

@@ -595,7 +595,7 @@ section#header-title h1 .glyphicon {
-webkit-border-radius: 5px;
border-radius: 5px;
}
/* line 587, ../sass/screen.scss */
/* line 584, ../sass/screen.scss */
#content #row-users-producers .col-md-6 .panel {
height: 100%;
margin-bottom: 20px;
@@ -604,15 +604,34 @@ section#header-title h1 .glyphicon {
-webkit-box-shadow: none;
box-shadow: none;
}
/* line 594, ../sass/screen.scss */
/* line 591, ../sass/screen.scss */
#content #row-users-producers .col-md-6.producer {
padding-left: 0px;
}
/* line 594, ../sass/screen.scss */
#content #row-users-producers .col-md-6.producer .word-animate {
margin-top: 18px;
height: auto;
}
/* line 598, ../sass/screen.scss */
#content #row-users-producers .col-md-6.producer .word-animate span.functionality {
background-color: #FFF8DC;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
padding: 8px 15px 5px 15px;
}
/* line 603, ../sass/screen.scss */
#content #row-users-producers .col-md-6.producer .word-animate span.functionality .glyphicon {
position: relative;
top: 4px;
right: 6px;
}
/* line 613, ../sass/screen.scss */
#content #row-users-producers .col-md-6.users {
padding-right: 0px;
}
/* line 602, ../sass/screen.scss */
/* line 617, ../sass/screen.scss */
#content #row-users-producers .col-md-6 .hook {
font-family: 'capsuularegular';
font-size: 23px;
@@ -620,94 +639,94 @@ section#header-title h1 .glyphicon {
margin-top: 10px;
margin-bottom: 30px;
}
/* line 611, ../sass/screen.scss */
/* line 626, ../sass/screen.scss */
#content #row-users-producers .col-md-6 .links a {
margin-bottom: 5px;
}
/* line 637, ../sass/screen.scss */
/* line 652, ../sass/screen.scss */
#content #row-users-producers p,
#content #row-functionalities-rates p {
padding-bottom: 4px;
}
/* line 643, ../sass/screen.scss */
/* line 658, ../sass/screen.scss */
#content #row-functionalities-rates .block {
position: relative;
margin-bottom: 25px;
padding-left: 70px;
min-height: 50px;
}
/* line 649, ../sass/screen.scss */
/* line 664, ../sass/screen.scss */
#content #row-functionalities-rates .block .glyphicon {
font-size: 40px;
position: absolute;
left: 0px;
top: 0px;
}
/* line 656, ../sass/screen.scss */
/* line 671, ../sass/screen.scss */
#content #row-functionalities-rates .block p {
font-family: 'capsuularegular';
font-size: 18px;
}
/* line 661, ../sass/screen.scss */
/* line 676, ../sass/screen.scss */
#content #row-functionalities-rates .block a {
text-decoration: none;
color: black;
}
/* line 665, ../sass/screen.scss */
/* line 680, ../sass/screen.scss */
#content #row-functionalities-rates .block a:hover {
color: #F2B84B;
}
/* line 672, ../sass/screen.scss */
/* line 687, ../sass/screen.scss */
#content #row-functionalities-rates .block-points-sale-products img {
width: 40px;
}
/* line 680, ../sass/screen.scss */
/* line 695, ../sass/screen.scss */
#content #block-services .panel-body .panel-body {
padding-bottom: 0px;
}
/* line 682, ../sass/screen.scss */
/* line 697, ../sass/screen.scss */
#content #block-services .panel-body .panel-body h3 {
margin-top: 0px;
}
/* line 691, ../sass/screen.scss */
/* line 706, ../sass/screen.scss */
#content #block-rates table th {
font-weight: bold;
font-size: 14px;
}
/* line 700, ../sass/screen.scss */
/* line 715, ../sass/screen.scss */
#content #btn-demo:hover, #content #btn-demo:focus, #content #btn-demo:active {
color: black;
}

/* line 710, ../sass/screen.scss */
/* line 725, ../sass/screen.scss */
#content #contact {
display: none;
}
/* line 714, ../sass/screen.scss */
/* line 729, ../sass/screen.scss */
#content #contact .icon {
width: 55px;
top: -15px;
margin-left: -70px;
}
/* line 720, ../sass/screen.scss */
/* line 735, ../sass/screen.scss */
#content #contact .form-control:focus {
/*@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px $jaune) ;
border-color: $jaune ;*/
}
/* line 725, ../sass/screen.scss */
/* line 740, ../sass/screen.scss */
#content #contact .form-group {
text-align: center;
}
/* line 729, ../sass/screen.scss */
/* line 744, ../sass/screen.scss */
#content #contact .img-right {
float: right;
}
/* line 732, ../sass/screen.scss */
/* line 747, ../sass/screen.scss */
#content #contact .img-right img {
width: 300px;
}

/* line 738, ../sass/screen.scss */
/* line 753, ../sass/screen.scss */
#bookmarked-producers {
padding: 0px;
padding-top: 15px;
@@ -716,7 +735,7 @@ section#header-title h1 .glyphicon {
border-bottom: solid 1px #e0e0e0;
background-color: white;
}
/* line 746, ../sass/screen.scss */
/* line 761, ../sass/screen.scss */
#bookmarked-producers h2 {
float: left;
font-family: 'highvoltageregular';
@@ -727,30 +746,30 @@ section#header-title h1 .glyphicon {
padding: 0px;
color: #323232;
}
/* line 757, ../sass/screen.scss */
/* line 772, ../sass/screen.scss */
#bookmarked-producers #producers {
position: relative;
top: -5px;
left: 5px;
}
/* line 763, ../sass/screen.scss */
/* line 778, ../sass/screen.scss */
#bookmarked-producers #discover {
padding-bottom: 20px;
text-align: center;
}
/* line 767, ../sass/screen.scss */
/* line 782, ../sass/screen.scss */
#bookmarked-producers #discover p {
padding-bottom: 0px;
color: white;
}
/* line 772, ../sass/screen.scss */
/* line 787, ../sass/screen.scss */
#bookmarked-producers #discover .btn {
background-color: white;
color: #F2B84B;
border: solid 1px white;
}

/* line 781, ../sass/screen.scss */
/* line 796, ../sass/screen.scss */
#footer {
position: absolute;
bottom: 0px;
@@ -762,7 +781,7 @@ section#header-title h1 .glyphicon {
border-top: 0px none;
color: white;
}
/* line 792, ../sass/screen.scss */
/* line 807, ../sass/screen.scss */
#footer a {
color: white;
font-family: 'capsuularegular';
@@ -773,38 +792,38 @@ section#header-title h1 .glyphicon {
border-right: solid 1px white;
border: 0px none;
}
/* line 802, ../sass/screen.scss */
/* line 817, ../sass/screen.scss */
#footer a:hover {
text-decoration: underline;
}
/* line 806, ../sass/screen.scss */
/* line 821, ../sass/screen.scss */
#footer a:last-child {
border: 0px none;
}

/* line 816, ../sass/screen.scss */
/* line 831, ../sass/screen.scss */
.site-producers #producers-list #producer-search {
padding-bottom: 15px;
}
/* line 820, ../sass/screen.scss */
/* line 835, ../sass/screen.scss */
.site-producers #producers-list .alert-no-results {
display: none;
}
/* line 824, ../sass/screen.scss */
/* line 839, ../sass/screen.scss */
.site-producers #producers-list .panel {
border: solid 1px #e0e0e0;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
/* line 828, ../sass/screen.scss */
/* line 843, ../sass/screen.scss */
.site-producers #producers-list .panel .panel-body {
border: 0px none;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
/* line 832, ../sass/screen.scss */
/* line 847, ../sass/screen.scss */
.site-producers #producers-list .panel .panel-body h2 {
font-family: 'capsuularegular';
font-weight: bold;
@@ -814,24 +833,24 @@ section#header-title h1 .glyphicon {
margin-bottom: 5px;
padding-bottom: 0px;
}
/* line 842, ../sass/screen.scss */
/* line 857, ../sass/screen.scss */
.site-producers #producers-list .panel .panel-body p {
padding-bottom: 0px;
}
/* line 846, ../sass/screen.scss */
/* line 861, ../sass/screen.scss */
.site-producers #producers-list .panel .panel-body .producer-type {
text-transform: uppercase;
margin-bottom: 10px;
font-size: 14px;
}
/* line 857, ../sass/screen.scss */
/* line 872, ../sass/screen.scss */
.site-producers #producers-list .panel .panel-footer {
-moz-border-radius: 0px 0px 8px 8px;
-webkit-border-radius: 0px;
border-radius: 0px 0px 8px 8px;
border: 0px none;
}
/* line 863, ../sass/screen.scss */
/* line 878, ../sass/screen.scss */
.site-producers #producers-list .panel .logo {
float: right;
position: relative;
@@ -845,7 +864,7 @@ section#header-title h1 .glyphicon {
text-align: right;
overflow: hidden;
}
/* line 874, ../sass/screen.scss */
/* line 889, ../sass/screen.scss */
.site-producers #producers-list .panel .logo .img-logo {
position: absolute;
top: 50%;
@@ -854,7 +873,7 @@ section#header-title h1 .glyphicon {
max-width: 90px;
max-height: 90px;
}
/* line 886, ../sass/screen.scss */
/* line 901, ../sass/screen.scss */
.site-producers #producers-map {
height: 750px;
border: solid 1px #e0e0e0;
@@ -862,51 +881,51 @@ section#header-title h1 .glyphicon {
-webkit-border-radius: 8px;
border-radius: 8px;
}
/* line 891, ../sass/screen.scss */
/* line 906, ../sass/screen.scss */
.site-producers #producers-map.fixed {
position: fixed !important;
top: 20px;
width: 300px;
height: 750px;
}
/* line 899, ../sass/screen.scss */
/* line 914, ../sass/screen.scss */
.site-producers #producers-map a {
text-decoration: none;
}
/* line 903, ../sass/screen.scss */
/* line 918, ../sass/screen.scss */
.site-producers #producers-map .popup-producer {
font-size: 14px;
color: #505050;
}
/* line 907, ../sass/screen.scss */
/* line 922, ../sass/screen.scss */
.site-producers #producers-map .popup-producer .name {
font-family: 'capsuularegular';
font-weight: bold;
font-size: 23px;
color: #323232;
}
/* line 913, ../sass/screen.scss */
/* line 928, ../sass/screen.scss */
.site-producers #producers-map .popup-producer .type {
text-transform: uppercase;
font-size: 13px;
margin-bottom: 12px;
}
/* line 918, ../sass/screen.scss */
/* line 933, ../sass/screen.scss */
.site-producers #producers-map .popup-producer .address {
margin-bottom: 12px;
}
/* line 921, ../sass/screen.scss */
/* line 936, ../sass/screen.scss */
.site-producers #producers-map .popup-producer .link {
color: white;
}

/* line 931, ../sass/screen.scss */
/* line 946, ../sass/screen.scss */
#content .site-about .panel .panel-heading h2 {
margin: 0px;
padding: 0px;
font-size: 25px;
}
/* line 939, ../sass/screen.scss */
/* line 954, ../sass/screen.scss */
#content .site-about .panel .panel-body h2 {
font-size: 20px;
text-transform: none;
@@ -914,88 +933,88 @@ section#header-title h1 .glyphicon {
padding-bottom: 0px;
margin-top: 0px;
}
/* line 947, ../sass/screen.scss */
/* line 962, ../sass/screen.scss */
#content .site-about .panel .panel-body p:last-child {
margin-bottom: 0px;
padding-bottom: 5px;
}
/* line 955, ../sass/screen.scss */
/* line 970, ../sass/screen.scss */
#content .site-about #few-numbers .item {
text-align: center;
padding-top: 20px;
padding-bottom: 20px;
}
/* line 960, ../sass/screen.scss */
/* line 975, ../sass/screen.scss */
#content .site-about #few-numbers .item .number {
font-family: 'highvoltageregular';
font-weight: bold;
font-size: 35px;
}
/* line 966, ../sass/screen.scss */
/* line 981, ../sass/screen.scss */
#content .site-about #few-numbers .item .description {
font-size: 16px;
}
/* line 970, ../sass/screen.scss */
/* line 985, ../sass/screen.scss */
#content .site-about #few-numbers .item .detail {
color: gray;
}
/* line 976, ../sass/screen.scss */
/* line 991, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials {
transition: all 0.4s;
}
/* line 979, ../sass/screen.scss */
/* line 994, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .item, #content .site-about #carousel-producers-testimonials .carousel-caption {
transition: all 0.4s;
}
/* line 983, ../sass/screen.scss */
/* line 998, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .carousel-indicators {
display: none;
}
/* line 987, ../sass/screen.scss */
/* line 1002, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .carousel-control {
background: none;
}
/* line 990, ../sass/screen.scss */
/* line 1005, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .carousel-control span.glyphicon {
top: 50px;
}
/* line 996, ../sass/screen.scss */
/* line 1011, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .item .carousel-caption {
top: 20px;
color: #323232;
text-shadow: none;
padding: 0px;
}
/* line 1002, ../sass/screen.scss */
/* line 1017, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .item .carousel-caption img {
display: block;
width: 150px;
height: auto;
margin: 0px auto 15px auto;
}
/* line 1010, ../sass/screen.scss */
/* line 1025, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .item .carousel-caption .producer-testimony {
margin-bottom: 12px;
}
/* line 1014, ../sass/screen.scss */
/* line 1029, ../sass/screen.scss */
#content .site-about #carousel-producers-testimonials .item .carousel-caption .producer-details {
font-style: italic;
}

/* line 1022, ../sass/screen.scss */
/* line 1037, ../sass/screen.scss */
#content #mentions {
padding-top: 20px;
}
/* line 1025, ../sass/screen.scss */
/* line 1040, ../sass/screen.scss */
#content #mentions div.content {
width: 60%;
font-size: 90%;
}
/* line 1030, ../sass/screen.scss */
/* line 1045, ../sass/screen.scss */
#content #mentions p {
padding-bottom: 15px;
}
/* line 1034, ../sass/screen.scss */
/* line 1049, ../sass/screen.scss */
#content #mentions h2 {
color: black;
padding-bottom: 40px;
@@ -1003,7 +1022,7 @@ section#header-title h1 .glyphicon {
line-height: 35px;
font-family: 'highvoltageregular';
}
/* line 1042, ../sass/screen.scss */
/* line 1057, ../sass/screen.scss */
#content #mentions h3 {
font-family: "highvoltageregular";
font-size: 18px;
@@ -1012,44 +1031,44 @@ section#header-title h1 .glyphicon {
color: black;
}

/* line 1057, ../sass/screen.scss */
/* line 1072, ../sass/screen.scss */
.vegas-loading {
display: none;
}

/* line 1064, ../sass/screen.scss */
/* line 1079, ../sass/screen.scss */
#profil-user .form-group.field-user-no_mail label {
font-weight: normal;
}
/* line 1068, ../sass/screen.scss */
/* line 1083, ../sass/screen.scss */
#profil-user .form-group label {
cursor: pointer;
}
/* line 1073, ../sass/screen.scss */
/* line 1088, ../sass/screen.scss */
#profil-user #mails-days-distribution .form-group {
float: left;
margin-right: 15px;
}
/* line 1077, ../sass/screen.scss */
/* line 1092, ../sass/screen.scss */
#profil-user #mails-days-distribution .form-group label {
font-weight: normal;
}
/* line 1083, ../sass/screen.scss */
/* line 1098, ../sass/screen.scss */
#profil-user p.strong {
font-weight: bold;
}
/* line 1087, ../sass/screen.scss */
/* line 1102, ../sass/screen.scss */
#profil-user h2 {
text-transform: none;
font-size: 25px;
}
/* line 1091, ../sass/screen.scss */
/* line 1106, ../sass/screen.scss */
#profil-user h2:first-child {
margin-top: 0px;
}

/* login */
/* line 1102, ../sass/screen.scss */
/* line 1117, ../sass/screen.scss */
.back-white, .site-login .col-lg-5, .site-signup .col-lg-5 {
background-color: white;
padding: 30px;
@@ -1058,7 +1077,7 @@ section#header-title h1 .glyphicon {
border-radius: 5px;
}

/* line 1109, ../sass/screen.scss */
/* line 1124, ../sass/screen.scss */
.site-login .col-lg-5 {
margin: 0px auto;
float: none;
@@ -1066,19 +1085,19 @@ section#header-title h1 .glyphicon {
}

/* signup */
/* line 1119, ../sass/screen.scss */
/* line 1134, ../sass/screen.scss */
.modal-backdrop {
z-index: 999;
}

/* line 1124, ../sass/screen.scss */
/* line 1139, ../sass/screen.scss */
.site-signup .col-lg-5 {
margin: 0px auto;
float: none;
max-width: 500px;
}

/* line 1134, ../sass/screen.scss */
/* line 1149, ../sass/screen.scss */
#modal-cgv .modal-body h2 {
margin-bottom: 5px;
padding-bottom: 0px;
@@ -1086,41 +1105,41 @@ section#header-title h1 .glyphicon {
margin-top: 0px;
}

/* line 1144, ../sass/screen.scss */
/* line 1159, ../sass/screen.scss */
#form-signup #user-producer {
margin-bottom: 30px;
}
/* line 1149, ../sass/screen.scss */
/* line 1164, ../sass/screen.scss */
#form-signup #signupform-id_producer option:disabled {
font-weight: bold;
color: black;
}
/* line 1155, ../sass/screen.scss */
/* line 1170, ../sass/screen.scss */
#form-signup #champs-producer {
display: none;
}
/* line 1159, ../sass/screen.scss */
/* line 1174, ../sass/screen.scss */
#form-signup #buttons-signup {
margin-top: 30px;
}
/* line 1163, ../sass/screen.scss */
/* line 1178, ../sass/screen.scss */
#form-signup .field-signupform-is_test {
display: none;
}

/* line 1168, ../sass/screen.scss */
/* line 1183, ../sass/screen.scss */
#col-left {
padding: 0px;
z-index: 15;
}
/* line 1172, ../sass/screen.scss */
/* line 1187, ../sass/screen.scss */
#col-left .affix {
width: 25%;
border-right: solid 1px #e0e0e0;
background-color: #FAFAFA;
height: 100%;
}
/* line 1179, ../sass/screen.scss */
/* line 1194, ../sass/screen.scss */
#col-left #link-home {
text-decoration: none;
font-size: 22px;
@@ -1129,28 +1148,28 @@ section#header-title h1 .glyphicon {
padding: 10px;
background-color: white;
}
/* line 1187, ../sass/screen.scss */
/* line 1202, ../sass/screen.scss */
#col-left #link-home img {
height: 50px;
margin-bottom: 5px;
float: left;
}
/* line 1193, ../sass/screen.scss */
/* line 1208, ../sass/screen.scss */
#col-left #link-home .text {
padding-left: 62px;
}
/* line 1196, ../sass/screen.scss */
/* line 1211, ../sass/screen.scss */
#col-left #link-home .text .bap {
font-family: "comfortaalight";
font-size: 24px;
}
/* line 1201, ../sass/screen.scss */
/* line 1216, ../sass/screen.scss */
#col-left #link-home .text .plateforme {
font-size: 17px;
font-family: "myriadpro-light";
color: #F2B84B;
}
/* line 1209, ../sass/screen.scss */
/* line 1224, ../sass/screen.scss */
#col-left h2 {
font-family: 'myriadpro-regular';
color: black;
@@ -1158,37 +1177,37 @@ section#header-title h1 .glyphicon {
margin-bottom: 10px;
padding: 15px 0px 5px 15px;
}
/* line 1217, ../sass/screen.scss */
/* line 1232, ../sass/screen.scss */
#col-left #links {
background-color: white;
margin-bottom: 20px;
}
/* line 1223, ../sass/screen.scss */
/* line 1238, ../sass/screen.scss */
#col-left #links ul li a {
text-align: center;
border-right: solid 1px #e0e0e0;
}
/* line 1227, ../sass/screen.scss */
/* line 1242, ../sass/screen.scss */
#col-left #links ul li a:hover {
background-color: #F2B84B;
color: white;
}
/* line 1233, ../sass/screen.scss */
/* line 1248, ../sass/screen.scss */
#col-left #links ul li:last-child a {
border-right: 0px none;
}
/* line 1243, ../sass/screen.scss */
/* line 1258, ../sass/screen.scss */
#col-left #producers nav.nav-producers ul li a {
padding-left: 50px;
height: 40px;
}
/* line 1249, ../sass/screen.scss */
/* line 1264, ../sass/screen.scss */
#col-left #producers nav.nav-producers ul li.active a {
background-color: #F2B84B;
position: relative;
color: white;
}
/* line 1254, ../sass/screen.scss */
/* line 1269, ../sass/screen.scss */
#col-left #producers nav.nav-producers ul li.active a:after {
right: -40px;
top: 50%;
@@ -1203,18 +1222,18 @@ section#header-title h1 .glyphicon {
border-width: 20px;
margin-top: -20px;
}
/* line 1273, ../sass/screen.scss */
/* line 1288, ../sass/screen.scss */
#col-left ul {
list-style-type: none;
margin: 0px;
padding: 0px;
}
/* line 1278, ../sass/screen.scss */
/* line 1293, ../sass/screen.scss */
#col-left ul li {
margin: 0px;
padding: 0px;
}
/* line 1282, ../sass/screen.scss */
/* line 1297, ../sass/screen.scss */
#col-left ul li a {
text-decoration: none;
font-family: 'comfortaaregular';
@@ -1225,18 +1244,18 @@ section#header-title h1 .glyphicon {
display: block;
color: black;
}
/* line 1292, ../sass/screen.scss */
/* line 1307, ../sass/screen.scss */
#col-left ul li a span.name, #col-left ul li a span.wording {
display: none;
}
/* line 1299, ../sass/screen.scss */
/* line 1314, ../sass/screen.scss */
#col-left p {
padding: 20px;
padding-top: 0px;
color: gray;
}

/* line 1307, ../sass/screen.scss */
/* line 1322, ../sass/screen.scss */
#content .header-title {
height: 79px;
padding: 20px 20px;
@@ -1251,7 +1270,7 @@ section#header-title h1 .glyphicon {
-webkit-box-shadow: 0px 0px 8px #e0e0e0;
box-shadow: 0px 0px 8px #e0e0e0;
}
/* line 1319, ../sass/screen.scss */
/* line 1334, ../sass/screen.scss */
#content .header-title h1 {
color: black;
font-family: 'myriadpro-regular';
@@ -1259,7 +1278,7 @@ section#header-title h1 .glyphicon {
font-size: 25px;
text-transform: uppercase;
}
/* line 1327, ../sass/screen.scss */
/* line 1342, ../sass/screen.scss */
#content .header-title h2 {
color: gray;
text-transform: none;
@@ -1268,16 +1287,16 @@ section#header-title h1 .glyphicon {
line-height: 20px;
}

/* line 1338, ../sass/screen.scss */
/* line 1353, ../sass/screen.scss */
.header-producer {
z-index: 1;
}
/* line 1341, ../sass/screen.scss */
/* line 1356, ../sass/screen.scss */
.header-producer #block-main-img {
height: 144px;
overflow: hidden;
}
/* line 1345, ../sass/screen.scss */
/* line 1360, ../sass/screen.scss */
.header-producer #block-main-img #main-img {
width: 100%;
height: auto;
@@ -1287,7 +1306,7 @@ section#header-title h1 .glyphicon {
-webkit-border-radius: 0px;
border-radius: 0px;
}
/* line 1354, ../sass/screen.scss */
/* line 1369, ../sass/screen.scss */
.header-producer h1 {
font-family: 'comfortaaregular';
text-align: center;
@@ -1295,23 +1314,23 @@ section#header-title h1 .glyphicon {
top: 30px;
left: 40px;
}
/* line 1361, ../sass/screen.scss */
/* line 1376, ../sass/screen.scss */
.header-producer h1 span {
background-color: rgba(255, 255, 255, 0.8);
padding: 10px 30px;
border: dotted 1px black;
}

/* line 1372, ../sass/screen.scss */
/* line 1387, ../sass/screen.scss */
nav#menu-producer {
border-bottom: solid 1px #e0e0e0;
}
/* line 1376, ../sass/screen.scss */
/* line 1391, ../sass/screen.scss */
nav#menu-producer ul li {
padding: 0px;
margin: 0px;
}
/* line 1380, ../sass/screen.scss */
/* line 1395, ../sass/screen.scss */
nav#menu-producer ul li a {
border-right: solid 1px #e0e0e0;
text-decoration: none;
@@ -1319,42 +1338,42 @@ nav#menu-producer ul li a {
-webkit-border-radius: 0px;
border-radius: 0px;
}
/* line 1385, ../sass/screen.scss */
/* line 1400, ../sass/screen.scss */
nav#menu-producer ul li a:hover {
background-color: #F2B84B;
color: white;
}

/* line 1395, ../sass/screen.scss */
/* line 1410, ../sass/screen.scss */
.site-contact .col-lg-6 {
margin: 0px auto;
float: none;
}
/* line 1400, ../sass/screen.scss */
/* line 1415, ../sass/screen.scss */
.site-contact .form-group.submit {
text-align: center;
}

/* line 1406, ../sass/screen.scss */
/* line 1421, ../sass/screen.scss */
.site-opinion .col-lg-6 {
margin: 0px auto;
float: none;
}
/* line 1411, ../sass/screen.scss */
/* line 1426, ../sass/screen.scss */
.site-opinion .field-opinionform-istest {
display: none;
}
/* line 1415, ../sass/screen.scss */
/* line 1430, ../sass/screen.scss */
.site-opinion .form-group.submit {
text-align: center;
}

/* line 1422, ../sass/screen.scss */
/* line 1437, ../sass/screen.scss */
#site-prices .panel p {
padding-bottom: 0px;
}

/* line 1429, ../sass/screen.scss */
/* line 1444, ../sass/screen.scss */
#contact-form .field-contactform-istest {
display: none;
}
@@ -2238,62 +2257,66 @@ termes.
}
/* line 167, ../sass/_responsive.scss */
.home #main #row-users-producers .panel .hook {
margin-bottom: 10px;
margin-bottom: 25px;
}
/* line 170, ../sass/_responsive.scss */
.home #main #row-users-producers .panel .hook br {
display: none;
}
/* line 176, ../sass/_responsive.scss */
/* line 174, ../sass/_responsive.scss */
.home #main #row-users-producers .panel .hook .word-animate {
font-size: 20px;
}
/* line 180, ../sass/_responsive.scss */
.home #main #row-users-producers .panel .links a {
display: block;
margin-bottom: 5px;
}
/* line 183, ../sass/_responsive.scss */
/* line 187, ../sass/_responsive.scss */
.home #main #row-users-producers .producer, .home #main #row-users-producers .users {
padding-right: 0px;
}
/* line 187, ../sass/_responsive.scss */
/* line 191, ../sass/_responsive.scss */
.home #main #row-users-producers .users {
padding-left: 0px;
}
/* line 190, ../sass/_responsive.scss */
/* line 194, ../sass/_responsive.scss */
.home #main #row-users-producers .users .panel {
margin-bottom: 0px;
}

/* line 199, ../sass/_responsive.scss */
/* line 203, ../sass/_responsive.scss */
.site-producers #wrapper-producers-list {
padding: 0px;
}
/* line 204, ../sass/_responsive.scss */
/* line 208, ../sass/_responsive.scss */
.site-producers #wrapper-producers-list #producers-list .panel .panel-body {
text-align: center;
}
/* line 207, ../sass/_responsive.scss */
/* line 211, ../sass/_responsive.scss */
.site-producers #wrapper-producers-list #producers-list .panel .panel-body .logo {
display: none;
}
/* line 215, ../sass/_responsive.scss */
/* line 219, ../sass/_responsive.scss */
.site-producers #producers-map {
display: none;
}

/* line 221, ../sass/_responsive.scss */
/* line 225, ../sass/_responsive.scss */
.site-about .col-md-8, .site-about .col-md-4 {
padding: 0px;
}

/* line 227, ../sass/_responsive.scss */
/* line 231, ../sass/_responsive.scss */
.site-contact .col-lg-5 {
padding: 0px;
}

/* line 233, ../sass/_responsive.scss */
/* line 237, ../sass/_responsive.scss */
#content .site-service #panel-go-further {
margin-bottom: 0px;
}
/* line 236, ../sass/_responsive.scss */
/* line 240, ../sass/_responsive.scss */
#content .site-service #panel-go-further a {
display: block;
margin-bottom: 5px;

+ 71
- 0
frontend/web/js/frontend.js Целия файл

@@ -35,11 +35,82 @@
*/

$(document).ready(function () {
opendistrib_home_text_animation();
opendistrib_signup();
producersModule.init();
aboutProducersTestimonialsCarousel.init();
});

function opendistrib_home_text_animation() {
var
words = [
'<span class="glyphicon glyphicon-eye-open"></span> présenter votre activité',
'<span class="glyphicon glyphicon-calendar"></span> gérer vos prises de commandes',
'<span class="glyphicon glyphicon-download-alt"></span> télécharger vos récapitulatifs de commande',
'<span class="glyphicon glyphicon-send"></span> communiquer avec vos clients',
'<span class="glyphicon glyphicon-file"></span> générer vos bons de livraisons et factures',
'<span class="glyphicon glyphicon-euro"></span> comptabiliser les paiements',
'<span class="glyphicon glyphicon-stats"></span> obtenir des statistiques de vente'
],
part,
i = 0,
offset = 0,
len = words.length,
forwards = true,
skip_count = 0,
skip_delay = 10,
speed = 3000;

var wordflick = function(){

part = words[i];
$('#row-users-producers .producer .word-animate span').html(part);

setInterval(function(){
i ++;
if(i >= len){
i=0;
}

part = words[i];
$('#row-users-producers .producer .word-animate span').hide().html(part).fadeIn();

/*if (forwards) {
if(offset >= words[i].length){
++skip_count;
if (skip_count == skip_delay) {
forwards = false;
skip_count = 0;
}
}
}
else {
if(offset == 0){
forwards = true;
i++;
offset = 0;
if(i >= len){
i=0;
}
}
}
part = words[i].substr(0, offset);
if (skip_count == 0) {
if (forwards) {
offset++;
}
else {
offset--;
}
}*/
}, speed);
};

$(document).ready(function(){
wordflick();
});
}

var UrlManager = {
getBaseUrl: function () {
return $('meta[name=baseurl]').attr('content') + '/';

+ 5
- 1
frontend/web/sass/_responsive.scss Целия файл

@@ -165,11 +165,15 @@ termes.

.panel {
.hook {
margin-bottom: 10px;
margin-bottom: 25px;

br {
display: none;
}

.word-animate {
font-size: 20px;
}
}

.links {

+ 18
- 3
frontend/web/sass/screen.scss Целия файл

@@ -581,9 +581,6 @@ section#header-title {
@include border-radius(5px) ;

.col-md-6 {
//display: table-cell;
//width: 50%;

.panel {
height: 100%;
margin-bottom: 20px;
@@ -593,6 +590,24 @@ section#header-title {

&.producer {
padding-left: 0px;

.word-animate {
margin-top: 18px;
height: auto;

span.functionality {
background-color: #FFF8DC;
@include border-radius(8px);
padding: 8px 15px 5px 15px;

.glyphicon {
position: relative;
top: 4px;
right: 6px;
}
}

}
}

&.users {

+ 11
- 1
producer/controllers/NewsletterController.php Целия файл

@@ -44,7 +44,17 @@ class NewsletterController extends ProducerBaseController
{
public function behaviors()
{
return [];
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@']
]
],
],
];
}

public function actionIndex()

+ 2
- 1
producer/controllers/SubscriptionController.php Целия файл

@@ -42,6 +42,7 @@ use common\forms\SubscriptionForm;
use common\helpers\GlobalParam;
use common\logic\Product\Product\Model\Product;
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription;
use common\logic\Subscription\Subscription\Model\Subscription;
use common\logic\Subscription\Subscription\Model\SubscriptionSearch;
use yii\base\UserException;
use yii\filters\AccessControl;
@@ -166,7 +167,7 @@ class SubscriptionController extends ProducerBaseController
$model->friday = $subscription->friday;
$model->saturday = $subscription->saturday;
$model->sunday = $subscription->sunday;
$model->auto_payment = $subscription->auto_payment;
$model->auto_payment = Subscription::AUTO_PAYMENT_DEDUCTED;
$model->week_frequency = $subscription->week_frequency;

// produits

+ 3
- 1
producer/views/order/order.php Целия файл

@@ -56,7 +56,9 @@ $this->setTitle('Commander');

<script>
var appInitValues = {
urlLogin: '<?= \Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/producer', 'id' => $this->context->getProducerCurrent()->id, 'return_url' => \Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order', 'slug_producer' => $this->context->getProducerCurrent()->slug])]) ?>'
urlLogin: '<?= \Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/producer', 'id' => $this->context->getProducerCurrent()->id, 'return_url' => \Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order', 'slug_producer' => $this->context->getProducerCurrent()->slug])]) ?>',
producerOptionOrderEntryPoint: '<?= $producer->option_order_entry_point ?>',
<?php if (isset($order)): ?>pointSaleActiveId: <?= $order->id_point_sale ?><?php endif; ?>
};
</script>


+ 20
- 3
producer/views/subscription/_form.php Целия файл

@@ -36,9 +36,13 @@ pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/

use common\logic\Order\Order\Wrapper\OrderManager;
use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\logic\Subscription\Subscription\Wrapper\SubscriptionManager;

$producerManager = ProducerManager::getInstance();
$subscriptionManager = SubscriptionManager::getInstance();
$orderManager = OrderManager::getInstance();

\producer\assets\VuejsSubscriptionFormAsset::register($this) ;

@@ -130,15 +134,14 @@ $producerManager = ProducerManager::getInstance();
</div>
<div class="clr"></div>
<h3><span>Paiement</span></h3>

<!--<h3><span>Paiement</span></h3>
<?php if($producerManager->getConfig('credit')): ?>
<div class="form-group field-subscriptionform-auto_payment">
<label><input type="checkbox" id="subscriptionform-auto_payment" name="SubscriptionForm[auto_payment]" v-model="autoPayment"> Paiement automatique</label>
<div class="hint-block">Cochez cette case si vous souhaitez que votre Crédit soit automatiquement débité.</div>
<div class="help-block"></div>
</div>
<?php endif; ?>
<?php endif; ?>-->
<div class="days" v-if="pointSaleActive">
<h3 id="step-days"><span>Jours</span></h3>
@@ -253,6 +256,20 @@ $producerManager = ProducerManager::getInstance();
<textarea id="subscriptionform-comment" class="form-control comment-textarea" v-model="comment"></textarea>
</div>
</div>


<?php if($idSubscription): ?>
<?php
$subscription = $subscriptionManager->findOneSubscriptionById($idSubscription);
$ordersIncomingSubscriptionArray = $orderManager->findOrdersIncomingBySubscription($subscription);
?>
<?php if($subscription && $ordersIncomingSubscriptionArray): ?>
<div class="alert alert-warning">
<span class="glyphicon glyphicon-alert"></span>
Attention, en modifiant votre abonnement, vos <?= count($ordersIncomingSubscriptionArray) ?> commande(s) à venir vont être re-générées.
</div>
<?php endif; ?>
<?php endif; ?>
<button class="btn btn-primary" disabled="disabled" v-if="disableSubmitButton">Enregistrer</button>
<button class="btn btn-primary" v-else>Enregistrer</button>

+ 1
- 1
producer/views/subscription/form.php Целия файл

@@ -46,6 +46,6 @@ else {

<div class="subscription-create">
<?= $this->render('_form', [
'idSubscription' => $idSubscription
'idSubscription' => $idSubscription,
]) ?>
</div>

+ 2
- 2
producer/views/subscription/index.php Целия файл

@@ -162,7 +162,7 @@ $columns = [
],
] ;
if($producerManager->getConfig('credit')) {
/*if($producerManager->getConfig('credit')) {
$columns[] = [
'format' => 'raw',
'label' => 'Paiement automatique',
@@ -178,7 +178,7 @@ if($producerManager->getConfig('credit')) {
}
}
] ;
}
}*/
$columns[] = [
'class' => 'yii\grid\ActionColumn',

+ 35
- 50
producer/web/js/vuejs/order-order.js Целия файл

@@ -16,6 +16,7 @@ var app = new Vue({
distribution: null,
pointsSale: [],
pointSaleActive: null,
pointSaleActiveId: null,
pointsSaleCodes: [],
products: [],
categories: [],
@@ -28,6 +29,7 @@ var app = new Vue({
delivery: false,
deliveryAddress: null,
urlLogin: '#',
producerOptionOrderEntryPoint: null,
calendar: {
columns: 2,
mode: 'single',
@@ -70,25 +72,25 @@ var app = new Vue({
}, window.appInitValues);
},
mounted: function() {
let fr = new Intl.Locale("fr-FR");
var dateDefined = $('#order-distribution-date').size() || $('#distribution-date').size() ;

if(dateDefined) {
if($('#order-distribution-date').size()) {
this.date = new Date($('#order-distribution-date').html()) ;
}
else {
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('first') ;
this.initDate();
this.init('first');
},
methods: {
initDate: function() {
var dateDefined = $('#order-distribution-date').size() || $('#distribution-date').size() ;
if(dateDefined && (this.producerOptionOrderEntryPoint != 'point-sale' || this.pointSaleActiveId)) {
if($('#order-distribution-date').size()) {
this.date = new Date($('#order-distribution-date').html()) ;
}
else {
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() ;
}
},
getDate: function() {
return this.formatDate(this.date) ;
},
@@ -134,16 +136,13 @@ var app = new Vue({

axios.get("ajax-infos",{params: {
date : this.getDate(),
pointSaleId: this.pointSaleActive ? this.pointSaleActive.id : 0
pointSaleId: this.pointSaleActiveId ? this.pointSaleActiveId : (this.pointSaleActive ? this.pointSaleActive.id : 0)
}})
.then(function(response) {

// distributions
var distributions = response.data.distributions;

app.calendar.attrs = [];
app.calendar.availableDates = [];

var distributions = response.data.distributions;
if (distributions.length) {
app.distributions = distributions;
var arrayDate;
@@ -161,12 +160,10 @@ var app = new Vue({
}
}

// distribution
if (response.data.distribution) {
app.distribution = response.data.distribution;
}

// liste commandes
var orders = [];
if (response.data.orders) {
orders = response.data.orders;
@@ -177,7 +174,6 @@ var app = new Vue({
arrayDate = orders[i].date_distribution.split('-');
var dateOrder = new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]);
if (app.isAvailableDate(dateOrder)) {

app.calendar.attrs.push({
highlight: true,
popover: {
@@ -185,40 +181,19 @@ var app = new Vue({
hideIndicator: true
},
dates: orders[i].date_distribution


/*highlight: {
backgroundColor: '#FF7F00'
},
contentStyle: {
color: 'white'
},
popover: {
label: orders[i].pointSale.name + ' / ' + app.formatPrice(orders[i].amount_total),
hideIndicator: true
},
dates: orders[i].date_distribution,*/
});
}
}
}

// catégories
if(response.data.categories) {
app.categories = response.data.categories ;
app.setCategoryCurrent(response.data.categories[0]) ;
}

// producer
app.producer = response.data.producer;

// user
app.user = response.data.user;

// credit
app.useCredit = response.data.producer.use_credit_checked_default;

// points de vente
if (response.data.points_sale) {
app.pointsSale = [];
var orderPointSale = 0;
@@ -233,6 +208,10 @@ var app = new Vue({
}
}

if(app.pointSaleActiveId) {
app.pointSaleActive = app.getPointSale(app.pointSaleActiveId);
}

if(app.isChangeState('point-sale', 'point-sale', 'date')) {
app.date = null ;
app.dateFormat = null ;
@@ -249,12 +228,11 @@ var app = new Vue({
}

if(updateOrder) {
// products
if(response.data.products) {
app.products = response.data.products ;
app.products = response.data.products;
}

// order
app.order = null ;
if(response.data.order) {
app.order = response.data.order ;
@@ -276,7 +254,14 @@ var app = new Vue({
}

if(type == 'first') {
if(app.producer.option_order_entry_point == 'point-sale') {
if(app.getDate() && app.pointSaleActive) {
app.step = 'products' ;

if(response.data.products) {
app.products = response.data.products;
}
}
else if(app.producer.option_order_entry_point == 'point-sale') {
app.step = 'point-sale' ;
}
else if(app.getDate() && app.producer && app.producer.option_order_entry_point == 'date') {

Loading…
Отказ
Запис