src/Manager/PriceManager.php line 389

Open in your IDE?
  1. <?php
  2. namespace App\Manager;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use App\Entity\Cart;
  5. use App\Service\Mailer;
  6. use App\Manager\CustomerManager;
  7. use App\Manager\CartManager;
  8. use App\Entity\Product;
  9. use App\Entity\TaxClass;
  10. use App\Entity\TaxRate;
  11. class PriceManager {
  12. private $em;
  13. private $customerMgr;
  14. private $cartMgr;
  15. private $customer;
  16. private $currentDiscountType = false;
  17. private $currentMarketingRule = false;
  18. // private $rules = [];
  19. public function __construct(EntityManagerInterface $em, CartManager $cartMgr)
  20. {
  21. $this->cartMgr = $cartMgr;
  22. $this->em = $em;
  23. $this->customer = false;
  24. // $this->rules = $this->em->getRepository('App:MarketingRule')->getActiveRules();
  25. }
  26. public function getPrice(Product $product, $qty = 1, $useCart = true, $withEcoTax = true) {
  27. $this->customer = $this->cartMgr->getCustomer();
  28. $discountType = "";
  29. $discountAmount = 0;
  30. $discountPercent = "";
  31. $cart = $this->cartMgr->getCart();
  32. $normalPrice = $product->getPrice(false, $cart->getPriceGroup());
  33. $price = $product->getPrice(false, $cart->getPriceGroup());
  34. $ecoTax = $product->getEcotax();
  35. $this->currentMarketingRule = null;
  36. if($this->customer === false){
  37. return $product->getPrice(true, $cart->getPriceGroup());
  38. }
  39. if($this->cartMgr->isExpert()){
  40. return $product->getPrice(true, $cart->getPriceGroup());
  41. }
  42. // if($useCart){
  43. // }else{
  44. // $cart = false;
  45. // }
  46. // remise standard
  47. $tmp = $this->round($normalPrice) - $this->round($this->getStandardDiscount($product, $qty));
  48. if ($tmp < $price) {
  49. $price = $tmp;
  50. $discountType = "standard";
  51. } else {
  52. $this->hasSpecialPrice = false;
  53. }
  54. // $tmp = $this->round($price) - $this->round($this->getSpecialDiscounts($product, $qty));
  55. // if ($tmp < $price) {
  56. // $price = $tmp;
  57. // $discountType = "specialDiscounts";
  58. // }
  59. // $tmp = $this->round($normalPrice) - $this->round($this->getSpecialDiscounts($product, $qty));
  60. // if ($tmp < $price) {
  61. // $price = $tmp;
  62. // $discountType = "SpecialDiscounts";
  63. // }
  64. if ($this->isLockedPrice($product)) {
  65. return $this->round($price);
  66. }
  67. //remise de bienvenue
  68. $tmp = $this->round($normalPrice) - $this->round($this->getWelcomeDiscount($product));
  69. if ($tmp < $price) {
  70. $price = $tmp;
  71. $discountType = "bienvenue";
  72. }
  73. // remise soleil
  74. $tmp = $this->round($normalPrice) - $this->round($this->getSoleilDiscount($product, $useCart));
  75. if ($tmp < $price) {
  76. $price = $tmp;
  77. $discountType = "soleil";
  78. }
  79. //remises dynamiques
  80. $discounts = $this->getDiscountsByProduct($product);
  81. foreach($discounts as $discount){
  82. if($discount->isTypeOffered() && ($discount->getQtyRequested() < $cart->getItemQuantityByProduct($product))) {
  83. $discountType = $discount->getType();
  84. $this->currentMarketingRule = $discount;
  85. $price = $product->getPrice(true);
  86. }else{
  87. $additonalPercentDiscount = 0;
  88. if($discount->getSkipSoleilDiscount() === false) {
  89. $additonalPercentDiscount = $this->getSoleilPercentDiscount($product);
  90. }
  91. $tmp = $normalPrice - $discount->getProductDiscountByCart($product, $cart);
  92. if($additonalPercentDiscount>0) {
  93. $tmp = $this->getReducedPriceByPercent($tmp, $additonalPercentDiscount);
  94. }
  95. $tmp = $this->round($tmp);
  96. if ($tmp < $price) {
  97. $price = $tmp;
  98. $discountType = $discount->getType();
  99. $this->currentMarketingRule = $discount;
  100. }
  101. }
  102. }
  103. $this->currentDiscountType = $discountType;
  104. return $this->round($price) + ($withEcoTax ? $this->round($ecoTax) : 0);
  105. }
  106. public function getStandardDiscount(Product $product) {
  107. $price = $product->getPrice();
  108. $specialPrice = $this->em->getRepository('App:SpecialPrice')->getDiscount($product);
  109. if (!empty($specialPrice)) {
  110. return $price - $specialPrice->getPrice();
  111. }
  112. return 0;
  113. }
  114. public function getSoleilDiscount(Product $product, $useCart = true) {
  115. if ($this->isLockedPrice($product) || !$this->hasSoleilDiscount())
  116. return 0;
  117. $cart = $this->cartMgr->getCart();
  118. $price = $product->getPrice();
  119. $cartTotal = $this->getCartTotal();
  120. $nonSoleilTotal = $cart->getNonSoleilTotal();
  121. $soleilTotal = $cart->getSoleilTotal();
  122. if(!$useCart){ // on ajoute la prix du produit pour obtenir la remise après ajout au panier
  123. $cartTotal += $price;
  124. $nonSoleilTotal += $price;
  125. $soleilTotal += $price;
  126. }
  127. $discount = 0;
  128. if (($product->getSoleil() == 0) && ($nonSoleilTotal > 100)) {
  129. $discount = $product->getPrice(false) * 0.1;
  130. } else if (($product->getSoleil() == 1) && ($soleilTotal > 100)) {
  131. $coef = 0.25;
  132. $discount = $product->getPrice(false) * $coef;
  133. if ($this->hasTVADiscount()) {
  134. $discount += ($product->getPrice(false) - $discount) * 0.2;
  135. }
  136. } else if ($product->getSoleil() == 1) {
  137. if ($this->hasTVADiscount()) {
  138. $discount += ($product->getPrice(false) - $discount) * 0.2;
  139. }
  140. }
  141. return $discount;
  142. }
  143. public function getSoleilPercentDiscount(Product $product) {
  144. if ($this->isLockedPrice($product) || !$this->hasSoleilDiscount())
  145. return 0;
  146. $cart = $this->cartMgr->getCart();
  147. $price = $product->getPrice();
  148. $cartTotal = $this->getCartTotal();
  149. $nonSoleilTotal = $cart->getNonSoleilTotal();
  150. $soleilTotal = $cart->getSoleilTotal();
  151. $percent = 0;
  152. if (($product->getSoleil() == 0) && ($nonSoleilTotal > 100)) {
  153. $percent = 10;
  154. } else if (($product->getSoleil() == 1) && ($soleilTotal > 100)) {
  155. $percent = 25;
  156. }
  157. return $percent;
  158. }
  159. public function getWelcomeDiscount(Product $product) {
  160. // if ($this->isLockedPrice($product))
  161. // return 0;
  162. // if (!$this->hasCartTotal())
  163. // return 0;
  164. if(!$product->isProduct())
  165. return 0;
  166. $manufacturer = $product->getManufacturer();
  167. if($manufacturer && !$manufacturer->hasWelcomeDiscount()) {
  168. return 0;
  169. }
  170. if (!$product->hasWelcomeDiscount()) {
  171. return 0;
  172. }
  173. if ($this->hasWelcomeDiscount()) {
  174. return $product->getPrice(false) * 0.1;
  175. }
  176. return 0;
  177. }
  178. public function getFidelityDiscount(Product $product) {
  179. if ($this->isLockedPrice($product))
  180. return 0;
  181. $customer = $this->cartMgr->getCustomer();
  182. if($customer) {
  183. if ($customer->hasPlatiniumDiscount()) {
  184. return $product->getPrice() * 0.05;
  185. } else if ($customer->hasEliteDiscount()) {
  186. return $product->getPrice() * 0.1;
  187. }
  188. }
  189. return 0;
  190. }
  191. public function getPalierDiscount(Product $product) {
  192. if ($this->isLockedPrice($product))
  193. return 0;
  194. if ($this->customer && !$this->customer->hasSoleil())
  195. return 0;
  196. if (($product->getSoleil() == 1)) {
  197. if ($this->getCartTotal() >= 2500) {
  198. return $product->getPrice() * 0.30;
  199. } else if ($this->getCartTotal() >= 2000) {
  200. return $product->getPrice() * 0.20;
  201. } else if ($this->getCartTotal() >= 1500) {
  202. return $product->getPrice() * 0.15;
  203. } else if ($this->getCartTotal() >= 1000) {
  204. return $product->getPrice() * 0.10;
  205. } else if ($this->getCartTotal() >= 400) {
  206. return $product->getPrice() * 0.05;
  207. }
  208. // } else {
  209. } else if (($product->getSoleil() == 0)) {
  210. if ($this->getCartTotal() >= 2500) {
  211. return $product->getPrice() * 0.1;
  212. } else if ($this->getCartTotal() >= 2000) {
  213. return $product->getPrice() * 0.05;
  214. }
  215. }
  216. return 0;
  217. }
  218. public function getSpecialDiscounts(Product $product, $qty = 1) {
  219. $from = mktime(0, 0, 0, 11, 1, 2025);
  220. $limit = mktime(23, 59, 59, 12, 15, 2025);
  221. $now = time();
  222. if (($now < $from) || ($now > $limit)) {
  223. return 0;
  224. }
  225. // $refs = ['3006063','3006064','3006067','3006071','3006075','3006345','3006352','3006354','3006411','3006412','3006415','3006419','3006420','3006423','3006427','3006428','3006431','3006435','3006436','3006439','3006443','3006444','3006447','3006451','3006452','3006455','3006731','3006732','3006733','3006734','3006735','3006736','3006737','3006738','3006739','3006740','3006741','3006742','3006743','3006744','3006745','3006746','3006747','3006748','3006749','3006750','3006751','3006752','3006753','3006754','3006360','3006363','3006688','3006689','3006692','3006755','3006756','3006758'];
  226. // if(in_array($product->getModelSAP(), $refs)){
  227. // if($qty>=3){
  228. // return $product->getPrice() * (1-($qty-floor($qty/3))/$qty);
  229. // }
  230. // }
  231. // return 0;
  232. $refs = ['3006063','3006064','3006067','3006071','3006075','3006345','3006352','3006354','3006411','3006412','3006415','3006419','3006420','3006423','3006427','3006428','3006431','3006435','3006436','3006439','3006443','3006444','3006447','3006451','3006452','3006455','3006731','3006732','3006733','3006734','3006735','3006736','3006737','3006738','3006739','3006740','3006741','3006742','3006743','3006744','3006745','3006746','3006747','3006748','3006749','3006750','3006751','3006752','3006753','3006754','3006360','3006363','3006688','3006689','3006692','3006755','3006756','3006758'];
  233. if(in_array($product->getModelSAP(), $refs)){
  234. if($qty>=20){
  235. return $product->getPrice() * 0.3 + $this->getSoleilDiscount($product);
  236. }else if($qty>=15){
  237. return $product->getPrice() * 0.25 + $this->getSoleilDiscount($product);
  238. }else if($qty>=10){
  239. return $product->getPrice() * 0.20 + $this->getSoleilDiscount($product);
  240. }else if($qty>=5){
  241. return $product->getPrice() * 0.15 + $this->getSoleilDiscount($product);
  242. }
  243. }
  244. return 0;
  245. $refs = ['200013', '200014', '200015', '200016', '200017', '200018', '200019', '200020', '200021', '200029', '200033', '200034', '200035', '200040', '200068', '200069', '200070', '200071', '200072', '200073', '200074', '200075', '200076', '200077'];
  246. if(in_array($product->getModel(), $refs)){
  247. return $product->getPrice() * 0.15;
  248. }
  249. $refs = ['22661', '22672', '22668', '22670', '22662', '22663', '22664', '22665', '22666'];
  250. if(in_array($product->getId(), $refs)){
  251. if($qty>=11){
  252. return $product->getPrice() * (1-($qty-1)/$qty);
  253. }
  254. }
  255. $refs = ['22035', '22036', '22037', '22038', '22039', '22635', '22636'];
  256. if(in_array($product->getId(), $refs)){
  257. if($qty>=16){
  258. return $product->getPrice() * (1-($qty-2)/$qty);
  259. }
  260. }
  261. return 0;
  262. }
  263. public function getSpecialDiscountsCart(Product $product, $qty) {
  264. // echo('getSpecialDiscountsCart '. $product->getModel().' '.$qty);
  265. $from = mktime(0, 0, 0, 4, 5, 2023);
  266. $limit = mktime(23, 59, 59, 12, 31, 2023);
  267. $now = time();
  268. if (($now < $from) || ($now > $limit)) {
  269. return 0;
  270. }
  271. $refs = ['13521', '13700.6', '13702.6', '15407R', '15408R', '15409R', '17086', '17091', '17092', '17093', '17094', '17095', '17097', '17126R', '17127R', '17145', '17156V', '17173', '17174', '17175', '17180J', '17181J', '17190B', '17191B', '17195V', '17196V', '18104G', '18105G', '18136', '18413V', '18417B', '18419A', '18420A', '18423A', '18424A', '18426A', '18427A', '18427V', '18428A', '18448.R', '18452.R', '18456.N', '18456.R', '64130', '64131', '75505.1', '75505.4', '75506.1', '75511.8', '75511.9', '75512.1', '75512.9', '75527.1', '75527.5', '75533', '75534', '75535', '75536', '75537', '75539', '75540', '75541', '75542', '75543', '75544', '75549.2', '75550.1', '75550.5', '75550.7', '75551.1', '75551.5', '75552.1', '75554.5', '75555.5', '75562.3', '75562.4', '75597', '75601.3', '75602.3', '75605.3', '75622.6', '75628.2', '75628.3', '75661.2', '75665.1', '75669.1', '75678.2', '75680.2', '75681.1', '75681.2', '75682.1', '75682.2', '75683.1', '75683.2', '75684.1', '75684.2', '75685.1', '75685.2', '75686.1', '75686.2', '75687.1', '75687.2', '75688.1', '75688.2', '75717.1', '75817.2', '75845.1', '75894.1', '75894.2', '75899.1', '75900.1', '75900.2', '75900.3', '75900.4', '75901.1', '75901.2', '75901.3', '75901.4', '75902.2', '75902.4', '75903.2', '75905.1', '75905.2', '75905.3', '75905.4', '75910.1', '75910.2', '75910.3', '75910.4', '75911.3', '75911.4', '75912.1', '75912.2', '75912.3', '75912.4', '75913.1', '75913.2', '75913.3', '75913.4', '75914.1', '75914.3', '75914.4', '75915.2', '75915.3', '75915.4', '75920.1', '75920.3', '75921.1', '75921.3', '75922.1', '75922.3', '75930.1', '75930.2', '75930.3', '75930.4', '75931.2', '75931.3', '75931.4', '75932.1', '75932.2', '75932.3', '75932.4', '75933.1', '75933.2', '75933.3', '75933.4', '75934.1', '75934.2', '75934.3', '75935.1', '75935.2', '75935.3', '75935.4', '76072.2', '76088.1', '76089.1', '76090.1', '76091.1', '76091.2', '76158.1', '76158.2', '76159.1', '76159.2', '76160.2', '76161.1', '76161.2', '77503', '77992.8', '77994.6', '77994.8', '78194', '78443.5', '78444.4', '78444.5', '78445.4', '78445.5', '78445.6', '78445.7', '78445.8', '78448.3', '78458', '78459', '78462', '79144.1', '79640.1', '79645.1', 'D208152', 'D220011', 'D220016', 'D220035', 'D220056', 'D220058', 'D220066', 'D220081', 'D220086', 'D220111', 'D220116', 'D220135', 'D220156', 'D220158', 'D220168', 'D220181', 'D220186', 'D220211', 'D220216', 'D220235', 'D220256', 'D220258', 'D220266', 'D220268', 'D220281', 'D220286', 'D220311', 'D220316', 'D220356', 'D220358', 'D220366', 'D220368', 'D220411', 'D220416', 'D220435', 'D220456', 'D220458', 'D220466', 'D220468', 'D221006', 'D221016', 'D221018', 'D221021', 'D221023', 'D221024', 'D221026', 'D221028', 'D221029', 'D221035', 'D221036', 'D221039', 'D221045', 'D221046', 'D221056', 'D221057', 'D221061', 'D221074', 'D221079', 'D221098', 'D221105', 'D221157', 'D221162', 'D221199', 'D221204', 'D221205', 'D221206', 'D221209', 'D221210', 'MO10357', 'MO10358', 'MO10359', 'MO10365', 'MO10366', 'MO10373', 'MO10380', 'MO10387', 'MO10394', 'MO10395', 'MO10396', 'MO10397', 'MO10398', 'MO10399', 'MO10400', 'MO10401', 'MO10402', 'MO10403', 'MO10404', 'MO10405', 'MO10406', 'MO10407', 'MO10408', 'MO10411', 'MO10412', 'MO10413', 'MO10414', 'MO10419', 'MO10420', 'MO10456', 'MO10464', 'MO10465', 'MO10466', 'MO10467', 'MO10592', 'MO10593', 'MO10685', 'MO10686', 'MO10689', 'MO10692', 'MO10838', 'MO10839', 'MO10841', 'MO10842', 'MO10843', 'MO10844', 'MO10845', 'MO10846', 'MO10847', 'MO10848', 'MO10849', 'MO10850', 'MO10851', 'MO10852', 'MO10853', 'MO10854', 'MO10855', 'MO10856', 'MO10857', 'PP10018', 'PP10028', 'PP10044', 'PP10050', 'PP10056', 'PP10061'];
  272. if(in_array($product->getModel(), $refs)){
  273. return $product->getPrice() * 0.5;
  274. }
  275. $refs = ['76072.2', '76088.1', '76091.1', '76091.2', '76102.2', '76103.2', '76105.2', '76106.2', '76161.1', '76161.2', '76162.1', '76162.2', '76162.3', '76170.1', '76170.2', '76170.3', '76171.1', '76171.2', '76171.3', '76172.2', '76172.3', '76173.3', '76174.2', '76174.3', '76175.2', '76175.3', '76180.1', '76180.2', '76180.3', '76181.1', '76181.2', '76181.3', '76184.1', '76185.1', '76185.2', '76186.1', '76186.2', '76187.1', '76187.2', '76188.1', '76188.2', '76189.1', '76189.2', '76190.1', '76195.1', '76197.2', '76198.1', '76199.2', '76208.1', '76208.2', '76209.1', '76209.2', '76210.2', '76213.2', '76232.1', '76232.2', '76232.3', '76240.1', '76240.2', '76240.3', '76241.1', '76241.2', '76241.3', '76242.1', '76242.2', '76242.3', '76243.1', '76243.2', '76243.3', '76244.2', '76244.3', '76245.3', '76246.3', '76247.1', '76247.2', '76247.3', '76248.1', '76248.2', '76248.3', '76252.2', '76260.1', '76260.2', '76260.3', '76261.1', '76261.2', '76261.3', '76263.2', '76265.2', '76266.2', '76269.2', '76272.2', '76273.1', '76273.2', '76273.3', '76274.1', '76274.2', '76274.3', '76278.2', '76288.1', '76288.2', '76289.1', '76289.2', '76290.1', '76290.2', '76291.1', '76291.2', '76292.1', '76292.2', '76299.1', '76299.2', '76300.1', '76300.2', '76303.1', '76305.1', '76306.1', '76307.1', '76308.1', '76310.1', '76310.2', '76318.1', '76318.2', '76319.1', '76319.2', '76320.1', '76320.2', '76321.1', '76321.2', '76322.1', '76322.2', '76323.1', '76323.2', '76324.1', '76324.2', '76325.1', '76325.2', '76326.1', '76326.2', '76327.1', '76327.2', '76328.1', '76328.2', '76329.1', '76329.2', '78458', '78459', '78462', 'CH10050', 'D208152', 'D400240', 'MO10456', 'MO10464', 'MO10465', 'MO10466', 'MO10467', '15408R', '71045.4', '71045.7', '71045.8', '71045.9', '71046.7', '71200.5', '71201.3', '71201.5', '71203.2', '71203.3', '71208.5', '71209.3', '71209.5', '71210.2', '71211.2', '76066.5', '76066.6', '76066.7', '76067.5', '76067.6', '76067.7', '76068.5', '76068.6', '76068.7', '76069.5', '76069.6', '76069.7', '76070.5', '76070.6', '76070.7', '76071.5', '76071.6', '76071.7'];
  276. if(in_array($product->getModel(), $refs)){
  277. if($qty >= 10){
  278. return $product->getPrice() * 0.5;
  279. }else if($qty >= 5){
  280. return $product->getPrice() * 0.45;
  281. }else if($qty >= 4){
  282. return $product->getPrice() * 0.4;
  283. }else if($qty >= 3){
  284. return $product->getPrice() * 0.35;
  285. }else if($qty >= 2){
  286. return $product->getPrice() * 0.3;
  287. }
  288. }
  289. return 0;
  290. }
  291. public function hasSoleilDiscount() {
  292. if($this->customer) {
  293. return $this->customer->hasSoleil();
  294. }
  295. return true;
  296. }
  297. public function hasWelcomeDiscount() {
  298. $customer = $this->cartMgr->getCustomer();
  299. if(empty($customer) || !$customer->hasBienvenue()) {
  300. return false;
  301. }
  302. $date = date('Y-m-d H:i:s', time() - 365 * 24 * 60 * 60);
  303. $sql = "select count(*) as nb from orders where customers_id = ".$customer->getId()." and date_purchased>'" . $date . "' and (orders_status = 1 OR orders_status = 2 OR orders_status = 3 OR orders_status = 88896)";
  304. $st = $this->em->getConnection()->executeQuery($sql);
  305. $count = $st->fetch();
  306. return $count['nb'] == 0;
  307. }
  308. public function hasTVADiscount() {
  309. //return true;
  310. $start = mktime(10, 0, 0, 9, 27, 2019);
  311. $end = mktime(23, 59, 59, 9, 29, 2019);
  312. $now = time();
  313. return ($now >= $start) && ($now <= $end);
  314. }
  315. public function getCartTotal() {
  316. $cart = $this->cartMgr->getCart();
  317. return $cart->getTotalProducts();
  318. }
  319. protected function round($value) {
  320. return round($value, 2);
  321. }
  322. protected function getReducedPriceByPercent($price, $percent) {
  323. return $price*(1-$percent/100);
  324. }
  325. public function isLockedPrice(Product $product) {
  326. if(!$product->isProduct())
  327. return false;
  328. $manufacturer = $product->getManufacturer();
  329. return $manufacturer && ($manufacturer->getLockedPrice() == 1);
  330. }
  331. public function getPriceInfos(Product $product) {
  332. $price = $this->getPrice($product, 1, true);
  333. $normalPrice = $this->round($product->getPrice(true));
  334. return [
  335. 'normal' => $normalPrice,
  336. 'price' => $price,
  337. 'discountType' => $this->currentDiscountType,
  338. 'percent' => $normalPrice > 0 ? number_format(round((($price-$normalPrice)/$normalPrice)*100), 2, ".", "") : ''
  339. ];
  340. }
  341. public function getPriceGrid(Product $product) {
  342. $max_qty = 1;
  343. $p_tmp = 0;
  344. $priceLines = array();
  345. $from = 0;
  346. $normalPrice = $this->round($product->getPrice(false));
  347. for ($i = 1; $i <= $max_qty; $i++) {
  348. $p = $this->getPrice($product, $i, false, false);
  349. if (count($priceLines) > 0) {
  350. $priceLines[count($priceLines) - 1]['to'] = ($i - 1);
  351. }
  352. if ($p_tmp != $p) {
  353. $p_tmp = $p;
  354. $from = $i;
  355. $priceLines[] = array(
  356. 'price' => $p,
  357. 'normal' => $normalPrice,
  358. 'priceFormat' => number_format($p, 2, ".", ""),
  359. 'normalFormat' => number_format($normalPrice, 2, ".", ""),
  360. 'percent' => number_format(round((($p-$normalPrice)/$normalPrice)*100), 2, ".", ""),
  361. 'from' => $from,
  362. 'to' => "",
  363. 'discountType' => $this->currentDiscountType
  364. );
  365. }
  366. }
  367. return $priceLines;
  368. }
  369. public function updateCartPrice(Cart $cart){
  370. $items = $cart->getItems();
  371. if($this->cartHasOfferedProducts($cart)) {
  372. $this->applyDiscountsToCart($cart);
  373. }
  374. foreach($items as $item){
  375. $price = $this->getPrice($item->getProduct(true, $cart->getPriceGroup()), $item->getQuantity());
  376. $this->setCartItemPrice($item);
  377. }
  378. $this->cartMgr->save($cart);
  379. }
  380. public function setCartItemPrice(\App\Entity\CartItem $item){
  381. if($item->getQuantityOffered() > 0) {
  382. $soleilDiscount = 0;
  383. if($item->getMarketingRule()) {
  384. $soleilDiscount = $item->getMarketingRule()->getSkipSoleilDiscount() === true ? 0 : $this->getSoleilDiscount($item->getProduct(), true);
  385. }
  386. $price = $item->getProduct()->getPrice(true, $item->getCart()->getPriceGroup()) - $this->round($soleilDiscount);
  387. $item->setUnitPrice($price);
  388. $item->setTotalPrice($price * ($item->getQuantity() - $item->getQuantityOffered()));
  389. }else if($this->currentDiscountType != \App\Entity\MarketingRule::TYPE_OFFERED){
  390. $item->setUnitPrice($this->getPrice($item->getProduct(), $item->getQuantity(true), true));
  391. $item->setTotalPrice($this->getPrice($item->getProduct(), $item->getQuantity(), true) * $item->getQuantity());
  392. }else{
  393. $item->setUnitPrice($item->getProduct()->getPrice(true, $item->getCart()->getPriceGroup()));
  394. $item->setTotalPrice($item->getProduct()->getPrice(true, $item->getCart()->getPriceGroup()) * $item->getQuantity());
  395. }/*else{
  396. $item->setUnitPrice($item->getProduct()->getPrice());
  397. $qty = $item->getQuantity();
  398. $qtyOffered = 0;
  399. if($qty >= $this->currentMarketingRule->getQtyRequested()){
  400. $qtyOffered = $this->currentMarketingRule->getQtyOffered() * floor($qty / $this->currentMarketingRule->getQtyRequested());
  401. }
  402. $item->setTotalPrice($item->getProduct()->getPrice() * ($qty - $qtyOffered));
  403. }*/
  404. $item->setMarketingRule($this->currentMarketingRule);
  405. $item->setDiscountType($this->currentDiscountType);
  406. }
  407. protected function getPercent($discount, $normalPrice) {
  408. return round(($discount) / $normalPrice * 100) . "%";
  409. }
  410. public function getDiscountsByProduct(Product $product, $onlyActive = true) {
  411. if($this->cartMgr->isExpert())
  412. return null;
  413. return $this->em->getRepository(\App\Entity\MarketingRule::class)->getByProduct($product, $onlyActive);
  414. }
  415. public function getBestDiscountByProduct(Product $product, $onlyActive = true) {
  416. if($this->cartMgr->isExpert())
  417. return null;
  418. $discounts = $this->em->getRepository(\App\Entity\MarketingRule::class)->getByProduct($product, $onlyActive);
  419. $best = null;
  420. $bestAmount = null;
  421. foreach($discounts as $discount){
  422. $discountAmount = $discount->getProductDiscountByCart($product, null);
  423. if(empty($best) || ($bestAmount<$discountAmount)) {
  424. $best = $discount;
  425. $bestAmount = $discountAmount;
  426. }
  427. }
  428. return empty($best) ? [] : [$best];
  429. }
  430. public function getDiscountsByCart(Cart $cart) {
  431. $products = $cart->getProducts();
  432. return $this->em->getRepository(\App\Entity\MarketingRule::class)->getByProducts($products, true);
  433. }
  434. public function cartHasOfferedProducts(Cart $cart) {
  435. if($this->cartMgr->isExpert())
  436. return false;
  437. $discounts = $this->getDiscountsByCart($cart);
  438. foreach($discounts as $discount) {
  439. if($discount->getType() == \App\Entity\MarketingRule::TYPE_OFFERED) {
  440. return true;
  441. }
  442. }
  443. return false;
  444. }
  445. public function applyDiscountsToCart(Cart $cart) {
  446. $discounts = $this->getDiscountsByCart($cart);
  447. foreach($discounts as $discount) {
  448. if($discount->getType() == \App\Entity\MarketingRule::TYPE_OFFERED) {
  449. $cart->applyDiscount($discount);
  450. }
  451. }
  452. }
  453. public function setPrice(Product $product, $price, \App\Entity\PriceGroup $group) {
  454. $productPrice = $this->em->getRepository(\App\Entity\ProductPrice::class)->findOneBy(
  455. [
  456. 'product' => $product,
  457. 'group' => $group
  458. ]
  459. );
  460. if(empty($productPrice)) {
  461. $productPrice = new \App\Entity\ProductPrice();
  462. $productPrice->setGroup($group);
  463. $productPrice->setProduct($product);
  464. }
  465. $productPrice->setPrice($price);
  466. $this->em->persist($productPrice);
  467. $this->em->flush();
  468. }
  469. public function setPriceByCode(Product $product, $price, string $code) {
  470. $priceGroup = $this->em->getRepository(\App\Entity\PriceGroup::class)->findOneByCode($code);
  471. if($priceGroup) {
  472. return $this->setPrice($product, $price, $priceGroup);
  473. }
  474. return null;
  475. }
  476. public function getTaxClassByRate(float $taxRate): ?TaxClass
  477. {
  478. $taxRateEntity = $this->em->getRepository(TaxRate::class)
  479. ->findOneBy(['taxRate' => $taxRate]);
  480. return $taxRateEntity?->getTaxClass() ?? null;
  481. }
  482. public function removePrice(Product $product, \App\Entity\PriceGroup $group) {
  483. $productPrice = $this->em->getRepository(\App\Entity\ProductPrice::class)->findOneBy(
  484. [
  485. 'product' => $product,
  486. 'group' => $group
  487. ]
  488. );
  489. if($productPrice) {
  490. $this->em->remove($productPrice);
  491. $this->em->flush();
  492. }
  493. return true;
  494. }
  495. }