You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 line
15KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Solver\Price;
  3. use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface;
  4. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  5. use Lc\CaracoleBundle\Model\Reduction\ReductionCartModel;
  6. use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
  7. use Lc\CaracoleBundle\Solver\Product\ProductSolver;
  8. class OrderShopPriceSolver
  9. {
  10. //TODO vérifier si les round sont cohérents
  11. use PriceSolverTrait;
  12. protected OrderProductPriceSolver $orderProductPriceResolver;
  13. protected ProductSolver $productSolver;
  14. protected ProductFamilySolver $productFamilySolver;
  15. public function __construct(
  16. OrderProductPriceSolver $orderProductPriceResolver,
  17. ProductSolver $productSolver,
  18. ProductFamilySolver $productFamilySolver
  19. ) {
  20. $this->orderProductPriceResolver = $orderProductPriceResolver;
  21. $this->productSolver = $productSolver;
  22. $this->productFamilySolver = $productFamilySolver;
  23. }
  24. //Inclus les ReductionCatalog des OrderProducts
  25. public function getTotalOrderProducts(OrderShopInterface $orderShop): float
  26. {
  27. // A tester calculer ce montant en faisant TotalOrderWithTax - TotalOrderTaxes
  28. $total = 0;
  29. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  30. $total += $this->orderProductPriceResolver->getTotalWithReduction($orderProduct);
  31. }
  32. return $this->round($total);
  33. }
  34. //Inclus les ReductionCatalog des OrderProducts
  35. public function getMarginOrderProducts(OrderShopInterface $orderShop): float
  36. {
  37. $total = 0;
  38. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  39. $total += $this->orderProductPriceResolver->getTotalMargin($orderProduct);
  40. }
  41. return $this->round($total);
  42. }
  43. public function getMarginOrderProductsWithReductions(OrderShopInterface $orderShop, $cache = false): float
  44. {
  45. if ($cache && $orderShop->getStatMarginOrderProductsWithReductions() !== null) {
  46. return $orderShop->getStatMarginOrderProductsWithReductions();
  47. } else {
  48. $total = $this->getMarginOrderProducts($orderShop);
  49. $totalReductionAmount = 0;
  50. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  51. $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax(
  52. $orderShop,
  53. $orderReductionCart
  54. );
  55. }
  56. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  57. $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax(
  58. $orderShop,
  59. $orderReductionCredit
  60. );
  61. }
  62. $total -= $totalReductionAmount;
  63. return $this->round($total);
  64. }
  65. }
  66. public function getMarginOrderProductsWithReductionsPercent(OrderShopInterface $orderShop): float
  67. {
  68. if ($this->getTotalOrderProducts($orderShop)) {
  69. return $this->round(
  70. $this->getMarginOrderProductsWithReductions(
  71. $orderShop
  72. ) / $this->getTotalOrderProductsWithReductions($orderShop) * 100
  73. );
  74. } else {
  75. return 0;
  76. }
  77. }
  78. public function getMarginOrderProductsPercent(OrderShopInterface $orderShop): float
  79. {
  80. if ($this->getTotalOrderProducts($orderShop)) {
  81. return $this->round(
  82. $this->getMarginOrderProducts($orderShop) / $this->getTotalOrderProducts($orderShop) * 100
  83. );
  84. } else {
  85. return 0;
  86. }
  87. }
  88. public function getBrandTaxesOrderProductsWithReductionsPercent(OrderShopInterface $orderShop): float
  89. {
  90. if ($this->getTotalOrderProducts($orderShop)) {
  91. return $this->round(
  92. $this->getMarginOrderProducts($orderShop) / $this->getTotalBuyingPriceOrderProducts(
  93. $orderShop->getOrderProducts()
  94. ) * 100
  95. );
  96. } else {
  97. return 0;
  98. }
  99. }
  100. public function getTotalOrderProductsWithTax(OrderShopInterface $orderShop): float
  101. {
  102. return $this->getTotalOrderProductsWithTaxByOrderProducts($orderShop->getOrderProducts());
  103. }
  104. public function getTotalBuyingPriceOrderProducts($orderProducts): float
  105. {
  106. $total = 0;
  107. foreach ($orderProducts as $orderProduct) {
  108. $total += $this->orderProductPriceResolver->getTotalBuyingPrice($orderProduct);
  109. }
  110. return $total;
  111. }
  112. public function getTotalBuyingPriceOrderProductsWithTax($orderProducts): float
  113. {
  114. $total = 0;
  115. foreach ($orderProducts as $orderProduct) {
  116. $total += $this->orderProductPriceResolver->getTotalBuyingPriceWithTax($orderProduct);
  117. }
  118. return $this->round($total);
  119. }
  120. public function getTotalOrderProductsWithTaxByOrderProducts($orderProducts): float
  121. {
  122. $total = 0;
  123. foreach ($orderProducts as $orderProduct) {
  124. $total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct);
  125. }
  126. return $this->round($total);
  127. }
  128. public function getTotalOrderProductsTaxes(OrderShopInterface $orderShop): float
  129. {
  130. $total = 0;
  131. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  132. $total += $this->orderProductPriceResolver->getTotalTaxes($orderProduct) / $this->getReductionsCoef(
  133. $orderShop
  134. );
  135. }
  136. return $this->round($total);
  137. }
  138. public function getOrderProductsTaxesAsArray(OrderShopInterface $orderShop): array
  139. {
  140. $orderProductsTaxes = [];
  141. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  142. $idTaxRate = $orderProduct->getTaxRate()->getId();
  143. if (!isset($orderProductsTaxes[$idTaxRate])) {
  144. $orderProductsTaxes[$idTaxRate] = [
  145. 'label' => $orderProduct->getTaxRate()->getValue() . '%',
  146. 'totalOrderProducts' => 0,
  147. 'totalTaxes' => 0,
  148. ];
  149. }
  150. $orderProductsTaxes[$idTaxRate]['totalOrderProducts'] += $this->round($this->orderProductPriceResolver->getTotalWithReduction(
  151. $orderProduct
  152. ) / $this->getReductionsCoef($orderShop));
  153. $orderProductsTaxes[$idTaxRate]['totalTaxes'] += $this->round($this->orderProductPriceResolver->getTotalTaxes(
  154. $orderProduct
  155. ) / $this->getReductionsCoef($orderShop));
  156. }
  157. return $orderProductsTaxes;
  158. }
  159. private function getReductionsCoef(OrderShopInterface $orderShop): float
  160. {
  161. return $this->getTotalOrderProducts($orderShop) / $this->getTotalOrderProductsWithReductions($orderShop);
  162. }
  163. private function getTaxRateAverage(OrderShopInterface $orderShop): float
  164. {
  165. return $this->round($this->getTotalOrderProductsWithTax($orderShop) / $this->getTotalOrderProducts($orderShop));
  166. }
  167. public function getTotalOrderProductsWithReductions(OrderShopInterface $orderShop, $cache = false)
  168. {
  169. if ($cache && $orderShop->getStatTotalOrderProductsWithReductions() !== null) {
  170. return $orderShop->getStatTotalOrderProductsWithReductions();
  171. } else {
  172. $total = $this->getTotalOrderProducts($orderShop);
  173. $total -= $this->getTotalReductionCartsAmount($orderShop);
  174. $total -= $this->getTotalReductionCreditsAmount($orderShop);
  175. return $this->round($total);
  176. }
  177. }
  178. public function getTotalOrderProductsWithReductionCarts(OrderShopInterface $orderShop)
  179. {
  180. $total = $this->getTotalOrderProducts($orderShop);
  181. $total -= $this->getTotalReductionCartsAmount($orderShop);
  182. return $this->round($total);
  183. }
  184. public function getTotalReductionCartsAmount(OrderShopInterface $orderShop)
  185. {
  186. $totalReductionAmount = 0;
  187. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  188. $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax(
  189. $orderShop,
  190. $orderReductionCart
  191. );
  192. }
  193. return $this->round($totalReductionAmount);
  194. }
  195. public function getTotalReductionCreditsAmount(OrderShopInterface $orderShop)
  196. {
  197. $totalReductionAmount = 0;
  198. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  199. $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax(
  200. $orderShop,
  201. $orderReductionCredit
  202. );
  203. }
  204. return $this->round($totalReductionAmount);
  205. }
  206. public function getTotalOrderProductsWithTaxAndReductions(OrderShopInterface $orderShop, $cache = false)
  207. {
  208. if ($cache && $orderShop->getStatTotalOrderProductsWithTaxAndReductions() !== null) {
  209. return $orderShop->getStatTotalOrderProductsWithTaxAndReductions();
  210. } else {
  211. $total = $this->getTotalOrderProductsWithTax($orderShop);
  212. $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
  213. $total -= $this->getTotalReductionCreditsAmountWithTax($orderShop);
  214. return $this->round($total);
  215. }
  216. }
  217. public function getTotalOrderProductsWithTaxAndReductionCarts(OrderShopInterface $orderShop)
  218. {
  219. $total = $this->getTotalOrderProductsWithTax($orderShop);
  220. $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
  221. return $this->round($total);
  222. }
  223. public function getTotalReductionCartsAmountWithTax(OrderShopInterface $orderShop)
  224. {
  225. $totalReductionAmount = 0;
  226. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  227. $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart);
  228. }
  229. return $this->round($totalReductionAmount);
  230. }
  231. public function getTotalReductionCreditsAmountWithTax(OrderShopInterface $orderShop)
  232. {
  233. $totalReductionAmount = 0;
  234. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  235. $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithTax(
  236. $orderShop,
  237. $orderReductionCredit
  238. );
  239. }
  240. return $this->round($totalReductionAmount);
  241. }
  242. public function getOrderProductsReductionCartAmountWithoutTax(OrderShopInterface $order, $orderReductionCart)
  243. {
  244. $amount = 0;
  245. if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) {
  246. if ($orderReductionCart->getUnit() == 'percent') {
  247. $amount = $this->amountReductionByPercentValue(
  248. $this->getTotalOrderProducts($order),
  249. $orderReductionCart->getValue()
  250. );
  251. } else {
  252. if ($orderReductionCart->getUnit() == 'amount') {
  253. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
  254. $amount = $orderReductionCart->getValue();
  255. } else {
  256. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
  257. $amount = $this->round($orderReductionCart->getValue() / $this->getTaxRateAverage($order));
  258. }
  259. }
  260. }
  261. }
  262. }
  263. return $this->round($amount);
  264. }
  265. public function getOrderProductsReductionCartAmountWithTax(OrderShopInterface $order, $orderReductionCart)
  266. {
  267. $amount = 0;
  268. if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) {
  269. if ($orderReductionCart->getUnit() == 'percent') {
  270. $amount = $this->amountReductionByPercentValue(
  271. $this->getTotalOrderProductsWithTax($order),
  272. $orderReductionCart->getValue()
  273. );
  274. } elseif ($orderReductionCart->getUnit() == 'amount') {
  275. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
  276. $amount = $this->round($orderReductionCart->getValue() * $this->getTaxRateAverage($order));
  277. } elseif ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
  278. $amount = $orderReductionCart->getValue();
  279. }
  280. }
  281. }
  282. return $this->round($amount);
  283. }
  284. public function getOrderProductsReductionCreditAmountWithoutTax(
  285. OrderShopInterface $order,
  286. OrderReductionCreditInterface $orderReductionCredit
  287. ) {
  288. $amount = 0;
  289. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
  290. $amount = $orderReductionCredit->getValue();
  291. } else {
  292. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
  293. $amount = $this->round($orderReductionCredit->getValue() / $this->getTaxRateAverage($order));
  294. }
  295. }
  296. return $this->round($amount);
  297. }
  298. public function getOrderProductsReductionCreditAmountWithTax(
  299. OrderShopInterface $order,
  300. OrderReductionCreditInterface $orderReductionCredit
  301. ) {
  302. $amountWithTax = 0;
  303. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
  304. $amountWithTax = $this->round($orderReductionCredit->getValue() * $this->getTaxRateAverage($order));
  305. } elseif ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
  306. $amountWithTax = $orderReductionCredit->getValue();
  307. }
  308. return $this->round($amountWithTax);
  309. }
  310. public function getTotalReductions(OrderShopInterface $orderShop)
  311. {
  312. $total = 0;
  313. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  314. $total += $this->getOrderProductsReductionCartAmountWithoutTax($orderShop, $orderReductionCart);
  315. }
  316. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  317. $total += $this->getOrderProductsReductionCreditAmountWithoutTax($orderShop, $orderReductionCredit);
  318. }
  319. return $this->round($total);
  320. }
  321. public function getTotalReductionsWithTax(OrderShopInterface $orderShop)
  322. {
  323. $total = 0;
  324. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  325. $total += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart);
  326. }
  327. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  328. $total += $this->getOrderProductsReductionCreditAmountWithTax($orderShop, $orderReductionCredit);
  329. }
  330. return $this->round($total);
  331. }
  332. }