<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Product;
/**
* @ORM\Table(name="marketing_rules")
* @ORM\Entity(repositoryClass="App\Repository\MarketingRuleRepository")
* @ORM\HasLifecycleCallbacks()
*/
class MarketingRule extends TranslatedEntity
{
protected $tranlatedEntity = 'MarketingRuleDescription';
const TYPE_PERCENT = 'percent';
const TYPE_PERCENT_SOLEIL = 'percent-soleil';
const TYPE_AMOUNT = 'amount';
const TYPE_OFFERED = 'offered';
const TYPE_PRICE = 'price';
const TYPE_PERCENT_BY_QTY = 'percent-qty';
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \App\Entity\Customer
*
* @ORM\ManyToOne(targetEntity="App\Entity\Customer")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="customers_id", nullable=true)
*/
private $customer;
/**
* @var array
*
* @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleProductDiscounted", mappedBy="marketingRule", cascade={"persist", "remove"})
*/
private $productsDiscounted;
/**
* @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleDescription", mappedBy="marketingRule")
*/
private $descriptions = [];
/**
* @var \DateTime|null
*
* @ORM\Column(name="date_from", type="datetime", nullable=true)
*/
private $dateFrom;
/**
* @var \DateTime|null
*
* @ORM\Column(name="date_to", type="datetime", nullable=true)
*/
private $dateTo;
/**
* @var int
*
* @ORM\Column(name="visible", type="integer", nullable=true)
*/
private $visible;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, nullable=true)
*/
private $title = '';
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=true)
*/
private $description = '';
/**
* @var string
*
* @ORM\Column(name="type", type="string", length=50, nullable=false)
*/
private $type = self::TYPE_AMOUNT;
/**
* @var float
*
* @ORM\Column(name="percent_discount", type="decimal", precision=15, scale=4, nullable=true)
*/
private $percentDiscount = '0.0000';
/**
* @var float
*
* @ORM\Column(name="amount_discount", type="decimal", precision=15, scale=4, nullable=true)
*/
private $amountDiscount = '0.0000';
/**
* @var int
*
* @ORM\Column(name="qty_requested", type="integer", nullable=true)
*/
private $qtyRequested = '0';
/**
* @var ?float
*
* @ORM\Column(name="amount_requested", type="decimal", precision=15, scale=4,nullable=true)
*/
private $amountRequested = '0.0000';
/**
* @var ?float
*
* @ORM\Column(name="amount_soleil_requested", type="decimal", precision=15, scale=4, nullable=true)
*/
private $amountSoleilRequested = '0.0000';
/**
* @var ?float
*
* @ORM\Column(name="amount_vivog_requested", type="decimal", precision=15, scale=4, nullable=true)
*/
private $amountVivogRequested = '0.0000';
/**
* @var array
*
* @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleProductRequested", mappedBy="marketingRule", cascade={"persist", "remove"})
*/
private $productsRequested;
/**
* @var int
*
* @ORM\Column(name="qty_offered", type="integer", nullable=true)
*/
private $qtyOffered = 0;
/**
* @var boolean
*
* @ORM\Column(name="active", type="boolean", options={"default"=false})
*/
private $active = false;
/**
* @var boolean
*
* @ORM\Column(name="skip_soleil", type="boolean", options={"default"=true})
*/
private $skipSoleilDiscount = true;
/**
* @var array
*
* @ORM\OneToMany(targetEntity="App\Entity\Coupon", mappedBy="marketingRule", cascade={"persist", "remove"})
*/
private $coupons;
/**
* @var array
*
* @ORM\OneToMany(targetEntity="App\Entity\MarketingRuleCustomer", mappedBy="marketingRule", cascade={"persist", "remove"})
*/
private $customers;
public function __construct()
{
$this->productsDiscounted = new \Doctrine\Common\Collections\ArrayCollection();
$this->productsRequested = new \Doctrine\Common\Collections\ArrayCollection();
$this->coupons = new \Doctrine\Common\Collections\ArrayCollection();
$this->customers = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId(): int {
return $this->id;
}
public function getCustomer(): \App\Entity\Customer {
return $this->customer;
}
public function getProductsDiscounted() {
return $this->productsDiscounted;
}
public function getProductDiscounted(Product $product) {
foreach($this->getProductsDiscounted() as $pd) {
if($pd->getProduct() == $product)
return $pd;
}
return null;
}
public function getDateFrom(): ?\DateTime {
return $this->dateFrom;
}
public function getDateTo(): ?\DateTime {
return $this->dateTo;
}
public function getVisible(): int {
return $this->visible;
}
public function getTitle(): string {
return $this->title;
}
public function getDescription(): string {
return $this->description;
}
public function getType(): string {
return $this->type;
}
public function getPercentDiscount(): float {
return $this->percentDiscount;
}
public function getAmountDiscount(): float {
return $this->amountDiscount;
}
public function getAmountRequested(): ?float {
return $this->amountRequested;
}
public function getAmountSoleilRequested(): ?float {
return $this->amountSoleilRequested;
}
public function getAmountVivogRequested(): ?float {
return $this->amountVivogRequested;
}
public function getQtyRequested(): int {
return $this->qtyRequested;
}
public function getProductsRequested() {
return $this->productsRequested;
}
public function getQtyOffered(): int {
return $this->qtyOffered;
}
public function getActive(): bool {
return $this->active;
}
public function getCoupons() {
return $this->coupons;
}
public function getCustomers() {
return $this->customers;
}
public function getDescriptions() {
return $this->descriptions;
}
public function getSkipSoleilDiscount(): bool {
return $this->skipSoleilDiscount;
}
public function setId(int $id): void {
$this->id = $id;
}
public function setCustomer(\App\Entity\Customer $customer): void {
$this->customer = $customer;
}
public function setProductsDiscounted(array $productsDiscounted): void {
$this->productsDiscounted = $productsDiscounted;
}
public function setDateFrom(?\DateTime $dateFrom): void {
$this->dateFrom = $dateFrom;
}
public function setDateTo(?\DateTime $dateTo): void {
if($dateTo) {
$dateTo->setTime(23, 59, 59);
}
$this->dateTo = $dateTo;
}
public function setVisible(int $visible): void {
$this->visible = $visible;
}
public function setTitle(string $title): void {
$this->title = $title;
}
public function setDescription(string $description): void {
$this->description = $description;
}
public function setType(string $type): void {
$this->type = $type;
}
public function setPercentDiscount(float $percentDiscount): void {
$this->percentDiscount = $percentDiscount;
}
public function setAmountDiscount(float $amountDiscount): void {
$this->amountDiscount = $amountDiscount;
}
public function setAmountRequested(float $amountRequested): void {
$this->amountRequested = $amountRequested;
}
public function setAmountSoleilRequested(float $amountSoleilRequested): void {
$this->amountSoleilRequested = $amountSoleilRequested;
}
public function setAmountVivogRequested(?float $amountVivogRequested): void {
$this->amountVivogRequested = $amountVivogRequested;
}
public function setQtyRequested(int $qtyRequested): void {
$this->qtyRequested = $qtyRequested;
}
public function setProductsRequested(array $productsRequested): void {
$this->productsRequested = $productsRequested;
}
public function setQtyOffered(int $qtyOffered): void {
$this->qtyOffered = $qtyOffered;
}
public function setActive(bool $active): void {
$this->active = $active;
}
public function setCoupons(array $coupons): void {
$this->coupons = $coupons;
}
public function setCustomers(array $customers): void {
$this->customers = $customers;
}
public function setDescriptions($descriptions): void {
$this->descriptions = $descriptions;
}
public function setSkipSoleilDiscount(bool $skipSoleilDiscount): void {
$this->skipSoleilDiscount = $skipSoleilDiscount;
}
public function hasCustomer(Customer $customer, $strict = false) {
$output = false;
$requiredCustomers = $this->getCustomers();
if(!$strict && (count($requiredCustomers)==0))
return true;
foreach($this->getCustomers() as $c){
if($c->getCustomer() == $customer)
return true;
}
return false;
}
public function hasDiscountedProduct(Product $product) {
foreach($this->getProductsDiscounted() as $p){
if($p->getProduct() == $product)
return true;
}
return false;
}
public function getCartDiscount(Cart $cart) {
if(!$this->checkRequirements($cart)){
return false;
}
if($this->getType() == self::TYPE_PERCENT){
return -1 * $cart->getTotalProducts()- $cart->getTotalProducts()*$this->percentDiscount/100;
}
if($this->getType() == self::TYPE_AMOUNT){
return -1 * $this->amountDiscount;
}
return 0;
}
public function getProductDiscountByCart(Product $product, ?Cart $cart, $additionnalDiscount = 0) {
if(!is_null($cart) && !$this->checkRequirements($cart)){
return 0;
}
$qty = is_null($cart) ? 1 : $cart->getItemQuantityByProduct($product);
if($this->getType() == self::TYPE_PERCENT){
return $product->getPrice()*$this->percentDiscount/100 + $additionnalDiscount;
}else if($this->getType() == self::TYPE_AMOUNT){
return $this->amountDiscount - $additionnalDiscount;
}else if(($this->getType() == self::TYPE_PERCENT_SOLEIL) && $product->isSoleil()){
return $product->getPrice()*$this->percentDiscount/100 + $additionnalDiscount;
}else if(($this->getType() == self::TYPE_PERCENT_BY_QTY)){
if($qty>=20){
return $product->getPrice() * 0.3 + $additionnalDiscount;
}else if($qty>=15){
return $product->getPrice() * 0.25 + $additionnalDiscount;
}else if($qty>=10){
return $product->getPrice() * 0.20 + $additionnalDiscount;
}else if($qty>=5){
return $product->getPrice() * 0.15 + $additionnalDiscount;
}
}else if(($qty > 0) && ($this->getType() == self::TYPE_OFFERED)){
return 0;
}else if($this->getType() == self::TYPE_PRICE){
$discountedProduct = $this->getProductDiscounted($product);
if($discountedProduct && $discountedProduct->getPrice() && ($discountedProduct->getPrice() < $product->getPrice())) {
return $product->getPrice()-$discountedProduct->getPrice();
}
}
return 0;
}
public function getProductsDiscountedQty(Cart $cart) {
$qty = 0;
foreach($this->productsDiscounted as $pDiscounted) {
if($cart->hasProduct($pDiscounted->getProduct())) {
$qty += $cart->getItemQuantityByProduct($pDiscounted->getProduct());
}
}
return $qty;
}
public function getNbProductsOffered(Cart $cart, ?Product $product = null) {
if($this->getType() != self::TYPE_OFFERED) {
return 0;
}
if($product && $this->hasDiscountedProduct($product)) {
$qtyInCart = $cart->getItemQuantityByProduct($product);
$groups = floor($qtyInCart / $this->getQtyRequested());
return $groups * $this->getQtyOffered();
}/*else{
$qtyInCart = $this->getProductsDiscountedQty($cart);
$groups = floor($qtyInCart / $this->getQtyRequested());
return $groups * $this->getQtyOffered();
}*/
}
public function checkRequirements(Cart $cart) {
if($this->amountVivogRequested > 0){
return $cart->getVivogTotal() >= $this->amountVivogRequested;
}
if(($this->amountSoleilRequested > 0) && ($cart->getSoleilTotal() >= $this->amountSoleilRequested)){
return true;
}
if(($this->amountRequested > 0) && ($cart->getTotalProducts() >= $this->amountRequested)){
return true;
}
$list = count($this->productsRequested) == 0 ? $this->productsDiscounted : $this->productsRequested;
// die($this->qtyRequested . ' ' . count($this->productsRequested) . ' ' . count($this->productsDiscounted));
if(($this->qtyRequested > 0) && $list){
$cpt = 0;
foreach($list as $requested) {
$cpt += $cart->getItemQuantityByProduct($requested->getProduct());
}
return $cpt >= $this->qtyRequested;
}
if($this->getType() == self::TYPE_PERCENT && ($this->amountRequested==0 && $this->amountSoleilRequested == 0)){
return true;
}
if($this->getType() == self::TYPE_PERCENT_SOLEIL && ($this->amountRequested==0 && $this->amountSoleilRequested == 0)){
return true;
}
if($this->getType() == self::TYPE_PRICE){
return true;
}
if($this->getType() == self::TYPE_PERCENT_BY_QTY){
return true;
}
return false;
}
public function getMarketingRuleDescription($lang='fr') : ?MarketingRuleDescription {
foreach($this->getDescriptions() as $desc){
if($desc->getLanguage()->getCode() == $lang)
return $desc;
}
return null;
}
public function isVisible() {
return !empty($this->visible);
}
public function isTypeOffered() {
return $this->getType() == self::TYPE_OFFERED;
}
}