| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- <?php
- namespace addons\CloudStock\api\services;
- use addons\CloudStock\common\enums\CloudStockEnum;
- use addons\CloudStock\common\logic\order\PayNotify;
- use addons\CloudStock\common\logic\order\RestrictPurchases;
- use addons\CloudStock\common\models\CloudStockAgent;
- use addons\CloudStock\common\models\CloudStockBatchFillOrder;
- use addons\CloudStock\common\models\CloudStockFillOrder;
- use addons\CloudStock\common\models\CloudStockGoods;
- use addons\CloudStock\common\models\CloudStockLevel;
- use addons\CloudStock\common\models\CouponSetting;
- use addons\CloudStock\common\services\BaseService;
- use common\enums\AddonsEnum;
- use common\enums\StatusEnum;
- use common\helpers\FormatHelper;
- use common\helpers\StringHelper;
- use common\models\goods\Goods;
- use Exception;
- use RuntimeException;
- use Yii;
- class CloudStockFillOrderService extends BaseService
- {
- /**
- * 创建订单前验证
- *
- * @param int $goodsId
- * @param int $number
- *
- * @return array
- */
- public function createBeforeCheck(int $goodsId, int $number): array
- {
- // 当前会员是否可以补货当前商品
- $rr = CloudStockGoods::canFillGood($this->mall_id, $goodsId, $this->stock_agent->level, $this->user_id);
- if (false === $rr) {
- throw new RuntimeException(CloudStockGoods::getStaticError() ?: '暂不能补货当前商品');
- }
- $agent_level = $this->stock_agent->level;
- $level_model = CloudStockLevel::findOne(['mall_id' => $this->mall_id, 'level' => $agent_level, 'status' => StatusEnum::ENABLED]);
- if (!empty($level_model['is_open_fill_min']) && !empty($level_model['fill_min']) && $number < $level_model['fill_min']) {
- throw new RuntimeException('每次补货的最低数量为' . $level_model['fill_min']);
- }
- $all_stocks = CloudStockGoods::allPerantAgentGoodStocks($goodsId, $this->user_id, $this->mall_id);
- if (false === $all_stocks) {
- throw new RuntimeException(CloudStockGoods::getStaticError());
- }
- if ($number > $all_stocks) {
- throw new RuntimeException('补货数量超过了商品库存');
- }
- $stock_good = CloudStockGoods::findOne(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'goods_id' => $goodsId]);
- if (empty($stock_good)) {
- throw new RuntimeException('商品数据异常');
- }
- if (!empty($stock_good['min_replenish']) && $number < $stock_good['min_replenish']) {
- throw new RuntimeException('最低补货数量:' . $stock_good['min_replenish']);
- }
- if (!empty($stock_good['restrict_permissions'])) {
- $restrict_permissions = json_decode($stock_good['restrict_permissions'], true);
- if (!empty($restrict_permissions)) {
- $cloud_stock_agent = CloudStockAgent::find()->where(['user_id' => $this->user_id, 'status' => StatusEnum::ENABLED, 'mall_id' => $this->mall_id])->one();
- if (in_array($cloud_stock_agent['level'], $restrict_permissions)) {
- throw new RuntimeException('您当前等级禁止购买此商品');
- }
- }
- }
- try {
- RestrictPurchases::check($this->mall_id, $this->user_id, [$goodsId], $number);
- } catch (Exception $e) {
- throw new RuntimeException($e->getMessage());
- }
- return [
- 'stock_good' => $stock_good
- ];
- }
- /**
- * 购物车订单预览
- *
- * @param array $goodsNumberArr
- *
- * @return array
- */
- public function preview(array $goodsNumberArr): array
- {
- if (empty($goodsNumberArr)) {
- return [];
- }
- $goodsList = Goods::lists([
- 'select' => 'id, goods_name, cover_pic, price, stock',
- 'where' => [
- [
- 'mall_id' => $this->mall_id,
- 'status' => StatusEnum::ENABLED,
- 'id' => array_column($goodsNumberArr, 'goods_id'),
- 'is_on_sale' => 1,
- 'is_attr' => 0
- ]
- ],
- 'index' => 'id'
- ]);
- $cloudStockGoodsList = CloudStockGoods::lists([
- 'where' => [
- [
- 'mall_id' => $this->mall_id,
- 'status' => StatusEnum::ENABLED,
- 'goods_id' => array_column($goodsList, 'id')
- ]
- ],
- 'select' => 'id, goods_id, agent_price, is_allow_fill, is_take_by_range, min_replenish,is_buhuo,is_peihuo'
- ]);
- $goodsNumberArr = array_column($goodsNumberArr, null, 'goods_id');
- $is_buhuo_arr = [];
- foreach ($cloudStockGoodsList as &$item) {
- $item['num'] = $goodsNumberArr[$item['goods_id']]['num'];
- $item['goods_info'] = $goodsList[$item['goods_id']] ?? [];
- $item['give_text'] = '';
- if($item['is_buhuo'] == 1){
- $is_buhuo_arr[] = [
- 'goods_id'=>$item['goods_id'],
- 'num'=>$item['num'],
- ];
- }
- }
- unset($item);
- $goodsService = new CloudStockGoodsService(['user_id' => $this->user_id, 'mall_id' => $this->mall_id, 'stock_agent' => $this->stock_agent]);
- $totalAmount = $goodsService->getTotalOrderFields(
- $cloudStockGoodsList,
- $goodsList,
- array_column($goodsNumberArr, 'num', 'goods_id')
- );
- $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
- $give_text_arr = [];
- if(empty($is_buhuo_arr) == false){
- $coupon = CouponSetting::getGiveCoupon($this->mall_id,$is_buhuo_arr,$this->stock_agent->level);
- foreach ($is_buhuo_arr as $item){
- if(empty($coupon[$item['goods_id']]) == false){
- $give_text = '当前商品一次性补货每满'.$coupon[$item['goods_id']]['rule_num'].'件('.$coupon[$item['goods_id']]['rule_num'].'的整数倍),可获得';
- $coupon_text = [];
- foreach ($coupon[$item['goods_id']]['coupon_arr'] as $arr){
- $coupon_text[] = $arr['num'].'张“'.$arr['name'].'”';
- }
- $give_text .= implode('、',$coupon_text).'优惠券';
- $give_text_arr[$item['goods_id']] = $give_text;
- }
- }
- foreach ($cloudStockGoodsList as $key=>$item){
- if(isset($give_text_arr[$item['goods_id']])){
- $cloudStockGoodsList[$key]['give_text'] = $give_text_arr[$item['goods_id']];
- }
- }
- }
- return [
- 'goods_list' => $cloudStockGoodsList,
- 'total_amount' => $totalAmount,
- 'condition' => json_decode($configs['rand_condition'] ?? '', true),
- 'is_enable_rand_fee' => $configs['is_enable_rand_fee'] ?? 0,
- 'give_text' => $give_text_arr
- ];
- }
- /**
- * 过滤不能下单的商品
- *
- * @return void
- */
- public function filterGoods(array &$goodsNumberArr)
- {
- $csGoodsService = new CloudStockGoodsService(['user_id' => $this->user_id, 'mall_id' => $this->mall_id, 'stock_agent' => $this->stock_agent]);
- $enableGoodsList = $csGoodsService->getEnableGoodsList(array_column($goodsNumberArr, 'goods_id'));
- foreach ($goodsNumberArr as $key => $item) {
- if (!in_array($item['goods_id'], $enableGoodsList)) {
- unset($goodsNumberArr[$key]);
- }
- }
- }
- /**
- * @param array $cartList
- *
- * @return array
- * @throws Exception
- */
- public function batchFill(array $cartList): array
- {
- $transaction = Yii::$app->db->beginTransaction();
- $fillResArr = [];
- $order_trade_info = [];
- try {
- foreach ($cartList as $item) {
- $fillRes = $this->fill(['goods_id' => $item['goods_id'], 'number' => $item['num']]);
- // 创建支付流水
- $order_trade_info[] = [
- 'order_no' => $fillRes['order_no'],
- 'amount' => $fillRes['pay_money'],
- 'title' => '云库存补货订单',
- 'notify_class' => PayNotify::class,
- 'order_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
- ];
- $fillResArr[] = $fillRes;
- }
- //
- $batchFillOrder = CloudStockBatchFillOrder::setData([
- 'mall_id' => $this->mall_id,
- 'user_id' => $this->user_id,
- 'full_order_info' => $fillResArr,
- ]);
- if ($batchFillOrder === false || empty($batchFillOrder['id'])) {
- throw new RuntimeException(CloudStockBatchFillOrder::getStaticError() ?: '创建补货订单失败');
- }
- $transaction->commit();
- } catch (Exception $e) {
- Yii::$app->custom->logs(FormatHelper::exception($e, '批量补货报错'), compact('cartList', 'fillResArr', 'order_trade_info'));
- $transaction->rollBack();
- throw $e;
- }
- $res_trade = Yii::$app->services->pay->createTrade($this->mall_id, $this->user_id, $order_trade_info);
- if ($res_trade == false) {
- throw new RuntimeException('生成支付流水失败');
- }
- $transaction = Yii::$app->db->beginTransaction();
- try {
- // 更新批量补货订单
- CloudStockBatchFillOrder::setData([
- 'mall_id' => $this->mall_id,
- 'id' => $batchFillOrder['id'],
- 'trade_id' => $res_trade['trade_id'],
- 'trade_no' => $res_trade['trade_no']
- ]);
- // 更新补货订单支付流水
- CloudStockFillOrder::updateAll(
- [
- 'updated_at' => time(),
- 'trade_id' => $res_trade['trade_id'],
- 'trade_no' => $res_trade['trade_no'],
- 'batch_fill_order_id' => $batchFillOrder['id']
- ],
- [
- 'mall_id' => $this->mall_id,
- 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED],
- 'id' => array_column($fillResArr, 'fill_order_id')
- ]
- );
- // 购物车改为已下单状态
- (new CloudStockFillCartService(['user_id' => $this->user_id, 'mall_id' => $this->mall_id]))->cart2Order($batchFillOrder['id']);
- $transaction->commit();
- } catch (Exception $e) {
- Yii::$app->custom->logs(FormatHelper::exception($e, '批量补货报错'), compact('cartList', 'fillResArr', 'order_trade_info'));
- $transaction->rollBack();
- throw $e;
- }
- // 获取设置
- $configs = Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
- $is_enable_rand_fee = $configs['is_enable_rand_fee'] ?? 0;
- return [
- 'trade_no' => $res_trade['trade_no'],
- 'trade_id' => $res_trade['trade_id'],
- 'order_ids' => array_column($fillResArr, 'fill_order_id'),
- 'is_enable_rand_fee' => $is_enable_rand_fee,
- 'batch_order_id' => $batchFillOrder['id']
- ];
- }
- /**
- * 补货单件补货
- *
- * @param array $post
- *
- * @return array
- */
- public function fill(array $post)
- {
- $checkRes = $this->createBeforeCheck($post['goods_id'], $post['number']);
- if (empty($checkRes['stock_good'])) {
- throw new RuntimeException('提交信息异常');
- }
- $stock_good = $checkRes['stock_good'];
- $agent_price = json_decode($stock_good['agent_price'], true);
- $agent_price = array_column($agent_price, null, 'level');
- $unit_price = 0;
- if (!empty($agent_price[$this->stock_agent->level])) {
- $unit_price = $agent_price[$this->stock_agent->level]['price'];
- if (!empty($stock_good['is_take_by_range'])) {
- foreach ($agent_price[$this->stock_agent->level]['price_list'] as $item) {
- if ($item['start_num'] <= $post['number'] && $post['number'] <= $item['end_num']) {
- $unit_price = $item['price'];
- }
- }
- }
- }
- if ($unit_price <= 0) {
- throw new RuntimeException('商品配置异常,请稍后再试');
- }
- $pay_money = bcmul($unit_price, $post['number'], 2);
- $order_no = StringHelper::generateOrderNo('CSF');
- $params = [
- 'user_id' => $this->user_id,
- 'pay_money' => $pay_money,
- 'order_no' => $order_no,
- 'is_pay' => CloudStockEnum::FILL_STATUS_NOT_PAY,
- 'goods_id' => $post['goods_id'],
- 'num' => $post['number'],
- ];
- $res_fill_order = CloudStockFillOrder::setData($this->mall_id, $params);
- if (false === $res_fill_order) {
- throw new RuntimeException(CloudStockFillOrder::getStaticError());
- }
- return [
- 'fill_order_id' => $res_fill_order['id'],
- 'order_no' => $order_no,
- 'pay_money' => $pay_money,
- ];
- }
- /**
- * @param int $batchOrderId
- *
- * @return void
- */
- public function getBatchFillOrderDetails(int $batchOrderId): array
- {
- // 获取设置
- $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
- $batchOrder = CloudStockBatchFillOrder::getOne(
- [
- [
- 'mall_id' => $this->mall_id,
- 'user_id' => $this->user_id,
- 'id' => $batchOrderId,
- 'status' => StatusEnum::ENABLED
- ]
- ],
- true,
- [
- 'fillOrders' => function ($query) {
- $query
- ->select('id, batch_fill_order_id, order_no, goods_id, num, created_at')
- ->with([
- 'goods' => function ($query) {
- $query->select('id, cover_pic, goods_name, price');
- }
- ]);
- },
- 'paymentTrade' => function ($query) {
- $query->select('id, pay_fee, rand_fee, total_fee, pay_time');
- }
- ],
- false,
- 'id, trade_id'
- );
- if (empty($batchOrder)) {
- return [];
- }
- if (!empty($batchOrder['paymentTrade'])) {
- $batchOrder['paymentTrade']['pay_time_text'] = date('Y-m-d H:i:s', $batchOrder['paymentTrade']['pay_time']);
- }
- if (!empty($batchOrder['fillOrders'])) {
- foreach ($batchOrder['fillOrders'] as &$fillOrder) {
- $fillOrder['created_at_text'] = date('Y-m-d H:i:s', $fillOrder['created_at']);
- }
- }
- return [
- 'order_info' => $batchOrder,
- 'is_enable_rand_fee' => $configs['is_enable_rand_fee'] ?? 0
- ];
- }
- }
|