modules/CDev/SalesTax/src/Model/Tax/Rate.php line 11

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace CDev\SalesTax\Model\Tax;
  7. use Doctrine\ORM\Mapping as ORM;
  8. /**
  9.  * Rate
  10.  *
  11.  * @ORM\Entity
  12.  * @ORM\Table (name="sales_tax_rates")
  13.  */
  14. class Rate extends \XLite\Model\AEntity
  15. {
  16.     /**
  17.      * Rate type codes
  18.      */
  19.     public const TYPE_ABSOLUTE 'a';
  20.     public const TYPE_PERCENT  'p';
  21.     /**
  22.      * Taxable bases
  23.      */
  24.     public const TAXBASE_SUBTOTAL                     'ST';
  25.     public const TAXBASE_DISCOUNTED_SUBTOTAL          'DST';
  26.     public const TAXBASE_SUBTOTAL_SHIPPING            'ST+SH';
  27.     public const TAXBASE_DISCOUNTED_SUBTOTAL_SHIPPING 'DST+SH';
  28.     public const TAXBASE_SHIPPING                     'SH';
  29.     public const TAXBASE_PERSONAL                     'P';
  30.     /**
  31.      * Rate unique ID
  32.      *
  33.      * @var integer
  34.      *
  35.      * @ORM\Id
  36.      * @ORM\GeneratedValue (strategy="AUTO")
  37.      * @ORM\Column         (type="integer", options={ "unsigned": true })
  38.      */
  39.     protected $id;
  40.     /**
  41.      * Value
  42.      *
  43.      * @var float
  44.      *
  45.      * @ORM\Column (type="decimal", precision=14, scale=4)
  46.      */
  47.     protected $value 0.0000;
  48.     /**
  49.      * Type
  50.      *
  51.      * @var string
  52.      *
  53.      * @ORM\Column (type="string", options={ "fixed": true }, length=1)
  54.      */
  55.     protected $type self::TYPE_PERCENT;
  56.     /**
  57.      * Position
  58.      *
  59.      * @var integer
  60.      *
  61.      * @ORM\Column (type="integer")
  62.      */
  63.     protected $position 0;
  64.     /**
  65.      * Tax (relation)
  66.      *
  67.      * @var \CDev\SalesTax\Model\Tax
  68.      *
  69.      * @ORM\ManyToOne  (targetEntity="CDev\SalesTax\Model\Tax", inversedBy="rates")
  70.      * @ORM\JoinColumn (name="tax_id", referencedColumnName="id", onDelete="CASCADE")
  71.      */
  72.     protected $tax;
  73.     /**
  74.      * Zone (relation)
  75.      *
  76.      * @var \XLite\Model\Zone
  77.      *
  78.      * @ORM\ManyToOne  (targetEntity="XLite\Model\Zone")
  79.      * @ORM\JoinColumn (name="zone_id", referencedColumnName="zone_id", onDelete="CASCADE")
  80.      */
  81.     protected $zone;
  82.     /**
  83.      * Tax class (relation)
  84.      *
  85.      * @var \XLite\Model\TaxClass
  86.      *
  87.      * @ORM\ManyToOne  (targetEntity="XLite\Model\TaxClass")
  88.      * @ORM\JoinColumn (name="tax_class_id", referencedColumnName="id", onDelete="CASCADE")
  89.      */
  90.     protected $taxClass;
  91.     /**
  92.      * Membership (relation)
  93.      *
  94.      * @var \XLite\Model\Membership
  95.      *
  96.      * @ORM\ManyToOne  (targetEntity="XLite\Model\Membership")
  97.      * @ORM\JoinColumn (name="membership_id", referencedColumnName="membership_id", onDelete="CASCADE")
  98.      */
  99.     protected $membership;
  100.     /**
  101.      * For product without tax class
  102.      *
  103.      * @var boolean
  104.      *
  105.      * @ORM\Column (type="boolean")
  106.      */
  107.     protected $noTaxClass false;
  108.     /**
  109.      * Taxable base
  110.      *
  111.      * @var string
  112.      *
  113.      * @ORM\Column (type="string", length=16)
  114.      */
  115.     protected $taxableBase self::TAXBASE_SUBTOTAL;
  116.     /**
  117.      * Check if rate is applied by specified zones and membership
  118.      *
  119.      * @param array                   $zones      Zone id list
  120.      * @param \XLite\Model\Membership $membership Membership OPTIONAL
  121.      * @param \XLite\Model\TaxClass   $taxClass   Tax class OPTIONAL
  122.      *
  123.      * @return boolean
  124.      */
  125.     public function isApplied(
  126.         array $zones,
  127.         \XLite\Model\Membership $membership null,
  128.         \XLite\Model\TaxClass $taxClass null
  129.     ) {
  130.         $result $this->getZone() && in_array($this->getZone()->getZoneId(), $zones);
  131.         if (
  132.             $result
  133.             && !\XLite\Core\Config::getInstance()->CDev->SalesTax->ignore_memberships
  134.             && $this->getMembership()
  135.         ) {
  136.             $result $membership && $this->getMembership()->getMembershipId() == $membership->getMembershipId();
  137.         }
  138.         return $result;
  139.     }
  140.     /**
  141.      * Check if rate is applied to object
  142.      *
  143.      * @param mixed $object
  144.      *
  145.      * @return boolean
  146.      */
  147.     public function isAppliedToObject($object)
  148.     {
  149.         return (
  150.             $this->getNoTaxClass()
  151.             && !$object->getTaxClass()
  152.         )
  153.         || (
  154.             !$this->getNoTaxClass()
  155.             && (
  156.                 !$this->getTaxClass()
  157.                 || (
  158.                     $object->getTaxClass()
  159.                     && $object->getTaxClass()->getId() == $this->getTaxClass()->getId()
  160.                 )
  161.             )
  162.         );
  163.     }
  164.     // {{{ Calculation
  165.     /**
  166.      * Calculate
  167.      *
  168.      * @param array $items Items
  169.      *
  170.      * @return float
  171.      */
  172.     public function calculate(array $items)
  173.     {
  174.         $cost 0;
  175.         if ($this->getBasis($items) && $this->getQuantity($items)) {
  176.             $cost $this->getType() == static::TYPE_PERCENT
  177.                 $this->calculatePercent($items)
  178.                 : $this->calculateAbsolute($items);
  179.         }
  180.         return $cost;
  181.     }
  182.     /**
  183.      * Calculate shipping tax cost
  184.      *
  185.      * @param float $shippingCost Shipping cost
  186.      *
  187.      * @return float
  188.      */
  189.     public function calculateShippingTax($shippingCost)
  190.     {
  191.         $cost 0;
  192.         if ($shippingCost) {
  193.             $cost $this->getType() == static::TYPE_PERCENT
  194.                 $shippingCost $this->getValue() / 100
  195.                 $this->getValue();
  196.         }
  197.         return $cost;
  198.     }
  199.     /**
  200.      * Calculate surcharges tax cost
  201.      *
  202.      * @param $surchargesCost
  203.      *
  204.      * @return float
  205.      */
  206.     public function calculateSurchargesTax($surchargesCost)
  207.     {
  208.         $cost 0;
  209.         if ($surchargesCost) {
  210.             $cost $this->getType() == static::TYPE_PERCENT
  211.                 $surchargesCost $this->getValue() / 100
  212.                 $this->getValue();
  213.         }
  214.         return $cost;
  215.     }
  216.     /**
  217.      * Get list of allowed taxable base types
  218.      *
  219.      * @return array
  220.      */
  221.     protected static function getAllowedTaxableBaseTypes()
  222.     {
  223.         return [
  224.             static::TAXBASE_SUBTOTAL,
  225.             static::TAXBASE_DISCOUNTED_SUBTOTAL,
  226.             static::TAXBASE_SUBTOTAL_SHIPPING,
  227.             static::TAXBASE_DISCOUNTED_SUBTOTAL_SHIPPING,
  228.             static::TAXBASE_SHIPPING,
  229.         ];
  230.     }
  231.     /**
  232.      * Get taxable base type
  233.      *
  234.      * @return string
  235.      */
  236.     public function getTaxableBaseType()
  237.     {
  238.         $result \XLite\Core\Config::getInstance()->CDev->SalesTax->taxableBase;
  239.         if (!in_array($result, static::getAllowedTaxableBaseTypes())) {
  240.             $result $this->getTaxableBase();
  241.         }
  242.         return $result;
  243.     }
  244.     /**
  245.      * Get basis
  246.      *
  247.      * @param array $items Items
  248.      *
  249.      * @return float
  250.      */
  251.     protected function getBasis(array $items)
  252.     {
  253.         $basis 0;
  254.         foreach ($items as $item) {
  255.             $basis += $this->getItemBasis($item);
  256.         }
  257.         return $basis;
  258.     }
  259.     /**
  260.      * Get item basis
  261.      *
  262.      * @param \XLite\Model\OrderItem $item Order item
  263.      *
  264.      * @return float
  265.      */
  266.     protected function getItemBasis($item)
  267.     {
  268.         $basis 0;
  269.         $formulaParts explode('+'$this->getTaxableBaseType());
  270.         foreach ($formulaParts as $part) {
  271.             switch ($part) {
  272.                 case 'ST':
  273.                     $basis += $item->getSubtotal();
  274.                     break;
  275.                 case 'DST':
  276.                     $basis += $item->getDiscountedSubtotal();
  277.                     break;
  278.                 case 'SH':
  279.                     $basis += $item->getShippingCost();
  280.                     break;
  281.             }
  282.         }
  283.         return $basis;
  284.     }
  285.     /**
  286.      * Get quantity
  287.      *
  288.      * @param array $items Items
  289.      *
  290.      * @return integer
  291.      */
  292.     protected function getQuantity(array $items)
  293.     {
  294.         $quantity 0;
  295.         foreach ($items as $item) {
  296.             $quantity += $item->getAmount();
  297.         }
  298.         return $quantity;
  299.     }
  300.     /**
  301.      * calculateExcludePercent
  302.      *
  303.      * @param array $items ____param_comment____
  304.      *
  305.      * @return array
  306.      */
  307.     protected function calculatePercent(array $items)
  308.     {
  309.         return $this->getBasis($items) * $this->getValue() / 100;
  310.     }
  311.     /**
  312.      * Calculate tax as percent
  313.      *
  314.      * @param array $items Items
  315.      *
  316.      * @return array
  317.      */
  318.     protected function calculateAbsolute(array $items)
  319.     {
  320.         return $this->getValue() * $this->getQuantity($items);
  321.     }
  322.     // }}}
  323.     /**
  324.      * Get id
  325.      *
  326.      * @return integer
  327.      */
  328.     public function getId()
  329.     {
  330.         return $this->id;
  331.     }
  332.     /**
  333.      * Set value
  334.      *
  335.      * @param float $value
  336.      * @return Rate
  337.      */
  338.     public function setValue($value)
  339.     {
  340.         $this->value $value;
  341.         return $this;
  342.     }
  343.     /**
  344.      * Get value
  345.      *
  346.      * @return float
  347.      */
  348.     public function getValue()
  349.     {
  350.         return $this->value;
  351.     }
  352.     /**
  353.      * Set type
  354.      *
  355.      * @param string $type
  356.      * @return Rate
  357.      */
  358.     public function setType($type)
  359.     {
  360.         $this->type $type;
  361.         return $this;
  362.     }
  363.     /**
  364.      * Get type
  365.      *
  366.      * @return string
  367.      */
  368.     public function getType()
  369.     {
  370.         return $this->type;
  371.     }
  372.     /**
  373.      * Set position
  374.      *
  375.      * @param integer $position
  376.      * @return Rate
  377.      */
  378.     public function setPosition($position)
  379.     {
  380.         $this->position $position;
  381.         return $this;
  382.     }
  383.     /**
  384.      * Get position
  385.      *
  386.      * @return integer
  387.      */
  388.     public function getPosition()
  389.     {
  390.         return $this->position;
  391.     }
  392.     /**
  393.      * Set noTaxClass
  394.      *
  395.      * @param boolean $noTaxClass
  396.      * @return Rate
  397.      */
  398.     public function setNoTaxClass($noTaxClass)
  399.     {
  400.         $this->noTaxClass $noTaxClass;
  401.         return $this;
  402.     }
  403.     /**
  404.      * Get noTaxClass
  405.      *
  406.      * @return boolean
  407.      */
  408.     public function getNoTaxClass()
  409.     {
  410.         return $this->noTaxClass;
  411.     }
  412.     /**
  413.      * Set taxableBase
  414.      *
  415.      * @param string $taxableBase
  416.      * @return Rate
  417.      */
  418.     public function setTaxableBase($taxableBase)
  419.     {
  420.         $this->taxableBase $taxableBase;
  421.         return $this;
  422.     }
  423.     /**
  424.      * Get taxableBase
  425.      *
  426.      * @return string
  427.      */
  428.     public function getTaxableBase()
  429.     {
  430.         return $this->taxableBase;
  431.     }
  432.     /**
  433.      * Set tax
  434.      *
  435.      * @param \CDev\SalesTax\Model\Tax $tax
  436.      * @return Rate
  437.      */
  438.     public function setTax(\CDev\SalesTax\Model\Tax $tax null)
  439.     {
  440.         $this->tax $tax;
  441.         return $this;
  442.     }
  443.     /**
  444.      * Get tax
  445.      *
  446.      * @return \CDev\SalesTax\Model\Tax
  447.      */
  448.     public function getTax()
  449.     {
  450.         return $this->tax;
  451.     }
  452.     /**
  453.      * Set zone
  454.      *
  455.      * @param \XLite\Model\Zone $zone
  456.      * @return Rate
  457.      */
  458.     public function setZone(\XLite\Model\Zone $zone null)
  459.     {
  460.         $this->zone $zone;
  461.         return $this;
  462.     }
  463.     /**
  464.      * Get zone
  465.      *
  466.      * @return \XLite\Model\Zone
  467.      */
  468.     public function getZone()
  469.     {
  470.         return $this->zone;
  471.     }
  472.     /**
  473.      * Set taxClass
  474.      *
  475.      * @param \XLite\Model\TaxClass $taxClass
  476.      * @return Rate
  477.      */
  478.     public function setTaxClass(\XLite\Model\TaxClass $taxClass null)
  479.     {
  480.         $this->taxClass $taxClass;
  481.         return $this;
  482.     }
  483.     /**
  484.      * Get taxClass
  485.      *
  486.      * @return \XLite\Model\TaxClass
  487.      */
  488.     public function getTaxClass()
  489.     {
  490.         return $this->taxClass;
  491.     }
  492.     /**
  493.      * Set membership
  494.      *
  495.      * @param \XLite\Model\Membership $membership
  496.      * @return Rate
  497.      */
  498.     public function setMembership(\XLite\Model\Membership $membership null)
  499.     {
  500.         $this->membership $membership;
  501.         return $this;
  502.     }
  503.     /**
  504.      * Get membership
  505.      *
  506.      * @return \XLite\Model\Membership
  507.      */
  508.     public function getMembership()
  509.     {
  510.         return $this->membership;
  511.     }
  512. }