Order.php 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. <?php
  2. /**
  3. * 厦门云联储网络科技有限公司
  4. * https://www.baokuaiyun.com
  5. * Copyright (c) 2023 爆块云 All rights reserved.
  6. */
  7. namespace app\models;
  8. use app\jobs\order\OrderSendStringCodeRedPacketJob;
  9. use app\utils\AutoSendCoupon;
  10. use app\jobs\order\OrderCancelJob;
  11. use Yii;
  12. use Codeception\PHPUnit\ResultPrinter\HTML;
  13. use app\constants\OptionSetting;
  14. use app\models\Option;
  15. /**
  16. * This is the model class for table "{{%order}}".
  17. *
  18. * @property integer $id
  19. * @property integer $store_id
  20. * @property integer $user_id
  21. * @property integer $saas_id
  22. * @property string $order_no
  23. * @property string $total_price
  24. * @property string $send_price
  25. * @property string $take_price
  26. * @property string $pay_price
  27. * @property string $express_price
  28. * @property string $name
  29. * @property string $mobile
  30. * @property string $address
  31. * @property string $remark
  32. * @property integer $is_pay
  33. * @property integer $pay_type
  34. * @property integer $pay_time
  35. * @property integer $send_time
  36. * @property string $express
  37. * @property string $express_no
  38. * @property integer $confirm_time
  39. * @property integer $is_comment
  40. * @property integer $apply_delete
  41. * @property integer $supper_apply_delete
  42. * @property integer $created_at
  43. * @property integer $is_delete
  44. * @property integer $is_price
  45. * @property integer $parent_id
  46. * @property string $first_price
  47. * @property string $second_price
  48. * @property string $third_price
  49. * @property string $coupon_sub_price
  50. * @property string $content
  51. * @property integer $is_offline
  52. * @property integer $clerk_id
  53. * @property string $address_data
  54. * @property string $offline_qrcode
  55. * @property string $before_update_price
  56. * @property integer $shop_id
  57. * @property string $discount
  58. * @property integer $user_coupon_id
  59. * @property string $integral
  60. * @property integer $give_integral
  61. * @property integer $give_coin
  62. * @property integer $parent_id_1
  63. * @property integer $parent_id_2
  64. * @property integer $is_sale
  65. * @property string $words
  66. * @property string $version
  67. * @property string $express_price_1
  68. * @property integer $mch_id
  69. * @property integer $is_recycle
  70. * @property string $seller_comments
  71. * @property integer $order_union_id
  72. * @property string $rebate
  73. * @property string $before_update_express
  74. * @property integer $is_transfer
  75. * @property integer $type
  76. * @property string $share_price
  77. * @property integer $is_show
  78. * @property integer $order_origin
  79. * @property integer $is_open_offline
  80. * @property integer $trade_status
  81. * @property integer $is_settle
  82. * @property string $transaction_id
  83. * @property string $alipay_trade_no
  84. * @property string $adapay_payment_id
  85. * @property integer $adapay_share_finish
  86. * @property string $is_platform
  87. * @property integer $combine_money
  88. * @property integer $is_combine_pay
  89. * @property integer $order_type
  90. * @property string $book_info
  91. * @property string $updated_at
  92. * @property string $is_delivery
  93. * @property integer $md_id
  94. * @property integer $is_trans
  95. * @property integer $profit
  96. * @property integer $province_id
  97. * @property integer $city_id
  98. * @property integer $district_id
  99. * @property integer $town_id
  100. * @property integer $village_id
  101. * @property integer $food_flag_id
  102. * @property integer $food_book_ext
  103. * @property integer $pay_user_id
  104. * @property string $food_code
  105. * @property integer $ag_rebate
  106. * @property integer $verify_card_id
  107. * @property integer $holder_first_price
  108. * @property integer $holder_second_price
  109. * @property integer $holder_third_price
  110. * @property integer $holder_is_price
  111. * @property integer $share_send_type
  112. * @property integer $share_order_profit
  113. * @property integer $limit_id
  114. * @property integer $limit_price
  115. * @property integer $is_send_limit
  116. * @property integer $old_holder_first_price
  117. * @property integer $old_holder_second_price
  118. * @property integer $old_holder_third_price
  119. * @property integer $old_parent_id
  120. * @property integer $old_parent_id_1
  121. * @property integer $old_parent_id_2
  122. * @property string $get_verify_id
  123. * @property string $integral_difference_price
  124. * @property string $integral_price
  125. * @property integer $is_use_platform_mch
  126. * @property integer $buy_level_id
  127. * @property integer $level_order_id
  128. * @property integer $level_diff_price
  129. * @property string $hanging_order_id
  130. * @property integer $pt_order_id
  131. * @property string $activity_cut_price_order_id
  132. * @property string $activity_wechat_room_id
  133. * @property integer $trans_status
  134. * @property string $trans_error
  135. * @property integer $seckill_order_id
  136. * @property string $chain_level_value
  137. * @property string $level_price_json
  138. * @property string $get_coupon_id
  139. * @property string $rand_discount
  140. * @property integer $is_wastore
  141. * @property string $is_gross_profit
  142. * @property string $gross_profit
  143. * @property integer $md_group_activities_id
  144. * @property integer $md_group_activities_status
  145. * @property integer $is_yunst_sharing
  146. * @property string $huifu_id
  147. * @property string $trans_type
  148. * @property string $hf_seq_id
  149. * @property string $fee_amount
  150. * @property string $out_trans_id
  151. * @property string $party_order_id
  152. * @property string $req_seq_id
  153. * @property string $union_id
  154. * @property integer $string_code_reward_status
  155. * @property integer $make_concessions_status
  156. * @property integer $order_source
  157. */
  158. class Order extends \yii\db\ActiveRecord
  159. {
  160. /**
  161. * 订单流转状态:默认
  162. */
  163. const ORDER_FLOW_DEFAULT = -1;
  164. /**
  165. * 订单流转状态:待发货
  166. */
  167. const ORDER_FLOW_NO_SEND = 0;
  168. /**
  169. * 订单流转状态:已取消
  170. */
  171. const ORDER_FLOW_CANCEL = 1;
  172. /**
  173. * 订单流转状态:已发货
  174. */
  175. const ORDER_FLOW_SEND = 2;
  176. /**
  177. * 订单流转状态:已完成
  178. */
  179. const ORDER_FLOW_CONFIRM = 3;
  180. const TRADE_STATUS_TEXT = [
  181. self::ORDER_FLOW_DEFAULT => '待付款',
  182. self::ORDER_FLOW_NO_SEND => '待发货',
  183. self::ORDER_FLOW_SEND => '已发货',
  184. self::ORDER_FLOW_CANCEL => '已取消',
  185. self::ORDER_FLOW_CONFIRM => '已完成',
  186. ];
  187. public $valid_order_flow = [
  188. self::ORDER_FLOW_DEFAULT,
  189. self::ORDER_FLOW_NO_SEND,
  190. self::ORDER_FLOW_SEND,
  191. self::ORDER_FLOW_CANCEL,
  192. self::ORDER_FLOW_CONFIRM
  193. ];
  194. /**
  195. * 申请取消订单: 默认
  196. */
  197. const ORDER_APPLY_DELETE_DEFAULT = 0;
  198. /**
  199. * 申请取消订单: 申请中
  200. */
  201. const ORDER_APPLY_DELETE = 1;
  202. /**
  203. * 订单来源 公众号或网站
  204. */
  205. const ORDER_SOURCE_WEB = 1;
  206. /**
  207. * 订单来源 app
  208. */
  209. const ORDER_SOURCE_APP = 2;
  210. /**
  211. * 订单来源 小程序
  212. */
  213. const ORDER_SOURCE_MINI = 3;
  214. /**
  215. * 订单来源 收银台
  216. */
  217. const ORDER_SOURCE_CASHIER = 4;
  218. /**
  219. * 订单来源 后台录入
  220. */
  221. const ORDER_SOURCE_MANAGE = 5;
  222. /**
  223. * 用户取消类型
  224. */
  225. const CANCEL_USER_TYPE = 0;
  226. /**
  227. * 后台取消类型
  228. */
  229. const CANCEL_BACK_TYPE = 1;
  230. /**
  231. * 是否取消(手动):已取消
  232. */
  233. const IS_DELETE_TRUE = 1;
  234. /**
  235. * 是否取消(手动):未取消
  236. */
  237. const IS_DELETE_FALSE = 0;
  238. /**
  239. * 是否支付:已支付
  240. */
  241. const IS_PAY_TRUE = 1;
  242. /**
  243. * 是否支付:未支付
  244. */
  245. const IS_PAY_FALSE = 0;
  246. /**
  247. * 支付方式:未支付
  248. */
  249. const PAY_TYPE_UNPAID = 0;
  250. /**
  251. * 支付方式:微信支付
  252. */
  253. const PAY_TYPE_WECHAT = 1;
  254. const PAY_TYPE_KEY_WECHAT = 'wechat';
  255. /**
  256. * 支付方式:货到付款
  257. */
  258. const PAY_TYPE_COD = 2;
  259. /**
  260. * 支付方式:余额支付
  261. */
  262. const PAY_TYPE_BALANCE_PAID = 3;
  263. /**
  264. * 支付方式:支付宝支付
  265. */
  266. const PAY_TYPE_ALI = 4;
  267. const PAY_TYPE_KEY_ALI = 'alipay';
  268. /**
  269. * 支付方式:收银台钱包支付
  270. */
  271. const PAY_TYPE_CASHIER_PURSE = 6;
  272. /**
  273. * 支付方式:线下转账
  274. */
  275. const PAY_TYPE_OFFLINE = 11;
  276. const PAY_TYPE_KEY_OFFLINE = 'offline';
  277. const PAY_TYPE_NAME_OFFLINE = '线下转账';
  278. /**
  279. * 支付方式:每月月付
  280. */
  281. const PAY_TYPE_MONTH = 12;
  282. const PAY_TYPE_KEY_MONTH = 'month';
  283. const PAY_TYPE_NAME_MONTH = '每月月付';
  284. /**
  285. * 支付方式:yunst_pay通联支付
  286. */
  287. const PAY_TYPE_YUNST_WECHAT_PAY = 13;
  288. const PAY_TYPE_KEY_YUNST_WECHAT_PAY = 'yunst_wechat_pay';
  289. const PAY_TYPE_NAME_YUNST_WECHAT_PAY = '通联微信支付';
  290. /**
  291. * 支付方式:yunst_pay通联支付
  292. */
  293. const PAY_TYPE_YUNST_ALI_PAY = 14;
  294. const PAY_TYPE_KEY_YUNST_ALI_PAY = 'yunst_ali_pay';
  295. const PAY_TYPE_NAME_YUNST_ALI_PAY = '通联支付宝支付';
  296. /**
  297. * 支付方式:adapay_wx AdaPay微信支付
  298. */
  299. const PAY_TYPE_ADAPAY_WX = 101;
  300. const PAY_TYPE_KEY_ADAPAY_WX = 'adapay_wx';
  301. const PAY_TYPE_NAME_ADAPAY_WX = 'Adapay微信';
  302. /**
  303. * 支付方式:adapay_alipay AdaPay支付宝支付
  304. */
  305. const PAY_TYPE_ADAPAY_ALIPAY = 401;
  306. const PAY_TYPE_KEY_ADAPAY_ALIPAY = 'adapay_alipay';
  307. const PAY_TYPE_NAME_ADAPAY_ALIPAY = 'Adapay支付宝';
  308. /**
  309. * 支付方式:adapay_quickpay_frontpay AdaPay快捷支付
  310. */
  311. const PAY_TYPE_ADAPAY_QUICKPAY_FRONTPAY = 1001;
  312. const PAY_TYPE_KEY_ADAPAY_QUICKPAY_FRONTPAY = 'adapay_quickpay_frontpay';
  313. const PAY_TYPE_NAME_ADAPAY_QUICKPAY_FRONTPAY = 'AdaPay快捷';
  314. /**
  315. * 支付方式:聚合正扫
  316. * T_JSAPI: 微信公众号
  317. * T_MINIAPP: 微信小程序
  318. * T_H5:微信直连H5支付
  319. * T_APP:微信APP支付
  320. * T_NATIVE:微信正扫
  321. *
  322. * A_JSAPI: 支付宝JS
  323. * A_NATIVE: 支付宝正扫
  324. *
  325. * U_NATIVE: 银联正扫
  326. * U_JSAPI: 银联JS
  327. * D_NATIVE: 数字人民币正扫
  328. */
  329. const PAY_TYPE_HUIFU_WECHAT_PAY = 2000;
  330. const PAY_TYPE_KEY_HUIFU_WECHAT_PAY = 'huifu_wechat';
  331. const PAY_TYPE_NAME_HUIFU_WECHAT_PAY = '汇付微信支付';
  332. const PAY_TYPE_HUIFU_ALI_PAY = 2010;
  333. const PAY_TYPE_KEY_HUIFU_ALI_PAY = 'huifu_ali';
  334. const PAY_TYPE_NAME_HUIFU_ALI_PAY = '汇付支付宝支付';
  335. const PAY_TYPE_HUIFU_UNION_PAY = 2020;
  336. const PAY_TYPE_KEY_HUIFU_UNION_PAY = 'huifu_union';
  337. const PAY_TYPE_NAME_HUIFU_UNION_PAY = '汇付银联支付';
  338. const PAY_TYPE_QUICK_PAY = 3000;
  339. const PAY_TYPE_KEY_QUICK_PAY = 'quick_pay';
  340. const PAY_TYPE_NAME_QUICK_PAY = '快捷支付';
  341. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_JSAPI = 2001;
  342. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_T_JSAPI = 'huifu_payment_jspay_t_jsapi';
  343. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_T_JSAPI = '汇付微信公众号';
  344. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_MINIAPP = 2002;
  345. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_T_MINIAPP = 'huifu_payment_jspay_t_miniapp';
  346. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_T_MINIAPP = '汇付微信小程序';
  347. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_A_JSAPI = 2003;
  348. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_A_JSAPI = 'huifu_payment_jspay_a_jsapi';
  349. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_A_JSAPI = '汇付支付宝JS';
  350. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_JSAPI = 2021;
  351. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_UNION_JSAPI = 'huifu_payment_jspay_union_jsapi';
  352. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_UNION_JSAPI = '汇付银联JS';
  353. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_NATIVE = 2022;
  354. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_UNION_NATIVE = 'huifu_payment_jspay_union_native';
  355. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_UNION_NATIVE = '汇付银联NATIVE';
  356. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_H5 = 2005;
  357. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_T_H5 = 'huifu_payment_jspay_t_h5';
  358. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_T_H5 = '汇付微信直连H5支付';
  359. const PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_APP = 2006;
  360. const PAY_TYPE_KEY_HUIFU_PAYMENT_JSPAY_T_APP = 'huifu_payment_jspay_t_app';
  361. const PAY_TYPE_NAME_HUIFU_PAYMENT_JSPAY_T_APP = '汇付微信APP支付';
  362. const PAY_TYPE_HUIFU_PAYMENT_A_NATIVE= 2007;
  363. const PAY_TYPE_KEY_HUIFU_PAYMENT_A_NATIVE = 'huifu_payment_a_native';
  364. const PAY_TYPE_NAME_HUIFU_PAYMENT_A_NATIVE = '汇付支付宝正扫';
  365. const PAY_TYPE_KEY_YSDL = 'ysdl';
  366. const PAY_TYPE_NAME_YSDL = '云数动力';
  367. /**
  368. * 订单类型:商城订单
  369. */
  370. const ORDER_TYPE_STORE = 0;
  371. /**
  372. * 订单类型:当面付订单
  373. */
  374. const ORDER_TYPE_POND = 1;
  375. /**
  376. * 订单类型:认养订单
  377. */
  378. const ORDER_TYPE_Adopt = 5;
  379. /**
  380. * 订单类型:上门服务订单
  381. */
  382. const ORDER_TYPE_WORKER = 6;
  383. const ORDER_TYPE_EXT_WORKER_FIRST_PAY = 601; //定金订单
  384. const ORDER_TYPE_EXT_WORKER_LAST_PAY = 602; //尾款订单
  385. const ORDER_TYPE_EXT_WORKER_ADD_TIME = 603; //加钟订单
  386. const ORDER_TYPE_INTEGRAL = 7;
  387. //活动类型
  388. const ACTIVITY_TYPE_CUT_PRICE = 1;
  389. //拼团活动类型
  390. const ACTIVITY_PT_PRICE = 2;
  391. //秒杀活动类型
  392. const ACTIVITY_SECKILL_PRICE = 3;
  393. //群优惠活动类型
  394. const ACTIVITY_WECHAT_ROOM = 4;
  395. /**
  396. * 订单是否显示:显示
  397. */
  398. const IS_SHOW_TRUE = 1;
  399. /**
  400. * 订单是否显示:不显示
  401. */
  402. const IS_SHOW_FALSE = 0;
  403. /**
  404. * 是否过售后时间:是
  405. */
  406. const IS_SALE_TRUE = 1;
  407. /**
  408. * 是否过售后时间:否
  409. */
  410. const IS_SALE_FALSE = 0;
  411. /**
  412. * 自提订单
  413. */
  414. const IS_OFFLINE_TRUE = 1;
  415. const IS_OFFLINE_FALSE = 0;
  416. /**
  417. * 类型
  418. */
  419. // const SEND_TYPE_DADA = 1;
  420. // const SEND_TYPE_UU = 2;
  421. // const SEND_TYPE_PEISONG = 3;
  422. /**
  423. * 同城配送
  424. */
  425. const IS_SAME_CITY_NO = 0; //否
  426. const IS_SAME_CITY_YES = 1; //是
  427. /**
  428. * 是否是组合支付:是
  429. */
  430. const IS_COMBINE_PAY = 1;
  431. /**
  432. * 是否是组合支付:否
  433. */
  434. const NOT_COMBINE_PAY = 0;
  435. /**
  436. * 订单支付方式
  437. */
  438. const PAY_TYP_NAME = [
  439. 0=>'未支付',
  440. 1=>'微信支付',
  441. 2=>'货到付款',
  442. 3=>'余额支付',
  443. 4=>'支付宝支付',
  444. 5=>'抖音支付',
  445. 6=>'线下支付',
  446. self::PAY_TYPE_OFFLINE => self::PAY_TYPE_NAME_OFFLINE,
  447. self::PAY_TYPE_MONTH => self::PAY_TYPE_NAME_MONTH,
  448. self::PAY_TYPE_ADAPAY_WX => self::PAY_TYPE_NAME_ADAPAY_WX,
  449. self::PAY_TYPE_ADAPAY_ALIPAY => self::PAY_TYPE_NAME_ADAPAY_ALIPAY,
  450. self::PAY_TYPE_ADAPAY_QUICKPAY_FRONTPAY => self::PAY_TYPE_NAME_ADAPAY_QUICKPAY_FRONTPAY,
  451. self::PAY_TYPE_HUIFU_WECHAT_PAY => self::PAY_TYPE_NAME_HUIFU_WECHAT_PAY,
  452. self::PAY_TYPE_HUIFU_ALI_PAY => self::PAY_TYPE_NAME_HUIFU_ALI_PAY,
  453. ];
  454. /**
  455. * 订单支付方式
  456. */
  457. const HUIFU_PAYMENT_TYPE = [
  458. self::PAY_TYPE_HUIFU_WECHAT_PAY,
  459. self::PAY_TYPE_HUIFU_ALI_PAY,
  460. ];
  461. /**
  462. * 订单支付方式
  463. */
  464. const HUIFU_PAYMENT_PAY_TYPE = [
  465. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_JSAPI => 'T_JSAPI',
  466. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_MINIAPP => 'T_MINIAPP',
  467. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_A_JSAPI => 'A_JSAPI',
  468. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_NATIVE => 'U_NATIVE',
  469. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_JSAPI => 'U_JSAPI',
  470. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_H5 => 'T_H5',
  471. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_APP => 'T_APP',
  472. self::PAY_TYPE_HUIFU_PAYMENT_A_NATIVE => 'A_NATIVE',
  473. ];
  474. /**
  475. * 微信参数集合
  476. */
  477. const WX_DATA_PAY_TYPE = [
  478. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_JSAPI,
  479. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_MINIAPP,
  480. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_H5,
  481. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_T_APP
  482. ];
  483. /**
  484. * 支付宝参数集合支付方式
  485. */
  486. const ALIPAY_DATA_PAY_TYPE = [
  487. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_A_JSAPI
  488. ];
  489. /**
  490. * 银联参数集合支付方式
  491. */
  492. const UNION_JSAPI_DATA_PAY_TYPE = [
  493. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_JSAPI,
  494. self::PAY_TYPE_HUIFU_PAYMENT_JSPAY_UNION_NATIVE
  495. ];
  496. const FROM_APP = 'app';
  497. const FROM_MINI = 'mini';
  498. const FROM_H5 = 'h5';
  499. const FROM_OFFICIAL = 'official';
  500. const PLATFORM_FROM_UNION = 'union'; //联盟端
  501. const PLATFORM_FROM_SAAS= 'saas'; //saas独立小程序端
  502. const PLATFORM_FROM_H5= 'h5'; //联盟h5端
  503. /**
  504. * @inheritdoc
  505. */
  506. public static function tableName()
  507. {
  508. return '{{%order}}';
  509. }
  510. /**
  511. * @inheritdoc
  512. */
  513. public function rules()
  514. {
  515. return [
  516. [['store_id', 'user_id', 'order_no', 'first_price', 'second_price', 'third_price'], 'required'],
  517. [['store_id', 'user_id', 'is_pay', 'pay_type', 'pay_time', 'send_time',
  518. 'confirm_time', 'is_comment', 'apply_delete', 'supper_apply_delete', 'created_at', 'updated_at', 'is_delete', 'is_price', 'parent_id',
  519. 'is_offline', 'clerk_id', 'shop_id', 'user_coupon_id', 'give_integral', 'give_coin', 'parent_id_1',
  520. 'parent_id_2', 'old_parent_id', 'old_parent_id_1', 'old_parent_id_2', 'is_sale', 'mch_id', 'order_union_id', 'is_transfer', 'type', 'is_show',
  521. 'is_open_offline', 'order_origin', 'trade_status', 'is_platform', 'is_combine_pay', 'order_type',
  522. 'is_delivery', 'md_id', 'is_trans', 'province_id', 'city_id', 'district_id', 'town_id', 'village_id', 'food_flag_id', 'pay_user_id', 'verify_card_id', 'holder_is_price', 'share_send_type','limit_id', 'is_send_limit','integral_price', 'is_use_platform_mch', 'buy_level_id', 'level_order_id', 'hanging_order_id', 'pt_order_id', 'saas_id','md_group_activities_id','md_group_activities_status'], 'integer'],
  523. [['total_price', 'pay_price', 'rand_discount', 'express_price', 'first_price', 'second_price', 'third_price',
  524. 'coupon_sub_price', 'before_update_price', 'discount', 'express_price_1', 'rebate',
  525. 'before_update_express', 'share_price', 'combine_money', 'profit', 'ag_rebate', 'holder_first_price', 'holder_second_price', 'holder_third_price', 'old_holder_first_price', 'old_holder_second_price', 'old_holder_third_price', 'share_order_profit', 'limit_price','integral_difference_price', 'level_diff_price', 'trans_status', 'seckill_order_id', 'take_price', 'send_price', 'sort'], 'number'],
  526. [['address_data', 'content', 'offline_qrcode', 'integral', 'words', 'seller_comments', 'book_info', 'food_book_ext', 'food_code', 'get_verify_id', 'get_coupon_id', 'union_id'], 'string'],
  527. [['order_no', 'name', 'mobile', 'express', 'express_no', 'version', 'alipay_trade_no', 'trans_error'], 'string', 'max' => 255],
  528. [['address', 'remark', 'shop_remark'], 'string', 'max' => 1000],
  529. [['md_id','ready_money','sale_time', 'activity_cut_price_order_id', 'activity_wechat_room_id'], 'safe'],
  530. [['delivery_time', 'adapay_payment_id', 'adapay_share_finish', 'chain_level_value', 'level_price_json', 'is_gross_profit', 'gross_profit'], 'safe'],
  531. [['transaction_id', 'tax_price', 'is_wastore'], 'safe'],
  532. ];
  533. }
  534. /**
  535. * @inheritdoc
  536. */
  537. public function attributeLabels()
  538. {
  539. return [
  540. 'id' => 'ID',
  541. 'store_id' => 'Store ID',
  542. 'user_id' => '用户id',
  543. 'saas_id' => '联盟用户id',
  544. 'order_no' => '订单号',
  545. 'total_price' => '订单总费用(包含运费)',
  546. 'pay_price' => '实际支付总费用(含运费)',
  547. 'express_price' => '运费',
  548. 'send_price' => 'send_price',
  549. 'take_price' => 'take_price',
  550. 'integral_price' => '积分数量',
  551. 'integral_difference_price' => '补积分差价',
  552. 'name' => '收货人姓名',
  553. 'mobile' => '收货人手机',
  554. 'address' => '收货地址',
  555. 'remark' => '订单备注',
  556. 'is_pay' => '支付状态:0=未支付,1=已支付',
  557. 'pay_type' => '支付方式:1=微信支付',
  558. 'pay_time' => '支付时间',
  559. 'send_time' => '发货时间',
  560. 'express' => '物流公司',
  561. 'express_no' => 'Express No',
  562. 'confirm_time' => '确认收货时间',
  563. 'is_comment' => '是否已评价:0=未评价,1=已评价',
  564. 'apply_delete' => '是否申请取消订单:0=否,1=申请取消订单',
  565. 'supper_apply_delete' => '是否申请供应商取消订单:0否 1申请取消',
  566. 'created_at' => 'Addtime',
  567. 'is_delete' => 'Is Delete',
  568. 'is_price' => '是否发放佣金',
  569. 'parent_id' => '用户上级ID',
  570. 'first_price' => '一级佣金',
  571. 'second_price' => '二级佣金',
  572. 'third_price' => '三级佣金',
  573. 'coupon_sub_price' => '优惠券抵消金额',
  574. 'content' => 'Content',
  575. 'is_offline' => '是否到店自提 0--否 1--是',
  576. 'clerk_id' => '核销员user_id',
  577. 'address_data' => '收货地址信息,json格式',
  578. 'offline_qrcode' => '核销码',
  579. 'before_update_price' => '修改前的价格',
  580. 'shop_id' => '自提自提点ID',
  581. 'discount' => '会员折扣',
  582. 'user_coupon_id' => '使用的优惠券ID',
  583. 'integral' => '积分使用',
  584. 'give_integral' => '是否发放积分【1=> 已发放 , 0=> 未发放】',
  585. 'give_coin' => '是否发放积分【1=> 已发放 , 0=> 未发放】',
  586. 'parent_id_1' => '用户上二级ID',
  587. 'parent_id_2' => '用户上三级ID',
  588. 'is_sale' => '是否超过售后时间',
  589. 'words' => '商家留言',
  590. 'version' => '版本',
  591. 'express_price_1' => '减免的运费',
  592. 'mch_id' => '入驻商户id',
  593. 'seller_comments' => '商家备注',
  594. 'order_union_id' => '合并订单的id',
  595. 'rebate' => '自购返利',
  596. 'before_update_express' => '价格修改前的运费',
  597. 'is_transfer' => '是否已转入商户账户:0=否,1=是',
  598. 'type' => '0普通订单1卡券兑换订单',
  599. 'share_price' => '发放佣金的金额',
  600. 'is_show' => '是否显示 0--不显示 1--显示(软删除用)',
  601. 'order_origin' => '订单来源 1:公众号或者网站 2:app 3:小程序 4:收银台',
  602. 'is_open_offline' => '是否是线下购物车下的订单',
  603. 'trade_status' => '订单状态,-1:默认,0:待发货,1:已取消,2:已发货,3:已确认',
  604. "limit_id"=>"临时关系ID",
  605. 'limit_price' => "临时绑定关系订单佣金",
  606. 'is_send_limit' => "是否发放临时关系佣金",
  607. 'get_verify_id' => '获取的卡券id',
  608. 'is_use_platform_mch' => '供应链系统下单时是否使用平台商户号,1使用,0未使用',
  609. 'sale_time' => '收银台销售时间',
  610. 'ready_money' => '现金支付相关',
  611. 'hanging_order_id' => '挂单订单id',
  612. 'activity_cut_price_order_id' => '砍价订单id',
  613. 'pt_order_id' => "拼团订单id",
  614. 'trans_error' => '转单错误信息',
  615. 'trans_status' => '转单状态',
  616. 'chain_level_value' => '等级链动佣金',
  617. 'get_coupon_id' => '优惠券id',
  618. 'rand_discount' => '随机立减',
  619. 'is_gross_profit' => '毛利润已计算',
  620. 'gross_profit' => '毛利润',
  621. 'md_group_activities_id' => '订单对应活动门店团购活动ID',
  622. 'md_group_activities_status' => '订单对应门店团购状态',
  623. 'make_concessions_status' => '商城让利合伙人 1:已发放,0:否',
  624. ];
  625. }
  626. public function getOrderDetail()
  627. {
  628. return $this->hasMany(OrderDetail::className(), ['order_id' => 'id'])->alias('od')
  629. ->leftJoin(['g' => Goods::tableName()], 'g.id=od.goods_id')->select(['od.*', 'g.name', 'g.attr goods_attr', 'g.cost_price']);
  630. }
  631. public function getDetail()
  632. {
  633. return $this->hasMany(OrderDetail::className(), ['order_id' => 'id']);
  634. }
  635. public function getGoods()
  636. {
  637. return $this->hasMany(Goods::className(), ['id' => 'goods_id'])->alias('g')
  638. ->viaTable(OrderDetail::tableName() . ' od', ['order_id' => 'id']);
  639. }
  640. public function getShop()
  641. {
  642. return $this->hasOne(Shop::className(), ['id' => 'shop_id']);
  643. }
  644. public function getClerk()
  645. {
  646. return $this->hasOne(User::className(), ['id' => 'clerk_id']);
  647. }
  648. public function getOrderForm()
  649. {
  650. return $this->hasMany(OrderForm::className(), ['order_id' => 'id'])->where(['is_delete' => 0]);
  651. }
  652. public function getUser()
  653. {
  654. return $this->hasOne(User::className(), ['id' => 'user_id']);
  655. }
  656. public function getRefund()
  657. {
  658. return $this->hasMany(OrderRefund::className(), ['order_id' => 'id']);
  659. }
  660. public function beforeSave($insert)
  661. {
  662. $this->content = \yii\helpers\Html::encode($this->content);
  663. if($this->trade_status == self::ORDER_FLOW_CONFIRM){
  664. if(empty($this->send_time)){
  665. $this->send_time = time();
  666. }
  667. }
  668. return parent::beforeSave($insert);
  669. }
  670. public function afterOtherDataSave()
  671. {
  672. \app\modules\admin\models\jushuitan\JuShuiTanForm::afterOrderSave($this);
  673. \app\modules\admin\models\WastoreForm::afterOrderOtherDataSave($this);
  674. }
  675. public function afterSave($insert, $changedAttributes)
  676. {
  677. debug_log([__METHOD__, __LINE__, "========start====== 商城订单:【{$this->id}】 订单状态:{$this->trade_status} 订单来源:{$this->order_source}"], "app_debug.log");
  678. if ($this->order_source == 1) return;
  679. parent::afterSave($insert, $changedAttributes);
  680. if($this->user_id && $this->store_id && ($this->trade_status == self::ORDER_FLOW_CONFIRM)){
  681. if(isset($changedAttributes['trade_status']) && ($changedAttributes['trade_status'] != self::ORDER_FLOW_CONFIRM)){
  682. $query = self::find()->where(['user_id' => $this->user_id, 'store_id' => $this->store_id, 'trade_status' => self::ORDER_FLOW_CONFIRM]);
  683. $count = $query->count();
  684. if($count == 1){
  685. // 赠送优惠券
  686. \app\utils\AutoSendCoupon::send($this->user_id, CouponAutoSend::EVENT_NEWUSER, $this->store_id, 0, CouponAutoSend::EXT_FIRST_ORDER);
  687. }
  688. if($count == 2){
  689. // 赠送优惠券
  690. \app\utils\AutoSendCoupon::send($this->user_id, CouponAutoSend::EVENT_NEWUSER, $this->store_id, 0, CouponAutoSend::EXT_SECOND_ORDER);
  691. }
  692. }
  693. }
  694. Worker::afterOrderSave($insert, $changedAttributes, $this);
  695. BookingOrderExt::afterOrderSave($insert, $changedAttributes, $this);
  696. \app\modules\admin\models\maiyatian\MaiyatianForm::afterOrderSave($insert, $changedAttributes, $this);
  697. \app\modules\admin\models\keloop\KeloopForm::afterOrderSave($insert, $changedAttributes, $this);
  698. \app\modules\admin\models\jushuitan\JuShuiTanForm::afterOrderSave($this, $changedAttributes);
  699. \app\models\ActivityRebateOrderNLog::afterOrderSave($insert, $changedAttributes, $this);
  700. \app\modules\admin\models\WastoreForm::afterOrderSave($insert, $changedAttributes, $this);
  701. \app\modules\admin\models\erp\InventoryForm::afterOrderSave($this, $insert, $changedAttributes);
  702. // 处理订单自动确认收货
  703. if (!$insert && isset($changedAttributes['trade_status']) && $this->trade_status == self::ORDER_FLOW_SEND && $this->order_source == 0) {
  704. $delivery_time = Option::get(OptionSetting::STORE_DELIVERY_TIME, $this->store_id, 'store', 0)['value'];
  705. //debug_log([__METHOD__, __LINE__, "处理订单自动确认收货:【{$this->id}】 售后时间:{$delivery_time}"], "app_debug.log");
  706. if ($delivery_time !== null) {
  707. $job = new \app\jobs\order\AutoConfirmOrderJob();
  708. $job->order_id = $this->id;
  709. $job->store_id = $this->store_id;
  710. $qid = \queue_push($job, (int)$delivery_time * 86400);
  711. }
  712. (new \app\utils\Share\BonusPool())->handleOrderAuto($this);
  713. }
  714. if (isset($changedAttributes['is_pay']) && $this->is_pay == self::IS_PAY_TRUE) {
  715. // (new \app\utils\OrderUtil())->OrderGrossProfit($this);
  716. // (new \app\utils\Share\BonusPool())->handleOrderAuto($this);
  717. // // \queue_push(new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]), 5);
  718. // // new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]);
  719. // // 创建任务实例
  720. // $job = new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]);
  721. // // 直接调用 execute() 方法来执行任务
  722. // $job->execute(null); // 如果不需要传递队列对象,可以传递 null
  723. //debug_log([__METHOD__, __LINE__, "============== 商城订单:【{$this->id}】 执行确认支付动作 =============="], "app_debug.log");
  724. }
  725. if (isset($changedAttributes['trade_status']) && $this->trade_status == self::ORDER_FLOW_CONFIRM) {
  726. // (new \app\utils\OrderUtil())->OrderGrossProfit($this);
  727. // (new \app\utils\Share\BonusPool())->handleOrderAuto($this);
  728. // // \queue_push(new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]), 5);
  729. // // new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]);
  730. // // 创建任务实例
  731. // $job = new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]);
  732. // // 直接调用 execute() 方法来执行任务
  733. // $job->execute(null); // 如果不需要传递队列对象,可以传递 null
  734. //debug_log([__METHOD__, __LINE__, "============== 商城订单:【{$this->id}】 执行确认收货动作 =============="], "app_debug.log");
  735. }
  736. // 处理订单确认收货后要做的事情
  737. if (!$insert && isset($changedAttributes['trade_status']) && $this->trade_status == self::ORDER_FLOW_CONFIRM && $this->order_source == 0) {
  738. //debug_log([__METHOD__, __LINE__, "============== 处理订单确认收货后id:【{$this->id}】 =============="], "app_debug.log");
  739. $after_sale_time = Option::get(OptionSetting::STORE_AFTER_SALE_TIME, $this->store_id, 'store', 0)['value'];
  740. $job = new \app\jobs\order\NoAfterSalesOrderJob();
  741. $job->order_id = $this->id;
  742. $job->store_id = $this->store_id;
  743. $delay = 0;
  744. if ($after_sale_time > 0) {
  745. $delay = $after_sale_time * 86400;
  746. }
  747. //需要兼容通联支付 t+1今天支付 明天的冻结余额才会增加 不能立即分账 否则出问题
  748. if (intval($this->pay_type) === self::PAY_TYPE_YUNST_WECHAT_PAY) {
  749. $today0 = strtotime(date('Y-m-d'));//今天0点时间
  750. if ($this->pay_time > $today0 && $delay < 86400) {
  751. $tomoTime = strtotime(date('Y-m-d', strtotime("+1 day"))) + 39600;
  752. $delay = $tomoTime - time();
  753. }
  754. }
  755. //兼容可能出现的股东分红会优先发放但是股东分红还未生成的情况
  756. //创建股东分红在订单支付之后 可能执行较慢 但是队列此时可能已经添加成功,可能会优先执行队列 导致先发后创建的问题
  757. if ($delay <= 0) {
  758. // $delay = 60;
  759. $delay = 10;
  760. }
  761. //debug_log([__METHOD__, __LINE__, "============== 重新执行 Order afterSave NoAfterSalesOrderJob,id:".$this->id." =======store_id:".$this->store_id."======="], "app_debug.log");
  762. \queue_push($job, $delay);
  763. \app\utils\Share\BonusPool::ShareHolderLevelJob($this->store_id, 0, $this->user_id);
  764. AutoSendCoupon::send($this->user_id, CouponAutoSend::EVENT_ORDER, $this->store_id);
  765. self::stbzConfirm($this);
  766. }
  767. if ($insert && in_array($this->order_type, [1,2])) {
  768. $autoCancleTime = \app\utils\OrderUtil::getAutoCancelTime($this->store_id);
  769. \queue_push(new \app\jobs\order\OrderBookNoPayJob(['order_id' => $this->id]), $autoCancleTime);
  770. }
  771. // if (($insert && $this->is_pay == 1) || (isset($changedAttributes['is_pay']) && $this->is_pay == 1)) {
  772. // (new \app\utils\OrderUtil())->OrderGrossProfit($this);
  773. // (new \app\utils\Share\BonusPool())->handleOrderAuto($this);
  774. // \queue_push(new OrderSendStringCodeRedPacketJob(['order_id' => $this->id, 'is_scan' => 0]), 5);
  775. // }
  776. if ($this->store_id && $this->user_id && !cache_lock(['ShareLevelJob', $this->store_id, $this->user_id], 30)) {
  777. \queue_push(new \app\jobs\ShareLevelJob(['store_id' => $this->store_id, 'user_id' => $this->user_id]), 30, 1);
  778. }
  779. if (!$insert && isset($changedAttributes['trade_status'])) {
  780. $res = \queue_push(new \app\jobs\AlipayThirdOrderJob(['order_id' => $this->id]), 5);
  781. }
  782. if ($insert && $this->trade_status == self::ORDER_FLOW_DEFAULT) {
  783. \queue_push(new OrderCancelJob(['order_id' => $this->id]), 900);
  784. }
  785. }
  786. public static function stbzGoodsHas($order) {
  787. $og = $order->goods;
  788. foreach($og as $item){
  789. if($item['stbz_goods_id']){
  790. return true;
  791. }
  792. }
  793. return false;
  794. }
  795. public static function stbzOrder($orderId) {
  796. try{
  797. $orderTransit = OrderTransit::findOne(['order_id' => $orderId, 'is_delete' => 0]);
  798. // var_dump($orderTransit->attributes);
  799. if($orderTransit){
  800. $thirdSn = $orderTransit->cloud_order_no;
  801. $stbzOrder = \stbz_client()->getApiResponse('get', '/v2/order', [
  802. 'search' => [
  803. 'thirdSn' => $thirdSn,
  804. ],
  805. 'page' => 1,
  806. 'limit' => 1,
  807. ]);
  808. $returnData = \json_decode($stbzOrder, true);
  809. // var_dump($returnData);
  810. if ($returnData['code'] == 1) {
  811. if($returnData['data'] && $returnData['data']['list']){
  812. foreach($returnData['data']['list'] as $orderList){
  813. return $orderList;
  814. }
  815. }
  816. }
  817. }
  818. } catch (\Exception $ex) {
  819. \Yii::error($ex);
  820. }
  821. return [];
  822. }
  823. public static function stbzConfirm($order) {
  824. try{
  825. $goods_sns = [];
  826. $orderList = self::stbzOrder($order->id);
  827. if($orderList['children']){
  828. foreach($orderList['children'] as $children){
  829. if($children['goods']){
  830. foreach($children['goods'] as $goods){
  831. $goods_sns[] = $goods['sn'];
  832. }
  833. }
  834. }
  835. }
  836. // var_dump($goods_sns);die;
  837. foreach($goods_sns as $goods_sn){
  838. $confirm = \stbz_client()->getApiResponse('post', '/v2/logistic/confirm', [
  839. 'goods_sn' => $goods_sn,
  840. ]);
  841. \Yii::error([__METHOD__, __LINE__, $order->id, $order->order_no, $orderList, $goods_sn, $confirm]);
  842. // var_dump($confirm);die;
  843. }
  844. } catch (\Exception $ex) {
  845. \Yii::error($ex);
  846. }
  847. }
  848. public function getPondDetail()
  849. {
  850. return $this->hasOne(OrderDetail::className(), ['order_id' => 'id']);
  851. }
  852. public function getPondGoods()
  853. {
  854. return $this->hasOne(Goods::className(), ['id' => 'goods_id'])->alias('g')
  855. ->viaTable(OrderDetail::tableName() . ' od', ['order_id' => 'id']);
  856. }
  857. public function getReceiver(){
  858. return $this->hasOne(SharingReceiver::className(),['order_no'=>'order_no']);
  859. }
  860. public function getStore(){
  861. return $this->hasOne(Store::className(),['id'=>'store_id']);
  862. }
  863. public static function getWxOrderLocalType($store_id, $order_no, $order) {
  864. /**
  865. *
  866. '1'=> [
  867. 'text' => '统一为快递',
  868. 'value' => 0
  869. ],
  870. '2' => [
  871. 'text' => '统一为同城配送',
  872. 'value' => 1
  873. ],
  874. '3' => [
  875. 'text' => '统一为虚拟发货',
  876. 'value' => 0
  877. ],
  878. '4' => [
  879. 'text' => '统一为用户自提',
  880. 'value' => 0
  881. ],
  882. '100' => [
  883. 'text' => '使用订单发货方式',
  884. 'value' => 0
  885. ],
  886. */
  887. $wx_local_type = Option::get(OptionSetting::STORE_WX_LOGISTICS_TYPE, $store_id)['value'];
  888. if(!$wx_local_type){
  889. $wx_local_type = 2;
  890. }
  891. if($wx_local_type == 1 && empty($order['express_no'])){
  892. $wx_local_type = 2;
  893. }
  894. if($wx_local_type == '100'){
  895. $wx_local_type = 2;
  896. $order = Order::findOne(['transaction_id' => $order_no]);
  897. if($order){
  898. $wx_local_type = 1;
  899. if($order['order_origin'] == Order::ORDER_SOURCE_CASHIER){
  900. $wx_local_type = 4;
  901. }
  902. if($order['order_type'] == Order::ORDER_TYPE_WORKER){
  903. $wx_local_type = 2;
  904. }
  905. if($order['is_delivery'] == 1){
  906. $wx_local_type = 2;
  907. }
  908. if($order['is_offline'] == 1){
  909. $wx_local_type = 4;
  910. }
  911. }
  912. }
  913. ////debug_log([__METHOD__, __LINE__, "====================|wx_local_type:".$wx_local_type], "app_debug_auto_cash_apply.log");
  914. return $wx_local_type;
  915. }
  916. public static function getStatusText($tradeStatus): string
  917. {
  918. return self::TRADE_STATUS_TEXT[$tradeStatus];
  919. }
  920. }