ProfitShareOrderEntity.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\Lakala\Entity;
  4. use SixShop\Core\Entity\BaseEntity;
  5. use SixShop\Lakala\Enum\ProfitShareOrderCMDTypeEnum;
  6. use SixShop\Lakala\Enum\ProfitShareOrderStatusEnum;
  7. use SixShop\Lakala\Enum\ReceiverStatusEnum;
  8. use SixShop\Lakala\Facade\Config;
  9. use SixShop\Lakala\Facade\LedgerService;
  10. use SixShop\Lakala\Model\ProfitShareOrderModel;
  11. use SixShop\Lakala\Model\ProfitShareReceiverModel;
  12. use think\Paginator;
  13. use function SixShop\Core\throw_logic_exception;
  14. /**
  15. * @mixin ProfitShareOrderModel
  16. */
  17. class ProfitShareOrderEntity extends BaseEntity
  18. {
  19. public function getOrderList(array $params, array $pageAndLimit): Paginator
  20. {
  21. return $this->withSearch(['out_separate_no', 'status'], $params)
  22. ->append(['status_text'])
  23. ->paginate($pageAndLimit);
  24. }
  25. /**
  26. * @param int $userID
  27. * @param int $receiverID
  28. * @param float $amount
  29. * @return self
  30. */
  31. public function createOrder(int $userID, int $receiverID, float $amount): self
  32. {
  33. $receiver = ProfitShareReceiverModel::where([
  34. 'id' => $receiverID,
  35. 'user_id' => $userID,
  36. 'status' => ReceiverStatusEnum::BOUND,
  37. ])->findOrEmpty();
  38. if ($receiver->isEmpty()) {
  39. throw_logic_exception('分账接收方不存在或未绑定');
  40. }
  41. $merInfo = LedgerService::queryLedgerMer($receiver->mer_cup_no, $receiver->org_id);
  42. $calculateData = $this->calculateOrder($amount, $merInfo->splitLowestRatio);
  43. $this->save([
  44. 'merchant_no' => $receiver->mer_cup_no,
  45. 'user_id' => $userID,
  46. 'total_amt' => $calculateData['total_amt'],
  47. 'lkl_org_no' => $receiver->org_id,
  48. 'cal_type' => 0, // 按照指定金额
  49. 'recv_merchant_no' => $receiver->mer_cup_no,
  50. 'recv_no' => $receiver->receiver_no,
  51. 'separate_value' => $calculateData['separate_value'],
  52. 'status' => ProfitShareOrderStatusEnum::PENDING,
  53. 'fee_amt' => $calculateData['fee_amt'],
  54. 'cmd_type' => ProfitShareOrderCMDTypeEnum::SEPARATE,
  55. ]);
  56. return $this;
  57. }
  58. /**
  59. * 计算分账数据
  60. *
  61. * @param float $amount
  62. * @return array{total_amt:int, fee_amt:int, separate_value:int}
  63. */
  64. private function calculateOrder(float $amount, float $splitLowestRatio): array
  65. {
  66. $splitLowestRatio = bcsub(100, (string)$splitLowestRatio, 2);
  67. $fee = Config::getConfig('profit_share_fee');
  68. $feeAmt = bcmul((string)$amount, (string)$fee, 2);
  69. if (bccomp($feeAmt, '1') == -1) {
  70. $feeAmt = 1;
  71. }
  72. $seprateValue = bcmul((string)$amount, '100', 2);
  73. $seprateValue = bcsub($seprateValue, $feeAmt);
  74. $totalAmout = bcmul($seprateValue, '100', 2);
  75. $totalAmout = bcdiv($totalAmout, (string)$splitLowestRatio);
  76. return [
  77. 'total_amt' => $totalAmout,
  78. 'fee_amt' => (int)$feeAmt,
  79. 'separate_value' => (int)$seprateValue,
  80. ];
  81. }
  82. }