Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

405 lines
16KB

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