328 lines
13KB

  1. <?php
  2. namespace Lc\ShopBundle\Services ;
  3. use Doctrine\Common\Collections\Collection;
  4. use Lc\ShopBundle\Context\OrderProductInterface;
  5. use Lc\ShopBundle\Context\OrderShopInterface;
  6. use Lc\ShopBundle\Context\ProductFamilyInterface;
  7. use Lc\ShopBundle\Context\ProductInterface;
  8. use Lc\ShopBundle\Context\ProductPropertyInterface;
  9. use Lc\ShopBundle\Context\ReductionCatalogInterface;
  10. class PriceUtils
  11. {
  12. public function getPrice($entity)
  13. {
  14. if($entity instanceof ProductPropertyInterface) {
  15. if($entity->getBehaviorPriceInherited() == 'by-piece') {
  16. return $entity->getPriceInherited() ;
  17. }
  18. elseif($entity->getBehaviorPriceInherited() == 'by-reference-unit') {
  19. if($entity->getQuantityInherited() > 0) {
  20. return $entity->getPriceByRefUnitInherited() * ($entity->getQuantityInherited() / $entity->getUnitInherited()->getCoefficient()) ;
  21. }
  22. }
  23. }
  24. if($entity instanceof OrderProductInterface) {
  25. return $entity->getPrice() ;
  26. }
  27. return null ;
  28. }
  29. public function getPriceWithTax($entity)
  30. {
  31. return $this->applyTax(
  32. $this->getPrice($entity),
  33. $entity->getTaxRateInherited()->getValue()
  34. ) ;
  35. }
  36. public function getPriceWithTaxAndReduction($entity)
  37. {
  38. return $this->getPriceWithTaxAndReductionCatalog(
  39. $entity,
  40. $this->getPrice($entity),
  41. $this->getPriceWithTax($entity)
  42. );
  43. }
  44. public function getPriceByRefUnit($entity)
  45. {
  46. if($entity instanceof ProductPropertyInterface) {
  47. if($entity->getBehaviorPriceInherited() == 'by-piece') {
  48. return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityInherited() ;
  49. }
  50. elseif($entity->getBehaviorPriceInherited() == 'by-reference-unit') {
  51. return $entity->getPriceByRefUnitInherited() ;
  52. }
  53. }
  54. if($entity instanceof OrderProductInterface) {
  55. return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityProduct() ;
  56. }
  57. return null ;
  58. }
  59. public function getPriceByRefUnitWithTax($entity)
  60. {
  61. return $this->applyTax(
  62. $this->getPriceByRefUnit($entity),
  63. $entity->getTaxRateInherited()->getValue()
  64. ) ;
  65. }
  66. public function getPriceByRefUnitWithTaxAndReduction($entity)
  67. {
  68. return $this->getPriceWithTaxAndReductionCatalog(
  69. $entity,
  70. $this->getPriceByRefUnit($entity),
  71. $this->getPriceByRefUnitWithTax($entity)
  72. );
  73. }
  74. public function getTotal($entity)
  75. {
  76. if($entity instanceof OrderProductInterface) {
  77. return $entity->getQuantityOrder() * $this->getPrice($entity) ;
  78. }
  79. if($entity instanceof OrderShopInterface) {
  80. $total = 0 ;
  81. foreach($entity->getOrderProducts() as $orderProduct) {
  82. $total += $this->getTotal($orderProduct) ;
  83. }
  84. return $total ;
  85. }
  86. return null ;
  87. }
  88. public function getTotalWithTax($entity)
  89. {
  90. if($entity instanceof OrderProductInterface) {
  91. return $this->applyTax(
  92. $this->getTotal($entity),
  93. $entity->getTaxRateInherited()->getValue()
  94. ) ;
  95. }
  96. if($entity instanceof OrderShopInterface) {
  97. $total = 0 ;
  98. foreach($entity->getOrderProducts() as $orderProduct) {
  99. $total += $this->getTotalWithTax($orderProduct) ;
  100. }
  101. return $total ;
  102. }
  103. //C'est bizzare ce truc là
  104. //if($entity instanceof OrderShopInterface) {
  105. // return $this->getTotalOrderProducts($entity->getOrderProducts(), true) ;
  106. //}
  107. return null ;
  108. }
  109. public function getTotalWithTaxAndReduction($entity)
  110. {
  111. if($entity instanceof OrderProductInterface) {
  112. return $this->getPriceWithTaxAndReductionCatalog(
  113. $entity,
  114. $this->getTotal($entity),
  115. $this->getTotalWithTax($entity)
  116. ) ;
  117. }
  118. if($entity instanceof OrderShopInterface) {
  119. return $this->getTotalOrderProductsWithTaxAndReduction($entity->getOrderProducts(), true, true) ;
  120. }
  121. }
  122. public function getTotalWithReduction($entity)
  123. {
  124. if($entity instanceof OrderProductInterface) {
  125. return $this->getPriceWithReductionCatalog(
  126. $entity,
  127. $this->getTotal($entity),
  128. $this->getTotalWithTax($entity)
  129. ) ;
  130. }
  131. if($entity instanceof OrderShopInterface) {
  132. return $this->getTotalOrderProductsWithReduction($entity->getOrderProducts(), true, true) ;
  133. }
  134. }
  135. public function getTotalOrderProducts($entity)
  136. {
  137. return $this->getSumOrderProductsDispatch($entity) ;
  138. }
  139. public function getTotalOrderProductsWithTax($entity)
  140. {
  141. return $this->getSumOrderProductsDispatch($entity, true) ;
  142. }
  143. public function getTotalOrderProductsWithReduction($entity)
  144. {
  145. return $this->getSumOrderProductsDispatch($entity, false, true) ;
  146. }
  147. public function getTotalOrderProductsWithTaxAndReduction($entity)
  148. {
  149. return $this->getSumOrderProductsDispatch($entity, true, true) ;
  150. }
  151. public function getSumOrderProductsDispatch($entity, $withTax = false, $withReduction = false)
  152. {
  153. if($entity instanceof OrderShopInterface) {
  154. return $this->getSumOrderProducts($entity->getOrderProducts(), $withTax, $withReduction) ;
  155. }
  156. if($entity instanceof Collection || is_array($entity)) {
  157. return $this->getSumOrderProducts($entity, $withTax, $withReduction) ;
  158. }
  159. }
  160. public function getSumOrderProducts($orderProducts, $withTax = false, $withReduction = false)
  161. {
  162. $total = 0 ;
  163. foreach($orderProducts as $orderProduct) {
  164. if($withTax && $withReduction) {
  165. $total += $this->getTotalWithTaxAndReduction($orderProduct) ;
  166. }
  167. elseif($withTax) {
  168. $total += $this->getTotalWithTax($orderProduct) ;
  169. }
  170. elseif($withReduction) {
  171. $total += $this->getTotalWithReduction($orderProduct) ;
  172. }
  173. else {
  174. $total += $this->getTotal($orderProduct) ;
  175. }
  176. }
  177. return $total ;
  178. }
  179. public function getPriceWithTaxAndReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null)
  180. {
  181. return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, true) ;
  182. }
  183. public function getPriceWithReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null)
  184. {
  185. return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, false) ;
  186. }
  187. public function getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog = null, $withTax = true): ?float
  188. {
  189. if($reductionCatalog) {
  190. $reductionCatalogValue = $reductionCatalog->getValue() ;
  191. $reductionCatalogUnit = $reductionCatalog->getUnit() ;
  192. $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate() ;
  193. }
  194. else {
  195. if($entity instanceof ProductPropertyInterface) {
  196. $reductionCatalog = $entity->getReductionCatalogInherited() ;
  197. if($reductionCatalog) {
  198. $reductionCatalogValue = $reductionCatalog->getValue() ;
  199. $reductionCatalogUnit = $reductionCatalog->getUnit() ;
  200. $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate() ;
  201. }
  202. }
  203. if($entity instanceof OrderProductInterface) {
  204. $orderProductReductionCatalog = $entity->getOrderProductReductionCatalog() ;
  205. if($orderProductReductionCatalog) {
  206. $reductionCatalogValue = $orderProductReductionCatalog->getValue() ;
  207. $reductionCatalogUnit = $orderProductReductionCatalog->getUnit() ;
  208. $reductionCatalogBehaviorTaxRate = $orderProductReductionCatalog->getBehaviorTaxRate() ;
  209. }
  210. }
  211. }
  212. if(isset($reductionCatalogValue) && isset($reductionCatalogUnit) && isset($reductionCatalogBehaviorTaxRate)) {
  213. if ($reductionCatalogUnit == 'percent') {
  214. $priceWithTax = $this->applyReductionPercent(
  215. $priceWithTax,
  216. $reductionCatalogValue
  217. );
  218. }
  219. elseif ($reductionCatalogUnit == 'amount') {
  220. if($reductionCatalogBehaviorTaxRate == 'tax-excluded') {
  221. $priceWithTax = $this->applyTax(
  222. $this->applyReductionAmount(
  223. $price,
  224. $reductionCatalogValue
  225. ),
  226. $entity->getTaxRateInherited()->getValue()
  227. );
  228. }
  229. elseif($reductionCatalogBehaviorTaxRate == 'tax-included') {
  230. $priceWithTax = $this->applyReductionAmount(
  231. $priceWithTax,
  232. $reductionCatalogValue
  233. );
  234. }
  235. }
  236. }
  237. if($withTax) {
  238. $priceReturn = $priceWithTax ;
  239. }
  240. else {
  241. $priceReturn = $this->applyPercentNegative($priceWithTax, $entity->getTaxRateInherited()->getValue()) ;
  242. }
  243. return $this->round($priceReturn) ;
  244. }
  245. public function getTotalTaxes($entity)
  246. {
  247. if($entity instanceof OrderProductInterface) {
  248. return $this->getTotalWithReduction($entity) * ($entity->getTaxRateInherited()->getValue() / 100) ;
  249. }
  250. if($entity instanceof OrderShopInterface) {
  251. $totalTaxes = 0 ;
  252. foreach($entity->getOrderProducts() as $orderProduct) {
  253. $totalTaxes += $this->getTotalTaxes($orderProduct) ;
  254. }
  255. return $totalTaxes ;
  256. }
  257. return 0 ;
  258. }
  259. public function applyTax($price, $taxRateValue)
  260. {
  261. return $this->round($this->applyPercent($price, $taxRateValue)) ;
  262. }
  263. public function applyReductionPercent($price, $percentage)
  264. {
  265. return $this->applyPercent($price, -$percentage) ;
  266. }
  267. public function applyReductionAmount($price, $amount)
  268. {
  269. return $price - $amount ;
  270. }
  271. public function applyPercent($price, $percentage)
  272. {
  273. return $price * ($percentage / 100 + 1) ;
  274. }
  275. public function applyPercentNegative($price, $percentage)
  276. {
  277. return $price / ($percentage / 100 + 1) ;
  278. }
  279. public function round($price)
  280. {
  281. return round((($price * 100)) / 100, 2);
  282. }
  283. }