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.

CommandeController.php 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. <?php
  2. namespace frontend\controllers;
  3. use common\models\ProductionProduit;
  4. use common\models\CommandeProduit;
  5. use Yii;
  6. use yii\filters\AccessControl;
  7. use common\models\Commande;
  8. use common\models\PointVente;
  9. use common\models\Production;
  10. use common\models\Produit;
  11. use common\models\Etablissement;
  12. use common\helpers\Departements;
  13. use yii\helpers\Html;
  14. use frontend\models\AddEtablissementForm;
  15. use common\models\UserEtablissement;
  16. use common\models\CreditHistorique ;
  17. use yii\web\NotFoundHttpException ;
  18. use common\models\ProductionPointVente ;
  19. use yii\base\UserException ;
  20. class CommandeController extends \yii\web\Controller {
  21. public function behaviors() {
  22. return [
  23. 'access' => [
  24. 'class' => AccessControl::className(),
  25. 'rules' => [
  26. [
  27. 'allow' => true,
  28. 'roles' => ['@'],
  29. ]
  30. ],
  31. ],
  32. ];
  33. }
  34. public function actionInfosProduction($id_production) {
  35. $production = Production::findOne($id_production);
  36. if ($production) {
  37. $arr = [] ;
  38. $produits_dispos = ProductionProduit::findProduits($production->id);
  39. $arr['produits_dispos'] = $produits_dispos ;
  40. $points_vente = PointVente::find()
  41. ->joinWith(['productionPointVente'=> function($q) use ($production) {
  42. $q->where(['id_production' => $production->id]) ;
  43. } ])
  44. ->where([
  45. 'id_etablissement' => $production->id_etablissement,
  46. ])
  47. ->all();
  48. $arr['points_vente'] = [] ;
  49. foreach($points_vente as $pv)
  50. {
  51. if(isset($pv->productionPointVente) &&
  52. isset($pv->productionPointVente[0]))
  53. {
  54. $arr['points_vente'][$pv->id] = $pv->productionPointVente[0]->livraison ;
  55. }
  56. else {
  57. $arr['points_vente'][$pv->id] = false ;
  58. }
  59. }
  60. return json_encode($arr);
  61. }
  62. return json_encode([]);
  63. }
  64. public static function initForm($commande = null) {
  65. // etablissements
  66. $etablissements = Yii::$app->user->identity->getEtablissementsFavoris() ;
  67. $id_etablissement = Yii::$app->request->get('id_etablissement', 0) ;
  68. $etablissement_paiement_ok = false ;
  69. if($id_etablissement)
  70. {
  71. $etablissement = Etablissement::findOne($id_etablissement);
  72. if($etablissement->etatPaiement() == Etablissement::PAIEMENT_OK || $etablissement->etatPaiement() == Etablissement::PAIEMENT_ESSAI)
  73. {
  74. $etablissement_paiement_ok = true ;
  75. }
  76. }
  77. // points de vente
  78. $points_vente = PointVente::find()
  79. ->with('pointVenteUser')
  80. ->where(['id_etablissement'=>$id_etablissement])
  81. ->andWhere('acces_restreint = 0 OR (acces_restreint = 1 AND (SELECT COUNT(*) FROM point_vente_user WHERE point_vente.id = point_vente_user.id_point_vente AND point_vente_user.id_user = :id_user) > 0)')
  82. ->params([':id_user' => Yii::$app->user->identity->id])
  83. ->all();
  84. $arr_points_vente = $points_vente;
  85. // jours de production
  86. $heure_limite = 20 ;
  87. $date = date('Y-m-d') ;
  88. if(isset($etablissement))
  89. {
  90. $heure_limite = $etablissement->heure_limite_commande ;
  91. if (date('H') >= $heure_limite) {
  92. $date = date('Y-m-d', strtotime(date('Y-m-d')) + ($etablissement->delai_commande)*(24*60*60) );
  93. } else {
  94. $date = date('Y-m-d', strtotime(date('Y-m-d')) + ($etablissement->delai_commande - 1)*(24*60*60));
  95. }
  96. }
  97. $jours_production = Production::find()
  98. ->where(['actif' => 1])
  99. ->andWhere('date > :date')
  100. ->andWhere(['id_etablissement'=>$id_etablissement])
  101. ->addParams([':date' => $date])
  102. ->all();
  103. $arr_jours_production = array('' => '--');
  104. foreach ($jours_production as $j)
  105. $arr_jours_production[$j->id] = date('d/m/Y', strtotime($j->date));
  106. // produits
  107. $produits = Produit::find()
  108. ->where(['actif' => 1, 'id_etablissement' => $id_etablissement])
  109. ->andWhere('vrac IS NULL OR vrac = 0')
  110. ->orderBy('order ASC')->all();
  111. $arr_produits = array();
  112. foreach ($produits as $p)
  113. $arr_produits[] = $p;
  114. // produits vrac
  115. $produits_vrac = Produit::find()->where(['actif' => 1, 'vrac' => 1])->orderBy('order ASC')->all();
  116. // produits selec
  117. $posts = Yii::$app->request->post();
  118. $produits_selec = [];
  119. if (isset($posts['Produit'])) {
  120. foreach ($posts['Produit'] as $key => $quantity) {
  121. $key = (int) str_replace('produit_', '', $key);
  122. $p = Produit::find()->where(['id' => $key])->one();
  123. if ($p && $quantity)
  124. $produits_selec[$p->id] = (int) $quantity;
  125. }
  126. }
  127. elseif (!is_null($commande)) {
  128. $produits_commande = CommandeProduit::find()->where(['id_commande' => $commande->id])->all();
  129. foreach ($produits_commande as $pc) {
  130. $produits_selec[$pc->id_produit] = (int) $pc->quantite;
  131. }
  132. }
  133. $produits_dispos = [];
  134. $production = null;
  135. if (!is_null($commande) && $commande->id_production) {
  136. $produits_dispos = ProductionProduit::findProduits($commande->id_production);
  137. $production = Production::find()->where(['id' => $commande->id_production])->one();
  138. }
  139. $commandes = Commande::find()
  140. ->where(['id_user' => Yii::$app->user->identity->id])
  141. ->all();
  142. if($id_etablissement)
  143. {
  144. $user_etablissement = UserEtablissement::find()
  145. ->where([
  146. 'id_etablissement' => $id_etablissement,
  147. 'id_user' => Yii::$app->user->identity->id
  148. ])
  149. ->one() ;
  150. $credit = $user_etablissement->credit ;
  151. }
  152. else {
  153. $credit = 0 ;
  154. }
  155. return [
  156. 'points_vente' => $arr_points_vente,
  157. 'jours_production' => $arr_jours_production,
  158. 'produits' => $produits,
  159. 'produits_selec' => $produits_selec,
  160. 'produits_dispos' => $produits_dispos,
  161. 'production' => $production,
  162. 'commandes_en_cours' => $commandes,
  163. 'produits_vrac' => $produits_vrac,
  164. 'etablissements' => $etablissements,
  165. 'id_etablissement' => $id_etablissement,
  166. 'etablissement_paiement_ok' => $etablissement_paiement_ok,
  167. 'credit' => $credit
  168. ];
  169. }
  170. public function actionIndex() {
  171. $model_form_etablissement = new AddEtablissementForm() ;
  172. if($model_form_etablissement->load(Yii::$app->request->post())
  173. && $model_form_etablissement->validate())
  174. {
  175. $model_form_etablissement->add() ;
  176. $model_form_etablissement->code = '' ;
  177. }
  178. // liste des etablissements
  179. $etablissements = Yii::$app->user->identity->getEtablissementsFavoris();
  180. // liste des boulangeries disponibles
  181. $arr_etablissements = Etablissement::getEtablissementsPopulateDropdown() ;
  182. $data_etablissements_dispos = $arr_etablissements['data'] ;
  183. $options_etablissements_dispos = $arr_etablissements['options'] ;
  184. // liste des commandes
  185. $commandes = Commande::find()
  186. ->with('commandeProduits', 'pointVente', 'creditHistorique')
  187. ->joinWith('production','production.etablissement')
  188. ->where(['id_user' => Yii::$app->user->id])
  189. //->andWhere('production.date < '.)
  190. ->orderBy('production.date DESC')
  191. ->limit(40)
  192. ->all();
  193. // initilisation commandes
  194. foreach ($commandes as $c)
  195. $c->init();
  196. return $this->render('index', [
  197. 'commandes' => $commandes,
  198. 'commande_ok' => Yii::$app->getRequest()->get('commande_ok', false),
  199. 'annule_ok' => Yii::$app->getRequest()->get('annule_ok', false),
  200. 'pate_deja_petrie' => Yii::$app->getRequest()->get('pate_deja_petrie', false),
  201. 'etablissements' => $etablissements,
  202. 'model_form_etablissement' => $model_form_etablissement,
  203. 'data_etablissements_dispos' => $data_etablissements_dispos,
  204. 'options_etablissements_dispos' => $options_etablissements_dispos,
  205. ]);
  206. }
  207. public function actionRemoveEtablissement($id = 0)
  208. {
  209. $user_etablissement = UserEtablissement::find()
  210. ->where(['id_etablissement'=>$id, 'id_user' => Yii::$app->user->identity->id])
  211. ->one() ;
  212. $user_etablissement->actif = 0 ;
  213. $user_etablissement->save() ;
  214. $this->redirect(['commande/index']) ;
  215. }
  216. public function actionCreate($id_etablissement = 0) {
  217. $commande = new Commande;
  218. $posts = Yii::$app->request->post();
  219. if($id_etablissement)
  220. $this->_verifEtablissementActif($id_etablissement) ;
  221. if ($commande->load($posts)) {
  222. $commande = Commande::find()->where('id_production = ' . $posts['Commande']['id_production'])->andWhere('id_user = ' . Yii::$app->user->id)->one();
  223. if (!$commande) {
  224. $commande = new Commande;
  225. $commande->load(Yii::$app->request->post());
  226. $commande->id_user = Yii::$app->user->id;
  227. $commande->date = date('Y-m-d H:i:s');
  228. $commande->type = Commande::TYPE_USER ;
  229. }
  230. $this->gestionForm($commande);
  231. }
  232. return $this->render('create', array_merge(self::initForm($commande), [
  233. 'model' => $commande,
  234. ]));
  235. }
  236. public function actionUpdate($id) {
  237. $commande = Commande::find()
  238. ->with('production')
  239. ->where(['id' => $id])
  240. ->one();
  241. if($commande->getEtat() != Commande::ETAT_MODIFIABLE)
  242. {
  243. throw new UserException('Cette commande n\'est pas modifiable.') ;
  244. }
  245. $this->_verifEtablissementActif($commande->production->id_etablissement) ;
  246. if ($commande && $commande->load(Yii::$app->request->post()))
  247. {
  248. $commande->date_update = date('Y-m-d H:i:s');
  249. $this->gestionForm($commande);
  250. }
  251. return $this->render('update', array_merge(self::initForm($commande), [
  252. 'model' => $commande,
  253. 'commande_introuvable' => !$commande,
  254. ]));
  255. }
  256. public function _verifEtablissementActif($id_etablissement)
  257. {
  258. $etablissement = Etablissement::findOne($id_etablissement) ;
  259. if($etablissement && !$etablissement->actif)
  260. {
  261. throw new NotFoundHttpException('Cet établissement est actuellement hors ligne.');
  262. }
  263. }
  264. public function gestionForm($commande) {
  265. $posts = Yii::$app->request->post();
  266. $produits = array();
  267. $quantite_totale = 0;
  268. foreach ($posts['Produit'] as $key => $quantity) {
  269. $key = (int) str_replace('produit_', '', $key);
  270. $p = Produit::find()->where(['id' => $key])->one();
  271. $quantite_totale += $quantity;
  272. if ($p && $quantity)
  273. $produits[] = $p;
  274. }
  275. // nombre de produits
  276. $err_nb_produits = false;
  277. if (!Yii::$app->user->identity->confiance && $quantite_totale > 3) {
  278. $err_nb_produits = true;
  279. }
  280. // date
  281. $err_date = false;
  282. $pate_deja_petrie = false;
  283. if (isset($commande->id_production)) {
  284. // date de commande
  285. $production = Production::find()->where(['id' => $commande->id_production])->one();
  286. if (date('H') >= 20) {
  287. $date = date('Y-m-d', strtotime(date('Y-m-d')) + 60 * 60 * 24);
  288. } else {
  289. $date = date('Y-m-d');
  290. }
  291. if ($production->date < $date) {
  292. $err_date = true;
  293. }
  294. }
  295. // point de vente
  296. $err_point_vente = false ;
  297. if(isset($production) && $production)
  298. {
  299. $ppv = ProductionPointVente::find()
  300. ->where([
  301. 'id_production' => $production->id,
  302. 'id_point_vente' => $posts['Commande']['id_point_vente']
  303. ])
  304. ->one() ;
  305. if(!$ppv || !$ppv->livraison)
  306. {
  307. $err_point_vente = true ;
  308. }
  309. $point_vente = PointVente::findOne($posts['Commande']['id_point_vente']) ;
  310. if($point_vente)
  311. {
  312. if(strlen($point_vente->code) && !$point_vente->verifCode($posts['code_point_vente_'.$point_vente->id]))
  313. {
  314. $err_point_vente = true ;
  315. }
  316. }
  317. else {
  318. $err_point_vente = true ;
  319. }
  320. }
  321. if ($commande->validate() && count($produits) && !$err_nb_produits && !$err_date && !$err_point_vente) {
  322. // gestion point de vente
  323. $pv = PointVente::find()
  324. ->with('pointVenteUser')
  325. ->where(['id' => $commande->id_point_vente])
  326. ->one() ;
  327. if($pv && strlen($pv->getCommentaire()))
  328. $commande->commentaire_point_vente = $pv->getCommentaire() ;
  329. else
  330. $commande->commentaire_point_vente = '' ;
  331. // sauvegarde de la commande
  332. $commande->save();
  333. // suppression de tous les enregistrements CommandeProduit
  334. if (!is_null($commande)) {
  335. CommandeProduit::deleteAll(['id_commande' => $commande->id]);
  336. }
  337. // produits dispos
  338. $produits_dispos = ProductionProduit::findProduits($production->id);
  339. // sauvegarde des produits
  340. foreach ($produits as $p) {
  341. // le produit doit etre dispo à la vente
  342. if (isset($produits_dispos[$p->id]) && $produits_dispos[$p->id]['actif']) {
  343. $commande_produit = new CommandeProduit();
  344. $commande_produit->id_commande = $commande->id;
  345. $commande_produit->id_produit = $p->id;
  346. $commande_produit->prix = $p->prix;
  347. $quantite_voulue = (int) $posts['Produit']['produit_' . $p->id];
  348. if ($produits_dispos[$p->id]['quantite_max'] && $quantite_voulue > $produits_dispos[$p->id]['quantite_restante'])
  349. $quantite_voulue = $produits_dispos[$p->id]['quantite_restante'];
  350. $commande_produit->quantite = $quantite_voulue;
  351. $commande_produit->save();
  352. }
  353. }
  354. // credit pain
  355. $credit_pain = isset($posts['credit_pain']) && $posts['credit_pain'] ;
  356. if($credit_pain && ($pv->credit_pain || $commande->getMontantPaye()))
  357. {
  358. $commande = Commande::find()
  359. ->with('commandeProduits')
  360. ->where(['id' => $commande->id])
  361. ->one() ;
  362. $commande->init() ;
  363. $montant_paye = $commande->getMontantPaye() ;
  364. // à payer
  365. if($commande->getStatutPaiement() == Commande::STATUT_IMPAYEE)
  366. {
  367. $montant_payer = $commande->montant - $montant_paye ;
  368. $credit = Yii::$app->user->identity->getCredit($production->id_etablissement) ;
  369. if($montant_payer > $credit)
  370. {
  371. $montant_payer = $credit ;
  372. }
  373. $commande->creditHistorique(
  374. CreditHistorique::TYPE_PAIEMENT,
  375. $montant_payer,
  376. $production->id_etablissement,
  377. Yii::$app->user->identity->id
  378. ) ;
  379. }
  380. // surplus à rembourser
  381. elseif($commande->getStatutPaiement() == Commande::STATUT_SURPLUS)
  382. {
  383. $montant_rembourser = $montant_paye - $commande->montant ;
  384. $commande->creditHistorique(
  385. CreditHistorique::TYPE_REMBOURSEMENT,
  386. $montant_rembourser,
  387. $production->id_etablissement,
  388. Yii::$app->user->identity->id
  389. ) ;
  390. }
  391. }
  392. // redirection
  393. $this->redirect(Yii::$app->urlManager->createUrl(['commande/index', 'commande_ok' => true, 'pate_deja_petrie' => $pate_deja_petrie]));
  394. }
  395. else {
  396. if (!count($produits))
  397. Yii::$app->session->setFlash('error', "Vous n'avez choisi aucun produit");
  398. if ($err_nb_produits)
  399. Yii::$app->session->setFlash('error', "Vous ne pouvez pas commander plus de 3 produits");
  400. if ($err_date)
  401. Yii::$app->session->setFlash('error', "Vous ne pouvez pas commander pour cette date.");
  402. if($err_point_vente)
  403. Yii::$app->session->setFlash('error', "Point de vente invalide.");
  404. }
  405. }
  406. public function actionAnnuler($id) {
  407. $commande = Commande::find()
  408. ->with('production','creditHistorique','commandeProduits')
  409. ->where(['id' => $id])
  410. ->one();
  411. if($commande->getEtat() != Commande::ETAT_MODIFIABLE)
  412. {
  413. throw new UserException('Vous ne pouvez plus annuler cette commande.') ;
  414. }
  415. $commande->init() ;
  416. if ($commande && Yii::$app->user->id == $commande->id_user) {
  417. // remboursement
  418. if($commande->getMontantPaye())
  419. {
  420. $commande->creditHistorique(
  421. CreditHistorique::TYPE_REMBOURSEMENT,
  422. $commande->getMontantPaye(),
  423. $commande->production->id_etablissement,
  424. Yii::$app->user->identity->id
  425. ) ;
  426. }
  427. // delete
  428. $commande->delete();
  429. CommandeProduit::deleteAll(['id_commande' => $commande->id]);
  430. }
  431. $this->redirect(Yii::$app->urlManager->createUrl(['commande/index', 'annule_ok' => true]));
  432. }
  433. public function actionVerifCodePointVente($id_point_vente, $code)
  434. {
  435. $point_vente = PointVente::findOne($id_point_vente) ;
  436. if($point_vente)
  437. {
  438. if($point_vente->verifCode($code))
  439. {
  440. return true ;
  441. }
  442. }
  443. return false ;
  444. }
  445. }