您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

276 行
9.9KB

  1. <?php
  2. namespace domain\Order\Order;
  3. use common\components\Tiller\TillerClientInterface;
  4. use common\components\Tiller\TillerClientV2;
  5. use common\components\Tiller\TillerClientV3;
  6. use common\helpers\MeanPayment;
  7. use domain\Order\OrderStatus\OrderStatus;
  8. use domain\Order\ProductOrder\ProductOrderSolver;
  9. use domain\Producer\Producer\ProducerSolver;
  10. use domain\_\AbstractManager;
  11. class TillerManager extends AbstractManager
  12. {
  13. protected ?bool $tillerActivated;
  14. protected ProducerSolver $producerSolver;
  15. protected TillerClientInterface $tillerClient;
  16. protected OrderSolver $orderSolver;
  17. protected OrderBuilder $orderBuilder;
  18. protected ProductOrderSolver $productOrderSolver;
  19. public function loadDependencies(): void
  20. {
  21. $this->producerSolver = $this->loadService(ProducerSolver::class);
  22. if($this->producerSolver->getProducerContext(false)) {
  23. $this->tillerActivated = $this->producerSolver->getConfig('tiller');
  24. $this->tillerClient = $this->getClient();
  25. }
  26. $this->orderSolver = $this->loadService(OrderSolver::class);
  27. $this->orderBuilder = $this->loadService(OrderBuilder::class);
  28. $this->productOrderSolver = $this->loadService(ProductOrderSolver::class);
  29. }
  30. public function getClient(): ?TillerClientInterface
  31. {
  32. $apiVersion = $this->producerSolver->getConfig('tiller_api_version');
  33. if($apiVersion == 'v2') {
  34. return new TillerClientV2(
  35. $this->producerSolver->getConfig('tiller_provider_token'),
  36. $this->producerSolver->getConfig('tiller_restaurant_token')
  37. );
  38. }
  39. elseif($apiVersion == 'v3') {
  40. return new TillerClientV3(
  41. $this->producerSolver->getConfig('tiller_store_id'),
  42. $this->producerSolver->getConfig('tiller_access_token')
  43. );
  44. }
  45. return null;
  46. }
  47. public function getUrlAuthorizeCode(): string
  48. {
  49. return $this->tillerClient->getUrlAuthorizeCode(
  50. $this->producerSolver->getConfig('tiller_client_id'),
  51. $this->producerSolver->getConfig('tiller_redirect_uri')
  52. );
  53. }
  54. public function isAuthenticated(): bool
  55. {
  56. return $this->tillerClient->isAuthenticated();
  57. }
  58. public function synchronizeDistribution(string $date): array
  59. {
  60. $return = [];
  61. if($this->tillerActivated) {
  62. $isSynchro = $this->isSynchronized($date);
  63. if (!$isSynchro) {
  64. $orders = Order::searchAll([
  65. 'distribution.date' => $date,
  66. 'order.tiller_synchronization' => 1,
  67. ], [
  68. 'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
  69. ]);
  70. if ($orders && count($orders)) {
  71. foreach ($orders as $order) {
  72. $res = $this->synchronizeOrder($order);
  73. if($res) {
  74. $return[] = $res;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. return $return;
  81. }
  82. public function synchronizeOrder(Order $order, bool $force = false)
  83. {
  84. $apiVersion = $this->producerSolver->getConfig('tiller_api_version');
  85. $date = $order->distribution->date;
  86. $strDate = date('Y-m-d\T12:i:s+0000', strtotime($date) + 1);
  87. $datetime = new \DateTime(date('Y-m-d 12:i:s', strtotime($date)));
  88. $this->orderBuilder->initOrder($order);
  89. $lines = [];
  90. foreach ($order->productOrder as $productOrder) {
  91. // v3
  92. if($apiVersion == 'v3') {
  93. $amount = round($this->productOrderSolver->getPriceWithTax($productOrder) * 100);
  94. // classique
  95. if(is_int($productOrder->quantity)) {
  96. $quantity = $productOrder->quantity;
  97. }
  98. // vrac
  99. else {
  100. $amount = $amount * $productOrder->quantity;
  101. $quantity = 1;
  102. }
  103. $lines[] = [
  104. 'name' => $productOrder->product->name,
  105. 'unitPrice' => [
  106. 'amount' => $amount,
  107. ],
  108. 'taxRate' => $productOrder->taxRate->value * 100,
  109. 'quantity' => $quantity
  110. ];
  111. }
  112. // v2
  113. else {
  114. $lines[] = [
  115. 'name' => $productOrder->product->name,
  116. 'price' => $this->productOrderSolver->getPriceWithTax($productOrder) * 100 * $productOrder->quantity,
  117. 'tax' => $productOrder->taxRate->value * 100,
  118. 'date' => $strDate,
  119. 'quantity' => $productOrder->quantity
  120. ];
  121. }
  122. }
  123. $typePaymentTiller = '';
  124. if ($order->mean_payment == MeanPayment::MONEY) {
  125. $typePaymentTiller = 'CASH';
  126. }
  127. if ($order->mean_payment == MeanPayment::CREDIT_CARD
  128. || $order->mean_payment == MeanPayment::CREDIT
  129. || $order->mean_payment == MeanPayment::TRANSFER
  130. || $order->mean_payment == MeanPayment::OTHER) {
  131. $typePaymentTiller = 'CARD';
  132. }
  133. if ($order->mean_payment == MeanPayment::CHEQUE) {
  134. $typePaymentTiller = 'BANK_CHECK';
  135. }
  136. if (!strlen($typePaymentTiller) || !$order->mean_payment) {
  137. $typePaymentTiller = 'CASH';
  138. }
  139. if (!$this->isSynchronized($date, $order->id) || $force) {
  140. // v3
  141. if($apiVersion == 'v3') {
  142. $payments = [];
  143. $amountPayment = round($this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_PAID) * 100);
  144. if($amountPayment) {
  145. $payments[] = [
  146. 'externalId' => ''.$order->id,
  147. 'amount' => $amountPayment
  148. ];
  149. }
  150. $returnTiller = $this->tillerClient->postOrder([
  151. 'externalId' => ''.$order->id,
  152. 'purchaseRequestType' => 'clickAndCollect',
  153. 'date' => $datetime->format(\DateTime::ATOM),
  154. 'order' => [
  155. 'currencyCode' => 'EUR',
  156. 'itemLines' => $lines,
  157. 'payments' => $payments
  158. ]
  159. ]);
  160. }
  161. // v2
  162. else {
  163. $returnTiller = $this->tillerClient->postOrder([
  164. 'externalId' => $order->id,
  165. 'type' => 1,
  166. 'status' => 'IN_PROGRESS',
  167. 'openDate' => $strDate,
  168. 'closeDate' => $strDate,
  169. 'lines' => $lines,
  170. 'payments' => [
  171. [
  172. 'type' => $typePaymentTiller,
  173. 'amount' => $this->orderSolver->getOrderAmountWithTax(
  174. $order,
  175. Order::AMOUNT_PAID
  176. ) * 100,
  177. 'status' => 'ACCEPTED',
  178. 'date' => $strDate
  179. ]
  180. ]
  181. ]);
  182. }
  183. $returnTillerObject = json_decode($returnTiller);
  184. if($apiVersion == 'v3') {
  185. $order->tiller_external_id = '' . $returnTillerObject->referenceId;
  186. }
  187. else {
  188. $order->tiller_external_id = '' . $returnTillerObject->id;
  189. }
  190. $order->save();
  191. return $returnTiller;
  192. }
  193. return null;
  194. }
  195. public function isSynchronized($date, $idOrder = null): bool
  196. {
  197. if ($this->tillerActivated) {
  198. $ordersTiller = $this->tillerClient->getOrders($date);
  199. $ordersOpendistrib = Order::searchAll([
  200. 'distribution.date' => $date,
  201. 'order.tiller_synchronization' => 1,
  202. ], [
  203. 'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
  204. ]);
  205. $ordersOpendistribSynchro = [];
  206. if ($ordersOpendistrib) {
  207. foreach ($ordersOpendistrib as $orderOpendistrib) {
  208. $this->orderBuilder->initOrder($orderOpendistrib);
  209. if($orderOpendistrib->tiller_external_id) {
  210. $ordersOpendistribSynchro[$orderOpendistrib->id] = true;
  211. }
  212. else {
  213. $ordersOpendistribSynchro[$orderOpendistrib->id] = false;
  214. }
  215. /*if (isset($ordersTiller->orders)) {
  216. foreach ($ordersTiller->orders as $orderTiller) {
  217. if ($orderOpendistrib->tiller_external_id == $orderTiller->id) {
  218. $amountTotalPaidOrderOpendistrib = (int)round(
  219. $this->orderSolver->getOrderAmountWithTax($orderOpendistrib, Order::AMOUNT_PAID) * 100
  220. );
  221. if ($amountTotalPaidOrderOpendistrib >= (int)$orderTiller->currentPayedAmount
  222. || $amountTotalPaidOrderOpendistrib >= (int)$orderTiller->currentBill) {
  223. $ordersOpendistribSynchro[$orderOpendistrib->id] = true;
  224. }
  225. }
  226. }
  227. }*/
  228. }
  229. }
  230. if($idOrder && isset($ordersOpendistribSynchro[$idOrder])) {
  231. return $ordersOpendistribSynchro[$idOrder];
  232. }
  233. else {
  234. foreach ($ordersOpendistribSynchro as $idOrder => $isSynchro) {
  235. if (!$isSynchro) {
  236. return false;
  237. }
  238. }
  239. }
  240. return true;
  241. }
  242. return false;
  243. }
  244. }