OrderCompleteService.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace app\common\service\order;
  3. use app\common\library\helper;
  4. use app\common\model\settings\Setting;
  5. use app\common\model\supplier\Capital as SupplierCapitalModel;
  6. use app\common\model\supplier\Supplier as SupplierModel;
  7. use app\common\model\user\User as UserModel;
  8. use app\common\model\settings\Setting as SettingModel;
  9. use app\common\model\plus\agent\Order as AgentOrderModel;
  10. use app\common\model\user\PointsLog as PointsLogModel;
  11. use app\common\enum\order\OrderTypeEnum;
  12. use app\common\model\order\OrderSettled as OrderSettledModel;
  13. /**
  14. * 已完成订单结算服务类
  15. */
  16. class OrderCompleteService
  17. {
  18. // 订单类型
  19. private $orderType;
  20. /**
  21. * 订单模型类
  22. * @var array
  23. */
  24. private $orderModelClass = [
  25. OrderTypeEnum::MASTER => 'app\common\model\order\Order',
  26. ];
  27. // 模型
  28. private $model;
  29. /* @var UserModel $model */
  30. private $UserModel;
  31. private $supplierModel;
  32. /**
  33. * 构造方法
  34. */
  35. public function __construct($orderType = OrderTypeEnum::MASTER)
  36. {
  37. $this->orderType = $orderType;
  38. $this->model = $this->getOrderModel();
  39. $this->UserModel = new UserModel;
  40. $this->supplierModel = new SupplierModel();
  41. }
  42. /**
  43. * 初始化订单模型类
  44. */
  45. private function getOrderModel()
  46. {
  47. $class = $this->orderModelClass[$this->orderType];
  48. return new $class;
  49. }
  50. /**
  51. * 执行订单完成后的操作
  52. */
  53. public function complete($orderList, $appId)
  54. {
  55. // 已完成订单结算
  56. // 条件:后台订单流程设置 - 已完成订单设置0天不允许申请售后
  57. if (SettingModel::getItem('trade', $appId)['order']['refund_days'] == 0) {
  58. $this->settled($orderList);
  59. }
  60. // 发放分销商佣金
  61. foreach ($orderList as $order) {
  62. AgentOrderModel::grantMoney($order, $this->orderType);
  63. }
  64. return true;
  65. }
  66. /**
  67. * 执行订单结算
  68. */
  69. public function settled($orderList)
  70. {
  71. // 订单id集
  72. $orderIds = helper::getArrayColumn($orderList, 'order_id');
  73. // 累积用户实际消费金额
  74. $this->setIncUserExpend($orderList);
  75. // 处理订单赠送的积分
  76. $this->setGiftPointsBonus($orderList);
  77. // 将订单设置为已结算
  78. $this->model->onBatchUpdate($orderIds, ['is_settled' => 1]);
  79. // 供应商结算
  80. $this->setIncSupplierMoney($orderList);
  81. return true;
  82. }
  83. /**
  84. * 供应商金额=支付金额-运费
  85. */
  86. private function setIncSupplierMoney($orderList)
  87. {
  88. // 计算并累积实际消费金额(需减去售后退款的金额)
  89. $supplierData = [];
  90. $supplierCapitalData = [];
  91. // 订单结算记录
  92. $orderSettledData = [];
  93. foreach ($orderList as $order) {
  94. if($order['shop_supplier_id'] == 0){
  95. continue;
  96. }
  97. // 供应价格+运费
  98. $supplierMoney = $order['supplier_money'];
  99. $sysMoney = $order['sys_money'];
  100. // B2b模式,如果有参与分销,减去分销的佣金
  101. // 商城设置
  102. $settings = Setting::getItem('store');
  103. $refundSupplierMoney = 0;
  104. $refundSysMoney = 0;
  105. // 减去订单退款的金额
  106. foreach ($order['product'] as $product) {
  107. if (
  108. !empty($product['refund'])
  109. && $product['refund']['type']['value'] == 10 // 售后类型:退货退款
  110. && $product['refund']['is_agree']['value'] == 10 // 商家审核:已同意
  111. ) {
  112. $supplierMoney -= $product['supplier_money'];
  113. $sysMoney -= $product['sys_money'];
  114. $refundSupplierMoney += $product['supplier_money'];
  115. $refundSysMoney += $product['sys_money'];
  116. }
  117. }
  118. // 分销佣金,只要未失效,都算结算,不管后续是否有退款,因此结算时间设置要注意
  119. $agentOrder = AgentOrderModel::getDetailByOrderId($order['order_id'], OrderTypeEnum::MASTER);
  120. $agentMoney = 0;
  121. if($agentOrder['is_invalid'] == 0){
  122. $agentMoney = $agentOrder['first_money'] + $agentOrder['second_money'] + $agentOrder['third_money'];
  123. $supplierMoney -= $agentMoney;
  124. }
  125. !isset($supplierData[$order['shop_supplier_id']]) && $supplierData[$order['shop_supplier_id']] = 0.00;
  126. $supplierMoney > 0 && $supplierData[$order['shop_supplier_id']] += $supplierMoney;
  127. $orderSettledData[] = [
  128. 'order_id' => $order['order_id'],
  129. 'shop_supplier_id' => $order['shop_supplier_id'],
  130. 'order_money' => $order['order_price'],
  131. 'pay_money' => $order['pay_price'],
  132. 'express_money' => $order['express_price'],
  133. 'supplier_money' => $order['supplier_money'],
  134. 'real_supplier_money' => $supplierMoney,
  135. 'sys_money' => $order['sys_money'],
  136. 'real_sys_money' => $sysMoney,
  137. 'agent_money' => $agentMoney,
  138. 'refund_money' => $refundSupplierMoney + $refundSysMoney,
  139. 'refund_supplier_money' => $refundSupplierMoney,
  140. 'refund_sys_money' => $refundSysMoney,
  141. 'app_id' => $order['app_id']
  142. ];
  143. // 商家结算记录
  144. $supplierCapitalData[] = [
  145. 'shop_supplier_id' => $order['shop_supplier_id'],
  146. 'money' => $supplierMoney,
  147. 'describe' => '订单结算,订单号:' . $order['order_no'],
  148. 'app_id' => $order['app_id']
  149. ];
  150. }
  151. // 累积到供应商表记录
  152. $this->supplierModel->onBatchIncSupplierMoney($supplierData);
  153. // 修改平台结算金额
  154. (new OrderSettledModel())->saveAll($orderSettledData);
  155. // 供应商结算明细金额
  156. (new SupplierCapitalModel())->saveAll($supplierCapitalData);
  157. return true;
  158. }
  159. /**
  160. * 处理订单赠送的积分
  161. */
  162. private function setGiftPointsBonus($orderList)
  163. {
  164. // 计算用户所得积分
  165. $userData = [];
  166. $logData = [];
  167. foreach ($orderList as $order) {
  168. // 计算用户所得积分
  169. $pointsBonus = $order['points_bonus'];
  170. if ($pointsBonus <= 0) continue;
  171. // 减去订单退款的积分
  172. foreach ($order['product'] as $product) {
  173. if (
  174. !empty($product['refund'])
  175. && $product['refund']['type']['value'] == 10 // 售后类型:退货退款
  176. && $product['refund']['is_agree']['value'] == 10 // 商家审核:已同意
  177. ) {
  178. $pointsBonus -= $product['points_bonus'];
  179. }
  180. }
  181. // 计算用户所得积分
  182. !isset($userData[$order['user_id']]) && $userData[$order['user_id']] = 0;
  183. $userData[$order['user_id']] += $pointsBonus;
  184. // 整理用户积分变动明细
  185. $logData[] = [
  186. 'user_id' => $order['user_id'],
  187. 'value' => $pointsBonus,
  188. 'describe' => "订单赠送:{$order['order_no']}",
  189. 'app_id' => $order['app_id'],
  190. ];
  191. }
  192. if (!empty($userData)) {
  193. // 累积到会员表记录
  194. $this->UserModel->onBatchIncPoints($userData);
  195. // 批量新增积分明细记录
  196. (new PointsLogModel)->onBatchAdd($logData);
  197. }
  198. return true;
  199. }
  200. /**
  201. * 累积用户实际消费金额
  202. */
  203. private function setIncUserExpend($orderList)
  204. {
  205. // 计算并累积实际消费金额(需减去售后退款的金额)
  206. $userData = [];
  207. foreach ($orderList as $order) {
  208. // 订单实际支付金额
  209. $expendMoney = $order['pay_price'];
  210. // 减去订单退款的金额
  211. foreach ($order['product'] as $product) {
  212. if (
  213. !empty($product['refund'])
  214. && $product['refund']['type']['value'] == 10 // 售后类型:退货退款
  215. && $product['refund']['is_agree']['value'] == 10 // 商家审核:已同意
  216. ) {
  217. $expendMoney -= $product['refund']['refund_money'];
  218. }
  219. }
  220. !isset($userData[$order['user_id']]) && $userData[$order['user_id']] = 0.00;
  221. $expendMoney > 0 && $userData[$order['user_id']] += $expendMoney;
  222. }
  223. // 累积到会员表记录
  224. $this->UserModel->onBatchIncExpendMoney($userData);
  225. return true;
  226. }
  227. }