cxfoot/models/common/integral/mall/CommonIntegralMallOrderSubmitForm.php
2023-10-27 14:25:12 +08:00

223 lines
8.8 KiB
PHP

<?php
/**
* @author Any
* @description KISS
* @date 2021年10月13日
* @version 1.0.0
*
* _____LOG_____
*
*/
namespace app\models\common\integral\mall;
use app\models\common\CommonGoodsListForm;
use app\models\integral\mall\IntegralMallGoods;
use app\models\integral\mall\IntegralMallGoodsAttr;
use app\models\integral\Integral;
use app\models\integral\mall\IntegralMallOrder;
use app\models\Goods;
use app\models\GoodsHub;
use app\models\Order;
use app\models\OrderDetail;
use app\models\Address;
use app\models\Model;
use app\models\UniqueOrderNo;
use app\components\SiteHelper;
use app\components\SysConst;
use app\components\Serializer;
use app\components\FlashStorage;
use app\models\PaymentTypes;
use app\models\common\payment\Payment;
use app\models\common\payment\PaymentOrder;
class CommonIntegralMallOrderSubmitForm extends Model
{
public $cx_mch_id;
public $goods_info;
public $user_id;
public $address_id;
public $pay_type;
public $remark;
public function rules()
{
return [
[['pay_type', 'remark'], 'trim'],
[['pay_type', 'remark'], 'string'],
[['goods_info'], 'safe'],
[['cx_mch_id', 'user_id', 'address_id'], 'integer'],
[['pay_type'], 'default' , 'value' => SysConst::$cxPayTypeEnIntegral],
[['cx_mch_id', 'goods_info', 'user_id', 'address_id'], 'required'],
];
}
public function save()
{
if(!$this->validate()){
return $this->getModelError();
}
//商品信息
$form = new CommonIntegralMallOrderDataForm();
$form->cx_mch_id = $this->cx_mch_id;
$form->user_id = $this->user_id;
$form->goods_info = $this->goods_info;
$res = $form->search();
if($res['code'] != 0)
return $res;
$pay_data = $res['data'];
$goods_list = $pay_data['goods_list'];
$pay_types = $pay_data['pay_types'];
//@TODO 并发情况 检查商品库存是否充足
$res = $this->checkGoodsStock($goods_list);
if($res['code'] != 0)
return $res;
//收货地址
$address = Address::findOne(['user_id' => $this->user_id, 'cx_mch_id' => $this->cx_mch_id, 'is_delete' => 0, 'id' => $this->address_id]);
if($address == null){
return $this->apiReturnError('所选收货地址不存在');
}
//支付方式检查
$res = $this->checkPayType($goods_list, $pay_types);
if($res['code'] != 0)
return $res;
//下订单
$t = \Yii::$app->db->beginTransaction();
$order = new Order();
$order->plugin_sign = SysConst::$cxPluginSceneIntegralMall;
$order->cx_mch_id = $this->cx_mch_id;
$order->user_id = $this->user_id;
$order->order_no = UniqueOrderNo::generate(UniqueOrderNo::ORDER_TYPE_INTEGRAL_MALL_ORDER,"\\app\models\Order");
$express_price = 0;
$coupon_discount_price = 0;
$total_discount_price = $coupon_discount_price + 0;
$use_user_coupon_id = 0;
$total_goods_original_price = array_sum(array_column($goods_list, 'price'));
$total_goods_original_price = sprintf('%.2f',$total_goods_original_price);
$total_goods_price = $total_goods_original_price - $total_discount_price;
$total_price = $express_price + $total_goods_price;
$total_price = sprintf('%.2f',$total_price);
$order->total_price = $total_price;
$order->total_pay_price = 0;
$order->express_original_price = $express_price;
$order->express_price = $express_price;
$order->total_goods_price = $total_goods_price;
$order->total_goods_original_price = $total_goods_original_price;
$order->use_user_coupon_id = $use_user_coupon_id;
$order->coupon_discount_price = $coupon_discount_price;
$order->name = $address->name;
$order->mobile = $address->mobile;
$order->address = $address->province.$address->city.$address->district.$address->detail;
$order->location = $address->location;
$order->remark = $this->remark;
$order->is_pay = 0;
$order->pay_type = 0;
$support_pay_types = array_column($pay_types, 'short_name');
$order->support_pay_types = json_encode($support_pay_types,JSON_UNESCAPED_UNICODE);
if(!$order->save()){
$t->rollBack();
return $this->getModelError($order);
}
//订单详情
$res = $this->saveOrderDetail($goods_list, $order->id);
if($res['code'] != 0){
$t->rollBack();
return $res;
}
//积分订单
$integral_mall_order = IntegralMallOrder::findOne(['cx_mch_id' => $this->cx_mch_id, 'order_id' => $order->id, 'is_delete' => 0]);
if($integral_mall_order == null){
$integral_mall_order = new IntegralMallOrder();
$integral_mall_order->cx_mch_id = $this->cx_mch_id;
$integral_mall_order->order_id = $order->id;
}
$total_integral_num = array_sum(array_column($goods_list, 'total_integral_num'));
$integral_mall_order->integral_num = $total_integral_num;
if(!$integral_mall_order->save()){
$t->rollBack();
return $this->getModelError($integral_mall_order);
}
$title = "积分兑换".$goods_list[0]['name'];
$paymentOrder = new PaymentOrder([
'orderNo' => $order->order_no,
'amount' => (float)$order->total_price,
'title' => $title,
'notifyClass' => '\\app\\models\\common\\notify\\payment\\IntegralMallOrderPaymentNotify',
'supportPayTypes' => array_column($pay_types, 'short_name'),
'payType' => PaymentTypes::payTypeKeyToId($this->pay_type)
]);
$payment = new Payment();
$paymentOrders[] = $paymentOrder;
$res = $payment->createOrder($paymentOrders);
if($res['code'] != 0){
$t->rollBack();
return $res;
}
$t->commit();
return $res;
}
private function checkGoodsStock($goods_list)
{
foreach ($goods_list as $index => $item){
if(!$item['has_stock']){
return $this->apiReturnError("{$item['name']}商品库存不足");
}
}
return $this->apiReturnSuccess();
}
private function checkPayType($goods_list, $pay_types)
{
if(!in_array($this->pay_type, array_column($pay_types, 'short_name'))){
return $this->apiReturnError('无效支付方式');
}
$total_integral_num = array_sum(array_column($goods_list, 'integral_num'));
if($this->pay_type == SysConst::$cxPayTypeEnIntegral){
//积分账户余额是否充足
$integral_model = Integral::findOne(['user_id' => $this->user_id, 'scene' => Integral::SCENARIO_DEFAULT, 'cx_mch_id' => $this->cx_mch_id, 'is_delete' => 0]);
if($integral_model == null || $integral_model->account_integral < $total_integral_num){
return $this->apiReturnError('积分账户余额不足');
}
}
return $this->apiReturnSuccess();
}
private function saveOrderDetail($goods_list, $order_id)
{
foreach ($goods_list as $index => $item){
$order_detail = OrderDetail::findOne(['order_id' => $order_id, 'goods_id' => $item['id']]);
if($order_detail == null){
$order_detail = new OrderDetail();
$order_detail->cx_mch_id = $this->cx_mch_id;
$order_detail->order_id = $order_id;
$order_detail->goods_id = $item['id'];
}
$order_detail->num = $item['goods_num'];
$order_detail->unit_price = $item['price'];
$order_detail->total_original_price = $item['total_original_price'];
$order_detail->total_price = $item['total_original_price'];
$order_detail->goods_attr_info = json_encode($item['goods_attr_info'], JSON_UNESCAPED_UNICODE);
$order_detail->plugin_sign = SysConst::$cxPluginSceneIntegralMall;
$order_detail->serial_no = $item['goods_attr_info']['serial_no'];
$order_detail->goods_type = $item['type'];
if(!$order_detail->save()){
return $this->getModelError($order_detail);
}
$res = Goods::handleStock($order_detail->goods_id, $item['goods_attr_info']['id'], $order_detail->num, Goods::STOCK_DECREASE, $this->cx_mch_id);
if($res['code'] != 0)
return $res;
}
return $this->apiReturnSuccess();
}
}