if($ordersArray) { | if($ordersArray) { | ||||
foreach ($ordersArray as $order) { | foreach ($ordersArray as $order) { | ||||
if(is_null($order->date_delete)) { | if(is_null($order->date_delete)) { | ||||
$revenues += $order->amount; | |||||
$revenues += $order->getAmountWithTax(); | |||||
$weight += $order->weight; | $weight += $order->weight; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$order = array_merge($order->getAttributes(), [ | $order = array_merge($order->getAttributes(), [ | ||||
'amount' => $order->getAmount(Order::AMOUNT_TOTAL), | |||||
'amount' => $order->getAmountWithTax(Order::AMOUNT_TOTAL), | |||||
'amount_paid' => $order->getAmount(Order::AMOUNT_PAID), | 'amount_paid' => $order->getAmount(Order::AMOUNT_PAID), | ||||
'amount_remaining' => $order->getAmount(Order::AMOUNT_REMAINING), | 'amount_remaining' => $order->getAmount(Order::AMOUNT_REMAINING), | ||||
'amount_surplus' => $order->getAmount(Order::AMOUNT_SURPLUS), | 'amount_surplus' => $order->getAmount(Order::AMOUNT_SURPLUS), | ||||
'lines' => $lines, | 'lines' => $lines, | ||||
'payments' => [[ | 'payments' => [[ | ||||
'type' => $typePaymentTiller, | 'type' => $typePaymentTiller, | ||||
'amount' => $order->getAmount(Order::AMOUNT_TOTAL) * 100, | |||||
'amount' => $order->getAmountWithTax(Order::AMOUNT_TOTAL) * 100, | |||||
'status' => 'ACCEPTED', | 'status' => 'ACCEPTED', | ||||
'date' => $strDate | 'date' => $strDate | ||||
]] | ]] |
<?php | <?php | ||||
/** | /** | ||||
Copyright distrib (2018) | |||||
contact@opendistrib.net | |||||
Ce logiciel est un programme informatique servant à aider les producteurs | |||||
à distribuer leur production en circuits courts. | |||||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
sur le site "http://www.cecill.info". | |||||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
de modification et de redistribution accordés par cette licence, il n'est | |||||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
titulaire des droits patrimoniaux et les concédants successifs. | |||||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
associés au chargement, à l'utilisation, à la modification et/ou au | |||||
développement et à la reproduction du logiciel par l'utilisateur étant | |||||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
avertis possédant des connaissances informatiques approfondies. Les | |||||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
termes. | |||||
* Copyright distrib (2018) | |||||
* | |||||
* contact@opendistrib.net | |||||
* | |||||
* Ce logiciel est un programme informatique servant à aider les producteurs | |||||
* à distribuer leur production en circuits courts. | |||||
* | |||||
* Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
* respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
* utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
* sur le site "http://www.cecill.info". | |||||
* | |||||
* En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
* de modification et de redistribution accordés par cette licence, il n'est | |||||
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
* seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
* titulaire des droits patrimoniaux et les concédants successifs. | |||||
* | |||||
* A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
* associés au chargement, à l'utilisation, à la modification et/ou au | |||||
* développement et à la reproduction du logiciel par l'utilisateur étant | |||||
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
* manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
* avertis possédant des connaissances informatiques approfondies. Les | |||||
* utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
* logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
* sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
* | |||||
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
* pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
* termes. | |||||
*/ | */ | ||||
namespace backend\controllers; | namespace backend\controllers; | ||||
use common\models\Product; | use common\models\Product; | ||||
use common\models\User ; | |||||
use common\models\Document ; | |||||
use common\helpers\GlobalParam ; | |||||
use common\models\Order ; | |||||
use common\models\User; | |||||
use common\models\Document; | |||||
use common\helpers\GlobalParam; | |||||
use common\models\Order; | |||||
use yii\base\UserException; | use yii\base\UserException; | ||||
class DocumentController extends BackendController | class DocumentController extends BackendController | ||||
{ | { | ||||
public function behaviors() | |||||
public function behaviors() | |||||
{ | { | ||||
return [ | |||||
'verbs' => [ | |||||
'class' => VerbFilter::className(), | |||||
'actions' => [ | |||||
], | |||||
], | |||||
'access' => [ | |||||
'class' => AccessControl::className(), | |||||
'rules' => [ | |||||
[ | |||||
'allow' => true, | |||||
'roles' => ['@'], | |||||
'matchCallback' => function ($rule, $action) { | |||||
return User::hasAccessBackend(); | |||||
} | |||||
] | |||||
], | |||||
], | |||||
]; | |||||
return [ | |||||
'verbs' => [ | |||||
'class' => VerbFilter::className(), | |||||
'actions' => [ | |||||
], | |||||
], | |||||
'access' => [ | |||||
'class' => AccessControl::className(), | |||||
'rules' => [ | |||||
[ | |||||
'allow' => true, | |||||
'roles' => ['@'], | |||||
'matchCallback' => function ($rule, $action) { | |||||
return User::hasAccessBackend(); | |||||
} | |||||
] | |||||
], | |||||
], | |||||
]; | |||||
} | } | ||||
public function actionCreate() | public function actionCreate() | ||||
$model = new $class(); | $model = new $class(); | ||||
if ($model->load(Yii::$app->request->post())) { | if ($model->load(Yii::$app->request->post())) { | ||||
$model->id_producer = GlobalParam::getCurrentProducerId() ; | |||||
if($model->save()) { | |||||
$model->id_producer = GlobalParam::getCurrentProducerId(); | |||||
if ($model->save()) { | |||||
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('create', $model)); | Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('create', $model)); | ||||
return $this->redirect(['/'.$model->getControllerUrlPath().'/update', 'id' => $model->id]); | |||||
} | |||||
else { | |||||
return $this->redirect(['/' . $model->getControllerUrlPath() . '/update', 'id' => $model->id]); | |||||
} else { | |||||
Yii::$app->getSession()->setFlash('error', 'Un problème est survenu lors de la création du document.'); | Yii::$app->getSession()->setFlash('error', 'Un problème est survenu lors de la création du document.'); | ||||
} | } | ||||
} | } | ||||
return $this->render('/document/create', [ | return $this->render('/document/create', [ | ||||
'title' => $this->getTitle('Ajouter'), | 'title' => $this->getTitle('Ajouter'), | ||||
'typeDocument' => $this->getDocumentType(), | 'typeDocument' => $this->getDocumentType(), | ||||
/** | /** | ||||
* Modifie un modèle Produit existant. | * Modifie un modèle Produit existant. | ||||
* Si la modification réussit, le navigateur est redirigé vers la page 'index'. | * Si la modification réussit, le navigateur est redirigé vers la page 'index'. | ||||
* | |||||
* | |||||
* @param integer $id | * @param integer $id | ||||
* @return mixed | * @return mixed | ||||
*/ | */ | ||||
public function actionUpdate($id) | public function actionUpdate($id) | ||||
{ | { | ||||
$model = $this->findModel($id) ; | |||||
$model = $this->findModel($id); | |||||
$class = $this->getClass(); | $class = $this->getClass(); | ||||
$model = $class::searchOne([ | $model = $class::searchOne([ | ||||
'id' => $id | |||||
]) ; | |||||
'id' => $id | |||||
]); | |||||
if($model->isStatusValid()) { | |||||
if ($model->isStatusValid()) { | |||||
throw new UserException('Vous ne pouvez pas modifier un document validé.'); | throw new UserException('Vous ne pouvez pas modifier un document validé.'); | ||||
} | } | ||||
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('update', $model)); | Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('update', $model)); | ||||
} | } | ||||
return $this->render('/document/update', [ | return $this->render('/document/update', [ | ||||
'title' => $this->getTitle('Modifier'), | 'title' => $this->getTitle('Modifier'), | ||||
'typeDocument' => $this->getDocumentType(), | 'typeDocument' => $this->getDocumentType(), | ||||
]); | ]); | ||||
} | } | ||||
public function actionAjaxAddressUser($idUser) | |||||
public function actionAjaxAddressUser($idUser) | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
if($idUser > 0) { | |||||
if ($idUser > 0) { | |||||
$user = User::findOne($idUser); | $user = User::findOne($idUser); | ||||
if($user) { | |||||
$address = $user['lastname'].' '.$user['name']."\n" ; | |||||
$address .= $user['address'] ; | |||||
if ($user) { | |||||
$address = $user['lastname'] . ' ' . $user['name'] . "\n"; | |||||
$address .= $user['address']; | |||||
return [ | return [ | ||||
'return' => 'success', | |||||
'address' => $address | |||||
] ; | |||||
'return' => 'success', | |||||
'address' => $address | |||||
]; | |||||
} | } | ||||
} | } | ||||
return ['return' => 'error'] ; | |||||
return ['return' => 'error']; | |||||
} | } | ||||
public function actionAjaxValidateDocument($idDocument, $classDocument) | public function actionAjaxValidateDocument($idDocument, $classDocument) | ||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
if($idDocument > 0 && Document::isValidClass($classDocument)) { | |||||
if ($idDocument > 0 && Document::isValidClass($classDocument)) { | |||||
$document = $classDocument::searchOne([ | $document = $classDocument::searchOne([ | ||||
'id' => $idDocument | 'id' => $idDocument | ||||
]) ; | |||||
]); | |||||
if($document) { | |||||
$document->changeStatus(Document::STATUS_VALID) ; | |||||
$document->save() ; | |||||
return ['return' => 'success'] ; | |||||
if ($document) { | |||||
$document->changeStatus(Document::STATUS_VALID); | |||||
$document->save(); | |||||
return ['return' => 'success']; | |||||
} | } | ||||
} | } | ||||
return ['return' => 'error'] ; | |||||
return ['return' => 'error']; | |||||
} | } | ||||
public function actionAjaxInit($idDocument, $classDocument) | |||||
public function actionAjaxInit($idDocument, $classDocument) | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
if($idDocument > 0 && Document::isValidClass($classDocument)) { | |||||
if ($idDocument > 0 && Document::isValidClass($classDocument)) { | |||||
$document = $classDocument::searchOne([ | $document = $classDocument::searchOne([ | ||||
'id' => $idDocument | |||||
]) ; | |||||
if($document) { | |||||
$productsArray = Product::searchAll() ; | |||||
$ordersArray = [] ; | |||||
foreach($document->orders as $order) { | |||||
$order->init() ; | |||||
$productsOrderArray = [] ; | |||||
foreach($order->productOrder as $productOrder) { | |||||
$productsOrderArray[$productOrder->id] = $productOrder->getAttributes() ; | |||||
'id' => $idDocument | |||||
]); | |||||
if ($document) { | |||||
$productsArray = Product::searchAll(); | |||||
$ordersArray = []; | |||||
foreach ($document->orders as $order) { | |||||
$order->init(); | |||||
$productsOrderArray = []; | |||||
foreach ($order->productOrder as $productOrder) { | |||||
$productsOrderArray[$productOrder->id] = $productOrder->getAttributes(); | |||||
} | } | ||||
$ordersArray[$order->id] = array_merge( | $ordersArray[$order->id] = array_merge( | ||||
$order->getAttributes(), | $order->getAttributes(), | ||||
[ | [ | ||||
'productOrder' => $productsOrderArray, | |||||
'productOrder' => $productsOrderArray, | |||||
] | ] | ||||
); | ); | ||||
} | } | ||||
return [ | return [ | ||||
'return' => 'success', | |||||
'document' => array_merge($document->getAttributes(), [ | |||||
'html_label' => $document->getHtmlLabel(), | |||||
'class' => $document->getClass() | |||||
]), | |||||
'idUser' => $document->user->id, | |||||
'products' => ArrayHelper::map($productsArray, 'id', function($product) { | |||||
return array_merge($product->getAttributes(),[ | |||||
'price_with_tax' => $product->price_with_tax, | |||||
'wording_unit' => $product->wording_unit, | |||||
]) ; | |||||
}), | |||||
'orders' => $ordersArray, | |||||
'total' => $document->getAmount(Order::AMOUNT_TOTAL) | |||||
] ; | |||||
'return' => 'success', | |||||
'document' => array_merge($document->getAttributes(), [ | |||||
'html_label' => $document->getHtmlLabel(), | |||||
'class' => $document->getClass() | |||||
]), | |||||
'idUser' => $document->user->id, | |||||
'products' => ArrayHelper::map($productsArray, 'id', function ($product) { | |||||
return array_merge($product->getAttributes(), [ | |||||
'price_with_tax' => $product->price_with_tax, | |||||
'wording_unit' => $product->wording_unit, | |||||
'tax_rate' => $product->taxRate->value | |||||
]); | |||||
}), | |||||
'orders' => $ordersArray, | |||||
'total' => $document->getAmount(Order::AMOUNT_TOTAL), | |||||
'total_with_tax' => $document->getAmountWithTax(Order::AMOUNT_TOTAL), | |||||
]; | |||||
} | } | ||||
} | } | ||||
return ['return' => 'error'] ; | |||||
return ['return' => 'error']; | |||||
} | } | ||||
public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price) | |||||
public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price) | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
if(Document::isValidClass($classDocument)) { | |||||
if (Document::isValidClass($classDocument)) { | |||||
$document = $classDocument::searchOne([ | $document = $classDocument::searchOne([ | ||||
'id' => $idDocument | |||||
]) ; | |||||
'id' => $idDocument | |||||
]); | |||||
$product = Product::searchOne([ | $product = Product::searchOne([ | ||||
'id' => $idProduct | |||||
]) ; | |||||
if($document && $product) { | |||||
if(count($document->orders) == 0) { | |||||
$order = new Order ; | |||||
$order->id_user = $document->id_user ; | |||||
$order->id_point_sale = null ; | |||||
$order->id_distribution = null ; | |||||
$order->origin = Order::ORIGIN_ADMIN ; | |||||
'id' => $idProduct | |||||
]); | |||||
if ($document && $product) { | |||||
if (count($document->orders) == 0) { | |||||
$order = new Order; | |||||
$order->id_user = $document->id_user; | |||||
$order->id_point_sale = null; | |||||
$order->id_distribution = null; | |||||
$order->origin = Order::ORIGIN_ADMIN; | |||||
$order->date = date('Y-m-d H:i:s'); | $order->date = date('Y-m-d H:i:s'); | ||||
$fieldIdDocument = 'id_'.$classDocument::tableName() ; | |||||
$order->$fieldIdDocument = $document->id ; | |||||
$order->save() ; | |||||
} | |||||
else { | |||||
$order = $document->orders[0] ; | |||||
$fieldIdDocument = 'id_' . $classDocument::tableName(); | |||||
$order->$fieldIdDocument = $document->id; | |||||
$order->save(); | |||||
} else { | |||||
$order = $document->orders[0]; | |||||
} | } | ||||
if($order) { | |||||
$productOrder = new ProductOrder ; | |||||
$productOrder->id_order = $order->id ; | |||||
$productOrder->id_product = $idProduct ; | |||||
if ($order) { | |||||
$productOrder = new ProductOrder; | |||||
$productOrder->id_order = $order->id; | |||||
$productOrder->id_product = $idProduct; | |||||
$quantity = $quantity / Product::$unitsArray[$product->unit]['coefficient']; | $quantity = $quantity / Product::$unitsArray[$product->unit]['coefficient']; | ||||
$productOrder->quantity = $quantity ; | |||||
$productOrder->price = (float) $price ; | |||||
$productOrder->unit = $product->unit ; | |||||
$productOrder->step = $product->step ; | |||||
$productOrder->quantity = $quantity; | |||||
$productOrder->price = (float)$price; | |||||
$productOrder->unit = $product->unit; | |||||
$productOrder->step = $product->step; | |||||
$productOrder->id_tax_rate = $productOrder->id_tax_rate ? | $productOrder->id_tax_rate = $productOrder->id_tax_rate ? | ||||
$product->taxRate->id : GlobalParam::getCurrentProducer()->taxRate->id ; | |||||
$productOrder->save() ; | |||||
$product->taxRate->id : GlobalParam::getCurrentProducer()->taxRate->id; | |||||
$productOrder->save(); | |||||
return [ | return [ | ||||
'return' => 'success', | 'return' => 'success', | ||||
] ; | |||||
} | |||||
]; | |||||
} | |||||
} | } | ||||
} | } | ||||
return [ | return [ | ||||
'return' => 'error' | 'return' => 'error' | ||||
] ; | |||||
]; | |||||
} | } | ||||
public function actionAjaxDeleteProductOrder($idProductOrder) | public function actionAjaxDeleteProductOrder($idProductOrder) | ||||
$productOrder = ProductOrder::searchOne([ | $productOrder = ProductOrder::searchOne([ | ||||
'id' => $idProductOrder | 'id' => $idProductOrder | ||||
]) ; | |||||
]); | |||||
if($productOrder) { | |||||
$productOrder->delete() ; | |||||
if ($productOrder) { | |||||
$productOrder->delete(); | |||||
return [ | return [ | ||||
'return' => 'success' | 'return' => 'success' | ||||
] ; | |||||
]; | |||||
} | } | ||||
return [ | return [ | ||||
'return' => 'error' | 'return' => 'error' | ||||
] ; | |||||
]; | |||||
} | } | ||||
protected function getClass() | protected function getClass() | ||||
{ | { | ||||
$class = get_class($this); | $class = get_class($this); | ||||
$class = str_replace('Controller', '', $class) ; | |||||
$class = str_replace('backend\controllers\\', '', $class) ; | |||||
return $class ; | |||||
$class = str_replace('Controller', '', $class); | |||||
$class = str_replace('backend\controllers\\', '', $class); | |||||
return $class; | |||||
} | } | ||||
protected function getDocumentType() | |||||
protected function getDocumentType() | |||||
{ | { | ||||
$class = $this->getClass(); | |||||
if($class == 'Invoice') { | |||||
$documentType = 'Facture' ; | |||||
} | |||||
elseif($class == 'DeliveryNote') { | |||||
$documentType = 'Bon de livraison' ; | |||||
} | |||||
elseif($class == 'Quotation') { | |||||
$documentType = 'Devis' ; | |||||
$class = $this->getClass(); | |||||
if ($class == 'Invoice') { | |||||
$documentType = 'Facture'; | |||||
} elseif ($class == 'DeliveryNote') { | |||||
$documentType = 'Bon de livraison'; | |||||
} elseif ($class == 'Quotation') { | |||||
$documentType = 'Devis'; | |||||
} | } | ||||
if(isset($documentType)) { | |||||
return $documentType ; | |||||
if (isset($documentType)) { | |||||
return $documentType; | |||||
} | } | ||||
return '' ; | |||||
return ''; | |||||
} | } | ||||
public function getFlashMessage($type = 'create', $model) | |||||
public function getFlashMessage($type = 'create', $model) | |||||
{ | { | ||||
$class = $this->getClass(); | $class = $this->getClass(); | ||||
$message = $this->getDocumentType() ; | |||||
$message .= ' <strong>'.Html::encode($model->name).'</strong> ' ; | |||||
if($type == 'create') { | |||||
$message .= 'ajouté' ; | |||||
} | |||||
elseif($type == 'update') { | |||||
$message .= 'modifié' ; | |||||
$message = $this->getDocumentType(); | |||||
$message .= ' <strong>' . Html::encode($model->name) . '</strong> '; | |||||
if ($type == 'create') { | |||||
$message .= 'ajouté'; | |||||
} elseif ($type == 'update') { | |||||
$message .= 'modifié'; | |||||
} | } | ||||
if($class == 'Invoice') { | |||||
$message .= 'e' ; | |||||
if ($class == 'Invoice') { | |||||
$message .= 'e'; | |||||
} | } | ||||
return $message ; | |||||
return $message; | |||||
} | } | ||||
protected function getTitle($prepend) | protected function getTitle($prepend) | ||||
{ | { | ||||
$class = $this->getClass(); | $class = $this->getClass(); | ||||
switch ($class) { | switch ($class) { | ||||
case 'Invoice' : | case 'Invoice' : | ||||
$title = $prepend . ' une facture'; | $title = $prepend . ' une facture'; | ||||
/** | /** | ||||
* Recherche un Document en fonction de son ID. | * Recherche un Document en fonction de son ID. | ||||
* | |||||
* | |||||
* @param integer $id | * @param integer $id | ||||
* @return Produit | |||||
* @return Produit | |||||
* @throws NotFoundHttpException si le modèle n'est pas trouvé | * @throws NotFoundHttpException si le modèle n'est pas trouvé | ||||
*/ | */ | ||||
protected function findModel($id) | protected function findModel($id) | ||||
{ | { | ||||
$class = $this->getClass() ; | |||||
$class = $this->getClass(); | |||||
if (($model = $class::findOne($id)) !== null) { | if (($model = $class::findOne($id)) !== null) { | ||||
return $model; | return $model; | ||||
} else { | } else { |
if (abs($order->amount - $amountPaid) < 0.0001) { | if (abs($order->amount - $amountPaid) < 0.0001) { | ||||
$html .= '<span class="label label-success">Payé</span>'; | $html .= '<span class="label label-success">Payé</span>'; | ||||
$buttonsCredit = Html::a('Rembourser ' . $order->getAmount(Order::AMOUNT_TOTAL, true), 'javascript:void(0);', ['class' => 'btn btn-default btn-xs rembourser', 'data-montant' => $order->amount, 'data-type' => 'refund']); | |||||
$buttonsCredit = Html::a('Rembourser ' . $order->getAmountWithTax(Order::AMOUNT_TOTAL, true), 'javascript:void(0);', ['class' => 'btn btn-default btn-xs rembourser', 'data-montant' => $order->amount, 'data-type' => 'refund']); | |||||
} elseif ($order->amount > $amountPaid) { | } elseif ($order->amount > $amountPaid) { | ||||
$amountToPay = $order->amount - $amountPaid; | $amountToPay = $order->amount - $amountPaid; | ||||
$html .= '<span class="label label-danger">Non payé</span> reste <strong>' . number_format($amountToPay, 2) . ' €</strong> à payer'; | $html .= '<span class="label label-danger">Non payé</span> reste <strong>' . number_format($amountToPay, 2) . ' €</strong> à payer'; | ||||
. '<td>' . date('d/m/Y H:i:s', strtotime($h->date)) . '</td>' | . '<td>' . date('d/m/Y H:i:s', strtotime($h->date)) . '</td>' | ||||
. '<td>' . Html::encode($h->strUserAction()) . '</td>' | . '<td>' . Html::encode($h->strUserAction()) . '</td>' | ||||
. '<td>' . $h->getStrWording() . '</td>' | . '<td>' . $h->getStrWording() . '</td>' | ||||
. '<td>' . ($h->isTypeDebit() ? '- ' . $h->getAmount(Order::AMOUNT_TOTAL, true) : '') . '</td>' | |||||
. '<td>' . ($h->isTypeCredit() ? '+ ' . $h->getAmount(Order::AMOUNT_TOTAL, true) : '') . '</td>' | |||||
. '<td>' . ($h->isTypeDebit() ? '- ' . $h->getAmountWithTax(Order::AMOUNT_TOTAL, true) : '') . '</td>' | |||||
. '<td>' . ($h->isTypeCredit() ? '+ ' . $h->getAmountWithTax(Order::AMOUNT_TOTAL, true) : '') . '</td>' | |||||
. '</tr>'; | . '</tr>'; | ||||
} | } | ||||
} else { | } else { |
'attribute' => 'amount', | 'attribute' => 'amount', | ||||
'header' => 'Montant', | 'header' => 'Montant', | ||||
'value' => function($invoice) { | 'value' => function($invoice) { | ||||
return $invoice->getAmount(Order::AMOUNT_TOTAL, true) ; | |||||
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; | |||||
} | } | ||||
], | ], | ||||
[ | [ |
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span> | <span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span> | ||||
<div class="info-box-content"> | <div class="info-box-content"> | ||||
<span class="info-box-text">Total (TTC)</span> | <span class="info-box-text">Total (TTC)</span> | ||||
<span class="info-box-number">{{ formatPrice(total) }}</span> | |||||
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div id="" class="info-box"> | <div id="" class="info-box"> | ||||
<th>Nom</th> | <th>Nom</th> | ||||
<th>Prix (unité)</th> | <th>Prix (unité)</th> | ||||
<th>Quantité</th> | <th>Quantité</th> | ||||
<th>Total</th> | |||||
<th>TVA</th> | |||||
<th>Total TTC</th> | |||||
<th>Supprimer</th> | <th>Supprimer</th> | ||||
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<template v-for="order in ordersArray"> | <template v-for="order in ordersArray"> | ||||
<tr v-for="productOrder in order.productOrder"> | <tr v-for="productOrder in order.productOrder"> | ||||
<td class="col-md-4">{{ | |||||
productsArray[productOrder.id_product].name | |||||
}} | |||||
<td class="col-md-4"> | |||||
{{ productsArray[productOrder.id_product].name }} | |||||
</td> | </td> | ||||
<td class="col-md-2">{{ formatPrice(productOrder.price) }}</td> | <td class="col-md-2">{{ formatPrice(productOrder.price) }}</td> | ||||
<td class="col-md-2">{{ productOrder.quantity }}</td> | <td class="col-md-2">{{ productOrder.quantity }}</td> | ||||
<td class="col-md-2">{{ formatPrice(productOrder.quantity * | |||||
productOrder.price) }} | |||||
<td class="col-md-1"> | |||||
{{ productsArray[productOrder.id_product].tax_rate * 100 }} % | |||||
</td> | </td> | ||||
<td class="col-md-2"> | <td class="col-md-2"> | ||||
{{ formatPrice(productOrder.quantity * productOrder.price) }} | |||||
</td> | |||||
<td class="col-md-1"> | |||||
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)"> | <a class="btn btn-default" @click="deleteProductOrder(productOrder.id)"> | ||||
<span class="glyphicon glyphicon-trash"></span> | <span class="glyphicon glyphicon-trash"></span> | ||||
</a> | </a> | ||||
</tr> | </tr> | ||||
</template> | </template> | ||||
<tr> | <tr> | ||||
<td colspan="3"><strong>Total</strong></td> | |||||
<td><strong>{{ formatPrice(total) }}</strong></td> | |||||
<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> | <td></td> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> |
'attribute' => 'amount', | 'attribute' => 'amount', | ||||
'header' => 'Montant', | 'header' => 'Montant', | ||||
'value' => function($invoice) { | 'value' => function($invoice) { | ||||
return $invoice->getAmount(Order::AMOUNT_TOTAL, true) ; | |||||
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; | |||||
} | } | ||||
], | ], | ||||
[ | [ |
'attribute' => 'amount', | 'attribute' => 'amount', | ||||
'header' => 'Montant', | 'header' => 'Montant', | ||||
'value' => function($invoice) { | 'value' => function($invoice) { | ||||
return $invoice->getAmount(Order::AMOUNT_TOTAL, true) ; | |||||
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; | |||||
} | } | ||||
], | ], | ||||
[ | [ |
</td> | </td> | ||||
<td><?= $order->getCartSummary() ; ?></td> | <td><?= $order->getCartSummary() ; ?></td> | ||||
<td><?= $order->getPointSaleSummary() ; ?></td> | <td><?= $order->getPointSaleSummary() ; ?></td> | ||||
<td><?= $order->getAmount(Order::AMOUNT_TOTAL, true) ; ?></td> | |||||
<td><?= $order->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; ?></td> | |||||
<td class="history"><?= $order->getStrHistory() ; ?></td> | <td class="history"><?= $order->getStrHistory() ; ?></td> | ||||
</tr> | </tr> | ||||
<?php endforeach; ?> | <?php endforeach; ?> |
productAddPrice: '', | productAddPrice: '', | ||||
productAddQuantity: 1, | productAddQuantity: 1, | ||||
ordersArray: [], | ordersArray: [], | ||||
total: 0 | |||||
total: 0, | |||||
total_with_tax: 0 | |||||
}, | }, | ||||
mounted: function() { | mounted: function() { | ||||
this.init() ; | this.init() ; | ||||
app.productsArray = response.data.products ; | app.productsArray = response.data.products ; | ||||
app.ordersArray = response.data.orders ; | app.ordersArray = response.data.orders ; | ||||
app.total = response.data.total ; | app.total = response.data.total ; | ||||
app.total_with_tax = response.data.total_with_tax ; | |||||
} | } | ||||
}) ; | }) ; | ||||
} | } |
$ordersOpendistribSynchro[$orderOpendistrib->id] = false ; | $ordersOpendistribSynchro[$orderOpendistrib->id] = false ; | ||||
foreach($ordersTiller->orders as $orderTiller) { | foreach($ordersTiller->orders as $orderTiller) { | ||||
if($orderOpendistrib->id == $orderTiller->externalId | if($orderOpendistrib->id == $orderTiller->externalId | ||||
&& ($orderOpendistrib->getAmount(Order::AMOUNT_TOTAL) * 100) == $orderTiller->currentBill) { | |||||
&& ($orderOpendistrib->getAmountWithTax(Order::AMOUNT_TOTAL) * 100) == $orderTiller->currentBill) { | |||||
$ordersOpendistribSynchro[$orderOpendistrib->id] = true ; | $ordersOpendistribSynchro[$orderOpendistrib->id] = true ; | ||||
} | } |
} | } | ||||
$str .= $this->getStrWording() ; | $str .= $this->getStrWording() ; | ||||
if(isset($this->order)) { | if(isset($this->order)) { | ||||
$str .= '<br />Montant de la commande : '.$this->order->getAmount(Order::AMOUNT_TOTAL, true) ; | |||||
$str .= '<br />Montant de la commande : '.$this->order->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; | |||||
} | } | ||||
if(isset($this->user)) { | if(isset($this->user)) { | ||||
$str .= '<br />Client : '.Html::encode($this->user->name. ' '.$this->user->lastname) ; | $str .= '<br />Client : '.Html::encode($this->user->name. ' '.$this->user->lastname) ; |
/* | /* | ||||
* Méthodes | * Méthodes | ||||
*/ | */ | ||||
public function getAmount($type = Order::AMOUNT_TOTAL, $format = false) | public function getAmount($type = Order::AMOUNT_TOTAL, $format = false) | ||||
{ | |||||
return $this->_getAmountGeneric($type, false, $format) ; | |||||
} | |||||
public function getAmountWithTax($type = Order::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($type, true, $format) ; | |||||
} | |||||
protected function _getAmountGeneric($type = Order::AMOUNT_TOTAL, $withTax = true, $format = false) | |||||
{ | { | ||||
$amount = 0; | $amount = 0; | ||||
$ordersArray = $this->orders; | $ordersArray = $this->orders; | ||||
foreach ($ordersArray as $order) { | foreach ($ordersArray as $order) { | ||||
$order->init(); | $order->init(); | ||||
$amount += $order->getAmount($type); | |||||
if($withTax) { | |||||
$amount += $order->getAmountWithTax($type); | |||||
} | |||||
else { | |||||
$amount += $order->getAmount($type); | |||||
} | |||||
} | } | ||||
if ($format) { | if ($format) { |
class Order extends ActiveRecordCommon | class Order extends ActiveRecordCommon | ||||
{ | { | ||||
var $amount = 0; | var $amount = 0; | ||||
var $amount_with_tax = 0; | |||||
var $paid_amount = 0; | var $paid_amount = 0; | ||||
var $weight = 0; | var $weight = 0; | ||||
[['id_user', 'date', 'id_point_sale', 'id_distribution', 'status'], 'required', 'message' => ''], | [['id_user', 'date', 'id_point_sale', 'id_distribution', 'status'], 'required', 'message' => ''], | ||||
[['id_user', 'id_point_sale', 'id_distribution', 'id_subscription', 'id_invoice', 'id_quotation', 'id_delivery_note'], 'integer'], | [['id_user', 'id_point_sale', 'id_distribution', 'id_subscription', 'id_invoice', 'id_quotation', 'id_delivery_note'], 'integer'], | ||||
[['auto_payment', 'tiller_synchronization'], 'boolean'], | [['auto_payment', 'tiller_synchronization'], 'boolean'], | ||||
[['status'], 'string'], | |||||
[['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment'], 'safe'] | [['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment'], 'safe'] | ||||
]; | ]; | ||||
} | } | ||||
public function initAmount() | public function initAmount() | ||||
{ | { | ||||
$this->amount = 0; | $this->amount = 0; | ||||
$this->amount_with_tax = 0; | |||||
$this->weight = 0; | $this->weight = 0; | ||||
if (isset($this->productOrder)) { | if (isset($this->productOrder)) { | ||||
foreach ($this->productOrder as $productOrder) { | foreach ($this->productOrder as $productOrder) { | ||||
$this->amount += Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) * $productOrder->quantity; | |||||
$this->amount += $productOrder->price * $productOrder->quantity; | |||||
$this->amount_with_tax += Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) * $productOrder->quantity; | |||||
if ($productOrder->unit == 'piece') { | if ($productOrder->unit == 'piece') { | ||||
if (isset($productOrder->product)) { | if (isset($productOrder->product)) { | ||||
$this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000; | $this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000; | ||||
* @param boolean $format | * @param boolean $format | ||||
* @return float | * @return float | ||||
*/ | */ | ||||
public function getAmount($type = self::AMOUNT_TOTAL, $format = false) | public function getAmount($type = self::AMOUNT_TOTAL, $format = false) | ||||
{ | |||||
return $this->_getAmountGeneric($type, $this->amount, $format) ; | |||||
} | |||||
public function getAmountWithTax($type = self::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($type, $this->amount_with_tax, $format) ; | |||||
} | |||||
protected function _getAmountGeneric($type, $amountOrder, $format) | |||||
{ | { | ||||
switch ($type) { | switch ($type) { | ||||
case self::AMOUNT_TOTAL : | case self::AMOUNT_TOTAL : | ||||
$amount = $this->amount; | |||||
$amount = $amountOrder; | |||||
break; | break; | ||||
case self::AMOUNT_PAID : | case self::AMOUNT_PAID : | ||||
$this->initPaidAmount(); | $this->initPaidAmount(); | ||||
$amount = $this->paid_amount; | $amount = $this->paid_amount; | ||||
break; | break; | ||||
case self::AMOUNT_REMAINING : | case self::AMOUNT_REMAINING : | ||||
$amount = $this->getAmount(self::AMOUNT_TOTAL) | |||||
- $this->getAmount(self::AMOUNT_PAID); | |||||
$amount = $this->getAmountWithTax(self::AMOUNT_TOTAL) | |||||
- $this->getAmountWithTax(self::AMOUNT_PAID); | |||||
break; | break; | ||||
case self::AMOUNT_SURPLUS : | case self::AMOUNT_SURPLUS : | ||||
$amount = $this->getAmount(self::AMOUNT_PAID) | |||||
- $this->getAmount(self::AMOUNT_TOTAL); | |||||
$amount = $this->getAmountWithTax(self::AMOUNT_PAID) | |||||
- $this->getAmountWithTax(self::AMOUNT_TOTAL); | |||||
break; | break; | ||||
default: | |||||
throw new NotFoundHttpException('Type de montant inconnu.') ; | |||||
} | } | ||||
if ($format) { | if ($format) { | ||||
return number_format($amount, 2) . ' €'; | |||||
return Price::format($amount) ; | |||||
} else { | } else { | ||||
return $amount; | return $amount; | ||||
} | } | ||||
$jsonOrder = [ | $jsonOrder = [ | ||||
'products' => [], | 'products' => [], | ||||
'amount' => $order->amount, | 'amount' => $order->amount, | ||||
'str_amount' => $order->getAmount(self::AMOUNT_TOTAL, true), | |||||
'str_amount' => $order->getAmountWithTax(self::AMOUNT_TOTAL, true), | |||||
'paid_amount' => $order->getAmount(self::AMOUNT_PAID), | 'paid_amount' => $order->getAmount(self::AMOUNT_PAID), | ||||
'comment' => $order->comment, | 'comment' => $order->comment, | ||||
]; | ]; | ||||
public function getPaymentStatus() | public function getPaymentStatus() | ||||
{ | { | ||||
// payé | // payé | ||||
if ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) < 0.01 && | |||||
$this->getAmount() - $this->getAmount(self::AMOUNT_PAID) > -0.01) { | |||||
if ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) < 0.01 && | |||||
$this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) > -0.01) { | |||||
return self::PAYMENT_PAID; | return self::PAYMENT_PAID; | ||||
} // à rembourser | } // à rembourser | ||||
elseif ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) { | |||||
elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) { | |||||
return self::PAYMENT_SURPLUS; | return self::PAYMENT_SURPLUS; | ||||
} // reste à payer | } // reste à payer | ||||
elseif ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) >= 0.01) { | |||||
elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) >= 0.01) { | |||||
return self::PAYMENT_UNPAID; | return self::PAYMENT_UNPAID; | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
$html = ''; | $html = ''; | ||||
$html .= $this->getAmount(self::AMOUNT_TOTAL, true) . '<br />'; | |||||
$html .= $this->getAmountWithTax(self::AMOUNT_TOTAL, true) . '<br />'; | |||||
if ($this->paid_amount) { | if ($this->paid_amount) { | ||||
if ($this->getPaymentStatus() == Order::PAYMENT_PAID) { | if ($this->getPaymentStatus() == Order::PAYMENT_PAID) { |
if (is_array($ordersUserArray) && count($ordersUserArray)) { | if (is_array($ordersUserArray) && count($ordersUserArray)) { | ||||
foreach ($ordersUserArray as &$order) { | foreach ($ordersUserArray as &$order) { | ||||
$order = array_merge($order->getAttributes(), [ | $order = array_merge($order->getAttributes(), [ | ||||
'amount_total' => $order->getAmount(Order::AMOUNT_TOTAL), | |||||
'amount_total' => $order->getAmountWithTax(Order::AMOUNT_TOTAL), | |||||
'date_distribution' => $order->distribution->date, | 'date_distribution' => $order->distribution->date, | ||||
'pointSale' => $order->pointSale->getAttributes() | 'pointSale' => $order->pointSale->getAttributes() | ||||
]); | ]); | ||||
if ($orderUser) { | if ($orderUser) { | ||||
$json['order'] = array_merge($orderUser->getAttributes(), [ | $json['order'] = array_merge($orderUser->getAttributes(), [ | ||||
'amount_total' => $orderUser->getAmount(Order::AMOUNT_TOTAL), | |||||
'amount_total' => $orderUser->getAmountWithTax(Order::AMOUNT_TOTAL), | |||||
'amount_paid' => $orderUser->getAmount(Order::AMOUNT_PAID), | 'amount_paid' => $orderUser->getAmount(Order::AMOUNT_PAID), | ||||
]); | ]); | ||||
} | } |
<li><span class="glyphicon glyphicon-time"></span><?= date('d/m/Y',strtotime($order->distribution->date)) ?></li> | <li><span class="glyphicon glyphicon-time"></span><?= date('d/m/Y',strtotime($order->distribution->date)) ?></li> | ||||
<li><span class="glyphicon glyphicon-map-marker"></span><?= Html::encode($order->pointSale->name) ?><?php if(strlen($order->pointSale->name)): ?> <span class="locality">à <?= Html::encode($order->pointSale->locality) ?></span><?php endif; ?></li> | <li><span class="glyphicon glyphicon-map-marker"></span><?= Html::encode($order->pointSale->name) ?><?php if(strlen($order->pointSale->name)): ?> <span class="locality">à <?= Html::encode($order->pointSale->locality) ?></span><?php endif; ?></li> | ||||
<li><span class="glyphicon glyphicon-th-list"></span><?= $order->countProducts(); ?> produit<?php if($order->countProducts() > 1): ?>s<?php endif; ?></li> | <li><span class="glyphicon glyphicon-th-list"></span><?= $order->countProducts(); ?> produit<?php if($order->countProducts() > 1): ?>s<?php endif; ?></li> | ||||
<li><span class="glyphicon glyphicon-chevron-right"></span><?= $order->getAmount(Order::AMOUNT_TOTAL, true); ?></li> | |||||
<li><span class="glyphicon glyphicon-chevron-right"></span><?= $order->getAmountWithTax(Order::AMOUNT_TOTAL, true); ?></li> | |||||
</ul> | </ul> | ||||
</div> | </div> | ||||
<div class="clr"></div> | <div class="clr"></div> |