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

382 lines
15KB

  1. <?php
  2. /**
  3. * Copyright distrib (2018)
  4. *
  5. * contact@opendistrib.net
  6. *
  7. * Ce logiciel est un programme informatique servant à aider les producteurs
  8. * à distribuer leur production en circuits courts.
  9. *
  10. * Ce logiciel est régi par la licence CeCILL soumise au droit français et
  11. * respectant les principes de diffusion des logiciels libres. Vous pouvez
  12. * utiliser, modifier et/ou redistribuer ce programme sous les conditions
  13. * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  14. * sur le site "http://www.cecill.info".
  15. *
  16. * En contrepartie de l'accessibilité au code source et des droits de copie,
  17. * de modification et de redistribution accordés par cette licence, il n'est
  18. * offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  19. * seule une responsabilité restreinte pèse sur l'auteur du programme, le
  20. * titulaire des droits patrimoniaux et les concédants successifs.
  21. *
  22. * A cet égard l'attention de l'utilisateur est attirée sur les risques
  23. * associés au chargement, à l'utilisation, à la modification et/ou au
  24. * développement et à la reproduction du logiciel par l'utilisateur étant
  25. * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  26. * manipuler et qui le réserve donc à des développeurs et des professionnels
  27. * avertis possédant des connaissances informatiques approfondies. Les
  28. * utilisateurs sont donc invités à charger et tester l'adéquation du
  29. * logiciel à leurs besoins dans des conditions permettant d'assurer la
  30. * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  31. * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  32. *
  33. * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  34. * pris connaissance de la licence CeCILL, et que vous en avez accepté les
  35. * termes.
  36. */
  37. namespace backend\controllers;
  38. use common\models\Product;
  39. use common\models\User;
  40. use common\models\Document;
  41. use common\helpers\GlobalParam;
  42. use common\models\Order;
  43. use yii\base\UserException;
  44. class DocumentController extends BackendController
  45. {
  46. public function behaviors()
  47. {
  48. return [
  49. 'verbs' => [
  50. 'class' => VerbFilter::className(),
  51. 'actions' => [
  52. ],
  53. ],
  54. 'access' => [
  55. 'class' => AccessControl::className(),
  56. 'rules' => [
  57. [
  58. 'allow' => true,
  59. 'roles' => ['@'],
  60. 'matchCallback' => function ($rule, $action) {
  61. return User::hasAccessBackend();
  62. }
  63. ]
  64. ],
  65. ],
  66. ];
  67. }
  68. public function actionCreate()
  69. {
  70. $class = $this->getClass();
  71. $model = new $class();
  72. if ($model->load(Yii::$app->request->post())) {
  73. $model->id_producer = GlobalParam::getCurrentProducerId();
  74. if ($model->save()) {
  75. Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('create', $model));
  76. return $this->redirect(['/' . $model->getControllerUrlPath() . '/update', 'id' => $model->id]);
  77. } else {
  78. Yii::$app->getSession()->setFlash('error', 'Un problème est survenu lors de la création du document.');
  79. }
  80. }
  81. return $this->render('/document/create', [
  82. 'title' => $this->getTitle('Ajouter'),
  83. 'typeDocument' => $this->getDocumentType(),
  84. 'model' => $model,
  85. ]);
  86. }
  87. /**
  88. * Modifie un modèle Produit existant.
  89. * Si la modification réussit, le navigateur est redirigé vers la page 'index'.
  90. *
  91. * @param integer $id
  92. * @return mixed
  93. */
  94. public function actionUpdate($id)
  95. {
  96. $model = $this->findModel($id);
  97. $class = $this->getClass();
  98. $model = $class::searchOne([
  99. 'id' => $id
  100. ]);
  101. if ($model->isStatusValid()) {
  102. throw new UserException('Vous ne pouvez pas modifier un document validé.');
  103. }
  104. if ($model && $model->load(Yii::$app->request->post()) && $model->save()) {
  105. Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('update', $model));
  106. }
  107. return $this->render('/document/update', [
  108. 'title' => $this->getTitle('Modifier'),
  109. 'typeDocument' => $this->getDocumentType(),
  110. 'model' => $model,
  111. ]);
  112. }
  113. public function actionAjaxAddressUser($idUser)
  114. {
  115. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  116. if ($idUser > 0) {
  117. $user = User::findOne($idUser);
  118. if ($user) {
  119. $address = $user['lastname'] . ' ' . $user['name'] . "\n";
  120. $address .= $user['address'];
  121. return [
  122. 'return' => 'success',
  123. 'address' => $address
  124. ];
  125. }
  126. }
  127. return ['return' => 'error'];
  128. }
  129. public function actionAjaxValidateDocument($idDocument, $classDocument)
  130. {
  131. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  132. if ($idDocument > 0 && Document::isValidClass($classDocument)) {
  133. $document = $classDocument::searchOne([
  134. 'id' => $idDocument
  135. ]);
  136. if ($document) {
  137. $document->changeStatus(Document::STATUS_VALID);
  138. $document->save();
  139. return ['return' => 'success'];
  140. }
  141. }
  142. return ['return' => 'error'];
  143. }
  144. public function actionAjaxInit($idDocument, $classDocument)
  145. {
  146. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  147. if ($idDocument > 0 && Document::isValidClass($classDocument)) {
  148. $document = $classDocument::searchOne([
  149. 'id' => $idDocument
  150. ]);
  151. if ($document) {
  152. $productsArray = Product::searchAll();
  153. $ordersArray = [];
  154. foreach ($document->orders as $order) {
  155. $order->init();
  156. $productsOrderArray = [];
  157. foreach ($order->productOrder as $productOrder) {
  158. $productsOrderArray[$productOrder->id] = $productOrder->getAttributes();
  159. }
  160. $ordersArray[$order->id] = array_merge(
  161. $order->getAttributes(),
  162. [
  163. 'productOrder' => $productsOrderArray,
  164. ]
  165. );
  166. }
  167. return [
  168. 'return' => 'success',
  169. 'document' => array_merge($document->getAttributes(), [
  170. 'html_label' => $document->getHtmlLabel(),
  171. 'class' => $document->getClass()
  172. ]),
  173. 'idUser' => $document->user->id,
  174. 'products' => ArrayHelper::map($productsArray, 'id', function ($product) {
  175. return array_merge($product->getAttributes(), [
  176. 'price_with_tax' => $product->price_with_tax,
  177. 'wording_unit' => $product->wording_unit,
  178. 'tax_rate' => $product->taxRate->value
  179. ]);
  180. }),
  181. 'orders' => $ordersArray,
  182. 'total' => $document->getAmount(Order::AMOUNT_TOTAL),
  183. 'total_with_tax' => $document->getAmountWithTax(Order::AMOUNT_TOTAL),
  184. ];
  185. }
  186. }
  187. return ['return' => 'error'];
  188. }
  189. public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price)
  190. {
  191. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  192. if (Document::isValidClass($classDocument)) {
  193. $document = $classDocument::searchOne([
  194. 'id' => $idDocument
  195. ]);
  196. $product = Product::searchOne([
  197. 'id' => $idProduct
  198. ]);
  199. if ($document && $product) {
  200. if (count($document->orders) == 0) {
  201. $order = new Order;
  202. $order->id_user = $document->id_user;
  203. $order->id_point_sale = null;
  204. $order->id_distribution = null;
  205. $order->origin = Order::ORIGIN_ADMIN;
  206. $order->date = date('Y-m-d H:i:s');
  207. $fieldIdDocument = 'id_' . $classDocument::tableName();
  208. $order->$fieldIdDocument = $document->id;
  209. $order->save();
  210. } else {
  211. $order = $document->orders[0];
  212. }
  213. if ($order) {
  214. $productOrder = new ProductOrder;
  215. $productOrder->id_order = $order->id;
  216. $productOrder->id_product = $idProduct;
  217. $quantity = $quantity / Product::$unitsArray[$product->unit]['coefficient'];
  218. $productOrder->quantity = $quantity;
  219. $productOrder->price = (float)$price;
  220. $productOrder->unit = $product->unit;
  221. $productOrder->step = $product->step;
  222. $productOrder->id_tax_rate = $productOrder->id_tax_rate ?
  223. $product->taxRate->id : GlobalParam::getCurrentProducer()->taxRate->id;
  224. $productOrder->save();
  225. return [
  226. 'return' => 'success',
  227. ];
  228. }
  229. }
  230. }
  231. return [
  232. 'return' => 'error'
  233. ];
  234. }
  235. public function actionAjaxDeleteProductOrder($idProductOrder)
  236. {
  237. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  238. $productOrder = ProductOrder::searchOne([
  239. 'id' => $idProductOrder
  240. ]);
  241. if ($productOrder) {
  242. $productOrder->delete();
  243. return [
  244. 'return' => 'success'
  245. ];
  246. }
  247. return [
  248. 'return' => 'error'
  249. ];
  250. }
  251. protected function getClass()
  252. {
  253. $class = get_class($this);
  254. $class = str_replace('Controller', '', $class);
  255. $class = str_replace('backend\controllers\\', '', $class);
  256. return $class;
  257. }
  258. protected function getDocumentType()
  259. {
  260. $class = $this->getClass();
  261. if ($class == 'Invoice') {
  262. $documentType = 'Facture';
  263. } elseif ($class == 'DeliveryNote') {
  264. $documentType = 'Bon de livraison';
  265. } elseif ($class == 'Quotation') {
  266. $documentType = 'Devis';
  267. }
  268. if (isset($documentType)) {
  269. return $documentType;
  270. }
  271. return '';
  272. }
  273. public function getFlashMessage($type = 'create', $model)
  274. {
  275. $class = $this->getClass();
  276. $message = $this->getDocumentType();
  277. $message .= ' <strong>' . Html::encode($model->name) . '</strong> ';
  278. if ($type == 'create') {
  279. $message .= 'ajouté';
  280. } elseif ($type == 'update') {
  281. $message .= 'modifié';
  282. }
  283. if ($class == 'Invoice') {
  284. $message .= 'e';
  285. }
  286. return $message;
  287. }
  288. protected function getTitle($prepend)
  289. {
  290. $class = $this->getClass();
  291. switch ($class) {
  292. case 'Invoice' :
  293. $title = $prepend . ' une facture';
  294. break;
  295. case 'DeliveryNote' :
  296. $title = $prepend . ' un bon de livraison';
  297. break;
  298. case 'Quotation' :
  299. $title = $prepend . ' un devis';
  300. break;
  301. }
  302. return $title;
  303. }
  304. /**
  305. * Recherche un Document en fonction de son ID.
  306. *
  307. * @param integer $id
  308. * @return Produit
  309. * @throws NotFoundHttpException si le modèle n'est pas trouvé
  310. */
  311. protected function findModel($id)
  312. {
  313. $class = $this->getClass();
  314. if (($model = $class::findOne($id)) !== null) {
  315. return $model;
  316. } else {
  317. throw new NotFoundHttpException('The requested page does not exist.');
  318. }
  319. }
  320. }