Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

393 lines
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, false);
  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. //TODO : ici c'est pas possibble d'arrondir sinon ça fou une merde du tonnerre de de dieu !!!!
  125. $total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct);
  126. }
  127. return $this->round($total);
  128. }
  129. public function getTotalOrderProductsTaxes(OrderShopInterface $orderShop): float
  130. {
  131. $total = 0;
  132. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  133. $total += $this->orderProductPriceResolver->getTotalTaxes($orderProduct) / $this->getReductionsCoef(
  134. $orderShop
  135. );
  136. }
  137. return $this->round($total);
  138. }
  139. public function getOrderProductsTaxesAsArray(OrderShopInterface $orderShop): array
  140. {
  141. $orderProductsTaxes = [];
  142. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  143. $idTaxRate = $orderProduct->getTaxRate()->getId();
  144. if (!isset($orderProductsTaxes[$idTaxRate])) {
  145. $orderProductsTaxes[$idTaxRate] = [
  146. 'label' => $orderProduct->getTaxRate()->getValue() . '%',
  147. 'totalOrderProducts' => 0,
  148. 'totalTaxes' => 0,
  149. ];
  150. }
  151. $orderProductsTaxes[$idTaxRate]['totalOrderProducts'] += $this->round($this->orderProductPriceResolver->getTotalWithReduction(
  152. $orderProduct
  153. ) / $this->getReductionsCoef($orderShop));
  154. $orderProductsTaxes[$idTaxRate]['totalTaxes'] += $this->round($this->orderProductPriceResolver->getTotalTaxes(
  155. $orderProduct
  156. ) / $this->getReductionsCoef($orderShop));
  157. }
  158. return $orderProductsTaxes;
  159. }
  160. private function getReductionsCoef(OrderShopInterface $orderShop): float
  161. {
  162. return $this->getTotalOrderProducts($orderShop) / $this->getTotalOrderProductsWithReductions($orderShop);
  163. }
  164. private function getTaxRateAverage(OrderShopInterface $orderShop): float
  165. {
  166. return $this->round($this->getTotalOrderProductsWithTax($orderShop) / $this->getTotalOrderProducts($orderShop));
  167. }
  168. public function getTotalOrderProductsWithReductions(OrderShopInterface $orderShop, $cache = false)
  169. {
  170. if ($cache && $orderShop->getStatTotalOrderProductsWithReductions() !== null) {
  171. return $orderShop->getStatTotalOrderProductsWithReductions();
  172. } else {
  173. $total = $this->getTotalOrderProducts($orderShop);
  174. $total -= $this->getTotalReductionCartsAmount($orderShop);
  175. $total -= $this->getTotalReductionCreditsAmount($orderShop);
  176. return $this->round($total);
  177. }
  178. }
  179. public function getTotalOrderProductsWithReductionCarts(OrderShopInterface $orderShop)
  180. {
  181. $total = $this->getTotalOrderProducts($orderShop);
  182. $total -= $this->getTotalReductionCartsAmount($orderShop);
  183. return $this->round($total);
  184. }
  185. public function getTotalReductionCartsAmount(OrderShopInterface $orderShop)
  186. {
  187. $totalReductionAmount = 0;
  188. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  189. $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax(
  190. $orderShop,
  191. $orderReductionCart
  192. );
  193. }
  194. return $this->round($totalReductionAmount);
  195. }
  196. public function getTotalReductionCreditsAmount(OrderShopInterface $orderShop)
  197. {
  198. $totalReductionAmount = 0;
  199. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  200. $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax(
  201. $orderShop,
  202. $orderReductionCredit
  203. );
  204. }
  205. return $this->round($totalReductionAmount);
  206. }
  207. public function getTotalOrderProductsWithTaxAndReductions(OrderShopInterface $orderShop, $cache = false)
  208. {
  209. if ($cache && $orderShop->getStatTotalOrderProductsWithTaxAndReductions() !== null) {
  210. return $orderShop->getStatTotalOrderProductsWithTaxAndReductions();
  211. } else {
  212. $total = $this->getTotalOrderProductsWithTax($orderShop);
  213. $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
  214. $total -= $this->getTotalReductionCreditsAmountWithTax($orderShop);
  215. return $this->round($total);
  216. }
  217. }
  218. public function getTotalOrderProductsWithTaxAndReductionCarts(OrderShopInterface $orderShop)
  219. {
  220. $total = $this->getTotalOrderProductsWithTax($orderShop);
  221. $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
  222. return $this->round($total);
  223. }
  224. public function getTotalReductionCartsAmountWithTax(OrderShopInterface $orderShop)
  225. {
  226. $totalReductionAmount = 0;
  227. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  228. $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart);
  229. }
  230. return $this->round($totalReductionAmount);
  231. }
  232. public function getTotalReductionCreditsAmountWithTax(OrderShopInterface $orderShop)
  233. {
  234. $totalReductionAmount = 0;
  235. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  236. $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithTax(
  237. $orderShop,
  238. $orderReductionCredit
  239. );
  240. }
  241. return $this->round($totalReductionAmount);
  242. }
  243. public function getOrderProductsReductionCartAmountWithoutTax(OrderShopInterface $order, $orderReductionCart)
  244. {
  245. $amount = 0;
  246. if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) {
  247. if ($orderReductionCart->getUnit() == 'percent') {
  248. $amount = $this->amountReductionByPercentValue(
  249. $this->getTotalOrderProducts($order),
  250. $orderReductionCart->getValue()
  251. );
  252. } else {
  253. if ($orderReductionCart->getUnit() == 'amount') {
  254. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
  255. $amount = $orderReductionCart->getValue();
  256. } else {
  257. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
  258. $amount = $this->round($orderReductionCart->getValue() / $this->getTaxRateAverage($order));
  259. }
  260. }
  261. }
  262. }
  263. }
  264. return $this->round($amount);
  265. }
  266. public function getOrderProductsReductionCartAmountWithTax(OrderShopInterface $order, $orderReductionCart)
  267. {
  268. $amount = 0;
  269. if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) {
  270. if ($orderReductionCart->getUnit() == 'percent') {
  271. $amount = $this->amountReductionByPercentValue(
  272. $this->getTotalOrderProductsWithTax($order),
  273. $orderReductionCart->getValue()
  274. );
  275. } elseif ($orderReductionCart->getUnit() == 'amount') {
  276. if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
  277. $amount = $this->round($orderReductionCart->getValue() * $this->getTaxRateAverage($order));
  278. } elseif ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
  279. $amount = $orderReductionCart->getValue();
  280. }
  281. }
  282. }
  283. return $this->round($amount);
  284. }
  285. public function getOrderProductsReductionCreditAmountWithoutTax(
  286. OrderShopInterface $order,
  287. OrderReductionCreditInterface $orderReductionCredit
  288. ) {
  289. $amount = 0;
  290. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
  291. $amount = $orderReductionCredit->getValue();
  292. } else {
  293. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
  294. $amount = $this->round($orderReductionCredit->getValue() / $this->getTaxRateAverage($order));
  295. }
  296. }
  297. return $this->round($amount);
  298. }
  299. public function getOrderProductsReductionCreditAmountWithTax(
  300. OrderShopInterface $order,
  301. OrderReductionCreditInterface $orderReductionCredit
  302. ) {
  303. $amountWithTax = 0;
  304. if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
  305. $amountWithTax = $this->round($orderReductionCredit->getValue() * $this->getTaxRateAverage($order));
  306. } elseif ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
  307. $amountWithTax = $orderReductionCredit->getValue();
  308. }
  309. return $this->round($amountWithTax);
  310. }
  311. public function getTotalReductions(OrderShopInterface $orderShop)
  312. {
  313. $total = 0;
  314. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  315. $total += $this->getOrderProductsReductionCartAmountWithoutTax($orderShop, $orderReductionCart);
  316. }
  317. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  318. $total += $this->getOrderProductsReductionCreditAmountWithoutTax($orderShop, $orderReductionCredit);
  319. }
  320. return $this->round($total);
  321. }
  322. public function getTotalReductionsWithTax(OrderShopInterface $orderShop)
  323. {
  324. $total = 0;
  325. foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  326. $total += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart);
  327. }
  328. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  329. $total += $this->getOrderProductsReductionCreditAmountWithTax($orderShop, $orderReductionCredit);
  330. }
  331. return $this->round($total);
  332. }
  333. }