PreOrderGoods.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: shenyang
  5. * Date: 2018/11/26
  6. * Time: 3:54 PM
  7. */
  8. namespace app\common\modules\orderGoods\models;
  9. use app\backend\modules\goods\models\GoodsTradeSet;
  10. use app\common\exceptions\AppException;
  11. use app\common\models\OrderGoods;
  12. use app\common\models\BaseModel;
  13. use app\common\modules\shop\ShopConfig;
  14. use app\frontend\models\Goods;
  15. use app\frontend\models\goods\Sale;
  16. use app\frontend\models\GoodsOption;
  17. use app\frontend\modules\deduction\OrderGoodsDeductManager;
  18. use app\frontend\modules\deduction\OrderGoodsDeductionCollection;
  19. use app\frontend\modules\goods\services\TradeGoodsPointsServer;
  20. use app\frontend\modules\orderGoods\price\option\NormalOrderGoodsOptionPrice;
  21. use app\frontend\modules\orderGoods\price\option\NormalOrderGoodsPrice;
  22. use app\frontend\modules\order\models\PreOrder;
  23. use app\frontend\modules\orderGoods\taxFee\OrderGoodsTaxFeeManager;
  24. use Illuminate\Support\Carbon;
  25. use Illuminate\Support\Collection;
  26. /**
  27. * Class PreOrderGoods
  28. * @package app\frontend\modules\orderGoods\models
  29. * @property float price
  30. * @property float goods_price
  31. * @property float coupon_price
  32. * @property float discount_price
  33. * @property float goods_cost_price
  34. * @property float goods_market_price
  35. * @property float $deduction_amount
  36. * @property float payment_amount
  37. * @property int goods_id
  38. * @property Goods goods
  39. * @property int id
  40. * @property int pre_id
  41. * @property int order_id
  42. * @property int uid
  43. * @property int total
  44. * @property int uniacid
  45. * @property int goods_option_id
  46. * @property string goods_option_title
  47. * @property string goods_sn
  48. * @property string thumb
  49. * @property int type
  50. * @property string title
  51. * @property GoodsOption goodsOption
  52. * @property OrderGoodsDeductionCollection orderGoodsDeductions
  53. * @property Collection orderGoodsDiscounts
  54. * @property Collection orderGoodsTaxFees
  55. * @property Sale sale
  56. */
  57. class PreOrderGoods extends OrderGoods
  58. {
  59. use PreOrderGoodsTrait;
  60. protected $hidden = ['goods', 'sale', 'belongsToGood', 'hasOneGoodsDispatch'];
  61. /**
  62. * @var PreOrder
  63. */
  64. public $order;
  65. /**
  66. * @var Collection
  67. */
  68. public $coupons;
  69. protected $appends = ['pre_id', 'points', 'show_time_word'];
  70. /**
  71. * @param $key
  72. * @return mixed
  73. * @throws AppException
  74. */
  75. public function getPriceBefore($key)
  76. {
  77. return $this->getPriceCalculator()->getPriceBefore($key);
  78. }
  79. /**
  80. * @param $key
  81. * @return mixed
  82. * @throws AppException
  83. */
  84. public function getPriceBeforeWeight($key)
  85. {
  86. return $this->getPriceCalculator()->getPriceBeforeWeight($key);
  87. }
  88. /**
  89. * @param $key
  90. * @return mixed
  91. * @throws AppException
  92. */
  93. public function getPriceAfter($key)
  94. {
  95. return $this->getPriceCalculator()->getPriceAfter($key);
  96. }
  97. /**
  98. * 为订单model提供的方法 ,设置所属的订单model
  99. * @param PreOrder $order
  100. */
  101. public function init(PreOrder $order)
  102. {
  103. $this->order = $order;
  104. }
  105. public function touchPreAttributes()
  106. {
  107. $this->uid = (int)$this->uid;
  108. $this->uniacid = (int)$this->uniacid;
  109. $this->goods_id = (int)$this->goods_id;
  110. $this->title = (string)$this->title;
  111. $this->thumb = (string)$this->thumb;
  112. $this->type = (int)$this->type;
  113. $this->goods_sn = (string)$this->goods_sn;
  114. $this->product_sn = (string)$this->product_sn;
  115. $this->goods_price = (string)$this->goods_price;
  116. $this->price = (float)$this->price;
  117. $this->goods_cost_price = (float)$this->goods_cost_price;
  118. $this->goods_market_price = (float)$this->goods_market_price;
  119. $this->coupon_price = (float)$this->coupon_price;
  120. $this->need_address = (float)$this->need_address;
  121. $this->payment_amount = round($this->getPaymentAmount(),2,PHP_ROUND_HALF_EVEN);
  122. $this->vip_price = $this->getVipPrice();
  123. if ($this->isOption()) {
  124. $this->goods_option_id = (int)$this->goods_option_id;
  125. $this->goods_option_title = (string)$this->goods_option_title;
  126. $this->goods_sn = $this->goodsOption->goods_sn ? (string)$this->goodsOption->goods_sn : $this->goods_sn;
  127. $this->product_sn = $this->goodsOption->product_sn ? (string)$this->goodsOption->product_sn : $this->product_sn;
  128. }
  129. }
  130. private function getShowTimeWord()
  131. {
  132. //商品交易设置
  133. $goods_trade_set = GoodsTradeSet::where('goods_id', $this->goods_id)->first();
  134. if (!$goods_trade_set || !$goods_trade_set->arrived_day || !app('plugins')->isEnabled('address-code')) {
  135. return '';
  136. } else {
  137. $arrived_day = $goods_trade_set->arrived_day;
  138. $arrived_word = $goods_trade_set->arrived_word;
  139. if ($arrived_day > 1) {
  140. $arrived_day -= 1;
  141. $time_format = Carbon::createFromTimestamp(time())->addDays($arrived_day)->format('Y-m-d');
  142. } else {
  143. $time_format = Carbon::createFromTimestamp(time())->format('Y-m-d');
  144. }
  145. $time_format .= " {$goods_trade_set->arrived_time}:00";
  146. $timestamp = strtotime($time_format);
  147. if ($timestamp < time()) {
  148. $timestamp += 86400;
  149. }
  150. $show_time = ltrim(date('m', $timestamp), '0').'月';
  151. $show_time .= ltrim(date('d', $timestamp), '0').'日';
  152. $show_time .= $goods_trade_set->arrived_time;
  153. return str_replace('[送达时间]', $show_time, $arrived_word);
  154. }
  155. }
  156. public function getUidAttribute()
  157. {
  158. return $this->order->uid;
  159. }
  160. public function getUniacidAttribute()
  161. {
  162. return $this->order->uniacid;
  163. }
  164. /**
  165. * @return PreOrder
  166. * @throws AppException
  167. */
  168. public function getOrder()
  169. {
  170. if (!isset($this->order)) {
  171. throw new AppException('调用顺序错误,Order对象还没有载入');
  172. }
  173. return $this->order;
  174. }
  175. public function getDiscounts()
  176. {
  177. //blank not discount
  178. if ($this->order->isDiscountDisable()) {
  179. return collect();
  180. }
  181. $discounts = collect();
  182. foreach (\app\common\modules\shop\ShopConfig::current()->get('shop-foundation.goods-discount') as $configItem) {
  183. $discount = call_user_func($configItem['class'], $this);
  184. $discount->setWeight($configItem['weight']);
  185. $discounts->push($discount);
  186. }
  187. return $discounts;
  188. }
  189. public function getOrderGoodsDiscounts()
  190. {
  191. if (!$this->getRelation('orderGoodsDiscounts')) {
  192. $this->setRelation('orderGoodsDiscounts', $this->newCollection());
  193. }
  194. return $this->orderGoodsDiscounts;
  195. }
  196. public function getTaxFees()
  197. {
  198. $taxFees = collect();
  199. foreach (\app\common\modules\shop\ShopConfig::current()->get('shop-foundation.goods-tax-fee') as $configItem) {
  200. $taxFee = call_user_func($configItem['class'], $this);
  201. $taxFee->setWeight($configItem['weight']);
  202. $taxFees->push($taxFee);
  203. }
  204. return $taxFees;
  205. }
  206. public function getOrderGoodsTaxFees()
  207. {
  208. if (!$this->getRelation('orderGoodsTaxFees')) {
  209. $this->setRelation('orderGoodsTaxFees', $this->newCollection());
  210. }
  211. return $this->orderGoodsTaxFees;
  212. }
  213. public function getOrderGoodsDeductions()
  214. {
  215. if (!$this->getRelation('orderGoodsDeductions')) {
  216. $preOrderGoodsDeduction = new OrderGoodsDeductManager($this);
  217. $this->setRelation('orderGoodsDeductions', $preOrderGoodsDeduction->getOrderGoodsDeductions());
  218. }
  219. return $this->orderGoodsDeductions;
  220. }
  221. public function getCouponPriceAttribute()
  222. {
  223. return $this->getCouponAmount();
  224. }
  225. /**
  226. * @throws \Exception
  227. */
  228. public function afterSaving()
  229. {
  230. foreach ($this->relations as $models) {
  231. $models = $models instanceof Collection
  232. ? $models->all() : [$models];
  233. foreach (array_filter($models) as $model) {
  234. /**
  235. * @var BaseModel $model
  236. */
  237. // 添加 order_goods_id 外键
  238. if (!isset($model->order_goods_id) && $model->hasColumn('order_goods_id')) {
  239. $model->order_goods_id = $this->id;
  240. }
  241. // 添加 order_id 外键
  242. if (!isset($model->order_id) && $model->hasColumn('order_id')) {
  243. $model->order_id = $this->order_id;
  244. }
  245. }
  246. }
  247. $this->push();
  248. }
  249. public function save(array $options = [])
  250. {
  251. if (isset($this->id)) {
  252. return true;
  253. }
  254. return parent::save($options);
  255. }
  256. private function loadConfigRelations()
  257. {
  258. $relations = ShopConfig::current()->get('shop-foundation.order-goods.relations');
  259. foreach ($relations as $relation) {
  260. $relationModel = call_user_func($relation['class'], []);
  261. $relationModel->setOrderGoods($this);
  262. if (!$relationModel->enable()) {
  263. continue;
  264. }
  265. $this->setRelation($relation['key'], $relationModel);
  266. }
  267. }
  268. public function toArray()
  269. {
  270. $this->touchPreAttributes();
  271. $this->loadConfigRelations();
  272. return parent::toArray();
  273. }
  274. public function beforeSaving()
  275. {
  276. $this->touchPreAttributes();
  277. $this->loadConfigRelations();
  278. $this->deduction_amount = round($this->getDeductionAmount(),2,PHP_ROUND_HALF_EVEN);
  279. }
  280. /**
  281. * @return mixed
  282. */
  283. public function getGoodsPriceAttribute()
  284. {
  285. return $this->getGoodsPrice();
  286. }
  287. /**
  288. * @return mixed
  289. */
  290. public function getGoodsCostPriceAttribute()
  291. {
  292. return $this->getGoodsCostPrice();
  293. }
  294. /**
  295. * @var NormalOrderGoodsPrice
  296. */
  297. protected $priceCalculator;
  298. /**
  299. * 设置价格计算者
  300. */
  301. public function _getPriceCalculator()
  302. {
  303. if ($this->isOption()) {
  304. $priceCalculator = new NormalOrderGoodsOptionPrice($this);
  305. } else {
  306. $priceCalculator = new NormalOrderGoodsPrice($this);
  307. }
  308. return $priceCalculator;
  309. }
  310. /**
  311. * 获取价格计算者
  312. * @return NormalOrderGoodsPrice
  313. */
  314. public function getPriceCalculator()
  315. {
  316. if (!isset($this->priceCalculator)) {
  317. $this->priceCalculator = $this->_getPriceCalculator();
  318. }
  319. return $this->priceCalculator;
  320. }
  321. public function getVipPrice()
  322. {
  323. //订单禁用优惠返回,商品现价
  324. if ($this->order->isDiscountDisable()) {
  325. return $this->getPrice();
  326. }
  327. return $this->getPriceCalculator()->getVipPrice();
  328. }
  329. /**
  330. * @return mixed
  331. */
  332. public function getVipDiscountAmount()
  333. {
  334. $result = $this->getPriceCalculator()->getMemberLevelDiscountAmount();
  335. return $result;
  336. }
  337. public function getVipDiscountLog($key = null)
  338. {
  339. if ($key) {
  340. return $this->getPriceCalculator()->getVipDiscountLog()?$this->getPriceCalculator()->getVipDiscountLog()->$key : null;
  341. }
  342. return $this->getPriceCalculator()->getVipDiscountLog();
  343. }
  344. /**
  345. * @return float|mixed
  346. * @throws AppException
  347. */
  348. public function getPaymentAmountAttribute()
  349. {
  350. return $this->getPaymentAmount();
  351. }
  352. /**
  353. * 均摊的支付金额
  354. * @return float|mixed
  355. * @throws AppException
  356. */
  357. public function getPaymentAmount()
  358. {
  359. return $this->getPriceCalculator()->getPaymentAmount();
  360. }
  361. /**
  362. * 抵扣金额
  363. * @return float
  364. */
  365. public function getDeductionAmount()
  366. {
  367. return $this->getPriceCalculator()->getDeductionAmount();
  368. }
  369. /**
  370. * 优惠券金额
  371. * @return int
  372. */
  373. public function getCouponAmount()
  374. {
  375. return $this->getPriceCalculator()->getCouponAmount();
  376. }
  377. /**
  378. * @return string
  379. */
  380. public function getPreIdAttribute()
  381. {
  382. return $this->goods_id . '-' . $this->goods_option_id;
  383. }
  384. /**
  385. * @return string
  386. */
  387. public function getPointsAttribute()
  388. {
  389. return $this->getPoints();
  390. }
  391. /**
  392. * @return string
  393. */
  394. public function getShowTimeWordAttribute()
  395. {
  396. return $this->getShowTimeWord();
  397. }
  398. /**
  399. * @param null $key
  400. * @return mixed
  401. */
  402. public function getParams($key = null)
  403. {
  404. $params = is_array($this->order->getRequest()->input('order_goods')) ? $this->order->getRequest()->input('order_goods') : json_decode($this->order->getRequest()->input('order_goods'), true);
  405. $result = collect($params ?: [])->where('pre_id', $this->pre_id)->first();
  406. if (isset($key)) {
  407. return $result[$key];
  408. }
  409. return $result;
  410. }
  411. /**
  412. * @description 获取积分
  413. * @return mixed|string
  414. */
  415. public function getPoints()
  416. {
  417. $tradeGoodsPointsServer = new TradeGoodsPointsServer();
  418. $tradeGoodsPointsServer->getPointSet($this->goods);
  419. if ($tradeGoodsPointsServer->close(TradeGoodsPointsServer::SINGLE_PAGE)) {
  420. return '';
  421. }
  422. $points = $tradeGoodsPointsServer->finalSetPoint();
  423. return $tradeGoodsPointsServer->getPoint($points, $this->price, $this->goods_cost_price);
  424. }
  425. }