src/Entity/MarketingRule.php line 13

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use App\Entity\Product;
  5. /**
  6. * @ORM\Table(name="marketing_rules")
  7. * @ORM\Entity(repositoryClass="App\Repository\MarketingRuleRepository")
  8. * @ORM\HasLifecycleCallbacks()
  9. */
  10. class MarketingRule extends TranslatedEntity
  11. {
  12. protected $tranlatedEntity = 'MarketingRuleDescription';
  13. const TYPE_PERCENT = 'percent';
  14. const TYPE_PERCENT_SOLEIL = 'percent-soleil';
  15. const TYPE_AMOUNT = 'amount';
  16. const TYPE_OFFERED = 'offered';
  17. const TYPE_PRICE = 'price';
  18. const TYPE_PERCENT_BY_QTY = 'percent-qty';
  19. /**
  20. * @var int
  21. *
  22. * @ORM\Column(name="id", type="integer", nullable=false)
  23. * @ORM\Id
  24. * @ORM\GeneratedValue(strategy="IDENTITY")
  25. */
  26. private $id;
  27. /**
  28. * @var \App\Entity\Customer
  29. *
  30. * @ORM\ManyToOne(targetEntity="App\Entity\Customer")
  31. * @ORM\JoinColumn(name="customer_id", referencedColumnName="customers_id", nullable=true)
  32. */
  33. private $customer;
  34. /**
  35. * @var array
  36. *
  37. * @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleProductDiscounted", mappedBy="marketingRule", cascade={"persist", "remove"})
  38. */
  39. private $productsDiscounted;
  40. /**
  41. * @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleDescription", mappedBy="marketingRule")
  42. */
  43. private $descriptions = [];
  44. /**
  45. * @var \DateTime|null
  46. *
  47. * @ORM\Column(name="date_from", type="datetime", nullable=true)
  48. */
  49. private $dateFrom;
  50. /**
  51. * @var \DateTime|null
  52. *
  53. * @ORM\Column(name="date_to", type="datetime", nullable=true)
  54. */
  55. private $dateTo;
  56. /**
  57. * @var int
  58. *
  59. * @ORM\Column(name="visible", type="integer", nullable=true)
  60. */
  61. private $visible;
  62. /**
  63. * @var string
  64. *
  65. * @ORM\Column(name="title", type="string", length=255, nullable=true)
  66. */
  67. private $title = '';
  68. /**
  69. * @var string
  70. *
  71. * @ORM\Column(name="description", type="string", length=255, nullable=true)
  72. */
  73. private $description = '';
  74. /**
  75. * @var string
  76. *
  77. * @ORM\Column(name="type", type="string", length=50, nullable=false)
  78. */
  79. private $type = self::TYPE_AMOUNT;
  80. /**
  81. * @var float
  82. *
  83. * @ORM\Column(name="percent_discount", type="decimal", precision=15, scale=4, nullable=true)
  84. */
  85. private $percentDiscount = '0.0000';
  86. /**
  87. * @var float
  88. *
  89. * @ORM\Column(name="amount_discount", type="decimal", precision=15, scale=4, nullable=true)
  90. */
  91. private $amountDiscount = '0.0000';
  92. /**
  93. * @var int
  94. *
  95. * @ORM\Column(name="qty_requested", type="integer", nullable=true)
  96. */
  97. private $qtyRequested = '0';
  98. /**
  99. * @var ?float
  100. *
  101. * @ORM\Column(name="amount_requested", type="decimal", precision=15, scale=4,nullable=true)
  102. */
  103. private $amountRequested = '0.0000';
  104. /**
  105. * @var ?float
  106. *
  107. * @ORM\Column(name="amount_soleil_requested", type="decimal", precision=15, scale=4, nullable=true)
  108. */
  109. private $amountSoleilRequested = '0.0000';
  110. /**
  111. * @var ?float
  112. *
  113. * @ORM\Column(name="amount_vivog_requested", type="decimal", precision=15, scale=4, nullable=true)
  114. */
  115. private $amountVivogRequested = '0.0000';
  116. /**
  117. * @var array
  118. *
  119. * @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleProductRequested", mappedBy="marketingRule", cascade={"persist", "remove"})
  120. */
  121. private $productsRequested;
  122. /**
  123. * @var int
  124. *
  125. * @ORM\Column(name="qty_offered", type="integer", nullable=true)
  126. */
  127. private $qtyOffered = 0;
  128. /**
  129. * @var boolean
  130. *
  131. * @ORM\Column(name="active", type="boolean", options={"default"=false})
  132. */
  133. private $active = false;
  134. /**
  135. * @var boolean
  136. *
  137. * @ORM\Column(name="skip_soleil", type="boolean", options={"default"=true})
  138. */
  139. private $skipSoleilDiscount = true;
  140. /**
  141. * @var array
  142. *
  143. * @ORM\OneToMany(targetEntity="App\Entity\Coupon", mappedBy="marketingRule", cascade={"persist", "remove"})
  144. */
  145. private $coupons;
  146. /**
  147. * @var array
  148. *
  149. * @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleCustomer", mappedBy="marketingRule", cascade={"persist", "remove"})
  150. */
  151. private $customers;
  152. public function __construct()
  153. {
  154. $this->productsDiscounted = new \Doctrine\Common\Collections\ArrayCollection();
  155. $this->productsRequested = new \Doctrine\Common\Collections\ArrayCollection();
  156. $this->coupons = new \Doctrine\Common\Collections\ArrayCollection();
  157. $this->customers = new \Doctrine\Common\Collections\ArrayCollection();
  158. }
  159. public function getId(): int {
  160. return $this->id;
  161. }
  162. public function getCustomer(): \App\Entity\Customer {
  163. return $this->customer;
  164. }
  165. public function getProductsDiscounted() {
  166. return $this->productsDiscounted;
  167. }
  168. public function getProductDiscounted(Product $product) {
  169. foreach($this->getProductsDiscounted() as $pd) {
  170. if($pd->getProduct() == $product)
  171. return $pd;
  172. }
  173. return null;
  174. }
  175. public function getDateFrom(): ?\DateTime {
  176. return $this->dateFrom;
  177. }
  178. public function getDateTo(): ?\DateTime {
  179. return $this->dateTo;
  180. }
  181. public function getVisible(): int {
  182. return $this->visible;
  183. }
  184. public function getTitle(): string {
  185. return $this->title;
  186. }
  187. public function getDescription(): string {
  188. return $this->description;
  189. }
  190. public function getType(): string {
  191. return $this->type;
  192. }
  193. public function getPercentDiscount(): float {
  194. return $this->percentDiscount;
  195. }
  196. public function getAmountDiscount(): float {
  197. return $this->amountDiscount;
  198. }
  199. public function getAmountRequested(): ?float {
  200. return $this->amountRequested;
  201. }
  202. public function getAmountSoleilRequested(): ?float {
  203. return $this->amountSoleilRequested;
  204. }
  205. public function getAmountVivogRequested(): ?float {
  206. return $this->amountVivogRequested;
  207. }
  208. public function getQtyRequested(): int {
  209. return $this->qtyRequested;
  210. }
  211. public function getProductsRequested() {
  212. return $this->productsRequested;
  213. }
  214. public function getQtyOffered(): int {
  215. return $this->qtyOffered;
  216. }
  217. public function getActive(): bool {
  218. return $this->active;
  219. }
  220. public function getCoupons() {
  221. return $this->coupons;
  222. }
  223. public function getCustomers() {
  224. return $this->customers;
  225. }
  226. public function getDescriptions() {
  227. return $this->descriptions;
  228. }
  229. public function getSkipSoleilDiscount(): bool {
  230. return $this->skipSoleilDiscount;
  231. }
  232. public function setId(int $id): void {
  233. $this->id = $id;
  234. }
  235. public function setCustomer(\App\Entity\Customer $customer): void {
  236. $this->customer = $customer;
  237. }
  238. public function setProductsDiscounted(array $productsDiscounted): void {
  239. $this->productsDiscounted = $productsDiscounted;
  240. }
  241. public function setDateFrom(?\DateTime $dateFrom): void {
  242. $this->dateFrom = $dateFrom;
  243. }
  244. public function setDateTo(?\DateTime $dateTo): void {
  245. if($dateTo) {
  246. $dateTo->setTime(23, 59, 59);
  247. }
  248. $this->dateTo = $dateTo;
  249. }
  250. public function setVisible(int $visible): void {
  251. $this->visible = $visible;
  252. }
  253. public function setTitle(string $title): void {
  254. $this->title = $title;
  255. }
  256. public function setDescription(string $description): void {
  257. $this->description = $description;
  258. }
  259. public function setType(string $type): void {
  260. $this->type = $type;
  261. }
  262. public function setPercentDiscount(float $percentDiscount): void {
  263. $this->percentDiscount = $percentDiscount;
  264. }
  265. public function setAmountDiscount(float $amountDiscount): void {
  266. $this->amountDiscount = $amountDiscount;
  267. }
  268. public function setAmountRequested(float $amountRequested): void {
  269. $this->amountRequested = $amountRequested;
  270. }
  271. public function setAmountSoleilRequested(float $amountSoleilRequested): void {
  272. $this->amountSoleilRequested = $amountSoleilRequested;
  273. }
  274. public function setAmountVivogRequested(?float $amountVivogRequested): void {
  275. $this->amountVivogRequested = $amountVivogRequested;
  276. }
  277. public function setQtyRequested(int $qtyRequested): void {
  278. $this->qtyRequested = $qtyRequested;
  279. }
  280. public function setProductsRequested(array $productsRequested): void {
  281. $this->productsRequested = $productsRequested;
  282. }
  283. public function setQtyOffered(int $qtyOffered): void {
  284. $this->qtyOffered = $qtyOffered;
  285. }
  286. public function setActive(bool $active): void {
  287. $this->active = $active;
  288. }
  289. public function setCoupons(array $coupons): void {
  290. $this->coupons = $coupons;
  291. }
  292. public function setCustomers(array $customers): void {
  293. $this->customers = $customers;
  294. }
  295. public function setDescriptions($descriptions): void {
  296. $this->descriptions = $descriptions;
  297. }
  298. public function setSkipSoleilDiscount(bool $skipSoleilDiscount): void {
  299. $this->skipSoleilDiscount = $skipSoleilDiscount;
  300. }
  301. public function hasCustomer(Customer $customer, $strict = false) {
  302. $output = false;
  303. $requiredCustomers = $this->getCustomers();
  304. if(!$strict && (count($requiredCustomers)==0))
  305. return true;
  306. foreach($this->getCustomers() as $c){
  307. if($c->getCustomer() == $customer)
  308. return true;
  309. }
  310. return false;
  311. }
  312. public function hasDiscountedProduct(Product $product) {
  313. foreach($this->getProductsDiscounted() as $p){
  314. if($p->getProduct() == $product)
  315. return true;
  316. }
  317. return false;
  318. }
  319. public function getCartDiscount(Cart $cart) {
  320. if(!$this->checkRequirements($cart)){
  321. return false;
  322. }
  323. if($this->getType() == self::TYPE_PERCENT){
  324. return -1 * $cart->getTotalProducts()- $cart->getTotalProducts()*$this->percentDiscount/100;
  325. }
  326. if($this->getType() == self::TYPE_AMOUNT){
  327. return -1 * $this->amountDiscount;
  328. }
  329. return 0;
  330. }
  331. public function getProductDiscountByCart(Product $product, ?Cart $cart, $additionnalDiscount = 0) {
  332. if(!is_null($cart) && !$this->checkRequirements($cart)){
  333. return 0;
  334. }
  335. $qty = is_null($cart) ? 1 : $cart->getItemQuantityByProduct($product);
  336. if($this->getType() == self::TYPE_PERCENT){
  337. return $product->getPrice()*$this->percentDiscount/100 + $additionnalDiscount;
  338. }else if($this->getType() == self::TYPE_AMOUNT){
  339. return $this->amountDiscount - $additionnalDiscount;
  340. }else if(($this->getType() == self::TYPE_PERCENT_SOLEIL) && $product->isSoleil()){
  341. return $product->getPrice()*$this->percentDiscount/100 + $additionnalDiscount;
  342. }else if(($this->getType() == self::TYPE_PERCENT_BY_QTY)){
  343. if($qty>=20){
  344. return $product->getPrice() * 0.3 + $additionnalDiscount;
  345. }else if($qty>=15){
  346. return $product->getPrice() * 0.25 + $additionnalDiscount;
  347. }else if($qty>=10){
  348. return $product->getPrice() * 0.20 + $additionnalDiscount;
  349. }else if($qty>=5){
  350. return $product->getPrice() * 0.15 + $additionnalDiscount;
  351. }
  352. }else if(($qty > 0) && ($this->getType() == self::TYPE_OFFERED)){
  353. return 0;
  354. }else if($this->getType() == self::TYPE_PRICE){
  355. $discountedProduct = $this->getProductDiscounted($product);
  356. if($discountedProduct && $discountedProduct->getPrice() && ($discountedProduct->getPrice() < $product->getPrice())) {
  357. return $product->getPrice()-$discountedProduct->getPrice();
  358. }
  359. }
  360. return 0;
  361. }
  362. public function getProductsDiscountedQty(Cart $cart) {
  363. $qty = 0;
  364. foreach($this->productsDiscounted as $pDiscounted) {
  365. if($cart->hasProduct($pDiscounted->getProduct())) {
  366. $qty += $cart->getItemQuantityByProduct($pDiscounted->getProduct());
  367. }
  368. }
  369. return $qty;
  370. }
  371. public function getNbProductsOffered(Cart $cart, ?Product $product = null) {
  372. if($this->getType() != self::TYPE_OFFERED) {
  373. return 0;
  374. }
  375. if($product && $this->hasDiscountedProduct($product)) {
  376. $qtyInCart = $cart->getItemQuantityByProduct($product);
  377. $groups = floor($qtyInCart / $this->getQtyRequested());
  378. return $groups * $this->getQtyOffered();
  379. }/*else{
  380. $qtyInCart = $this->getProductsDiscountedQty($cart);
  381. $groups = floor($qtyInCart / $this->getQtyRequested());
  382. return $groups * $this->getQtyOffered();
  383. }*/
  384. }
  385. public function checkRequirements(Cart $cart) {
  386. if($this->amountVivogRequested > 0){
  387. return $cart->getVivogTotal() >= $this->amountVivogRequested;
  388. }
  389. if(($this->amountSoleilRequested > 0) && ($cart->getSoleilTotal() >= $this->amountSoleilRequested)){
  390. return true;
  391. }
  392. if(($this->amountRequested > 0) && ($cart->getTotalProducts() >= $this->amountRequested)){
  393. return true;
  394. }
  395. $list = count($this->productsRequested) == 0 ? $this->productsDiscounted : $this->productsRequested;
  396. // die($this->qtyRequested . ' ' . count($this->productsRequested) . ' ' . count($this->productsDiscounted));
  397. if(($this->qtyRequested > 0) && $list){
  398. $cpt = 0;
  399. foreach($list as $requested) {
  400. $cpt += $cart->getItemQuantityByProduct($requested->getProduct());
  401. }
  402. return $cpt >= $this->qtyRequested;
  403. }
  404. if($this->getType() == self::TYPE_PERCENT && ($this->amountRequested==0 && $this->amountSoleilRequested == 0)){
  405. return true;
  406. }
  407. if($this->getType() == self::TYPE_PERCENT_SOLEIL && ($this->amountRequested==0 && $this->amountSoleilRequested == 0)){
  408. return true;
  409. }
  410. if($this->getType() == self::TYPE_PRICE){
  411. return true;
  412. }
  413. if($this->getType() == self::TYPE_PERCENT_BY_QTY){
  414. return true;
  415. }
  416. return false;
  417. }
  418. public function getMarketingRuleDescription($lang='fr') : ?MarketingRuleDescription {
  419. foreach($this->getDescriptions() as $desc){
  420. if($desc->getLanguage()->getCode() == $lang)
  421. return $desc;
  422. }
  423. return null;
  424. }
  425. public function isVisible() {
  426. return !empty($this->visible);
  427. }
  428. public function isTypeOffered() {
  429. return $this->getType() == self::TYPE_OFFERED;
  430. }
  431. }