海南旅游SAAS
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.

240 lines
7.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Common\PayType;
  4. use App\Common\StatementType;
  5. use App\Http\Controllers\Controller;
  6. use App\Models\Agent;
  7. use App\Models\Guide;
  8. use App\Models\Order;
  9. use App\Models\Supplier;
  10. use App\Models\Product;
  11. use App\Models\OrderProductItem;
  12. use App\Models\User;
  13. use App\Common\OrderStatus;
  14. use App\Service\SmsService;
  15. use App\Traits\DemandTraits;
  16. use App\Traits\SmsTraits;
  17. use EasyWeChat\Factory;
  18. use Illuminate\Support\Facades\DB;
  19. use Illuminate\Support\Facades\Storage;
  20. class VerificationController extends Controller
  21. {
  22. //核销订单
  23. public function verify()
  24. {
  25. $input_verify_code = request()->input('verify_code'); //订单ID
  26. $code_arr = explode('-', $input_verify_code);
  27. if (count($code_arr) != 2) {
  28. return $this->error('参数错误');
  29. }
  30. list($id, $verify_code) = $code_arr;
  31. $order = Order::with(['agentProduct:id,verifier', 'user', 'agent', 'guide'])
  32. ->where(['verify_code' => $verify_code])
  33. ->whereIn('status', [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE, OrderStatus::OFFLINE_PAID, OrderStatus::REFUSED_REFUND])
  34. ->find($id);
  35. if (!$order) {
  36. return $this->error('订单不存在或订单状态不允许核销');
  37. }
  38. //$mobile = User::where('id', $this->user_id)->value('mobile');
  39. //
  40. //$checkMobile = Product::query()->whereIn('id', explode(',', $order->product_ids))->where('verify_mobile', $mobile)->doesntExist();
  41. //if ($checkMobile) {
  42. // return $this->error('对不起,你没有核销权限,请联系管理员');
  43. //}
  44. $order->status = OrderStatus::SUCCESS;
  45. if ($order->save()) {
  46. //分账
  47. //线下订单不分账
  48. if ($order->pay_type != PayType::OFFLINE) {
  49. $this->fund($order);
  50. }
  51. //短信
  52. if (env('SMS_SWITCH', '') == true) {
  53. if (!empty($order->user->mobile)) {
  54. (new SmsService)->send('verify', [$order->order_no, SmsTraits::$systeaNameText['user']], [$order->user->mobile]);//用户
  55. }
  56. $supplierIds = OrderProductItem::query()->with('supplier')->where('order_id', $order->id)->distinct()->pluck('supplier_id');
  57. $phone = Supplier::query()->whereIn('id', $supplierIds)->pluck('contact_phone')->toArray();
  58. (new SmsService)->send('verify', [$order->order_no, SmsTraits::$systeaNameText['supplier']], $phone);//供应商
  59. (new SmsService)->send('verify', [$order->order_no, SmsTraits::$systeaNameText['agent']], [$order->agent->contact_phone]);//代理商
  60. }
  61. }
  62. return $this->success();
  63. }
  64. public function fund($order)
  65. {
  66. DB::beginTransaction();
  67. try {
  68. //最后批量插入
  69. $adminCreate = $statementCreate = [];
  70. $cost = 0;
  71. //如果有地接价格 分帐给地接
  72. if ($order->guide_price > 0) {
  73. $guidePrice = $order->guide_price;
  74. $cost = bcadd($cost, $order->guide_price, 6);
  75. //成本价 加上地接价格
  76. $statementCreate[] = [
  77. 'price' => $order->guide_price,
  78. 'type' => StatementType::ORDER,
  79. 'user_id' => $order->guide->id,
  80. 'user_type' => DemandTraits::$col[2],
  81. 'order_id' => $order->id
  82. ];
  83. //抽成
  84. if ($order->guide->rate > 0) {
  85. //计算抽成金额
  86. $guideCut = bcmul($order->guide_price, $order->guide->rate, 6);
  87. $cutPrice = $guideCut > 0 ? bcdiv($guideCut, 100, 6) : 0;
  88. //总后台抽成流水
  89. if ($cutPrice > 0) {
  90. $adminCreate[] = [
  91. 'price' => $cutPrice,
  92. 'type' => StatementType::CUT,
  93. 'cut_user_id' => $order->guide->id,
  94. 'cut_user_type' => DemandTraits::$col[2],
  95. 'order_id' => $order->id
  96. ];
  97. //地接被抽成流水
  98. $statementCreate[] = [
  99. 'price' => bcmul($cutPrice, -1, 2),
  100. 'type' => StatementType::CUT,
  101. 'user_id' => $order->guide->id,
  102. 'user_type' => DemandTraits::$col[2],
  103. 'order_id' => $order->id
  104. ];
  105. $guidePrice = bcsub($order->guide_price, $cutPrice, 6);
  106. $guide = Guide::query()->where('id', $order->guide->id)->lockForUpdate()->first();
  107. $guide->balance = bcadd($guide->balance, $guidePrice, 6);
  108. $guide->save();
  109. }
  110. }
  111. }
  112. //分账给供应商
  113. $orderItem = OrderProductItem::query()
  114. ->where('order_id', $order->id)
  115. ->with('supplier')
  116. ->select('*')
  117. ->selectRaw('sum(price) as sum_price')
  118. ->groupBy('supplier_id')
  119. ->get();
  120. foreach ($orderItem as $v) {
  121. $cost = bcadd($cost, $v->sum_price, 6);
  122. $supplierPrice = $v->sum_price;
  123. $statementCreate[] = [
  124. 'price' => $v->sum_price,
  125. 'type' => StatementType::ORDER,
  126. 'user_id' => $v->supplier_id,
  127. 'user_type' => DemandTraits::$col[1],
  128. 'order_id' => $order->id
  129. ];
  130. if ($v->supplier->rate > 0) {
  131. //计算抽成金额
  132. $supplierCut = bcmul($v->sum_price, $v->supplier->rate, 6);
  133. $cutPrice = $supplierCut > 0 ? bcdiv($supplierCut, 100, 6) : 0;
  134. if ($cutPrice > 0) {
  135. //总后台抽成流水
  136. $adminCreate[] = [
  137. 'price' => $cutPrice,
  138. 'type' => StatementType::CUT,
  139. 'cut_user_id' => $v->supplier_id,
  140. 'cut_user_type' => DemandTraits::$col[1],
  141. 'order_id' => $order->id
  142. ];
  143. //供应商被抽成流水
  144. $statementCreate[] = [
  145. 'price' => bcmul($cutPrice, -1, 6),
  146. 'type' => StatementType::CUT,
  147. 'user_id' => $v->supplier_id,
  148. 'user_type' => DemandTraits::$col[1],
  149. 'order_id' => $order->id
  150. ];
  151. $supplierPrice = bcsub($supplierPrice, $cutPrice, 6);
  152. }
  153. }
  154. $supplier = Supplier::query()->where('id', $v->supplier_id)->lockForUpdate()->first();
  155. $supplier->balance = bcadd($supplier->balance, $supplierPrice, 6);
  156. $supplier->save();
  157. }
  158. //分账给代理商
  159. //成本价 加上地接价格
  160. $agentPrice = bcsub($order->price, $cost, 2);
  161. if ($agentPrice > 0) {
  162. $statementCreate[] = [
  163. 'price' => $agentPrice,
  164. 'type' => StatementType::ORDER,
  165. 'user_id' => $order->agent_id,
  166. 'user_type' => DemandTraits::$col[0],
  167. 'order_id' => $order->id
  168. ];
  169. //抽成
  170. if ($order->agent->rate > 0) {
  171. //计算抽成金额
  172. $agentCut = bcmul($agentPrice, $order->agent->rate, 6);
  173. $cutPrice = $agentCut > 0 ? bcdiv($agentCut, 100, 6) : 0;
  174. //总后台抽成流水
  175. if ($cutPrice > 0) {
  176. $adminCreate[] = [
  177. 'price' => $cutPrice,
  178. 'type' => StatementType::CUT,
  179. 'cut_user_id' => $order->agent->id,
  180. 'cut_user_type' => DemandTraits::$col[0],
  181. 'order_id' => $order->id
  182. ];
  183. //代理商被抽成流水
  184. $statementCreate[] = [
  185. 'price' => bcmul($cutPrice, -1, 6),
  186. 'type' => StatementType::CUT,
  187. 'user_id' => $order->agent->id,
  188. 'user_type' => DemandTraits::$col[0],
  189. 'order_id' => $order->id
  190. ];
  191. $agentPrice = bcsub($agentPrice, $cutPrice, 6);
  192. }
  193. }
  194. //扣除微信支付手续费
  195. $chargePrice = bcmul($order->price, 0.006, 6);
  196. $statementCreate[] = [
  197. 'price' => bcmul($chargePrice, -1, 6),
  198. 'type' => StatementType::CHARGE,
  199. 'user_id' => $order->agent_id,
  200. 'user_type' => DemandTraits::$col[0],
  201. 'order_id' => $order->id
  202. ];
  203. $agentPrice = bcsub($agentPrice, $chargePrice, 6);
  204. $agent = Agent::query()->where('id', $order->agent->id)->lockForUpdate()->first();
  205. $agent->balance = bcadd($agent->balance, $agentPrice, 6);
  206. $agent->save();
  207. }
  208. //dd($adminCreate,$guideCreate);
  209. if (!empty($adminCreate)) {
  210. $order->statementAdmin()->createMany($adminCreate);
  211. }
  212. if (!empty($statementCreate)) {
  213. $order->statement()->createMany($statementCreate);
  214. }
  215. DB::commit();
  216. } catch (\Exception $e) {
  217. DB::rollBack();
  218. return $this->error($e->getMessage());
  219. }
  220. }
  221. }