Refund.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <?php namespace Porder\Lib\Source;
  2. use Dever;
  3. class Refund
  4. {
  5. # 前台审核
  6. public function audit($id, $type, $info, $address_id, $utype, $uid)
  7. {
  8. $refund = Dever::db('porder/source_refund')->find($id);
  9. if ($refund['status'] == 1) {
  10. if ($type == 1) {
  11. $refund['status'] = $update['status'] = 2;
  12. $update['pdate'] = time();
  13. $desc = '退款:审核通过';
  14. } else {
  15. $update['status'] = 5;
  16. $update['pdate'] = time();
  17. $update['fdate'] = time();
  18. $desc = '退款:审核驳回';
  19. Dever::db('porder/source')->update($refund['order_id'], ['refund_status' => 2]);
  20. }
  21. $update['audit_desc'] = $info;
  22. if ($address_id) {
  23. $update['address_id'] = $address_id;
  24. }
  25. Dever::db('porder/source_refund')->update($refund['id'], $update);
  26. if ($update['audit_desc']) {
  27. $desc .= '-' . $update['audit_desc'];
  28. }
  29. Dever::load(\Porder\Lib\Source\Log::class)->up($utype, $uid, $refund['order_id'], $desc);
  30. if ($refund['type'] == 2 && $refund['status'] == 2) {
  31. # 仅退款
  32. $order = Dever::db('porder/source')->find($refund['order_id']);
  33. $this->finish($order, $refund);
  34. }
  35. }
  36. return 'ok';
  37. }
  38. # 前台审核退货
  39. public function auditDelivery($id, $type, $info, $utype, $uid)
  40. {
  41. $refund = Dever::db('porder/source_refund')->find($id);
  42. if ($refund['status'] == 3) {
  43. if ($type == 1) {
  44. $refund['status'] = $update['status'] = 2;
  45. $update['delivery_pdate'] = time();
  46. $desc = '退款:审核通过';
  47. } else {
  48. $update['status'] = 6;
  49. $update['delivery_pdate'] = time();
  50. $update['fdate'] = time();
  51. $desc = '退款:审核驳回';
  52. Dever::db('porder/source')->update($refund['order_id'], ['refund_status' => 2]);
  53. }
  54. $update['delivery_audit_desc'] = $info;
  55. Dever::db('porder/source_refund')->update($refund['id'], $update);
  56. if ($update['delivery_audit_desc']) {
  57. $desc .= '-' . $update['delivery_audit_desc'];
  58. }
  59. Dever::load(\Porder\Lib\Source\Log::class)->up($utype, $uid, $refund['order_id'], $desc);
  60. if ($refund['status'] == 2) {
  61. $order = Dever::db('porder/source')->find($refund['order_id']);
  62. $this->finish($order, $refund);
  63. }
  64. }
  65. return 'ok';
  66. }
  67. # 买家发货
  68. public function express($order, $refund_id, $delivery_id, $content)
  69. {
  70. $refund = Dever::db('porder/source_refund')->find($refund_id);
  71. if ($refund['status'] == 2) {
  72. $update['status'] = 3;
  73. $update['ddate'] = time();
  74. $where = ['source_refund_id' => $refund['id']];
  75. $info = Dever::db('porder/source_refund_express')->find($where);
  76. if (!$info) {
  77. $where['order_id'] = $order['id'];
  78. $where['delivery_id'] = $delivery_id;
  79. $where['content'] = $content;
  80. Dever::db('porder/source_refund_express')->insert($where);
  81. Dever::load(\Porder\Lib\Source\Log::class)->up(1, $order['uid'], $order['id'], '退款:买家已发货');
  82. }
  83. Dever::db('porder/source_refund')->update($refund['id'], $update);
  84. }
  85. }
  86. # 完成退款 如果是支付订单,原路退回
  87. public function finish($order, $refund)
  88. {
  89. $refund = Dever::db('porder/source_refund')->find($refund['id']);
  90. if ($refund['status'] == 2 || $refund['status'] == 3) {
  91. # 查找已退款金额
  92. $history = Dever::db('porder/source_refund')->sum(['order_id' => $order['id'], 'status' => 4], 'cash');
  93. # 更新状态
  94. Dever::db('porder/source_refund')->update($refund['id'], ['status' => 4, 'fdate' => time()]);
  95. $score = Dever::load(\Pscore\Lib\Info::class)->get($order['score_id']);
  96. # 检测订单是否全都退了
  97. if ($history + $refund['cash'] >= $order['cash']) {
  98. Dever::db('porder/source')->update($order['id'], ['status' => 8, 'fdate' => time(), 'refund_status' => 2, 'refund_cash' => $order['cash']]);
  99. Dever::load(\Porder\Lib\Source\Log::class)->up(1, $order['uid'], $order['id'], '订单已全额退款');
  100. # 退货 恢复库存
  101. if ($refund['type'] == 1) {
  102. Dever::load(\Pstock\Lib\Info::class)->refundAll($order);
  103. }
  104. } else {
  105. # 只退了一部分
  106. $refund_detail = Dever::db('porder/source_refund_detail')->select(['source_refund_id' => $refund['id']]);
  107. if ($refund_detail) {
  108. foreach ($refund_detail as $k => $v) {
  109. Dever::db('porder/source_detail')->update($v['detail_id'], ['refund_cash' => ['+', $v['cash']], 'refund_num' => ['+', $v['num']]]);
  110. if ($v['num'] > 0 && $refund['type'] == 1) {
  111. # 恢复库存
  112. $detail = Dever::db('porder/source_detail')->find($v['detail_id']);
  113. Dever::load(\Pstock\Lib\Info::class)->refund($order, $detail['source_id'], $detail['sku_id'], $v['num']);
  114. }
  115. }
  116. # 重新计算返利
  117. $rebate = Dever::db('porder/rebate')->find(['table' => 'source', 'table_id' => $order['id']]);
  118. if ($rebate) {
  119. $detail = Dever::db('porder/source_detail')->select(['order_id' => $order['id']]);
  120. if ($detail) {
  121. $rebate = ['rule' => []];
  122. Dever::db('porder/rebate')->delete(['table' => 'source', 'table_id' => $order['id']]);
  123. Dever::db('pscore/user_log')->delete(['relation' => 'source_order_' . $order['id']]);
  124. foreach ($detail as $k => $v) {
  125. if ($v['pay_cash'] > 0) {
  126. $v['pay_cash'] -= $v['refund_cash'];
  127. if ($v['pay_cash'] > 0) {
  128. $money = Dever::math('mul', $v['pay_cash'], $score['exp']);
  129. $rebate = Dever::load(\Pbenefit\Lib\Item::class)->load('rebate')->get($order['uid'], $v['scope'], $money, $rebate['rule']);
  130. }
  131. }
  132. }
  133. if ($rebate && $rebate['rule']) {
  134. foreach ($rebate['rule'] as $v1) {
  135. $v1['table'] = 'source';
  136. $v1['table_id'] = $order['id'];
  137. $v1['rebate_rule_id'] = $v1['id'];
  138. unset($v1['id']);
  139. Dever::db('porder/rebate')->insert($v1);
  140. if ($v1['level'] == 0) {
  141. # 给自己返利
  142. Dever::load(\Pscore\Lib\Log::class)->action('返利', $v1['score_id'])->add($order['uid'], $v1['name'], $v1['value'], 2, 'source_order_' . $order['id']);
  143. } else {
  144. # 给上级返利
  145. $parent = Dever::load(\Invite\Lib\Relation::class)->getParent($order['uid'], $v1['level']);
  146. if ($parent) {
  147. Dever::load(\Pscore\Lib\Log::class)->action('返利', $v1['score_id'])->add($parent['uid'], $v1['name'], $v1['value'], 2, 'source_order_' . $order['id']);
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. Dever::db('porder/source')->update($order['id'], ['refund_status' => 2, 'refund_cash' => ['+', $refund['cash']]]);
  156. Dever::load(\Porder\Lib\Source\Log::class)->up(1, $order['uid'], $order['id'], '订单已部分退款');
  157. }
  158. # 开始退款
  159. $cash = $this->getCash($order, $refund['cash'], $history);
  160. # 退支付金额
  161. if ($cash['pay_cash'] > 0) {
  162. # 走支付退款流程
  163. $sector_id = $place_id = 0;
  164. if (class_exists('\\Place')) {
  165. $sector_id = Dever::get('Place')->sector['id'];
  166. $place_id = Dever::get('Place')->info['id'];
  167. } elseif ($muser = Dever::getData('muser')) {
  168. $sector_id = $muser['select']['info_id'];
  169. $place_id = $muser['select']['data_id'];
  170. }
  171. $money = Dever::math('mul', $cash['pay_cash'], $score['exp']);
  172. $state = Dever::load(\Place\Lib\Account::class)->refund($order['order_num'], $order['pay_money_cash'], $money, $order['order_num'] . '_' . $refund['id'], $sector_id, $place_id, 'source');
  173. print_r($state);die;
  174. Dever::db('porder/source_refund')->update($refund['id'], ['pay_status' => 2]);
  175. }
  176. echo 11;die;
  177. # 退余额
  178. if ($cash['wallet_cash'] > 0) {
  179. Dever::load(\Pscore\Lib\Log::class)->action('退款', $order['score_id'])->add($order['uid'], '订单号:'.$order['order_num'], $cash['wallet_cash']);
  180. }
  181. # 退礼品卡
  182. if ($cash['gift_cash'] > 0) {
  183. $order['gift_cash'] = $cash['gift_cash']*-1;
  184. Dever::load(\Puser\Lib\Gift::class)->use('source', $order, $score);
  185. }
  186. # 退优惠券
  187. if ($cash['coupon_cash'] > 0) {
  188. $order['coupon_cash'] = $cash['coupon_cash']*-1;
  189. Dever::load(\Puser\Lib\Coupon::class)->use('source', $order, $score);
  190. }
  191. }
  192. }
  193. # 计算退款金额
  194. public function getCash($order, $refund_amount, $history_refunded)
  195. {
  196. $keys = ['pay_cash', 'wallet_cash', 'gift_cash', 'coupon_cash'];
  197. $totals = [];
  198. foreach ($keys as $key) {
  199. $totals[$key] = $order[$key] ?? 0;
  200. }
  201. $refund = array_fill_keys($keys, 0);
  202. $already = min($history_refunded, array_sum($totals));
  203. $remain = max(0, $refund_amount);
  204. if ($remain <= 0) return $refund;
  205. foreach ($totals as $type => $amount) {
  206. if ($remain <= 0) break;
  207. $available = $amount > $already ? $amount - $already : 0;
  208. $already = $already > $amount ? $already - $amount : 0;
  209. $refund[$type] = min($available, $remain);
  210. $remain -= $refund[$type];
  211. }
  212. return $refund;
  213. }
  214. public function up($detail, $order, $utype, $uid, $type, $method, $desc_type, $desc)
  215. {
  216. $cash = 0;
  217. # 计算已退款的金额
  218. $where = ['order_id' => $order['id'], 'status' => 4];
  219. $refund = Dever::db('porder/source_refund')->find($where, ['col' => 'sum(cash) as cash']);
  220. if ($refund && $refund['cash']) {
  221. $order['cash'] -= $refund['cash'];
  222. }
  223. if ($method == 2) {
  224. if ($detail) {
  225. foreach ($detail as $k => $v) {
  226. $info = Dever::db('porder/source_detail')->find($v['detail_id']);
  227. $info['num'] -= $info['refund_num'];
  228. $info['total_cash'] -= $info['refund_cash'];
  229. if ($v['cash'] > $info['total_cash']) {
  230. Dever::error('退款金额不能大于剩余金额');
  231. }
  232. if ($v['num'] > 0 && $v['num'] > $info['num']) {
  233. Dever::error('退款数量不能大于剩余数量');
  234. }
  235. $cash += $v['cash'];
  236. }
  237. } else {
  238. Dever::error('请选择退款明细');
  239. }
  240. } else {
  241. $cash = $order['cash'];
  242. }
  243. $where = ['order_id' => $order['id'], 'refund_status' => 1];
  244. if ($cash > $order['cash']) {
  245. Dever::error('退款金额不能大于订单剩余总金额');
  246. }
  247. $update = $where;
  248. $update['refund_status'] = 2;
  249. $update['status'] = ['<', '4'];
  250. $refund = Dever::db('porder/source_refund')->find($update);
  251. $update['utype'] = $utype;
  252. $update['uid'] = $uid;
  253. $update['type'] = $type;
  254. $update['desc_type'] = $desc_type;
  255. $update['cash'] = $cash;
  256. $update['desc'] = $desc;
  257. $update['status'] = 1;
  258. if ($refund) {
  259. Dever::error('您有退款进行中,请先处理');
  260. } else {
  261. $id = Dever::db('porder/source_refund')->insert($update);
  262. if ($id) {
  263. Dever::db('porder/source')->update($order['id'], ['refund_status' => 1]);
  264. if ($detail) {
  265. foreach ($detail as $k => $v) {
  266. $v['source_refund_id'] = $id;
  267. Dever::db('porder/source_refund_detail')->insert($v);
  268. }
  269. }
  270. $msg = '退款:提交退款申请单';
  271. Dever::load(\Porder\Lib\Source\Log::class)->up($utype, $uid, $order['id'], $msg);
  272. }
  273. }
  274. }
  275. # 获取信息
  276. public function getList($order_id)
  277. {
  278. $refund = Dever::db('porder/source_refund')->select(['order_id' => $order_id]);
  279. if ($refund) {
  280. foreach ($refund as &$v) {
  281. $v = $this->getInfo($v);
  282. }
  283. }
  284. return $refund;
  285. }
  286. # 获取信息
  287. public function getInfo($info)
  288. {
  289. print_r($info);die;
  290. if ($info['type'] == 1) {
  291. $user = Dever::db('puser/info')->find($info['type_id']);
  292. } elseif ($info['type'] == 2) {
  293. $user = Dever::db('sector/user')->find($info['type_id']);
  294. } elseif ($info['type'] == 3) {
  295. $user = Dever::db('place/supplier')->find($info['type_id']);
  296. } else {
  297. $user['name'] = $user['mobile'] = '-';
  298. }
  299. $info['type'] = Dever::db('porder/source_log')->value('type', $info);
  300. $info['name'] = $user['name'];
  301. $info['mobile'] = $user['mobile'];
  302. $info['cdate_str'] = date('Y-m-d H:i:s', $info['cdate']);
  303. return $info;
  304. }
  305. }