@@ -38,6 +38,7 @@ | |||
namespace backend\controllers; | |||
use common\helpers\MeanPayment; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\User\User\Model\User; | |||
use Yii; | |||
@@ -162,7 +163,7 @@ class CronController extends BackendController | |||
$orderManager->initOrder($order); | |||
if ($order->auto_payment && $configCredit) { | |||
if ($orderManager->getOrderAmount($order, Order::AMOUNT_REMAINING) > 0) { | |||
$paymentManager->payOrder($order, $userManager->findOneUserById(User::ID_USER_SYSTEM), false); | |||
$paymentManager->payOrder($order, MeanPayment::CREDIT, $userManager->findOneUserById(User::ID_USER_SYSTEM), false); | |||
$countOrders++; | |||
} | |||
} |
@@ -362,7 +362,8 @@ class DistributionController extends BackendController | |||
'oneProductUnactivated' => $oneProductUnactivated, | |||
'isLinkedToValidDocument' => $orderManager->isLinkedToValidDocument($order), | |||
'isCreditAutoPayment' => $orderManager->isCreditAutoPayment($order), | |||
'isCreditContext' => $orderManager->isCreditContext($order) | |||
'isCreditContext' => $orderManager->isCreditContext($order), | |||
'isPaid' => $orderManager->isOrderPaid($order), | |||
]); | |||
} | |||
} |
@@ -41,6 +41,7 @@ namespace backend\controllers; | |||
use common\helpers\Ajax; | |||
use common\helpers\CSV; | |||
use common\helpers\GlobalParam; | |||
use common\helpers\MeanPayment; | |||
use common\helpers\Price; | |||
use common\logic\Document\DeliveryNote\Model\DeliveryNote; | |||
use common\logic\Document\Document\Model\Document; | |||
@@ -56,6 +57,7 @@ use yii\filters\VerbFilter; | |||
use yii\filters\AccessControl; | |||
use yii\web\NotFoundHttpException; | |||
use yii\helpers\Html; | |||
use common\logic\Payment\Model\Payment; | |||
class DocumentController extends BackendController | |||
{ | |||
@@ -161,20 +163,42 @@ class DocumentController extends BackendController | |||
public function actionUpdate($id) | |||
{ | |||
$model = $this->findModel($id); | |||
$documentManager = $this->getDocumentManager(); | |||
$paymentManager = $this->getPaymentManager(); | |||
$document = $this->findModel($id); | |||
if (!$model) { | |||
if (!$document) { | |||
throw new yii\web\NotFoundHttpException('Le document n\'a pas été trouvé.'); | |||
} | |||
if ($model && $model->load(\Yii::$app->request->post()) && $model->save()) { | |||
$this->setFlash('success', $this->getFlashMessage('update', $model)); | |||
if ($document && $document->load(\Yii::$app->request->post()) && $document->save()) { | |||
$this->setFlash('success', $this->getFlashMessage('update', $document)); | |||
} | |||
$payment = null; | |||
if($documentManager->isDocumentInvoice($document) && $documentManager->isStatusValid($document)) { | |||
$payment = $paymentManager->instanciatePayment( | |||
Payment::TYPE_PAYMENT, | |||
$documentManager->getAmountWithTax($document), | |||
$this->getProducerCurrent(), | |||
null, | |||
null, | |||
MeanPayment::TRANSFER, | |||
null, | |||
$document | |||
); | |||
if ($payment->load(\Yii::$app->request->post()) && $payment->save()) { | |||
$this->setFlash('success', 'Le règlement a bien été ajouté.'); | |||
return $this->redirect(['invoice/update', 'id' => $document->id]); | |||
} | |||
} | |||
return $this->render('/document/update', [ | |||
'title' => $this->getTitle('Modifier'), | |||
'typeDocument' => $this->getDocumentType(), | |||
'model' => $model, | |||
'model' => $document, | |||
'payment' => $payment | |||
]); | |||
} | |||
@@ -380,7 +380,7 @@ $this->setPageTitle('Distributions') ; | |||
<template v-if="order.isCreditAutoPayment"> | |||
({{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}) | |||
<span class="glyphicon glyphicon-time" title="Paiement automatique la veille de la distribution" v-if="(order.amount_paid == 0 || order.amount_paid < order.amount)"></span> | |||
<span class="glyphicon glyphicon-time" title="Paiement automatique la veille de la distribution" v-if="order.auto_payment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span> | |||
</template> | |||
@@ -411,11 +411,11 @@ $this->setPageTitle('Distributions') ; | |||
{{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par virement') }} | |||
</a> | |||
</li> | |||
<li> | |||
<!--<li> | |||
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit-card"> | |||
{{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par carte bancaire') }} | |||
</a> | |||
</li> | |||
</li>--> | |||
<li><a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">Historique</a></li> | |||
</ul> | |||
@@ -491,7 +491,7 @@ $this->setPageTitle('Distributions') ; | |||
<div class="row"> | |||
<div class="col-md-6"> | |||
<div class="info-box"> | |||
<span :class="'info-box-icon ' +((order.amount_paid == order.amount) ? 'bg-green' : 'bg-red')"><i class="fa fa-check"></i></span> | |||
<span :class="'info-box-icon ' +((order.isPaid) ? 'bg-green' : 'bg-red')"><i class="fa fa-check"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text">Montant</span> | |||
<span class="info-box-number"> | |||
@@ -552,7 +552,10 @@ $this->setPageTitle('Distributions') ; | |||
</td> | |||
<td class="column-delivery-note"> | |||
<a v-if="order.id_delivery_note" class="btn btn-default btn-xs" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note"> | |||
<span class="glyphicon glyphicon-file"></span> BL #{{ order.id_delivery_note }} | |||
<span class="glyphicon glyphicon-file"></span> BL | |||
</a> | |||
<a v-if="order.id_invoice" class="btn btn-default btn-xs" :href="UrlManager.getBaseUrl()+'invoice/update?id='+order.id_invoice"> | |||
<span class="glyphicon glyphicon-file"></span> FA | |||
</a> | |||
</td> | |||
</tr> | |||
@@ -592,8 +595,13 @@ $this->setPageTitle('Distributions') ; | |||
</div> | |||
<script type="text/x-template" id="order-state-payment"> | |||
<span class="label label-success" v-if="order.amount_paid == order.amount"> </span> | |||
<span class="label label-default" v-else-if="order.amount_paid == 0"> </span> | |||
<span class="label label-success" v-if="order.isPaid"> </span> | |||
<span class="label label-default" v-else> </span> | |||
<!--<span class="label label-success" v-if="order.amount_paid == order.amount"> </span> | |||
<span class="label label-default" v-else-if="order.amount_paid == 0"> </span>--> | |||
<!--<span class="label label-success input-group-addon" v-if="order.amount_paid == order.amount">débité</span> | |||
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non débité</span> | |||
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span> |
@@ -36,8 +36,8 @@ | |||
* termes. | |||
*/ | |||
use common\logic\Document\Document\Wrapper\DocumentManager; | |||
use common\logic\Producer\Producer\Wrapper\ProducerManager; | |||
use common\helpers\MeanPayment;use common\helpers\Price;use common\logic\Document\Document\Wrapper\DocumentManager; | |||
use common\logic\Document\Invoice\Wrapper\InvoiceManager;use common\logic\Payment\Wrapper\PaymentManager;use common\logic\Producer\Producer\Wrapper\ProducerManager; | |||
use common\logic\User\User\Wrapper\UserManager; | |||
use yii\helpers\Html; | |||
use yii\widgets\ActiveForm; | |||
@@ -46,7 +46,9 @@ use yii\widgets\ActiveForm; | |||
$producerManager = ProducerManager::getInstance(); | |||
$documentManager = DocumentManager::getInstance(); | |||
$invoiceManager = InvoiceManager::getInstance(); | |||
$userManager = UserManager::getInstance(); | |||
$paymentManager = PaymentManager::getInstance(); | |||
$documentClass = $documentManager->getClass($model); | |||
@@ -171,7 +173,12 @@ $documentClass = $documentManager->getClass($model); | |||
<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-text"> | |||
Total<span v-if="taxRateProducer != 0"> (TTC)</span> | |||
<?php if($invoiceManager->isInvoicePaid($model)): ?> | |||
<span class="label label-success">PAYÉE</span> | |||
<?php endif; ?> | |||
</span> | |||
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> | |||
<p v-if="invoiceUrl"> | |||
<a class="btn btn-sm btn-default" :href="invoiceUrl"> | |||
@@ -234,6 +241,54 @@ $documentClass = $documentManager->getClass($model); | |||
<div class="clr"></div> | |||
<?php if ($action == 'update' && $documentClass == 'Invoice'): ?> | |||
<div v-if="document.status == 'valid'"> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Règlement | |||
</div> | |||
<div class="panel-body"> | |||
<?php if($model->payments && count($model->payments) > 0): ?> | |||
<table class="table table-bordered"> | |||
<thead> | |||
<tr> | |||
<th>Moyen de paiement</th> | |||
<th>Montant</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<?php foreach($model->payments as $payment): ?> | |||
<tr> | |||
<td><?= $paymentManager->getStrMeanPayment($payment); ?></td> | |||
<td><?= Price::format($payment->amount); ?></td> | |||
</tr> | |||
<?php endforeach; ?> | |||
</tbody> | |||
</table> | |||
<?php endif; ?> | |||
<?php if(!$invoiceManager->isInvoicePaid($model)): ?> | |||
<div class="row"> | |||
<?php $form = ActiveForm::begin(); ?> | |||
<div class="col-md-4"> | |||
<?= $form->field($payment, 'mean_payment')->dropDownList(MeanPayment::getAll()); ?> | |||
</div> | |||
<div class="col-md-4"> | |||
<?= $form->field($payment, 'amount')->textInput(); ?> | |||
</div> | |||
<div class="col-md-4"> | |||
<div class="form-group"> | |||
<br> | |||
<?= Html::submitButton('Ajouter', ['class' => 'btn btn-primary']) ?> | |||
</div> | |||
</div> | |||
<?php ActiveForm::end(); ?> | |||
</div> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)"> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> |
@@ -50,5 +50,6 @@ $this->addBreadcrumb('Modifier') ; | |||
'action' => 'update', | |||
'model' => $model, | |||
'typeDocument' => $typeDocument, | |||
'payment' => $payment | |||
]) ?> | |||
</div> |
@@ -104,8 +104,14 @@ $this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon- | |||
[ | |||
'attribute' => 'amount', | |||
'header' => 'Montant', | |||
'format' => 'raw', | |||
'value' => function ($invoice) use ($invoiceManager) { | |||
return $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL, true); | |||
$amountWithTax = $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL); | |||
$html = $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL, true); | |||
if($amountWithTax && $invoiceManager->isInvoicePaid($invoice)) { | |||
$html .= ' <span class="label label-success">Payée</span>'; | |||
} | |||
return $html; | |||
} | |||
], | |||
[ |
@@ -100,6 +100,21 @@ class DocumentSolver extends AbstractService implements SolverInterface | |||
return null; | |||
} | |||
public function isDocumentDeliveryNote(DocumentInterface $document): bool | |||
{ | |||
return $this->getClass($document) == 'DeliveryNote'; | |||
} | |||
public function isDocumentInvoice(DocumentInterface $document): bool | |||
{ | |||
return $this->getClass($document) == 'Invoice'; | |||
} | |||
public function isDocumentQuotation(DocumentInterface $document): bool | |||
{ | |||
return $this->getClass($document) == 'Quotation'; | |||
} | |||
public function getClass(DocumentInterface $document, bool $pathComplete = false): string | |||
{ | |||
$classDocument = get_class($document); |
@@ -39,6 +39,7 @@ | |||
namespace common\logic\Document\Invoice\Model; | |||
use common\logic\Document\Document\Model\Document; | |||
use common\logic\Payment\Model\Payment; | |||
/** | |||
* This is the model class for table "invoice". | |||
@@ -64,4 +65,10 @@ class Invoice extends Document | |||
{ | |||
return $this->relationOrders('id_invoice'); | |||
} | |||
public function getPayments() | |||
{ | |||
return $this->hasMany(Payment::class, ['id_invoice' => 'id']) | |||
->orderBy(['payment.id' => SORT_DESC]); | |||
} | |||
} |
@@ -17,7 +17,7 @@ class InvoiceRepository extends AbstractRepository | |||
public function getDefaultOptionsSearch(): array | |||
{ | |||
return [ | |||
self::WITH => [], | |||
self::WITH => ['payments'], | |||
self::JOIN_WITH => ['user AS user_invoice', 'producer'], | |||
self::ORDER_BY => 'date ASC', | |||
self::ATTRIBUTE_ID_PRODUCER => 'invoice.id_producer' |
@@ -0,0 +1,26 @@ | |||
<?php | |||
namespace common\logic\Document\Invoice\Service; | |||
use common\helpers\Price; | |||
use common\logic\Document\Document\Service\DocumentSolver; | |||
use common\logic\Document\Invoice\Model\Invoice; | |||
class InvoiceSolver extends DocumentSolver | |||
{ | |||
public function getInvoiceAmountPaid(Invoice $invoice): float | |||
{ | |||
$amountPaid = 0; | |||
foreach($invoice->payments as $payment) { | |||
$amountPaid += $payment->amount; | |||
} | |||
return $amountPaid; | |||
} | |||
public function isInvoicePaid(Invoice $invoice): bool | |||
{ | |||
return $this->getInvoiceAmountPaid($invoice) >= Price::numberTwoDecimals($this->getAmountWithTax($invoice)); | |||
} | |||
} |
@@ -3,10 +3,10 @@ | |||
namespace common\logic\Document\Invoice\Wrapper; | |||
use common\logic\AbstractContainer; | |||
use common\logic\Document\Document\Service\DocumentSolver; | |||
use common\logic\Document\Invoice\Repository\InvoiceRepository; | |||
use common\logic\Document\Invoice\Service\InvoiceBuilder; | |||
use common\logic\Document\Invoice\Service\InvoiceDefinition; | |||
use common\logic\Document\Invoice\Service\InvoiceSolver; | |||
class InvoiceContainer extends AbstractContainer | |||
{ | |||
@@ -14,7 +14,7 @@ class InvoiceContainer extends AbstractContainer | |||
{ | |||
return [ | |||
InvoiceDefinition::class, | |||
DocumentSolver::class, | |||
InvoiceSolver::class, | |||
InvoiceRepository::class, | |||
InvoiceBuilder::class, | |||
]; | |||
@@ -25,9 +25,9 @@ class InvoiceContainer extends AbstractContainer | |||
return InvoiceDefinition::getInstance(); | |||
} | |||
public function getSolver(): DocumentSolver | |||
public function getSolver(): InvoiceSolver | |||
{ | |||
return DocumentSolver::getInstance(); | |||
return InvoiceSolver::getInstance(); | |||
} | |||
public function getRepository(): InvoiceRepository |
@@ -6,9 +6,11 @@ use common\logic\Document\Document\Wrapper\DocumentManager; | |||
use common\logic\Document\Invoice\Repository\InvoiceRepository; | |||
use common\logic\Document\Invoice\Service\InvoiceBuilder; | |||
use common\logic\Document\Invoice\Service\InvoiceDefinition; | |||
use common\logic\Document\Invoice\Service\InvoiceSolver; | |||
/** | |||
* @mixin InvoiceDefinition | |||
* @mixin InvoiceSolver | |||
* @mixin InvoiceRepository | |||
* @mixin InvoiceBuilder | |||
*/ |
@@ -9,6 +9,8 @@ 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\Document\Invoice\Repository\InvoiceRepository; | |||
use common\logic\Document\Invoice\Service\InvoiceSolver; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\Order\Service\OrderSolver; | |||
use common\logic\Order\ProductOrder\Repository\ProductOrderRepository; | |||
@@ -34,6 +36,8 @@ class OrderRepository extends AbstractRepository | |||
protected DistributionRepository $distributionRepository; | |||
protected PointSaleRepository $pointSaleRepository; | |||
protected UserPointSaleRepository $userPointSaleRepository; | |||
protected InvoiceRepository $invoiceRepository; | |||
protected InvoiceSolver $invoiceSolver; | |||
public function loadDependencies(): void | |||
{ | |||
@@ -47,6 +51,8 @@ class OrderRepository extends AbstractRepository | |||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); | |||
$this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class); | |||
$this->invoiceRepository = $this->loadService(InvoiceRepository::class); | |||
$this->invoiceSolver = $this->loadService(InvoiceSolver::class); | |||
} | |||
public function getDefaultOptionsSearch(): array | |||
@@ -424,4 +430,21 @@ class OrderRepository extends AbstractRepository | |||
return intval($total / 3); | |||
} | |||
public function isOrderPaid(Order $order): bool | |||
{ | |||
if($this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID) | |||
>= $this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL)) { | |||
return true; | |||
} | |||
if($order->invoice) { | |||
$invoice = $this->invoiceRepository->findOneInvoiceById($order->id_invoice); | |||
if($invoice && $this->invoiceSolver->isInvoicePaid($invoice)) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
} |
@@ -3,6 +3,7 @@ | |||
namespace common\logic\Payment\Service; | |||
use common\logic\AbstractBuilder; | |||
use common\logic\Document\Invoice\Model\Invoice; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\Order\Service\OrderSolver; | |||
use common\logic\Payment\Model\Payment; | |||
@@ -27,7 +28,8 @@ class PaymentBuilder extends AbstractBuilder | |||
User $user = null, | |||
User $userAction = null, | |||
string $meanPayment = null, | |||
Order $order = null | |||
Order $order = null, | |||
Invoice $invoice = null | |||
): Payment | |||
{ | |||
$payment = new Payment; | |||
@@ -48,6 +50,10 @@ class PaymentBuilder extends AbstractBuilder | |||
$payment->populateOrder($order); | |||
} | |||
if($invoice) { | |||
$payment->populateInvoice($invoice); | |||
} | |||
if($meanPayment) { | |||
$payment->mean_payment = $meanPayment; | |||
} | |||
@@ -62,14 +68,15 @@ class PaymentBuilder extends AbstractBuilder | |||
User $user = null, | |||
User $userAction = null, | |||
string $meanPayment = null, | |||
Order $order = null | |||
Order $order = null, | |||
Invoice $invoice = null | |||
): ?Payment | |||
{ | |||
if ($amount > -0.01 && $amount < 0.01) { | |||
return null; | |||
} | |||
$payment = $this->instanciatePayment($type, $amount, $producer, $user, $userAction, $meanPayment, $order); | |||
$payment = $this->instanciatePayment($type, $amount, $producer, $user, $userAction, $meanPayment, $order, $invoice); | |||
$payment->setComment($payment->getComment() . $this->orderSolver->getPaymentComment($payment)); | |||
$this->create($payment); | |||