OrderMarketing.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. namespace common\models\order;
  3. use addons\Boss\backend\controllers\SettingController;
  4. use addons\Coupon\common\models\AddonsCouponUseLog;
  5. use addons\Coupon\common\models\AddonsCouponUserRelate;
  6. use addons\GroupBuy\common\models\GroupBuyOrder;
  7. use common\enums\AddonsEnum;
  8. use common\enums\StatusEnum;
  9. use common\enums\UserWalletEnum;
  10. use common\models\mall\MallAddons;
  11. use services\common\UserWalletService;
  12. use Yii;
  13. use yii\db\Exception;
  14. /**
  15. * This is the model class for table "{{%order_marketing}}".
  16. *
  17. *
  18. * @property int $id 主键
  19. * @property int $order_detail_id mall_id
  20. * @property float $give_score 赠送积分
  21. * @property float $give_balance 赠送余额
  22. * @property string|null $give_currency 赠送货币(json字符串保存)
  23. * @property float $deduct_score 减扣积分
  24. * @property string|null $deduct_currency 减扣货币(json字符串保存)
  25. * @property float $pay_money 商品实际付款金额,单位:元
  26. * @property float $full_reduce_money 满减金额,单位:元
  27. * @property float $coupon_discount_money 优惠券优惠金额,单位:元
  28. * @property float $agent_deduct 经销商内购商品抵扣
  29. * @property string $agent_extra 经销商内购商品抵扣额外信息
  30. * @property int $user_coupon_id 用户优惠券id
  31. * @property string $user_card_id 亲友卡抵扣额外信息
  32. * @property int $member_price_deduct 会员价优惠金额
  33. * @property int $give_balance_settlement 赠送余额的结算方式:0:订单完成,1:支付完成
  34. * @property int $status 状态[-1:删除;0:禁用;1启用]
  35. * @property int $created_at 创建时间
  36. * @property int $updated_at 修改时间
  37. * @property int $give_score_settlement 赠送积分的结算方式:0订单完成;1支付完成
  38. * @property float $give_digital 赠送数字币
  39. * @property int $give_digital_settlement 赠送数字币的结算方式:0订单完成;1支付完成
  40. */
  41. class OrderMarketing extends \common\models\base\BaseActiveRecord
  42. {
  43. /**
  44. * {@inheritdoc}
  45. */
  46. public static function tableName()
  47. {
  48. return '{{%order_marketing}}';
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function rules()
  54. {
  55. return [
  56. [['order_detail_id', 'status', 'created_at', 'updated_at','give_score_settlement','give_balance_settlement'], 'integer'],
  57. [['give_score', 'give_balance', 'deduct_score', 'pay_money', 'full_reduce_money', 'member_price_deduct', 'coupon_discount_money', 'agent_deduct'], 'number'],
  58. [['give_currency', 'deduct_currency', 'user_coupon_id', 'agent_extra','user_card_id'], 'string'],
  59. [['give_digital'],'number'],
  60. [['give_digital_settlement'],'integer']
  61. ];
  62. }
  63. /**
  64. * {@inheritdoc}
  65. */
  66. public function attributeLabels()
  67. {
  68. return [
  69. 'id' => '主键',
  70. 'order_detail_id' => 'mall_id',
  71. 'give_score' => '赠送积分',
  72. 'give_balance' => '赠送余额',
  73. 'give_currency' => '赠送货币(json字符串保存)',
  74. 'deduct_score' => '减扣积分',
  75. 'deduct_currency' => '减扣货币(json字符串保存)',
  76. 'pay_money' => '商品实际付款金额,单位:元',
  77. 'full_reduce_money' => '满减金额,单位:元',
  78. 'coupon_discount_money' => '优惠券优惠金额,单位:元',
  79. 'user_coupon_id' => '用户优惠券id',
  80. 'member_price_deduct' => '会员价优惠金额',
  81. 'give_balance_settlement' => '赠送余额的结算方式:0:订单完成,1:支付完成',
  82. 'status' => '状态[-1:删除;0:禁用;1启用]',
  83. 'created_at' => '创建时间',
  84. 'updated_at' => '修改时间',
  85. ];
  86. }
  87. public function getOrderDetail()
  88. {
  89. return $this->hasOne(OrderDetail::class, ['id' => 'order_detail_id']);
  90. }
  91. /**
  92. * 营销支付赠送
  93. * @Author: lun
  94. * @DateTime: 2021/11/16 0016 19:51
  95. * @Copyright: copyright (c) 2021 广东七件事集团
  96. * @param $mallId
  97. * @param $user_id
  98. * @param $source_table_id
  99. * @return bool
  100. * @throws \Exception
  101. */
  102. public static function giveMarketing($mallId, $user_id, $source_table_id)
  103. {
  104. try {
  105. // 查询订单详情
  106. $detail_ids = OrderDetail::find()->select('id')->where(['order_id' => $source_table_id])->asArray()->column();
  107. if (empty($detail_ids)) throw new \Exception('订单详情id查询为空');
  108. // 获取订单的营销数据
  109. $order_marketing_list = self::find()->andWhere(['in', 'order_detail_id', $detail_ids])->all();
  110. if (empty($order_marketing_list)) return true;
  111. $give_type = [UserWalletService::WALLET_TYPE_SCORE];
  112. $give_money = [];
  113. // 循环计算赠送数量
  114. foreach ($order_marketing_list as $marketing) {
  115. if (!isset($give_money[UserWalletService::WALLET_TYPE_SCORE])) $give_money[UserWalletService::WALLET_TYPE_SCORE] = 0;
  116. $give_money[UserWalletService::WALLET_TYPE_SCORE] += $marketing->give_score;
  117. }
  118. // 插入资金
  119. foreach ($give_type as $type) {
  120. if ($give_money[$type] <= 0) continue;
  121. $insert_wallet[] = [
  122. 'mall_id' => $mallId,
  123. 'user_id' => $user_id,
  124. 'is_frozen' => false,
  125. 'wallet_type' => $type,
  126. 'money' => $give_money[$type],
  127. 'desc' => '订单支付赠送',
  128. 'source_table' => Order::tableName(),
  129. 'source_table_id' => $source_table_id,
  130. 'from_type' => UserWalletEnum::CONSUME,
  131. 'capital_type' => UserWalletEnum::CONSUME_ORDER_GIVE,
  132. ];
  133. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  134. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  135. }
  136. return true;
  137. } catch (\Exception $e) {
  138. self::setStaticError($e->getMessage());
  139. return false;
  140. }
  141. }
  142. /**
  143. * @desc:获取一个订单的marketing信息
  144. * @Author: hua
  145. * @Date: 2021/11/18
  146. * @Time: 9:41
  147. * @Copyright: copyright (c) 2021 广东七件事集团
  148. * @param $order
  149. * @return array
  150. */
  151. public static function getMarketingInfo($order)
  152. {
  153. $member_price = $coupon_discount_money = $full_reduce_money = $score = $score_deduct_money = $agent_deduct = $user_card_deduct = 0;
  154. if (!empty($order['detail'])) {
  155. $currency = [];
  156. $order_detail_ids = array_column($order['detail'], 'id');
  157. $order_marketing_list = self::lists(['where' => [['order_detail_id' => $order_detail_ids]]]);
  158. foreach ($order_marketing_list as $value) {
  159. $member_price += $value['member_price_deduct'];
  160. $coupon_discount_money += $value['coupon_discount_money'];
  161. $full_reduce_money += $value['full_reduce_money'];
  162. $score += $value['deduct_score'];
  163. $agent_deduct += $value['agent_deduct'];
  164. $deduct_currency = json_decode($value['deduct_currency'], true);
  165. if (!empty($deduct_currency)) {
  166. foreach ($deduct_currency as $currency_key => $item) {
  167. $name = $item['name'] ?? '';
  168. $currency[$currency_key] = [
  169. 'name' => $name . '抵扣',
  170. 'money' => -$item['money'],
  171. ];
  172. }
  173. }
  174. $user_card_id = json_decode($value['user_card_id'],true) ?? [];
  175. if(!empty(($user_card_id))){
  176. $user_card_deduct += $user_card_id['deduct_money'];
  177. }
  178. }
  179. }
  180. $member_price = bcmul($member_price,1,2);
  181. $full_reduce_money = bcmul($full_reduce_money,1,2);
  182. $coupon_discount_money = bcmul($coupon_discount_money,1,2);
  183. $agent_deduct = bcmul($agent_deduct,1,2);
  184. $user_card_deduct = bcmul($user_card_deduct,1,2);
  185. $marketing['deduct'] = [
  186. 'member_price' => ['name' => '会员优惠', 'money' => -$member_price],
  187. 'full_reduce' => ['name' => '满减', 'money' => -$full_reduce_money],
  188. 'coupon' => ['name' => '优惠券', 'money' => -$coupon_discount_money],
  189. ];
  190. if($user_card_deduct && $user_card_deduct > 0){
  191. $marketing['deduct']['user_card_deduct'] = ['name' => '折扣价', 'money' => -$user_card_deduct];
  192. }
  193. !empty($currency) && $marketing['deduct'] = array_merge($marketing['deduct'], $currency);
  194. if (MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_AGENT)){
  195. $marketing['deduct']['agent_deduct'] = ['name' => '经销商内购商品抵扣', 'money' => -$agent_deduct];
  196. }
  197. // 拼团免费开团优惠显示
  198. if (
  199. MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_GROUP_BUY) &&
  200. ($order['marketing_type'] === AddonsEnum::ADDONS_NAME_GROUP_BUY || $order['order_source'] === AddonsEnum::ADDONS_NAME_GROUP_BUY)
  201. ){
  202. // 查询是否是免费开团,是的话则显示优惠
  203. $groupBuyMarketing = GroupBuyOrder::find()
  204. ->where([
  205. 'order_id' => $order['id'],
  206. 'mall_id' => $order['mall_id'],
  207. 'status' => StatusEnum::ENABLED,
  208. 'is_free' => 1
  209. ])
  210. ->select('marketing')
  211. ->scalar();
  212. $groupBuyMarketing = json_decode($groupBuyMarketing, true) ?: [];
  213. if (isset($groupBuyMarketing['is_free_open_group'])) {
  214. $marketing['deduct']['is_free_open_group'] = $groupBuyMarketing['is_free_open_group'];
  215. }
  216. }
  217. return $marketing;
  218. }
  219. /**
  220. * 订单扣减返还
  221. * @Author: lun
  222. * @DateTime: 2021/11/20 0020 14:27
  223. * @Copyright: copyright (c) 2021 广东七件事集团
  224. * @param $order_id
  225. * @param $order_detail_id_all //该订单涉及的所有订单详情id
  226. * @param $order_detail_ids //要返还的订单详情id
  227. * @param $mall_id
  228. * @param $user_id
  229. * @param $desc
  230. * @param $from_type
  231. * @param $capital_type
  232. */
  233. public static function deductBack($order_id, $order_detail_id_all, $order_detail_ids, $mall_id, $user_id, $desc, $from_type = UserWalletEnum::CONSUME, $capital_type = UserWalletEnum::CONSUME_ORDER_CLOSE)
  234. {
  235. try {
  236. $order_marketing_list = OrderMarketing::lists([
  237. 'where' => [['order_detail_id' => $order_detail_ids], ['status' => StatusEnum::ENABLED]],
  238. 'select' => 'deduct_score,user_coupon_id,deduct_currency'
  239. ]);
  240. $back_score = 0;
  241. // $back_score = array_sum(array_column($order_marketing_list, 'deduct_score'));
  242. foreach($order_marketing_list as $val){
  243. $deduct_currency = (array)json_decode($val['deduct_currency'], true);
  244. if (strpos($val['deduct_currency'], 'offset') !== false) {
  245. $deduct_currency = (array)json_decode($val['deduct_currency'], true)['offset'];
  246. }
  247. if(isset($deduct_currency['score'])) $back_score += $val['deduct_score'];
  248. }
  249. if (!empty($back_score) && $back_score > 0) {
  250. $insert_wallet[] = [
  251. 'mall_id' => $mall_id,
  252. 'user_id' => $user_id,
  253. 'is_frozen' => false,
  254. 'not_add_total' => true,
  255. 'wallet_type' => UserWalletService::WALLET_TYPE_SCORE,
  256. 'money' => $back_score,
  257. 'desc' => $desc,
  258. 'source_table' => OrderDetail::tableName(),
  259. 'source_table_id' => join(',', $order_detail_ids),
  260. 'from_type' => $from_type,
  261. 'capital_type' => $capital_type,
  262. ];
  263. }
  264. $refund_user_coupon_id_arr = [];
  265. if ($from_type == UserWalletEnum::REFUND) {
  266. //退款
  267. $order_detail_id_diff = array_diff($order_detail_id_all, $order_detail_ids);
  268. if (empty($order_detail_id_diff)) $order_detail_id_diff = $order_detail_id_all;
  269. $order_marketing_list_diff = OrderMarketing::lists([
  270. 'where' => [['order_detail_id' => $order_detail_id_diff], ['status' => StatusEnum::ENABLED]],
  271. 'select' => 'user_coupon_id'
  272. ]);
  273. $user_coupon_id_arr_diff = [];
  274. foreach ($order_marketing_list_diff as $value) {
  275. $user_coupon_id = json_decode($value['user_coupon_id'], true);
  276. if (!empty($user_coupon_id)) $user_coupon_id_arr_diff = array_merge($user_coupon_id_arr_diff, array_keys($user_coupon_id));
  277. }
  278. foreach ($order_marketing_list as $item) {
  279. $user_coupon_id_arr = json_decode($item['user_coupon_id'], true);
  280. if (!empty($user_coupon_id_arr)) {
  281. foreach ($user_coupon_id_arr as $user_coupon_id => $money_) {
  282. if (in_array($user_coupon_id, $user_coupon_id_arr_diff)) $refund_user_coupon_id_arr[] = $user_coupon_id;
  283. }
  284. }
  285. }
  286. } else {
  287. //订单关闭
  288. $refund_user_coupon_id_arr = [];
  289. foreach ($order_marketing_list as $item) {
  290. $user_coupon_id = json_decode($item['user_coupon_id'], true);
  291. if (!empty($user_coupon_id)) $refund_user_coupon_id_arr = array_merge($refund_user_coupon_id_arr, array_keys($user_coupon_id));
  292. }
  293. }
  294. if (!empty($refund_user_coupon_id_arr)) {
  295. AddonsCouponUserRelate::updateAll(['is_use' => 0], ['id' => $refund_user_coupon_id_arr]);
  296. AddonsCouponUseLog::updateAll(['status' => StatusEnum::DELETE], ['order_id' => $order_id, 'user_coupon_id' => $refund_user_coupon_id_arr]);
  297. }
  298. // 返还货币,TODO 货币功能还未完成
  299. // 返还对应的资产
  300. if (empty($insert_wallet)) return true;
  301. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  302. if (empty($res)) throw new Exception(UserWalletService::getStaticError());
  303. return true;
  304. } catch (\Exception $e) {
  305. self::setStaticError($e->getMessage());
  306. return false;
  307. }
  308. }
  309. public static function handleGiveScore($mall_id, $marketing, $profit, $num = 1, $mch_id = 0)
  310. {
  311. return $marketing;
  312. /*
  313. try{
  314. if($profit <= 0) throw new \Exception('profit must be greater than 0');
  315. $setting = \Yii::$app->services->setting->mall->get($mall_id, 'score');
  316. if(empty(($setting['is_enable_score_giving'] ?? 0))) throw new \Exception('is_enable_score_giving is 0');
  317. $score_giving_goods_type = (array)json_decode(($setting['score_giving_goods_type'] ?? ''), true);
  318. if($mch_id){
  319. if(!in_array(1, $score_giving_goods_type)) throw new \Exception('1 is not in the scoregiving_goods_type');
  320. }else{
  321. if(!in_array(0, $score_giving_goods_type)) throw new \Exception('0 is not in the scoregiving_goods_type');
  322. }
  323. $score_giving_num = (float)($setting['score_giving_num'] ?? 0);
  324. if($score_giving_num <= 0) throw new \Exception('score_giving_num must be greater than 0');
  325. $score_name = $setting['score_name'] ?? '积分';
  326. $score_giving_type = $setting['score_giving_type'] ?? 0;
  327. $score_giving_settlement_method = $setting['score_giving_settlement_method'] ?? 0;
  328. $give_num = 0;
  329. if($score_giving_type == 1){
  330. $give_num = bcmul($score_giving_num, $num, 2);
  331. }else{
  332. $give_num = bcmul($profit * $num, $score_giving_num / 100, 2);
  333. }
  334. if(!isset($marketing['give_currency'])) {
  335. $marketing['give_currency'] = [];
  336. }else{
  337. $marketing['give_currency'] = json_decode($marketing['give_currency'], true);
  338. }
  339. if(!isset($marketing['give_currency']['score'])) {
  340. $marketing['give_currency']['score'] = ['name'=>$score_name, 'score'=>$give_num, 'score_giving_settlement_method' => $score_giving_settlement_method];
  341. }else{
  342. $marketing['give_currency']['score']['score'] += $give_num;
  343. }
  344. $marketing['give_currency'] = json_encode($marketing['give_currency']);
  345. }catch(\Exception $e){
  346. }finally{
  347. return $marketing;
  348. }
  349. */
  350. }
  351. }