StoreGoodsReserve.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. namespace addons\Store\common\models;
  3. use common\models\common\Region;
  4. use Exception;
  5. use Yii;
  6. use yii\helpers\ArrayHelper;
  7. use yii\helpers\Json;
  8. /**
  9. * This is the model class for table "qimall_addons_store_goods_reserve".
  10. *
  11. * @property int $id
  12. * @property int $mall_id 商城id
  13. * @property int $store_id 商家id
  14. * @property int $goods_id 商品id
  15. * @property float $price 售价
  16. * @property float $original_price 原价(划线价仅展示)
  17. * @property float $cost_price 成本价
  18. * @property int $reserve_date_type 可预约时间类型(1范围 2自选日期)
  19. * @property string|null $reserve_week 可预约周
  20. * @property string|null $reserve_date 可预约日期
  21. * @property int $reserve_time_range_type 预约模式(1按天预约 2按时间段预约)
  22. * @property int $time_slot_type 时间段划分方式(1自定义划分 2自动划分)
  23. * @property string|null $reserve_time_slot 时间段划分
  24. * @property int $reserve_price_type 价格设置方式(0统一售价 1按日期时间段设置)
  25. * @property string|null $reserve_time_slot_price 时间段价格设置
  26. * @property int $reserve_max_buy 每天最大预约数量
  27. * @property int $reserve_advance_hourse 提前预约时间(小时)
  28. * @property int $reserve_days_range 限制选择并购买的时间在设置内天数的商品
  29. * @property int $cancel_type 取消类型(1不允许取消 2服务开始前取消 3订单类型取消)
  30. * @property string $cancel_rule 取消退款规则
  31. * @property int $expired_handle_type 预约码过期后处理方式(1不退款 2自动退款)
  32. * @property int $province_id 省ID
  33. * @property int $city_id 市ID
  34. * @property int $district_id 区县ID
  35. * @property string $detail 详细地址
  36. * @property string $lat 纬度
  37. * @property string $lng 经度
  38. * @property string $region_name 省市区字符串
  39. * @property int $service_type 服务方式(1上门 2到店)
  40. * @property int $created_at 创建时间
  41. * @property int $updated_at 修改时间
  42. * @property string $ordering_information 订购须知
  43. * @property string $information_detail 须知详情
  44. * @property int $reserve_type 0商品预约,1项目服务预约
  45. * @property int $service_min 0商品预约,1项目服务预约
  46. * @property float $distance 0商品预约,1项目服务预约
  47. * @property int $appointments_number 同时间点可预约人数
  48. */
  49. class StoreGoodsReserve extends \common\models\base\BaseActiveRecord
  50. {
  51. /**
  52. * {@inheritdoc}
  53. */
  54. public static function tableName()
  55. {
  56. return 'qimall_addons_store_goods_reserve';
  57. }
  58. /**
  59. * {@inheritdoc}
  60. */
  61. public function rules()
  62. {
  63. return [
  64. [['mall_id', 'store_id', 'goods_id', 'reserve_date_type', 'reserve_time_range_type', 'time_slot_type', 'reserve_price_type',
  65. 'reserve_max_buy', 'reserve_advance_hourse','reserve_days_range', 'cancel_type', 'expired_handle_type', 'province_id',
  66. 'city_id', 'district_id', 'created_at', 'updated_at', 'reserve_type', 'service_min'], 'integer'],
  67. [['price', 'original_price', 'cost_price', 'distance'], 'number'],
  68. [['reserve_date', 'reserve_time_slot', 'reserve_time_slot_price', 'reserve_week', 'cancel_rule', 'detail','region_name'], 'string'],
  69. [['information_detail','ordering_information'],'string'],
  70. [[ 'lat', 'lng'],'safe'],
  71. [['service_type','appointments_number'],'integer']
  72. ];
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function attributeLabels()
  78. {
  79. return [
  80. 'id' => 'ID',
  81. 'mall_id' => 'Mall ID',
  82. 'store_id' => 'Store ID',
  83. 'goods_id' => 'Goods ID',
  84. 'price' => 'Price',
  85. 'original_price' => 'Original Price',
  86. 'cost_price' => 'Cost Price',
  87. 'reserve_date_type' => 'Reserve Date Type',
  88. 'reserve_week' => 'Reserve Week',
  89. 'reserve_date' => 'Reserve Date',
  90. 'reserve_time_range_type' => 'Reserve Time Range Type',
  91. 'time_slot_type' => 'Time Slot Type',
  92. 'reserve_time_slot' => 'Reserve Time Slot',
  93. 'reserve_price_type' => 'Reserve Price Type',
  94. 'reserve_time_slot_price' => 'Reserve Time Slot Price',
  95. 'reserve_max_buy' => 'Reserve Max Buy',
  96. 'reserve_advance_hourse' => 'Reserve Advance Hourse',
  97. 'reserve_days_range' => 'Reserve Days Range',
  98. 'cancel_type' => 'Cancel Type',
  99. 'cancel_rule' => 'Cancel Rule',
  100. 'expired_handle_type' => 'Expired Handle Type',
  101. 'province_id' => 'Province ID',
  102. 'city_id' => 'City ID',
  103. 'district_id' => 'District ID',
  104. 'detail' => 'Detail',
  105. 'lat' => 'Lat',
  106. 'lng' => 'Lng',
  107. 'region_name' => 'Region Name',
  108. 'service_type' => 'Service Type',
  109. 'created_at' => 'Created At',
  110. 'updated_at' => 'Updated At',
  111. 'ordering_information' => 'Ordering Information',
  112. 'information_detail' => 'Information Detail',
  113. 'reserve_type' => 'Reserve Type',
  114. 'appointments_number' => 'appointments_number',
  115. ];
  116. }
  117. public function getSkus()
  118. {
  119. return $this->hasMany(StoreGoodsReserveSku::class, ['goods_id' => 'goods_id']);
  120. }
  121. public function getGoods()
  122. {
  123. return $this->hasOne(StoreGoods::class, ['id' => 'goods_id']);
  124. }
  125. // 预约商品
  126. /**
  127. * @param array $goods
  128. * @param array $params
  129. * @return StoreGoodsReserve|false|null
  130. */
  131. public static function setData(&$goods, $params)
  132. {
  133. try {
  134. $model = self::findOne(['goods_id' => $goods['id']]);
  135. if (empty($model)) {
  136. $model = new self();
  137. $model->loadDefaultValues();
  138. }
  139. $goodsAttributes = [
  140. 'mall_id' => $goods['mall_id'],
  141. 'mch_id' => $goods['mch_id'],
  142. 'store_id' => $goods['store_id'],
  143. 'goods_id' => $goods['id'],
  144. 'price' => $goods['price'] ?? min(array_column($params['skus'], "price")),
  145. 'original_price' => $goods['original_price'] ?? min(array_column($params['skus'], "original_price")),
  146. 'cost_price' => $goods['cost_price'] ?? min(array_column($params['skus'], !empty($params['skus'][0]["cost_price"]) ? "cost_price" : "price")),
  147. ];
  148. $params['information_detail'] = $params['information_detail'] ?? '';
  149. $params['ordering_information'] = $params['ordering_information'] ?? '';
  150. $params['district_id'] = empty($params['district_id']) ? 0 : intval($params['district_id']);
  151. $params['province_id'] = empty($params['province_id']) ? 0 : intval($params['province_id']);
  152. $params['city_id'] = empty($params['city_id']) ? 0 : intval($params['city_id']);
  153. $params['reserve_advance_hourse'] = empty($params['reserve_advance_hourse']) ? 0 : intval($params['reserve_advance_hourse']);
  154. $params['distance'] = empty($params['distance']) ? 0 : intval($params['distance']);
  155. $params['service_min'] = empty($params['service_min']) ? 0 : intval($params['service_min']);
  156. $params['appointments_number'] = empty($params['appointments_number']) ? 0 : intval($params['appointments_number']);
  157. if (!empty($params['province_id'])) {
  158. $params['region_name'] = implode(" ", Region::find()
  159. ->where(['id' => [$params['province_id'], $params['city_id'], $params['district_id']]])
  160. ->orderBy('id asc')->select('name')->column());
  161. }
  162. if (empty($goods['is_attr'])) { // 是单规格 将商品设置到规格中
  163. $attributes = array_merge($params, $goodsAttributes);
  164. } else {
  165. $attributes = array_merge($goodsAttributes, $params);
  166. }
  167. is_array($attributes['reserve_week']) && $attributes['reserve_week'] = implode(',',$attributes['reserve_week']);
  168. is_array($attributes['reserve_date']) && $attributes['reserve_date'] = json_encode($attributes['reserve_date'],JSON_UNESCAPED_SLASHES);
  169. is_array($attributes['reserve_time_slot']) && $attributes['reserve_time_slot'] = json_encode($attributes['reserve_time_slot'],JSON_UNESCAPED_SLASHES);
  170. is_array($attributes['reserve_time_slot_price']) && $attributes['reserve_time_slot_price'] = json_encode($attributes['reserve_time_slot_price'],JSON_UNESCAPED_SLASHES);
  171. is_array($attributes['cancel_rule']) && $attributes['cancel_rule'] = json_encode($attributes['cancel_rule'],JSON_UNESCAPED_SLASHES);
  172. //($attributes['service_type'] ?? false) && $attributes['service_type'] = json_encode($attributes['service_type'],JSON_UNESCAPED_SLASHES);
  173. if (!$model->load($attributes, '') || !$model->save()) {
  174. throw new Exception($model->getErrorMessage());
  175. }
  176. // 处理预约商品规格
  177. $reserveGoods = ArrayHelper::toArray($model);
  178. if($goods['is_attr'] == 1){
  179. // 多规格预约商品
  180. $skus = $params['skus'];
  181. // 因为预约商品按天设置时商品售价存储位置不同,所以需要单独处理
  182. $is_day = true;
  183. $timeSlotPriceList = [];
  184. foreach ($skus as $item) {
  185. if ($item['reserve_price_type'] == 2 || $item['reserve_price_type'] == 1) {
  186. $timeSlotPriceList = array_merge($timeSlotPriceList, array_values($item['reserve_time_slot_price']));
  187. } else {
  188. $is_day = false;
  189. }
  190. }
  191. if (!empty($timeSlotPriceList) && $is_day) {
  192. $timeSkusGoods = array_column($timeSlotPriceList, 'price');
  193. $timeMinSkusGoods = array_search(min($timeSkusGoods), $timeSkusGoods);
  194. $timeSlotPriceList = $timeSlotPriceList[$timeMinSkusGoods] ?? [];
  195. }
  196. $skusGoods = array_column($skus, 'price');
  197. $minSkusGoods = array_search(min($skusGoods), $skusGoods);
  198. $reserveSkusGoods = $skus[$minSkusGoods] ?? [];
  199. $goodsModel = StoreGoods::findOne($goods['id']);
  200. if (!empty($goodsModel)) { // 赋值给主商品对应的商品
  201. if ($is_day) {
  202. $goodsModel->price = $timeSlotPriceList['price'] ?? 0;
  203. $goodsModel->original_price = $timeSlotPriceList['original_price'] ?? 0;
  204. } else {
  205. $goodsModel->price = $reserveSkusGoods['price'] ?? 0;
  206. $goodsModel->original_price = $reserveSkusGoods['original_price'] ?? 0;
  207. }
  208. $goodsModel->save();
  209. }
  210. $res = StoreGoodsReserveSku::setSkus($goods, $skus, $model);
  211. }else{
  212. $reserveGoods['service_min'] = $params['service_min'];
  213. $reserveGoods['unit'] = $goods['unit'] ?? '';
  214. is_array($reserveGoods['reserve_time_slot_price']) && $reserveGoods['reserve_time_slot_price'] =
  215. Json::encode($reserveGoods['reserve_time_slot_price']);
  216. $reserveGoods['price'] = $goodsAttributes['price'];
  217. $reserveGoods['name'] = '';
  218. $res = StoreGoodsReserveSku::setSku($reserveGoods);
  219. }
  220. if($res === false) throw new Exception('处理预约商品规格出现异常,msg:'.StoreGoodsReserveSku::getStaticError());
  221. return $model;
  222. } catch (Exception $e) {
  223. if (isset($trans)) $trans->rollback();
  224. self::$static_error = $e->getMessage();
  225. return false;
  226. }
  227. }
  228. }