GoodsForm.php 112 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\constants\OptionSetting;
  9. use app\jobs\CreatedMdGoods;
  10. use app\models\AgentFrontErpInventory;
  11. use app\models\Attr;
  12. use app\models\AttrGroup;
  13. use app\models\Coupon;
  14. use app\models\DeliveryRules;
  15. use app\models\Form;
  16. use app\models\Goods;
  17. use app\models\GoodsAreaRules;
  18. use app\models\GoodsBook;
  19. use app\models\GoodsBrand;
  20. use app\models\GoodsBrowse;
  21. use app\models\GoodsCat;
  22. use app\models\GoodsFullMinus;
  23. use app\models\GoodsPic;
  24. use app\models\Level;
  25. use app\models\Mch;
  26. use app\models\Option;
  27. use app\models\PostageRules;
  28. use app\models\ShareLevel;
  29. use app\models\Store;
  30. use app\models\StoreCloud;
  31. use app\models\UserCoupon;
  32. use app\models\VerifyCard;
  33. use app\models\Warehouse;
  34. use app\models\WarehouseZone;
  35. use app\models\WorkerGoods;
  36. use app\models\WorkerGoodsExt;
  37. use app\modules\admin\models\booking\BookingForm;
  38. use app\modules\mch\models\LevelListForm;
  39. use app\utils\Delivery\Delivery;
  40. use yii\base\BaseObject;
  41. use yii\base\Model;
  42. use yii\helpers\Json;
  43. use app\jobs\SyncMdGoodsJob;
  44. use app\utils\Tools;
  45. use app\models\GoodsChainLevel;
  46. use app\models\ShareHolderLevel;
  47. use app\models\MchGoodsCat;
  48. use app\modules\admin\models\MchForm;
  49. class GoodsForm extends Model
  50. {
  51. //从银豹同步时设置为1
  52. public $yinbaoSync = 0;
  53. public $store_id;
  54. public $status;
  55. public $keyword;
  56. public $cat_id;
  57. public $type;
  58. public $id;
  59. public $name;
  60. public $key_word;
  61. public $unit;
  62. public $price;
  63. public $can_set_md_price = 1;
  64. public $cost_price;
  65. public $original_price;
  66. public $integral_price;
  67. public $service;
  68. public $weight;
  69. public $freight;
  70. public $pieces;
  71. public $forehead;
  72. public $quick_purchase;
  73. public $content;
  74. public $goods_num;
  75. public $goods_no;
  76. public $integral;
  77. public $use_attr;
  78. public $is_negotiable;
  79. public $cover_pic;
  80. public $individual_share;
  81. public $share_type;
  82. public $share_commission_first;
  83. public $share_commission_second;
  84. public $share_commission_third;
  85. public $video_url;
  86. public $attr;
  87. public $attr_member_price_List;
  88. public $attr_setting_type;
  89. public $virtual_sales;
  90. public $confine_count;
  91. public $order_min_count;
  92. public $balance;
  93. public $is_level;
  94. public $goods_pic_list;
  95. public $goods_verify_card_list;
  96. public $goods_coupon_card_list;
  97. public $delivery_type;
  98. public $product_type;
  99. public $date_book;
  100. public $service_book;
  101. public $form;
  102. public $rate;
  103. public $rate_type;
  104. public $chain_rate;
  105. public $chain_rate_type;
  106. public $queue_rate;
  107. public $md_rate;
  108. public $md_rate_type;
  109. public $md_hx_rate;
  110. public $md_hx_rate_type;
  111. public $dl_p_rate;
  112. public $dl_c_rate;
  113. public $dl_d_rate;
  114. public $dl_t_rate;
  115. public $dl_p_rate_type;
  116. public $dl_c_rate_type;
  117. public $dl_d_rate_type;
  118. public $dl_t_rate_type;
  119. public $pic_url;
  120. public $supplier;
  121. public $is_change_attr;
  122. public $sort;
  123. public $delivery_rules_id;
  124. public $goods_area_rules_id;
  125. public $order_rules_buyer_location_id;
  126. public $food_ext_goods_id;
  127. public $is_wholesale;
  128. public $wholesale_num;
  129. public $wholesale_attr;
  130. public $pay_price;
  131. public $accessories_image;
  132. public $goods_send_profit;
  133. public $goods_take_price;
  134. public $service_book_desc;
  135. public $parameter_list;
  136. public $buy_type_info;
  137. public $browse_type_info;
  138. public $is_open;
  139. public $chain_level_value;
  140. public $chain_type;
  141. public $jst_goods_id;
  142. public $jst_supplier_id;
  143. public $desc;
  144. public $warn;
  145. public $worker_goods_cat_id;
  146. public $payment_type;
  147. public $final_profit;
  148. public $bind_worker;
  149. public $worker_ids;
  150. public $booking_goods_cat_id;
  151. public $share_commission_new_first;
  152. public $share_commission_new_second;
  153. public $share_commission_new_third;
  154. public $send_verify_card_num;
  155. public $send_coupon_card_num;
  156. public $brand_id;
  157. public $risk_blind;//无视风险
  158. public $share_holder_profit_switch;
  159. public $share_holder_high_profit;
  160. public $time_made_day;
  161. public $time_shelf_life;
  162. public $warehouse_id;
  163. public $warehouse_zone_id;
  164. public $mch;
  165. public $mch_id;
  166. public $mch_cat_id;
  167. public $updated_at;
  168. public $sub_name;
  169. /**
  170. * 初始化
  171. */
  172. // public function init()
  173. // {
  174. // if (!$this->store_id) {
  175. // $this->store_id = get_store_id();
  176. // }
  177. // }
  178. /**
  179. * 采购员关联store_id
  180. */
  181. public function set_saas_purchase_store_id()
  182. {
  183. $this->store_id = get_saas_purchase_store_id();
  184. }
  185. /**
  186. * @return array
  187. */
  188. public function rules()
  189. {
  190. return [
  191. [['status', 'quick_purchase','store_id', 'id',
  192. 'freight', 'pieces', 'goods_num', 'use_attr', 'individual_share', 'attr_setting_type',
  193. 'virtual_sales', 'confine_count', 'order_min_count', 'is_level', 'product_type' , 'is_change_attr', 'chain_rate_type', 'rate_type', 'md_rate_type', 'md_hx_rate_type', 'dl_p_rate_type', 'dl_c_rate_type', 'dl_d_rate_type', 'dl_t_rate_type',
  194. 'integral_price','sort','can_set_md_price', 'delivery_rules_id', 'goods_area_rules_id', 'is_wholesale',
  195. 'wholesale_num', 'order_rules_buyer_location_id', 'chain_type', 'brand_id', 'risk_blind', 'share_holder_profit_switch', 'warehouse_id', 'warehouse_zone_id'], 'integer'],
  196. [['keyword', 'key_word'], 'string', 'max' => 60],
  197. [['name','service', 'video_url', 'goods_no', 'cover_pic', 'desc', 'sub_name'], 'string', 'max' => 255],
  198. [['content','pic_url', 'wholesale_attr','accessories_image', 'warn', 'worker_ids', 'share_commission_new_first', 'share_commission_new_second', 'share_commission_new_third'], 'string'],
  199. [['attr', 'attr_member_price_List', 'goods_verify_card_list', 'service_book', 'date_book', 'form', 'supplier', 'parameter_list', 'goods_coupon_card_list'], 'safe',],
  200. [['unit'], 'string', 'max' => 10],
  201. [['status', 'quick_purchase', 'chain_type'], 'default', 'value' => 1],
  202. [['cat_id', 'integral', 'goods_pic_list', 'delivery_type'], 'default', 'value' => []],
  203. [['use_attr', 'is_negotiable', 'individual_share',
  204. 'share_type', 'forehead', 'freight', 'attr_setting_type',
  205. 'virtual_sales', 'confine_count', 'order_min_count', 'is_level', 'is_open', 'share_holder_profit_switch'], 'default', 'value' => 0],
  206. [['sort'], 'default', 'value' => 100],
  207. [['unit'], 'default', 'value' => '件'],
  208. [['price', 'cost_price', 'original_price', 'forehead', 'share_commission_first', 'share_commission_second', 'share_commission_third', 'weight', 'chain_rate', 'rate', 'md_rate', 'md_hx_rate', 'dl_p_rate', 'dl_c_rate', 'dl_d_rate', 'dl_t_rate', 'pay_price', 'send_verify_card_num', 'send_coupon_card_num', 'share_holder_high_profit', 'balance','queue_rate'], 'number', 'max' => 9999999999],
  209. [['food_ext_goods_id', 'goods_send_profit', 'goods_take_price', 'buy_type_info', 'service_book_desc', 'chain_level_value', 'worker_goods_cat_id', 'payment_type', 'final_profit', 'bind_worker','browse_type_info'], 'safe'],
  210. [['booking_goods_cat_id'], 'safe'],
  211. [['jst_goods_id', 'jst_supplier_id'], 'safe'],
  212. [['time_made_day', 'time_shelf_life'], 'safe'],
  213. [['mch', 'mch_id', 'mch_cat_id'], 'safe'],
  214. [['updated_at'], 'safe'],
  215. ];
  216. }
  217. public function attributeLabels()
  218. {
  219. return [
  220. 'name' => '商品名称',
  221. 'sub_name' => '商品副标题名称',
  222. 'keyword' => '关键字',
  223. 'cat_id' => '分类',
  224. 'unit' => '单位',
  225. 'price' => '售价',
  226. 'cost_price' => '成本价',
  227. 'original_price' => '原价',
  228. 'service' => '服务',
  229. 'forehead' => '满额包邮',
  230. 'quick_purchase' => '是否添加快速购买',
  231. 'content' => '图文详情',
  232. 'use_attr' => '是否使用规格',
  233. 'is_negotiable' => '是否开启面议',
  234. 'goods_pic_list' => '商品图片',
  235. 'is_change_attr' => "是否更改规格值",
  236. 'is_wholesale' => '是否是批发来源',
  237. 'wholesale_num' => '批发数',
  238. 'wholesale_attr' => '批发规格',
  239. 'parameter_list' => '商品参数',
  240. 'service_book_desc' => '酒店预约产品其他信息',
  241. 'desc' => '服务商品特色',
  242. 'warn' => '预定须知'
  243. ];
  244. }
  245. //导入云仓商品
  246. public function saveCloudGoods($num_type = 0){
  247. if(!$this->validate()) {
  248. return [
  249. 'code' => 1,
  250. 'msg' => $this->getErrorSummary(false)[0],
  251. ];
  252. }
  253. //获取议价比
  254. // $content = Option::get('cloud', 0, 'saas');
  255. // $content = json_decode($content['value'], true);
  256. $rate = 0;
  257. $content = Store::find()->where(['id' => $this->store_id])->select('rate')->asArray()->one();
  258. if ($content) {
  259. $rate = $content['rate'];
  260. }
  261. $store_cloud = StoreCloud::findOne(['store_id' => $this->store_id, 'is_delete' => 0]);
  262. //是否拥有选品权限
  263. if (!intval($store_cloud->can_distribution)) {
  264. return [
  265. 'code' => 1,
  266. 'msg' => '未开启选品权限',
  267. ];
  268. }
  269. //选品更新自动更新商城销售价格
  270. $cloud_is_update = Option::get('cloud_is_update', $this->store_id, 'store')['value'];
  271. if (intval($cloud_is_update)) {
  272. $repeat_update_goods_price = Option::get('repeat_update_goods_price', $this->store_id, 'store')['value'];
  273. if (!intval($repeat_update_goods_price)) {
  274. $num_type = 1;
  275. }
  276. }
  277. //请求接口
  278. $goods_url = "/goods/getAttrParams";
  279. $param = [
  280. 'id' => $this->id,
  281. 'mch_id' => $store_cloud->cloud_store_id
  282. ];
  283. $domain = (new OptionSetting)->getCloudDomainName();
  284. $goodsInfo = cloud_post($domain.$goods_url,$param);
  285. $goodsInfo = json_decode($goodsInfo, true);
  286. if($goodsInfo['code'] != 0){
  287. return [
  288. 'code' => 1,
  289. 'msg' => $goodsInfo['msg']
  290. ];
  291. }
  292. $goodsInfo = $goodsInfo['data'];
  293. if (empty($goodsInfo)) {
  294. return [
  295. 'code' => 1,
  296. 'msg' => '商品不存在',
  297. ];
  298. }
  299. $channel_rate = 10;
  300. if ($goodsInfo['data']['channel_rate']) {
  301. $channel_rate = $goodsInfo['data']['channel_rate'];
  302. }
  303. $channel_rate = bcdiv($channel_rate, 10, 2);
  304. $where = [
  305. 'AND', [
  306. 'cloud_goods_id' => $this->id,
  307. 'store_id' => $this->store_id,
  308. 'is_wholesale' => !empty($this->is_wholesale) ? $this->is_wholesale : 0,//批发与铺货不同步
  309. ], [
  310. 'OR', [
  311. 'is_delete' => 0
  312. ],[
  313. 'is_delete' => 1,
  314. 'is_forbidden' => 1
  315. ]
  316. ]
  317. ];
  318. $goods = Goods::find()->where($where)->one();
  319. if (empty($goods)) {
  320. $goods = new Goods();
  321. $num_type = 0;
  322. } else {
  323. if (empty($goodsInfo['id'])) {
  324. $goods->is_delete = 1;
  325. $goods->save();
  326. goto goods_delete;
  327. }
  328. }
  329. $is_front_delivery = 0;
  330. if (intval($goodsInfo['send_type']) === 5) {//仓库同城
  331. $is_front_delivery = 1;
  332. }
  333. $is_front_express = 0;
  334. if (intval($goodsInfo['send_type']) === 6) {//仓库快递
  335. $is_front_express = 1;
  336. }
  337. $is_front_centralize = 0;
  338. if (intval($goodsInfo['send_type']) === 1) {//集采
  339. $is_front_centralize = 1;
  340. }
  341. $agent_goods_status = 0;
  342. if (intval($goodsInfo['send_type']) === 3) {//代理配送
  343. $agent_goods_status = 1;
  344. if (intval($goodsInfo['is_need_install']) === 1) {
  345. $agent_goods_status = 2;
  346. }
  347. }
  348. $is_cloud_express = 0;
  349. if (in_array($goodsInfo['send_type'], [0, 4]) && !intval($goodsInfo['stbz_goods_id'])) {//快递 / 库存
  350. $is_cloud_express = 1;
  351. }
  352. $goods->is_cloud_express = $is_cloud_express;
  353. $goods->is_front_delivery = $is_front_delivery;
  354. $goods->is_front_centralize = $is_front_centralize;
  355. $goods->agent_goods_status = $agent_goods_status;
  356. $goods->is_front_express = $is_front_express;
  357. $goods->status = (int)$goodsInfo['status'];
  358. $goods->store_id = $this->store_id;
  359. $goods->name = $goodsInfo['name'] ?: '';
  360. $goods->unit = $goodsInfo['unit'] ?: '';//单位
  361. $goods->cover_pic = $goodsInfo['pic_url'] ?: "";
  362. $goods->weight = $goodsInfo['weight'] ?: "0.00";
  363. $sale_price_type = Option::get('sale_price_type', $this->store_id, 'store')['value'];
  364. $this->pay_price = 0;
  365. // if ($goodsInfo['original_price']) {
  366. // $this->price = $goods->price = $goodsInfo['original_price'];
  367. // $goods->original_price = ($this->price + ($goodsInfo['original_price'] * ($rate / 100))) ?: 0.00;
  368. // } else {
  369. if (!$num_type) {
  370. $this->price = $this->pay_price = intval($sale_price_type) === 0 ? ($goodsInfo['platform_negotiated_price'] + ($goodsInfo['platform_negotiated_price']) * ($rate / 100)) : $goodsInfo['original_price'];
  371. $goods->price = $this->pay_price ?: '0.00';
  372. $goods->original_price = doubleval($goodsInfo['market_price']) ?: ($goodsInfo['underlined_price'] ?? $goodsInfo['price']);
  373. }
  374. // }
  375. $this->cost_price = $goods->cost_price = bcmul($goodsInfo['platform_negotiated_price'], $channel_rate, 2);
  376. $goods->cloud_supplier_id = $goodsInfo['supplier_id'] ?: 0;
  377. $goods->cloud_goods_id = $this->id;
  378. $goods->detail = $goodsInfo['desc'] ?: "";
  379. $goods->stbz_goods_id = $goodsInfo['stbz_goods_id'] ?: 0;
  380. $goods->video_url = $goodsInfo['video_url'] ?: '';
  381. if (!empty($this->is_wholesale)) {
  382. $this->goods_num = $goods->goods_num = ($this->wholesale_num ?: 0);
  383. } else {
  384. $this->goods_num = $goods->goods_num = $goodsInfo['num'] ?: 0;
  385. }
  386. $goods->is_wholesale = $this->is_wholesale ?: 0;
  387. $this->use_attr = $goods->use_attr = (int)$goodsInfo['use_attr'] ?? 1;
  388. $this->goods_no = $goods->goods_no = $goodsInfo['goods_no'] ?: 0;
  389. if (!$goods->save()) {
  390. return [
  391. 'code' => 1,
  392. 'msg' => "导入失败" . json_encode($goods->errors, JSON_UNESCAPED_UNICODE)
  393. ];
  394. }
  395. $cloudBindInfo = [];
  396. $this->attr = json_decode($goodsInfo['attrs'], true);
  397. if (!$num_type) {
  398. if (!empty($this->wholesale_attr) && !empty($this->attr)) {
  399. $this->wholesale_attr = json_decode($this->wholesale_attr, true);
  400. $wholesale_attr_id = array_column($this->wholesale_attr, 'attr_id');
  401. sort($wholesale_attr_id);
  402. foreach ($this->attr as $index => $item) {
  403. $attr_id = array_column($item['attr_list'], 'attr_id');
  404. sort($attr_id);
  405. if (array_diff($wholesale_attr_id, $attr_id)) {
  406. $this->attr[$index]['num'] = 0;
  407. } else {
  408. $this->attr[$index]['num'] = $this->wholesale_num;
  409. $this->attr[$index]['price'] = $this->pay_price;
  410. }
  411. }
  412. }
  413. }
  414. $this->setAttr($goods, $rate ?: 10, $channel_rate, $num_type, $goodsInfo['original_price']);
  415. $pic_list = $goodsInfo['pic_list'];
  416. $pic_list = json_decode($pic_list, true);
  417. GoodsPic::deleteAll(['goods_id' => $goods->id]);
  418. $pic = new GoodsPic();
  419. $pic->goods_id = $goods->id;
  420. $pic->pic_url = $goodsInfo['pic_url'];
  421. $pic->save();
  422. if ($pic_list) {
  423. foreach ($pic_list as $item) {
  424. if (!empty($item)) {
  425. $pic = new GoodsPic();
  426. $pic->goods_id = $goods->id;
  427. $pic->pic_url = $item['pic_url'] ?? $item;
  428. if (!$pic->save()) {
  429. continue;
  430. };
  431. }
  432. }
  433. }
  434. if (is_string($this->cat_id)) {
  435. $this->cat_id = explode(',', $this->cat_id);
  436. }
  437. if ($this->cat_id && count($this->cat_id)) {
  438. if ($goods->id > 0) {
  439. GoodsCat::deleteAll(['goods_id' => $goods->id]);
  440. }
  441. foreach ($this->cat_id as $cat_id) {
  442. $goodsCat = new GoodsCat();
  443. $goodsCat->goods_id = $goods->id;
  444. $goodsCat->cat_id = $cat_id;
  445. $goodsCat->store_id = $goods->store_id;
  446. if (!$goodsCat->save()) {
  447. continue;
  448. }
  449. }
  450. }
  451. goods_delete:
  452. $cloudBindInfo[0]['goods_id'] = $goods->id;
  453. $cloudBindInfo[0]['cloud_supplier_id'] = $goods->cloud_supplier_id;
  454. $cloudBindInfo[0]['cloud_goods_id'] = $goods->cloud_goods_id;
  455. $data['goods_id'] = $goods->cloud_goods_id;
  456. $data['cloudBindInfo'] = $cloudBindInfo;
  457. $data['_goods'] = $goods;
  458. // 同步门店商品
  459. queue_push(new SyncMdGoodsJob(['goods_ids' => [$goods->id]]), 0, 1);
  460. return $data;
  461. }
  462. public function saveLeague() {
  463. $goods = Goods::findOne($this->id);
  464. //TODO id790 获取总设置
  465. $store_profit_max_model = Option::findOne(['name' => 'store_profit_max']);
  466. $store_profit_min_model = Option::findOne(['name' => 'store_profit_min']);
  467. $store_take_max_model = Option::findOne(['name' => 'store_send_min']);
  468. if ($this->goods_send_profit > 0 && $this->goods_send_profit < $store_profit_min_model->value) {
  469. return [
  470. 'code' => 1,
  471. 'msg' => '总平台设置最低让利比例为' . $store_profit_min_model->value . '未能达到'
  472. ];
  473. }
  474. if ($store_profit_max_model->value && $this->goods_send_profit > $store_profit_max_model->value) {
  475. return [
  476. 'code' => 1,
  477. 'msg' => '总平台设置最高让利比例为' . $store_profit_max_model->value . ',现已超出'
  478. ];
  479. }
  480. if($store_take_max_model->value && $this->goods_take_price > $store_take_max_model->value){
  481. return [
  482. 'code' => 1,
  483. 'msg' => '总平台设置最高扣除比例为' . $store_take_max_model->value . ',现已超出'
  484. ];
  485. }
  486. if(!$this->goods_send_profit){
  487. $this_goods_send_profit = 0;
  488. }else{
  489. $this_goods_send_profit = $this->goods_send_profit;
  490. }
  491. if(!$this->goods_take_price){
  492. $this_goods_take_price = 0;
  493. }else{
  494. $this_goods_take_price = $this->goods_take_price;
  495. }
  496. $goods->goods_take_price = $this_goods_take_price;
  497. $goods->goods_send_profit = $this_goods_send_profit;
  498. if ($goods->save()) {
  499. return [
  500. 'code' => 0,
  501. 'msg' => '操作成功'
  502. ];
  503. }
  504. return [
  505. 'code' => 1,
  506. 'msg' => '操作失败,' . array_shift($goods->getFirstErrors()),
  507. ];
  508. }
  509. public function save()
  510. {
  511. if(!$this->validate()) {
  512. return [
  513. 'code' => 1,
  514. 'msg' => $this->getErrorSummary(false)[0],
  515. ];
  516. }
  517. /* begin 2024/03/15 09:49:35 商品风控检测 WPing丶 */
  518. $is_risk = 0;
  519. $is_show_risk = Option::get(OptionSetting::IS_SHOW_RISK, $this->store_id, 'store', '')['value'];
  520. if (intval($is_show_risk)) {//根据后台设置的开关 判断是否需要隐藏风险提醒
  521. //检测商品价格信息是否有赔本的风险,如果有则先不保存数据提示客户后再进行下一步操作
  522. foreach((array)$this->attr as $attr_item) {
  523. if($this->jst_goods_id){
  524. break;
  525. }
  526. $max_discount_price = $this->risk($attr_item);
  527. $price = $this->use_attr == 1 ? $attr_item['price'] : $this->price;
  528. if($this->is_level) {
  529. $level_list = Level::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'status' => 1])
  530. ->select('level')->column();
  531. foreach($level_list as $level) {
  532. if(isset($attr_item['member'.$level]) && $attr_item['member'.$level] < $price) {
  533. $price = $attr_item['member'.$level];
  534. }
  535. }
  536. }
  537. $cost_price = $this->use_attr == 1 ? $attr_item['cost_price'] : $this->cost_price;
  538. $profit = bcsub($price,$cost_price,2);
  539. if($profit < $max_discount_price) {
  540. if($this->risk_blind == 0) {
  541. $attr_name = '';
  542. foreach($attr_item['attr_list'] as $kkk => $vvv) {
  543. if($kkk + 1 == count($attr_item['attr_list'])) {
  544. $attr_name.=$vvv['attr_group_name'].':'.$vvv['attr_name'];
  545. } else {
  546. $attr_name.=$vvv['attr_group_name'].':'.$vvv['attr_name'].',';
  547. }
  548. }
  549. if (intval($this->product_type) == Goods::GOODS_TYPE_NORMAL) {
  550. return [
  551. 'code' => 1,
  552. 'msg' => '规格为:'.$attr_name.'的商品当前价格有风险,是否确认保存?',
  553. 'is_risk' => 1,
  554. ];
  555. }
  556. } else {
  557. $is_risk = 1;
  558. }
  559. }
  560. }
  561. }
  562. /* end */
  563. // 同城配送需要校验信息
  564. // if (in_array('delivery', $this->delivery_type)) {
  565. // $res = Delivery::getBindAccount();
  566. // if ($res['code'] > 0) {
  567. // if ($res['code'] == 48001) {
  568. // return [
  569. // 'code' => 1,
  570. // 'msg' => '请在微信小程序后台开通即时配送物流服务'
  571. // ];
  572. // }
  573. // return $res;
  574. // }
  575. // if (empty($res['data']['shop_list'])) {
  576. // return [
  577. // 'code' => 1,
  578. // 'msg' => '当前未绑定运力账号,商品暂不能选择同城配送方式'
  579. // ];
  580. // }
  581. // $shop_list = $res['data']['shop_list'];
  582. // $count = 0;
  583. // foreach ($shop_list as $shop) {
  584. // if ($shop['audit_result'] == 0) {
  585. // $count++;
  586. // }
  587. // }
  588. // if ($count < 1) {
  589. // return [
  590. // 'code' => 1,
  591. // 'msg' => '当前暂无可用运力配送,商品暂不能选择同城配送方式'
  592. // ];
  593. // }
  594. // }
  595. $full_cut = [
  596. 'pieces' => 0,
  597. 'forehead' => 0
  598. ];
  599. if($this->pieces){
  600. $full_cut['pieces'] = $this->pieces;
  601. }
  602. if($this->forehead){
  603. $full_cut['forehead'] = $this->forehead;
  604. }
  605. //去掉逻辑
  606. // if ($this->product_type == Goods::GOODS_TYPE_INTEGRAL && $this->integral['forehead'] <= 0) {
  607. // return [
  608. // 'code' => 1,
  609. // 'msg' => '积分商品必须填写积分可兑换金额'
  610. // ];
  611. // }
  612. $t = \Yii::$app->db->beginTransaction();
  613. $goods = $this->id ? Goods::findOne($this->id) ?: new Goods(['yinbaoSync' => $this->yinbaoSync]) : new Goods(['yinbaoSync' => $this->yinbaoSync]);
  614. if($this->id){
  615. if($this->updated_at && ($this->updated_at != $goods->updated_at)){
  616. return [
  617. 'code' => 1,
  618. 'msg' => '商品信息发生变化,请刷新后重新编辑',
  619. ];
  620. }
  621. }
  622. $statusInit = $goods->status;
  623. !empty($this->jst_goods_id) && $goods->jst_goods_id = $this->jst_goods_id;
  624. !empty($this->jst_supplier_id) && $goods->jst_supplier_id = $this->jst_supplier_id;
  625. !empty($this->status) && $goods->status = $this->status;
  626. $goods->store_id = $this->store_id;
  627. $goods->name = $this->name;
  628. $goods->sub_name = $this->sub_name;
  629. $goods->key_word = $this->key_word;
  630. $goods->unit = $this->unit;
  631. $goods->price = $this->price;
  632. $goods->can_set_md_price = $this->can_set_md_price;
  633. $goods->integral_price = (isset($this->integral_price) && $this->integral_price> 0) ? intval($this->integral_price) : 0;
  634. $goods->cost_price = $this->cost_price;
  635. $goods->original_price = $this->original_price ?: $this->price;
  636. $goods->service = $this->service;
  637. $goods->weight = $this->weight;
  638. $goods->freight = $this->freight;
  639. $goods->pieces = $this->pieces;
  640. $goods->full_cut = Json::encode($full_cut);
  641. $goods->forehead = $this->forehead;
  642. $goods->quick_purchase = $this->quick_purchase;
  643. $goods->video_url = $this->video_url;
  644. $goods->detail = $this->content;
  645. $goods->goods_num = $this->goods_num ?? 0;
  646. $goods->goods_no = $this->goods_no;
  647. $goods->integral = json_encode($this->integral);
  648. $goods->use_attr = $this->use_attr;
  649. $goods->is_negotiable = $this->is_negotiable;
  650. $goods->cover_pic = $this->cover_pic;
  651. $goods->individual_share = $this->individual_share;
  652. $goods->share_type = $this->share_type;
  653. $goods->share_commission_first = $this->share_commission_first ? $this->share_commission_first : 0;
  654. $goods->share_commission_second = $this->share_commission_second ? $this->share_commission_second : 0;
  655. $goods->share_commission_third = $this->share_commission_third ? $this->share_commission_third : 0;
  656. $goods->attr_setting_type = $this->attr_setting_type ? 1 : 0;
  657. $goods->virtual_sales = $this->virtual_sales;
  658. $goods->confine_count = $this->confine_count;
  659. isset($this->order_min_count) && $goods->order_min_count = $this->order_min_count;
  660. $goods->balance = $this->balance;
  661. $goods->rate = $this->rate ? $this->rate : 0;
  662. $goods->rate_type = $this->rate_type == 1 ? 1 : 0;
  663. $goods->chain_rate = $this->chain_rate ? $this->chain_rate : 0;
  664. $goods->chain_rate_type = $this->chain_rate_type == 1 ? 1 : 0;
  665. $goods->queue_rate = $this->queue_rate ? $this->queue_rate : 0;
  666. $goods->md_rate = $this->md_rate ?: 0;
  667. $goods->md_rate_type = $this->md_rate_type == 1 ? 1 : 0;
  668. $goods->md_hx_rate = $this->md_hx_rate ?: 0;
  669. $goods->md_hx_rate_type = $this->md_hx_rate_type == 1 ? 1 : 0;
  670. $goods->dl_p_rate = $this->dl_p_rate ?: 0;
  671. $goods->dl_c_rate = $this->dl_c_rate ?: 0;
  672. $goods->dl_d_rate = $this->dl_d_rate ?: 0;
  673. $goods->dl_t_rate = $this->dl_t_rate ?: 0;
  674. $goods->dl_p_rate_type = $this->dl_p_rate_type == 1 ? 1 : 0;
  675. $goods->dl_c_rate_type = $this->dl_c_rate_type == 1 ? 1 : 0;
  676. $goods->dl_d_rate_type = $this->dl_d_rate_type == 1 ? 1 : 0;
  677. $goods->dl_t_rate_type = $this->dl_t_rate_type == 1 ? 1 : 0;
  678. $goods->is_level = $this->is_level;
  679. $goods->delivery_type = $this->delivery_type ? json_encode($this->delivery_type) : '["express"]';
  680. $goods->product_type = $this->product_type;
  681. $goods->form_name = $this->form['form_name'];
  682. $goods->is_form = $this->form['is_form'] ?: 0;
  683. $goods->delivery_rules_id = $this->delivery_rules_id;
  684. $goods->goods_area_rules_id = $this->goods_area_rules_id;
  685. $goods->order_rules_buyer_location_id = $this->order_rules_buyer_location_id;
  686. $goods->accessories_image = $this->accessories_image ?? '';
  687. $goods->service_book_desc = $this->service_book_desc;
  688. if(isset($this->time_made_day)){
  689. if(empty($this->time_made_day)){
  690. $goods->time_made_day = 0;
  691. }else{
  692. $goods->time_made_day = strtotime($this->time_made_day);
  693. }
  694. }
  695. isset($this->time_shelf_life) && $goods->time_shelf_life = intval($this->time_shelf_life);
  696. $goods->is_risk = $is_risk;
  697. $goodsBrand = GoodsBrand::findOne($this->brand_id);
  698. $goods->brand_id = $goodsBrand->id ?? 0;
  699. if ($goods->product_type === Goods::GOODS_TYPE_VIEW) {
  700. $goods->goods_num = $this->goods_num = 10000000;
  701. }
  702. //新单独分销
  703. $goods->share_commission_new_first = $this->share_commission_new_first ?: '';
  704. $goods->share_commission_new_second = $this->share_commission_new_second ?: '';
  705. $goods->share_commission_new_third = $this->share_commission_new_third ?: '';
  706. $goods->share_holder_profit_switch = $this->share_holder_profit_switch ?: '';
  707. $goods->share_holder_high_profit = $this->share_holder_high_profit ?: '';
  708. if (!empty($this->buy_type_info) && is_array($this->buy_type_info)) {
  709. if (!in_array($this->buy_type_info['type'], [0, 1, 2])) {
  710. return [
  711. 'code'=>1,
  712. 'msg'=>'商品购买类型设置错误'
  713. ];
  714. }
  715. if ((int)$this->buy_type_info['type'] === 1) {
  716. $level_list = Level::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'status' => 1])
  717. ->select('level')->column();
  718. if (!empty($this->buy_type_info['member_level'])) {
  719. foreach ($this->buy_type_info['member_level'] as $member_level) {
  720. if (!in_array($member_level, array_merge($level_list, [0, -1]))) {
  721. return [
  722. 'code'=>1,
  723. 'msg'=>'商品购买会员类型错误'
  724. ];
  725. }
  726. }
  727. } else {
  728. $this->buy_type_info['member_level'] = [
  729. 0
  730. ];
  731. }
  732. }
  733. }
  734. $goods->buy_type_info = json_encode($this->buy_type_info);
  735. if ($this->parameter_list){
  736. foreach ($this->parameter_list as $key => $value ) {
  737. if (empty($value['name']) || empty($value['value'])) {
  738. unset($this->parameter_list[$key]);
  739. }
  740. }
  741. $goods->parameter_list = json_encode($this->parameter_list,JSON_UNESCAPED_UNICODE);
  742. }else{
  743. $goods->parameter_list = '';
  744. }
  745. // if(isset($this->sort) && $this->sort> 0 ){
  746. // $goods->sort = $this->sort;
  747. // }
  748. if (isset($this->goods_verify_card_list)) {
  749. $verify_card_id = '';
  750. foreach($this->goods_verify_card_list as $val) {
  751. $verify_card_id .= $verify_card_id ? ','.$val['id'] : $val['id'];
  752. }
  753. $goods->verify_card_id = $verify_card_id;
  754. }
  755. if (isset($this->goods_coupon_card_list)) {
  756. $coupon_card_id = '';
  757. foreach($this->goods_coupon_card_list as $val) {
  758. $coupon_card_id .= $coupon_card_id ? ','.$val['id'] : $val['id'];
  759. }
  760. $goods->coupon_card_id = $coupon_card_id;
  761. } else {
  762. $goods->coupon_card_id = '';
  763. }
  764. $goods->send_verify_card_num = $this->send_verify_card_num;
  765. $goods->send_coupon_card_num = $this->send_coupon_card_num;
  766. if ((int)$this->product_type === 2) {
  767. $service_book = $this->service_book;
  768. $num = 0;
  769. if (!is_array($service_book['data'][0]['time'][0]['times'])) {
  770. return [
  771. 'code'=>1,
  772. 'msg'=>'预约商品信息规格有误'
  773. ];
  774. }
  775. foreach ($service_book['data'][0]['time'][0]['times'] as $item) {
  776. $num += $item['num'];
  777. }
  778. $goods->service_book_num = $num;
  779. }
  780. if ($this->product_type === Goods::GOODS_TYPE_WORKER) {
  781. $goods->status = 1;
  782. }
  783. if($this->mch){
  784. $statusChange = !$this->id || ($statusInit != $goods->status);
  785. $mchSetting = (new MchForm(['store_id' => $this->store_id]))->mchSetting();
  786. if($mchSetting['mch_goods_audit'] && $statusChange){
  787. $goods->mch_audit = 1;
  788. $goods->mch_audit_time = time();
  789. $goods->status = Goods::STATUS_DISABLE;
  790. }
  791. $goods->mch_id = $this->mch_id;
  792. }
  793. if ($goods->save()) {
  794. if($this->mch){
  795. $saveCat = MchGoodsCat::saveCat($goods->id, $this->mch_cat_id);
  796. if ($saveCat['code']) {
  797. $t->rollBack();
  798. return $saveCat;
  799. }
  800. }
  801. $goodsChainLevel = GoodsChainLevel::findOne(['goods_id' => $goods['id']]);
  802. if (!$goodsChainLevel) {
  803. $goodsChainLevel = new GoodsChainLevel();
  804. $goodsChainLevel->goods_id = $goods['id'];
  805. }
  806. $goodsChainLevel->type = $this->chain_type;
  807. $goodsChainLevel->is_open = $this->is_open;
  808. $goodsChainLevel->value = json_encode($this->chain_level_value);
  809. $goodsChainLevel->save();
  810. // 服务商品
  811. $bookingGoodsSave = $this->bookingGoodsSave($goods);
  812. if($bookingGoodsSave['code'] != 0){
  813. $t->rollBack();
  814. return $bookingGoodsSave;
  815. }
  816. // 服务商品
  817. if ($this->product_type === Goods::GOODS_TYPE_WORKER) {
  818. $payment_type = (int)$this->payment_type;
  819. $worker_ids = $this->worker_ids;
  820. $bind_worker = (int)$this->bind_worker;
  821. if (!in_array($payment_type, [0, 1])) {
  822. $t->rollBack();
  823. return [
  824. 'code'=>1,
  825. 'msg'=>'服务商品状态'
  826. ];
  827. }
  828. $goods_ext = WorkerGoodsExt::findOne(['goods_id' => $goods->id]) ?? new WorkerGoodsExt();
  829. $goods_ext->store_id = $goods->store_id;
  830. $goods_ext->goods_id = $goods->id;
  831. $goods_ext->payment_type = $payment_type;
  832. $goods_ext->desc = $this->desc;
  833. $goods_ext->warn = $this->warn;
  834. $goods_ext->cat_id = $this->worker_goods_cat_id;
  835. $goods_ext->final_profit = $this->final_profit;
  836. $goods_ext->bind_worker = $bind_worker;
  837. if (!$goods_ext->save()) {
  838. $t->rollBack();
  839. return [
  840. 'code'=>1,
  841. 'msg'=>'服务商品保存错误'
  842. ];
  843. };
  844. if ($worker_ids) {
  845. if ($bind_worker === 1) {
  846. $worker_ids = explode(',', $worker_ids);
  847. if (!empty($worker_ids)) {
  848. //将后台商品设置的服务人员删除
  849. WorkerGoods::updateAll(['status' => 0], ['goods_id' => $goods->id, 'public' => 1]);
  850. foreach ($worker_ids as $worker_id) {
  851. $worker = WorkerGoods::findOne(['goods_id' => $goods->id, 'worker_id' => $worker_id]);
  852. if (!$worker) {
  853. $worker = new WorkerGoods();
  854. $worker->public = 1;
  855. $worker->goods_id = $goods->id;
  856. $worker->worker_id = $worker_id;
  857. }
  858. $worker->status = 1;
  859. if (!$worker->save()) {
  860. $t->rollBack();
  861. return [
  862. 'code'=>1,
  863. 'msg'=>'服务人员保存错误'
  864. ];
  865. };
  866. }
  867. }
  868. }
  869. }
  870. }
  871. // 自定义表单
  872. Form::updateAll(['is_delete' => 1], ['store_id' => $this->store_id, 'goods_id' => $goods['id']]);
  873. if ($this->form['is_form'] == 1) {
  874. if (!$this->form['form_list']) {
  875. $t->rollBack();
  876. return [
  877. 'code'=>1,
  878. 'msg'=>'请填写表单设置'
  879. ];
  880. }
  881. }
  882. if ($this->form['form_list']) {
  883. $this->form['form_list'] = array_values($this->form['form_list']);
  884. foreach ($this->form['form_list'] as $index => $value) {
  885. if (!$value['name']) {
  886. $t->rollBack();
  887. return [
  888. 'code' => 1,
  889. 'msg' => '请输入字段名称'
  890. ];
  891. }
  892. if (in_array($value['type'], ['radio', 'checkbox'])) {
  893. if (!$value['default']) {
  894. $t->rollBack();
  895. return [
  896. 'code' => 1,
  897. 'msg' => '请输入单选或多选的默认值'
  898. ];
  899. }
  900. }
  901. if (isset($value['id'])) {
  902. $form = Form::findOne(['store_id' => $this->store_id, 'id' => $value['id']]);
  903. } else {
  904. $form = new Form();
  905. $form->goods_id = $goods['id'];
  906. }
  907. $form->is_delete = 0;
  908. $form->created_at = time();
  909. $form->type = $value['type'];
  910. $form->name = $value['name'];
  911. $form->default = isset($value['default']) ? $value['default'] : '';
  912. $form->required = $value['required'] ? $value['required'] : 0;
  913. $form->tip = $value['tip'];
  914. $form->sort = $index;
  915. $form->store_id = $this->store_id;
  916. if (!$form->save()) {
  917. $t->rollBack();
  918. return [
  919. 'code' => 1,
  920. 'msg' => $form->errors[0]
  921. ];
  922. }
  923. }
  924. }
  925. //判断如果规格发生改变就删除满减规则
  926. if (!empty($this->is_change_attr)) {
  927. GoodsFullMinus::updateAll(['is_delete' => 1], ['goods_id' => $goods->id]);
  928. }
  929. // 预约
  930. if ($this->product_type == Goods::GOODS_TYPE_DATE) {
  931. $goods->use_attr = 0;
  932. // if (empty($this->date_book)) {
  933. // $t->rollBack();
  934. // return [
  935. // 'code' => 1,
  936. // 'msg' => '请检查预约日期相关配置是否正确'
  937. // ];
  938. // }
  939. //
  940. // foreach ($this->date_book as $k => $v) {
  941. // if (intval($v['num']) < 0 || $v['price'] <= 0) {
  942. // $t->rollBack();
  943. // return [
  944. // 'code' => 1,
  945. // 'msg' => '请检查预约日期的价格和库存参数是否填写正确'
  946. // ];
  947. // }
  948. // }
  949. // $goods_book = GoodsBook::findOne(['goods_id' => $goods->id]);
  950. // if (!$goods_book) {
  951. // $goods_book = new GoodsBook();
  952. // }
  953. // $goods_book->goods_id = $goods->id;
  954. // $goods_book->date_book = Json::encode($this->date_book);
  955. // $goods_book->save();
  956. }
  957. if ($this->product_type == Goods::GOODS_TYPE_TIME) {
  958. if (empty($this->service_book) || !is_array($this->service_book) || empty($this->service_book['data'])) {
  959. $t->rollBack();
  960. return [
  961. 'code' => 1,
  962. 'msg' => '请检查服务商品预定参数'
  963. ];
  964. }
  965. // if (count($this->service_book['data']) != $this->service_book['date']) {
  966. // $t->rollBack();
  967. // return [
  968. // 'code' => 1,
  969. // 'msg' => '请检查是否少填写时间段和价格参数'
  970. // ];
  971. // }
  972. $service_book = $this->service_book;
  973. // foreach ($service_book[0]['time'] as $item) {
  974. // if (!$item['end_time'] || !$item['start_time']) {
  975. // return [
  976. // 'code' => 1,
  977. // 'msg' => '请检查是否少填写时间开始结束日期'
  978. // ];
  979. // }
  980. // foreach ($item['times'] as $time) {
  981. // if (!$time['time'] || !$time['price'] || !$time['num']) {
  982. // return [
  983. // 'code' => 1,
  984. // 'msg' => '请检查是否少填写时间段和价格参数'
  985. // ];
  986. // }
  987. // }
  988. // }
  989. //$time_arr = [];
  990. if (empty($service_book['data'][0]['time'])) {
  991. $t->rollBack();
  992. return [
  993. 'code' => 1,
  994. 'msg' => '请检查是否少填写时间段'
  995. ];
  996. }
  997. $num = 0;
  998. foreach ($service_book['data'][0]['time'] as $v) {
  999. if (empty($v['start_time']) || empty($v['end_time'])) {
  1000. $t->rollBack();
  1001. return [
  1002. 'code' => 1,
  1003. 'msg' => '请检查是否少填写时间段'
  1004. ];
  1005. }
  1006. if (empty($v['times']) || !is_array($v['times'])) {
  1007. $t->rollBack();
  1008. return [
  1009. 'code' => 1,
  1010. 'msg' => '请检查时间段下是否未选择详细时间'
  1011. ];
  1012. }
  1013. foreach ($v['times'] as $m) {
  1014. if (empty($m['time']) || empty($m['price'] || empty($m['num']))) {
  1015. $t->rollBack();
  1016. return [
  1017. 'code' => 1,
  1018. 'msg' => '请检查是否少填写时间点, 价格以及库存'
  1019. ];
  1020. }
  1021. $num += (int)$m['num'];
  1022. }
  1023. // $time_arr[] = [
  1024. // 'start_time' => $v['start_time'],
  1025. // 'end_time' => $v['end_time'],
  1026. // ];
  1027. }
  1028. // foreach ($this->service_book['data'] as $val) {
  1029. // if (empty($val['time'])) {
  1030. // $t->rollBack();
  1031. // return [
  1032. // 'code' => 1,
  1033. // 'msg' => '请检查是否少填写时间段'
  1034. // ];
  1035. // }
  1036. // foreach ($val['time'] as $v) {
  1037. // if (empty($v['start_time']) || empty($v['end_time'])) {
  1038. // $t->rollBack();
  1039. // return [
  1040. // 'code' => 1,
  1041. // 'msg' => '请检查是否少填写时间段'
  1042. // ];
  1043. // }
  1044. // if (empty($v['times']) || !is_array($v['times'])) {
  1045. // $t->rollBack();
  1046. // return [
  1047. // 'code' => 1,
  1048. // 'msg' => '请检查时间段下是否未选择详细时间'
  1049. // ];
  1050. // }
  1051. // foreach ($v['times'] as $m) {
  1052. // if (empty($m['time']) || empty($m['price'] || empty($m['num']))) {
  1053. // $t->rollBack();
  1054. // return [
  1055. // 'code' => 1,
  1056. // 'msg' => '请检查是否少填写时间点, 价格以及库存'
  1057. // ];
  1058. // }
  1059. // }
  1060. // $time_arr[] = [
  1061. // 'start_time' => $v['start_time'],
  1062. // 'end_time' => $v['end_time'],
  1063. // ];
  1064. // }
  1065. // }
  1066. // if (!empty($time_arr)) {
  1067. // if (!$this->compareDate($time_arr)) {
  1068. // $t->rollBack();
  1069. // return [
  1070. // 'code' => 1,
  1071. // 'msg' => '请勿重复设置时间段'
  1072. // ];
  1073. // }
  1074. // }
  1075. $goods_book = GoodsBook::findOne(['goods_id' => $goods->id]);
  1076. if (!$goods_book) {
  1077. $goods_book = new GoodsBook();
  1078. $goods_book->goods_id = $goods->id;
  1079. }
  1080. $goods_book->service_book = Json::encode($this->service_book);
  1081. $goods_book->save();
  1082. }
  1083. // 设置规格
  1084. try {
  1085. $this->setAttr($goods);
  1086. } catch(\Exception $e){}
  1087. if ($this->cat_id && count($this->cat_id)) {
  1088. if ($goods->id > 0) {
  1089. GoodsCat::deleteAll(['goods_id' => $goods->id]);
  1090. }
  1091. $goodsCatForm = new GoodsCat();
  1092. foreach ($this->cat_id as $cat_id) {
  1093. $goodsCat = clone $goodsCatForm;
  1094. $goodsCat->goods_id = $goods->id;
  1095. $goodsCat->cat_id = $cat_id;
  1096. $goodsCat->store_id = $goods->store_id;
  1097. if (!$goodsCat->save()) {
  1098. $t->rollBack();
  1099. return [
  1100. 'code' => 1,
  1101. 'msg' => '保存失败'
  1102. ];
  1103. }
  1104. }
  1105. }
  1106. if ($this->goods_pic_list) {
  1107. if ($goods->id > 0) {
  1108. GoodsPic::deleteAll(['goods_id' => $goods->id]);
  1109. }
  1110. $goodsPicForm = new GoodsPic();
  1111. foreach ($this->goods_pic_list as $pic) {
  1112. $goodsPic = clone $goodsPicForm;
  1113. $goodsPic->goods_id = $goods->id;
  1114. $goodsPic->pic_url = $pic['pic_url'];
  1115. if (!$goodsPic->save()) {
  1116. $t->rollBack();
  1117. return [
  1118. 'code' => 1,
  1119. 'msg' => '保存失败'
  1120. ];
  1121. }
  1122. }
  1123. }
  1124. // 处理商品浏览权限数据
  1125. // 删除关系表这个商品的所有数据
  1126. GoodsBrowse::deleteAll(['goods_id' => $goods->id]);
  1127. if (!empty($this->browse_type_info) && is_array($this->browse_type_info)) {
  1128. if (!in_array($this->browse_type_info['type'], [0, 1])) {
  1129. return [
  1130. 'code'=>1,
  1131. 'msg'=>'商品预览类型设置错误'
  1132. ];
  1133. }
  1134. if ((int)$this->browse_type_info['type'] === 1 && !in_array(0,$this->browse_type_info['member_level'])) {
  1135. $goodsBrowse = new GoodsBrowse();
  1136. foreach($this->browse_type_info['member_level'] as $level){
  1137. $goodsBrowseModel = clone $goodsBrowse;
  1138. $goodsBrowseModel->goods_id = $goods->id;
  1139. $goodsBrowseModel->level = $level;
  1140. $goodsBrowseModel->save();
  1141. }
  1142. }
  1143. }
  1144. $t->commit();
  1145. if ($goods->cloud_goods_id) {
  1146. $cloud_is_update = Option::get('cloud_is_update', $goods->store_id, 'store')['value'];
  1147. if ($cloud_is_update) {
  1148. $this->id = $goods->cloud_goods_id;
  1149. $this->store_id = $goods->store_id;
  1150. $goodsInfo = $this->saveCloudGoods();
  1151. if (!isset($goodsInfo['code'])) {
  1152. $merchantForm = new MerchantForm();
  1153. $merchantForm->mchGoodsImport($goodsInfo['cloudBindInfo'],$goodsInfo['goods_id']);
  1154. }
  1155. }
  1156. }
  1157. // 同步门店商品
  1158. queue_push(new SyncMdGoodsJob(['goods_ids' => [$goods->id]]), 0, 1);
  1159. Goods::skuAttr($goods);
  1160. return [
  1161. 'code' => 0,
  1162. 'msg' => '保存成功',
  1163. 'goods' => $goods,
  1164. ];
  1165. } else {
  1166. $t->rollBack();
  1167. return [
  1168. 'code' => 1,
  1169. 'msg' => '添加失败' . json_encode($goods->errors, JSON_UNESCAPED_UNICODE)
  1170. ];
  1171. }
  1172. }
  1173. // 服务商品
  1174. public function bookingGoodsSave($goods) {
  1175. if ($this->product_type == Goods::GOODS_TYPE_TIME) {
  1176. $bookingGoodsExtSave = BookingForm::bookingGoodsExtSave($goods->store_id, $goods->id, $this->booking_goods_cat_id);
  1177. if($bookingGoodsExtSave['code'] != 0){
  1178. return $bookingGoodsExtSave;
  1179. }
  1180. return [
  1181. 'code' => 0,
  1182. 'msg' => '保存成功',
  1183. 'bookingGoodsExtSave' => $bookingGoodsExtSave,
  1184. ];
  1185. }
  1186. }
  1187. public function saveFood($params = [])
  1188. {
  1189. if (!$this->validate()) {
  1190. return [
  1191. 'code' => 1,
  1192. 'msg' => $this->getErrorSummary(false)[0],
  1193. ];
  1194. }
  1195. $full_cut = [
  1196. 'pieces' => 0,
  1197. 'forehead' => 0
  1198. ];
  1199. if($this->pieces){
  1200. $full_cut['pieces'] = $this->pieces;
  1201. }
  1202. if($this->forehead){
  1203. $full_cut['forehead'] = $this->forehead;
  1204. }
  1205. $t = \Yii::$app->db->beginTransaction();
  1206. $goods = $this->id ? Goods::findOne($this->id) ?: new Goods() : new Goods();
  1207. $goods->store_id = $this->store_id;
  1208. $params['mch'] && $goods->mch_id = $params['mch_id'];
  1209. $goods->name = $this->name;
  1210. $goods->key_word = $this->key_word;
  1211. $goods->unit = $this->unit;
  1212. $goods->price = $this->price;
  1213. $goods->cost_price = $this->cost_price;
  1214. $goods->original_price = $this->original_price;
  1215. $goods->service = $this->service;
  1216. $goods->weight = $this->weight;
  1217. $goods->freight = $this->freight;
  1218. $goods->pieces = $this->pieces;
  1219. $goods->full_cut = Json::encode($full_cut);
  1220. $goods->forehead = $this->forehead;
  1221. $goods->quick_purchase = $this->quick_purchase;
  1222. $goods->video_url = $this->video_url;
  1223. $goods->detail = $this->content;
  1224. $goods->goods_num = $this->goods_num;
  1225. $goods->goods_no = $this->goods_no;
  1226. $goods->integral = json_encode( $this->integral);
  1227. $goods->use_attr = $this->use_attr;
  1228. $goods->is_negotiable = $this->is_negotiable;
  1229. $goods->cover_pic = $this->cover_pic;
  1230. $goods->individual_share = $this->individual_share;
  1231. $goods->share_commission_first = $this->share_commission_first ? $this->share_commission_first : 0;
  1232. $goods->share_commission_second = $this->share_commission_second ? $this->share_commission_second : 0;
  1233. $goods->share_commission_third = $this->share_commission_third ? $this->share_commission_third : 0;
  1234. $goods->attr_setting_type = $this->attr_setting_type ? 1 : 0;
  1235. $goods->virtual_sales = $this->virtual_sales;
  1236. $goods->confine_count = $this->confine_count;
  1237. isset($this->order_min_count) && $goods->order_min_count = $this->order_min_count;
  1238. $goods->rate = $this->rate ? $this->rate : 0;
  1239. $goods->rate_type = $this->rate_type == 1 ? 1 : 0;
  1240. $goods->chain_rate = $this->chain_rate ? $this->chain_rate : 0;
  1241. $goods->chain_rate_type = $this->chain_rate_type == 1 ? 1 : 0;
  1242. $goods->is_level = $this->is_level;
  1243. $goods->delivery_type = $this->delivery_type ? json_encode($this->delivery_type) : '["delivery","shop"]';
  1244. $goods->product_type = 0;
  1245. $goods->form_name = '';
  1246. $goods->is_form = 0;
  1247. $goods->food_ext_goods_id = $this->food_ext_goods_id ? : 0;
  1248. $goods->cat_id = $this->cat_id;
  1249. $goods->md_food_id = get_md_id();
  1250. if ($this->goods_verify_card_list) {
  1251. $verify_card_id = '';
  1252. foreach($this->goods_verify_card_list as $val) {
  1253. $verify_card_id .= $verify_card_id ? ','.$val['id'] : $val['id'];
  1254. }
  1255. $goods->verify_card_id = $verify_card_id;
  1256. }
  1257. if ($goods->save()) {
  1258. // 设置规格
  1259. try {
  1260. $this->setAttr($goods);
  1261. } catch(\Exception $e){}
  1262. if ($this->goods_pic_list) {
  1263. if ($goods->id > 0) {
  1264. GoodsPic::deleteAll(['goods_id' => $goods->id]);
  1265. }
  1266. $goodsPicForm = new GoodsPic();
  1267. foreach ($this->goods_pic_list as $pic) {
  1268. $goodsPic = clone $goodsPicForm;
  1269. $goodsPic->goods_id = $goods->id;
  1270. $goodsPic->pic_url = $pic['pic_url'];
  1271. if (!$goodsPic->save()) {
  1272. $t->rollBack();
  1273. return [
  1274. 'code' => 1,
  1275. 'msg' => '保存失败'
  1276. ];
  1277. }
  1278. }
  1279. }
  1280. $t->commit();
  1281. return [
  1282. 'code' => 0,
  1283. 'msg' => '保存成功'
  1284. ];
  1285. } else {
  1286. $t->rollBack();
  1287. return [
  1288. 'code' => 1,
  1289. 'msg' => '添加失败'
  1290. ];
  1291. }
  1292. }
  1293. public function getEdit($id)
  1294. {
  1295. if ($id) {
  1296. $goods = Goods::findOne($id);
  1297. if (empty($goods)) {
  1298. return [
  1299. 'code' => 1,
  1300. 'msg' => '商品获取失败'
  1301. ];
  1302. }
  1303. $erp_is_open = erp\InventoryForm::isOpen(get_store_id());
  1304. Goods::skuAttr($goods);
  1305. $getAttrGroupList = $goods->getAttrGroupList();
  1306. $goods = $goods->toArray();
  1307. $cat_id = GoodsCat::find()
  1308. ->where(['goods_id' => $goods['id'], 'is_delete' => 0])
  1309. ->select(['cat_id'])->asArray()->all();
  1310. $cat_id = array_column($cat_id, 'cat_id');
  1311. $goods['cat_id'] = $cat_id;
  1312. if ($goods['mch_id']) {
  1313. $mchList = (new MchForm(['store_id' => get_store_id()]))->mchSelectList();
  1314. $mchCommonCatSelectList = (new MchForm(['store_id' => get_store_id()]))->mchCommonCatSelectList();
  1315. $goods['mch'] = $mchList['data'][$goods['mch_id']];
  1316. $goods['mch_common_cat'] = $mchCommonCatSelectList['data'][$goods['mch']['mch_common_cat_id']];
  1317. $mch_goods_cat = MchGoodsCat::find()
  1318. ->where([ 'goods_id' => $goods['id'] ])
  1319. ->select(['cat_id'])
  1320. ->asArray()
  1321. ->all();
  1322. $mch_goods_cat_id = array_column($mch_goods_cat, 'cat_id');
  1323. $goods['mch_cat_id'] = $mch_goods_cat_id;
  1324. }
  1325. $goods['integral'] = json_decode($goods['integral'],true);
  1326. $goods['goods_pic_list'] = GoodsPic::find()->select(['pic_url'])
  1327. ->where(['goods_id' => $id])->asArray()->all();
  1328. foreach ($goods as &$val) {
  1329. $val = is_int($val) ? (string)$val : $val;
  1330. }
  1331. $goods['content'] = $goods['detail'];
  1332. // 获取等级分润配置
  1333. $gooodsChainLevel = GoodsChainLevel::findOne(['goods_id' => $id]);
  1334. $goods['is_open'] = '0';
  1335. $goods['chain_type'] = '1';
  1336. $goods['chain_level_value'] = [];
  1337. if ($gooodsChainLevel) {
  1338. $goods['is_open'] = (string)$gooodsChainLevel->is_open;
  1339. $goods['chain_type'] = (string)$gooodsChainLevel->type;
  1340. if ($chainLevelValue = json_decode($gooodsChainLevel->value)) {
  1341. $goods['chain_level_value'] = $chainLevelValue;
  1342. }
  1343. }
  1344. if (intval($goods['product_type']) === Goods::GOODS_TYPE_WORKER) {
  1345. $worker_id = WorkerGoods::find()->where(['goods_id' => $id, 'status' => 1])->select('worker_id')->column();
  1346. $goods['worker_ids'] = implode(',', $worker_id);
  1347. $worker_goods_ext = WorkerGoodsExt::findOne(['goods_id' => $id]);
  1348. $goods['desc'] = $worker_goods_ext->desc;
  1349. $goods['warn'] = $worker_goods_ext->warn;
  1350. $goods['worker_goods_cat_id'] = $worker_goods_ext->cat_id;
  1351. $goods['bind_worker'] = $worker_goods_ext->bind_worker;
  1352. $goods['final_profit'] = $worker_goods_ext->final_profit;
  1353. $goods['payment_type'] = $worker_goods_ext->payment_type;
  1354. }
  1355. } else {
  1356. $goods = null;
  1357. $goods['is_open'] = '0';
  1358. $goods['chain_level_value'] = [];
  1359. }
  1360. if (!empty($goods['buy_type_info'])) {
  1361. $goods['buy_type_info'] = json_decode($goods['buy_type_info'],true);
  1362. $goods['buy_type_info']['type'] = (int)$goods['buy_type_info']['type'];
  1363. if (isset($goods['buy_type_info']['member_level']) && is_numeric($goods['buy_type_info']['member_level'])) {
  1364. $goods['buy_type_info']['member_level'] = explode(',', $goods['buy_type_info']['member_level']);
  1365. }
  1366. } else {
  1367. $goods['buy_type_info'] = [
  1368. 'type' => 0,
  1369. 'member_level' => ['-1']
  1370. ];
  1371. }
  1372. // 获取商品浏览会员等级对应数据
  1373. $goodsBrowse = GoodsBrowse::find()->where(['goods_id' => $id])->asArray()->select('level')->column();
  1374. if(empty($goodsBrowse)){
  1375. $goods['browse_type_info'] = ['type' => 0,'member_level' => [0]];
  1376. }else{
  1377. $goods['browse_type_info'] = ['type' => 1,'member_level' => $goodsBrowse];
  1378. }
  1379. $send_type = Option::get(OptionSetting::STORE_SEND_TYPE, get_store_id(), 'store')['value'];
  1380. $send_type = Option::get(OptionSetting::STORE_SEND_TYPE, get_store_id(), 'pay', $send_type);
  1381. $send_type = $send_type ? Json::decode($send_type['value']) : [];
  1382. $send_type_arr = [];
  1383. foreach ((array)$send_type as $key => $send) {
  1384. if ($send['value'] == 1) {
  1385. $send_type_arr[$key] = $send['text'];
  1386. }
  1387. }
  1388. $arr = empty($send_type_arr) ? ['express' => '快递', 'shop' => '自提'] : $send_type_arr;
  1389. $goods['goods_delivery_type'] = !empty($goods['delivery_type']) ? Json::decode($goods['delivery_type']) : array_keys($arr);
  1390. $goods['delivery_type'] = $arr;
  1391. $goods['parameter_list'] = Json::decode($goods['parameter_list']);
  1392. $goods['rate_type'] = (string)(int)$goods['rate_type'];
  1393. $goods['chain_rate_type'] = (string)(int)$goods['chain_rate_type'];
  1394. $goods['md_rate_type'] = (string)(int)$goods['md_rate_type'];
  1395. $goods['md_hx_rate_type'] = (string)(int)$goods['md_hx_rate_type'];
  1396. $goods['dl_p_rate_type'] = (string)(int)$goods['dl_p_rate_type'];
  1397. $goods['dl_c_rate_type'] = (string)(int)$goods['dl_c_rate_type'];
  1398. $goods['dl_d_rate_type'] = (string)(int)$goods['dl_d_rate_type'];
  1399. $goods['dl_t_rate_type'] = (string)(int)$goods['dl_t_rate_type'];
  1400. $goods['is_front_delivery'] = (int)$goods['is_front_delivery'];
  1401. $goods['is_front_centralize'] = (int)$goods['is_front_centralize'];
  1402. $goods['agent_goods_status'] = (int)$goods['agent_goods_status'];
  1403. $goods['is_cloud_express'] = (int)$goods['is_cloud_express'];
  1404. //获取配送规则
  1405. $DeliveryRules = DeliveryRules::find()->where(['store_id' => get_store_id(), 'status' => 1, 'is_delete' => 0])->select('id, type, times, days')->asArray()->all();
  1406. foreach ($DeliveryRules as &$deliveryRule) {
  1407. if ((int)$deliveryRule['type'] === 0) {
  1408. $deliveryRule['times'] = date("Y-m-d H:i:s", $deliveryRule['times']);
  1409. }
  1410. }
  1411. // 获取运费规则
  1412. $postage = PostageRules::find()->where([
  1413. 'store_id' => get_store_id(),
  1414. 'is_delete' => 0,
  1415. 'mch_id' => 0
  1416. ])->select(['id', 'name', 'is_enable'])->asArray()->all();
  1417. if ($goods['mch_id'] || $this->mch_id) {
  1418. $postage = PostageRules::find()->where([
  1419. 'store_id' => 0,
  1420. 'is_delete' => 0,
  1421. 'mch_id' => get_mch_id(),
  1422. ])->select(['id', 'name', 'is_enable'])->asArray()->all();
  1423. }
  1424. array_unshift($postage, ['id' => 0, 'name' => '--']);
  1425. // 获取所有的会员等级
  1426. $level = Level::find()->where([
  1427. 'store_id' => get_store_id(),
  1428. 'is_delete' => 0,
  1429. 'status' => 1
  1430. ])->select(['level as id', 'name'])->orderBy(['id' => SORT_DESC])->asArray()->all();
  1431. //获取分销等级
  1432. $share_level = ShareLevel::find()->where(['store_id' => get_store_id(), 'is_delete' => ShareLevel::SHARE_NOT_DELETE, 'status' => ShareLevel::STATUS_ON])
  1433. ->select('level id, name')->orderBy('level ASC')->asArray()->all();
  1434. $share_level = array_merge([[
  1435. 'id' => 0,
  1436. 'name' => '默认等级'
  1437. ]], $share_level);
  1438. // 卡券
  1439. $verify_list = VerifyCard::find()
  1440. ->where([
  1441. 'store_id' => get_store_id(),
  1442. 'is_delete' => 0
  1443. ])->orderBy(['sort' => SORT_ASC])
  1444. ->select([
  1445. '*'
  1446. ])->asArray()
  1447. ->all();
  1448. $verify_list = Tools::getVerifyList($verify_list);
  1449. $coupon_list = Coupon::find()
  1450. ->where([
  1451. 'store_id' => get_store_id(),
  1452. 'is_delete' => 0,
  1453. 'is_business' => 0,
  1454. ])->andWhere(['<>', 'total_count', 0])
  1455. ->orderBy(['sort' => SORT_ASC])
  1456. ->asArray()
  1457. ->all();
  1458. foreach ($coupon_list as $coupon_index => $coupon_item) {
  1459. $coupon_send_count = UserCoupon::find()->where([
  1460. 'coupon_id' => $coupon_item['id'],
  1461. 'type' => [
  1462. UserCoupon::TYPE_STORE,
  1463. UserCoupon::TYPE_AUTO,
  1464. UserCoupon::TYPE_GET
  1465. ]
  1466. ])->select('id')->count();
  1467. if (intval($coupon_item['total_count']) !== -1 && $coupon_item['total_count'] <= $coupon_send_count) {
  1468. unset($coupon_list[$coupon_index]);
  1469. }
  1470. }
  1471. $coupon_list = array_values($coupon_list);
  1472. $goods_verify_card_list = [];
  1473. // 获取商品已添加核销卡
  1474. if (!empty($goods) && !empty($goods['verify_card_id'])) {
  1475. $verify_cards = explode(',', $goods['verify_card_id']);
  1476. foreach ($verify_cards as $k => $v) {
  1477. $res = VerifyCard::find()
  1478. ->select(['id','name'])
  1479. ->where(['id' => $v,'is_delete' => 0])
  1480. ->asArray()->one();
  1481. if ($res) {
  1482. $goods_verify_card_list[] = $res;
  1483. }
  1484. }
  1485. }
  1486. $goods_coupon_card_list = [];
  1487. // 获取商品已添加核销卡
  1488. if (!empty($goods) && !empty($goods['coupon_card_id'])) {
  1489. $verify_cards = explode(',', $goods['coupon_card_id']);
  1490. foreach ($verify_cards as $k => $v) {
  1491. $res = Coupon::find()
  1492. ->select(['id','name'])
  1493. ->where(['id' => $v,'is_delete' => 0])
  1494. ->asArray()->one();
  1495. if ($res) {
  1496. $goods_coupon_card_list[] = $res;
  1497. }
  1498. }
  1499. }
  1500. // 服务商品预约
  1501. $goods['service_book'] = [
  1502. 'date' => 0,
  1503. 'data' => [],
  1504. 'flag' => 1
  1505. ];
  1506. $goods['date_book'] = [
  1507. 'data' => [],
  1508. 'date' => 30
  1509. ];
  1510. $goods['form'] = [
  1511. 'form_list' => [],
  1512. 'is_form' => 0,
  1513. 'form_name' => ''
  1514. ];
  1515. if (isset($goods['id'])) {
  1516. $goods_book_config = GoodsBook::findOne(['goods_id' => $goods['id']]);
  1517. if ($goods_book_config) {
  1518. $service_book = $goods_book_config->service_book;
  1519. $date_book = $goods_book_config->date_book;
  1520. if ($service_book) {
  1521. $goods['service_book'] = Json::decode($service_book);
  1522. }
  1523. if ($date_book) {
  1524. $goods['date_book']['data'] = Json::decode($date_book);
  1525. $goods['date_book']['date'] = count($goods['date_book']['data']);
  1526. }
  1527. }
  1528. $goods['form']['form_list'] = Form::find()->where(['is_delete' => 0, 'store_id' => $this->store_id, 'goods_id' => $goods['id']])->orderBy(['sort' => SORT_ASC])->asArray()->all();
  1529. $goods['form']['is_form'] = intval($goods['is_form']);
  1530. $goods['form']['form_name'] = $goods['form_name'];
  1531. }
  1532. $nums = [];
  1533. $endtime = mktime(0, 0, 0, date('m') + 2, 1);
  1534. for($i = time(); $i < $endtime; $i+=86400){
  1535. $date = date('Y-m-d', $i);
  1536. $nums[] = [
  1537. 'date' => $date,
  1538. 'num' => '0',
  1539. 'price' => '0.00'
  1540. ];
  1541. }
  1542. $goods['service_book_desc'] = [
  1543. 'date_book' => $nums ,
  1544. 'date' => count($nums)
  1545. ];
  1546. if ($goods['product_type'] == Goods::GOODS_TYPE_DATE) {
  1547. $goods_info = Goods::findOne($goods['id']);
  1548. $goods['num'] = Goods::getGoodsNum($goods_info)['data'];
  1549. $goods['service_book_desc'] = [
  1550. 'date_book' => $goods['num'] ,
  1551. 'date' => count($goods['num'])
  1552. ];
  1553. }
  1554. $goods['share_commission_new_first'] = $goods['share_commission_new_first'] ? json_decode($goods['share_commission_new_first'], true) : null;
  1555. $goods['share_commission_new_second'] = $goods['share_commission_new_second'] ? json_decode($goods['share_commission_new_second'], true) : null;
  1556. $goods['share_commission_new_third'] = $goods['share_commission_new_third'] ? json_decode($goods['share_commission_new_third'], true) : null;
  1557. $order_rules_buyer_location = \app\models\OrderRulesBuyerLocation::find()->where([
  1558. 'store_id' => get_store_id(),
  1559. 'is_delete' => 0,
  1560. ])->select(['id', 'name', 'is_enable'])->asArray()->all();
  1561. // 获取等级
  1562. $shareHolderLevel = ShareHolderLevel::find()->where([
  1563. 'store_id' => get_store_id(),
  1564. 'is_delete' => 0,
  1565. 'status' => 1
  1566. ])->select(['id', 'name'])->orderBy(['id' => SORT_ASC])->asArray()->all();
  1567. if($goods['product_type'] == 2){
  1568. $bookingGoodsExt = \app\models\BookingGoodsExt::findOne(['goods_id' => $goods['id']]);
  1569. }
  1570. $goods['share_holder_profit_switch'] = (int)$goods['share_holder_profit_switch'];
  1571. $goods['share_holder_high_profit'] = (float)$goods['share_holder_high_profit'];
  1572. $warehouseList = Warehouse::find()->where([
  1573. 'store_id' => get_store_id(),
  1574. 'is_delete' => 0,
  1575. ])->select(['id', 'name'])->orderBy(['id' => SORT_ASC])->asArray()->all();
  1576. $warehouse_zone_list = WarehouseZone::find()->where([
  1577. 'store_id' => get_store_id(),
  1578. 'is_delete' => 0,
  1579. ])->select(['id', 'name'])->orderBy(['id' => SORT_ASC])->asArray()->all();
  1580. $is_show_risk = Option::get(OptionSetting::IS_SHOW_RISK, $this->store_id, 'store', '')['value'];
  1581. return [
  1582. 'code' => 0,
  1583. 'msg' => 'success',
  1584. 'data' => [
  1585. 'erp_is_open' => $erp_is_open,
  1586. 'warehouse_list' => $warehouseList,
  1587. 'warehouse_zone_list' => $warehouse_zone_list,
  1588. 'bookingGoodsExt' => $bookingGoodsExt,
  1589. 'info' => $goods,
  1590. 'AttrGroupList' => isset($getAttrGroupList) ? $getAttrGroupList : [],
  1591. 'postage' => $postage,
  1592. 'order_rules_buyer_location' => $order_rules_buyer_location,
  1593. 'level' => $level,
  1594. 'verify_list' => $verify_list,
  1595. 'coupon_list' => $coupon_list,
  1596. 'goods_verify_card_list' => $goods_verify_card_list,
  1597. 'goods_coupon_card_list' => $goods_coupon_card_list,
  1598. 'delivery_rules' => $DeliveryRules,
  1599. 'shareHolderLevel' => $shareHolderLevel,
  1600. 'share_level' => $share_level,
  1601. 'is_show_risk' => intval($is_show_risk)
  1602. ]
  1603. ];
  1604. }
  1605. public function getFoodEdit($id)
  1606. {
  1607. if ($id) {
  1608. $goods = Goods::findOne($id);
  1609. if (empty($goods)) {
  1610. return [
  1611. 'code' => 1,
  1612. 'msg' => '商品获取失败'
  1613. ];
  1614. }
  1615. $getAttrGroupList = $goods->getAttrGroupList();
  1616. $goods = $goods->toArray();
  1617. $goods['integral'] = json_decode($goods['integral'],true);
  1618. $goods['goods_pic_list'] = GoodsPic::find()->select(['pic_url'])
  1619. ->where(['goods_id' => $id])->asArray()->all();
  1620. foreach ($goods as &$val) {
  1621. $val = is_int($val) ? (string)$val : $val;
  1622. }
  1623. $goods['content'] = $goods['detail'];
  1624. } else {
  1625. $goods = null;
  1626. }
  1627. return [
  1628. 'code' => 0,
  1629. 'msg' => 'success',
  1630. 'data' => [
  1631. 'info' => $goods,
  1632. 'AttrGroupList' => isset($getAttrGroupList) ? $getAttrGroupList : [],
  1633. ]
  1634. ];
  1635. }
  1636. /**
  1637. * @param Goods $goods
  1638. */
  1639. public function setAttr($goods, $rate = 0, $channel_rate = 0, $num_type = 0, $original_price = 0)
  1640. {
  1641. if ($goods->product_type == Goods::GOODS_TYPE_TIME) {
  1642. $defaultAttr = '[{"attr_list":[{"attr_id":1,"attr_name":"默认"}],"num":0,"price":0,"integral_price":0,"no":"","pic":"","share_commission_first":"","share_commission_second":"","share_commission_third":""}]';
  1643. $goods->attr = $defaultAttr;
  1644. $goods->save();
  1645. return;
  1646. }
  1647. if (!$this->use_attr) {
  1648. [$default_attr, $default_attr_group] = $this->getDefaultAttr();
  1649. if (empty($this->attr)) {
  1650. $this->attr = [
  1651. [
  1652. 'attr_list' => [
  1653. [
  1654. 'attr_group_name' => $default_attr_group->attr_group_name,
  1655. 'attr_id' => $default_attr->id,
  1656. 'attr_name' => $default_attr->attr_name,
  1657. ],
  1658. ],
  1659. 'num' => intval($this->goods_num) ?: 0,
  1660. 'price' => $this->price,
  1661. 'integral_price' => $this->integral_price,
  1662. 'cost_price' => $this->cost_price,
  1663. 'no' => $this->goods_no,
  1664. 'is_wholesale' => (int)$this->is_wholesale,
  1665. 'wholesale_num' => intval($this->wholesale_num) ?: 0,
  1666. 'sku_id' => '',
  1667. 'original_price' => $original_price ?: $goods->original_price,
  1668. ],
  1669. ];
  1670. } else {
  1671. $attr_list = [
  1672. [
  1673. 'attr_group_name' => $default_attr_group->attr_group_name,
  1674. 'attr_id' => $default_attr->id,
  1675. 'attr_name' => $default_attr->attr_name,
  1676. ],
  1677. ];
  1678. $this->attr[0]['attr_list'] = $attr_list;
  1679. if (!empty($this->is_wholesale)) {
  1680. $this->attr[0]['num'] = intval($this->goods_num) ?: ($this->attr[0]['num'] ?: 0);
  1681. } else {
  1682. $this->attr[0]['num'] = intval($this->goods_num);
  1683. }
  1684. if (!$num_type) {
  1685. if (!empty($this->is_wholesale)) {
  1686. $this->attr[0]['price'] = doubleval($this->price) ?: ($this->attr[0]['price'] ?: 0);
  1687. } else {
  1688. $this->attr[0]['price'] = doubleval($this->price);
  1689. }
  1690. $this->attr[0]['integral_price'] = intval($this->integral_price) ?: 0;
  1691. $this->attr[0]['cost_price'] = doubleval($this->cost_price) ?: 0;
  1692. }
  1693. $this->attr[0]['no'] = $this->attr[0]['no'] ?: $this->goods_no;
  1694. $this->attr[0]['is_wholesale'] = (int)$this->is_wholesale;
  1695. $this->attr[0]['wholesale_num'] = (int)$this->wholesale_num ?: 0;
  1696. $this->attr[0]['sku_id'] = '';
  1697. $this->attr[0]['original_price'] = doubleval($original_price ?: $goods->original_price) ?: 0;
  1698. $this->attr = [
  1699. $this->attr[0]
  1700. ];
  1701. }
  1702. }
  1703. if (empty($this->attr) || !is_array($this->attr)) {
  1704. return;
  1705. }
  1706. $new_attr = [];
  1707. $goods_attr = json_decode($goods->attr, true);
  1708. foreach ($this->attr as $i => $item) {
  1709. // if ($item['original_price'] > 0) {
  1710. // $attr_price = $item['original_price'];
  1711. // } else {
  1712. // }
  1713. $cost_price = $item['cost_price'];
  1714. $attr_price = $item['price'];
  1715. if (!$num_type || !$goods_attr) {
  1716. $attr_price = (int)$rate > 0 && ((int)$this->use_attr === 1) ? doubleval($item['price']) + (doubleval($item['price']) * ($rate / 100)) : doubleval($item['price']);
  1717. $sale_price_type = Option::get('sale_price_type', $this->store_id, 'store')['value'];
  1718. if ($sale_price_type <= 0) {
  1719. if ((int)$rate > 0) {
  1720. $price = !empty($item['platform_negotiated_price']) ? $item['platform_negotiated_price'] : $item['price'];
  1721. $attr_price = $price + $price * ($rate / 100);
  1722. } else {
  1723. $attr_price = $item['price'];
  1724. }
  1725. } else {
  1726. $attr_price = $item['original_price'] ?: $item['price'];
  1727. }
  1728. if (isset($item['platform_negotiated_price'])) {
  1729. $cost_price = $item['platform_negotiated_price'];
  1730. if ($channel_rate > 0) {
  1731. $cost_price = bcmul($item['platform_negotiated_price'], $channel_rate, 2);
  1732. }
  1733. }
  1734. } else {
  1735. $currentAttrIds = array_column($item, 'attr_id');
  1736. sort($currentAttrIds);
  1737. foreach ($goods_attr as $goods_attr_item) {
  1738. // $goodsAttrIds = array_column($goods_attr_item, 'attr_id');
  1739. // sort($goodsAttrIds);
  1740. if ($item['no'] == $goods_attr_item['no']) {
  1741. $attr_price = $goods_attr_item['price'];
  1742. }
  1743. }
  1744. }
  1745. //云仓商品更新库存:仓库配送产品更新库存时候计算方式:仓库库存
  1746. //如果是仓库配送商品
  1747. if (intval($goods->is_front_delivery)) {
  1748. $curr_attr_id = array_column($item['attr_list'], 'attr_id');
  1749. sort($curr_attr_id);
  1750. $inventory_array = AgentFrontErpInventory::find()->where(['goods_id' => $goods->cloud_goods_id])
  1751. ->asArray()->all();
  1752. if ($inventory_array) {
  1753. foreach ($inventory_array as $inventory_item) {
  1754. $inventory_attr_ids = explode(',', $inventory_item['attr_ids']);
  1755. sort($inventory_attr_ids);
  1756. if (!array_diff($inventory_attr_ids, $curr_attr_id)) {
  1757. $item['num'] = $inventory_item['num'];
  1758. }
  1759. }
  1760. }
  1761. }
  1762. $new_attr_item = [
  1763. 'attr_list' => [],
  1764. 'num' => intval($item['num']),
  1765. 'price' => sprintf('%.2f', $attr_price),
  1766. 'integral_price' => intval($item['integral_price']),
  1767. 'no' => $item['no'] ?: '',
  1768. 'pic' => $item['pic'] ?: '',
  1769. // 'share_commission_first' => $item['share_commission_first'] ?: '',
  1770. // 'share_commission_second' => $item['share_commission_second'] ?: '',
  1771. // 'share_commission_third' => $item['share_commission_third'] ?: '',
  1772. 'is_wholesale' => (int)$this->is_wholesale ?: 0,
  1773. 'wholesale_num' => (int)$item['num'] ?: 0,
  1774. 'cost_price' => sprintf('%.2f', $cost_price ?? $item['price']),
  1775. 'sku_id' => $item['sku_id'],
  1776. 'original_price' => $item['original_price'] ?? sprintf('%.2f', $attr_price)
  1777. ];
  1778. $individual_share = $goods->individual_share;
  1779. $attr_setting_type = $goods->attr_setting_type;
  1780. if (intval($individual_share) === 1 && intval($attr_setting_type) === 1) {
  1781. $share_level = ShareLevel::find()->where(['store_id' => get_store_id(), 'is_delete' => ShareLevel::SHARE_NOT_DELETE, 'status' => ShareLevel::STATUS_ON])
  1782. ->select('level id, name')->orderBy('level ASC')->asArray()->all();
  1783. $share_level = array_merge([[
  1784. 'id' => 0,
  1785. 'name' => '默认等级'
  1786. ]], $share_level);
  1787. $share_commission_level = [];
  1788. // foreach ($share_level as $share_level_index => $share_level_) {
  1789. //新一级分销
  1790. // if (!isset($item['share_commission_new_first']) || ($item['share_commission_new_first'])) {
  1791. foreach ($share_level as $share_level_index => $share_level_) {
  1792. if (!isset($item['share_commission_new_first'][$share_level_index])) {
  1793. $item['share_commission_new_first'][$share_level_index]['name'] = 'share_commission_level_' . $share_level_['id'];
  1794. $item['share_commission_new_first'][$share_level_index]['value'] = 0;
  1795. } else {
  1796. foreach ($item['share_commission_new_first'] as $share_commission_new_index => $share_commission_new_item) {
  1797. if ($share_commission_new_item['name'] === 'share_commission_level_' . $share_level_['id']) {
  1798. $item['share_commission_new_first'][$share_level_index]['value'] = $share_commission_new_item['value'];
  1799. }
  1800. }
  1801. }
  1802. if (!isset($item['share_commission_new_second'][$share_level_index])) {
  1803. $item['share_commission_new_second'][$share_level_index]['name'] = 'share_commission_level_' . $share_level_['id'];
  1804. $item['share_commission_new_second'][$share_level_index]['value'] = 0;
  1805. } else {
  1806. foreach ($item['share_commission_new_second'] as $share_commission_new_index => $share_commission_new_item) {
  1807. if ($share_commission_new_item['name'] === 'share_commission_level_' . $share_level_['id']) {
  1808. $item['share_commission_new_second'][$share_level_index]['value'] = $share_commission_new_item['value'];
  1809. }
  1810. }
  1811. }
  1812. if (!isset($item['share_commission_new_third'][$share_level_index])) {
  1813. $item['share_commission_new_third'][$share_level_index]['name'] = 'share_commission_level_' . $share_level_['id'];
  1814. $item['share_commission_new_third'][$share_level_index]['value'] = 0;
  1815. } else {
  1816. foreach ($item['share_commission_new_third'] as $share_commission_new_index => $share_commission_new_item) {
  1817. if ($share_commission_new_item['name'] === 'share_commission_level_' . $share_level_['id']) {
  1818. $item['share_commission_new_third'][$share_level_index]['value'] = $share_commission_new_item['value'];
  1819. }
  1820. }
  1821. }
  1822. }
  1823. // }
  1824. // }
  1825. $share_commission_level['share_commission_new_first'] = $item['share_commission_new_first'];
  1826. $share_commission_level['share_commission_new_second'] = $item['share_commission_new_second'];
  1827. $share_commission_level['share_commission_new_third'] = $item['share_commission_new_third'];
  1828. $new_attr_item = array_merge($new_attr_item, $share_commission_level);
  1829. }
  1830. foreach ($item as $k => $v) {
  1831. if (strpos($k,'member') !== false) {
  1832. $new_attr_item[$k] = $v;
  1833. }
  1834. }
  1835. foreach ($item['attr_list'] as $a) {
  1836. $attr_group_model = AttrGroup::findOne(['store_id' => $this->store_id, 'attr_group_name' => $a['attr_group_name'], 'is_delete' => 0]);
  1837. if (!$attr_group_model) {
  1838. $attr_group_model = new AttrGroup();
  1839. $attr_group_model->attr_group_name = $a['attr_group_name'];
  1840. $attr_group_model->store_id = $this->store_id;
  1841. $attr_group_model->is_delete = 0;
  1842. $attr_group_model->save();
  1843. }
  1844. $attr_model = Attr::findOne(['attr_group_id' => $attr_group_model->id, 'attr_name' => $a['attr_name'], 'is_delete' => 0]);
  1845. if (!$attr_model) {
  1846. $attr_model = new Attr();
  1847. $attr_model->attr_name = $a['attr_name'];
  1848. $attr_model->attr_group_id = $attr_group_model->id;
  1849. $attr_model->is_delete = 0;
  1850. $attr_model->save();
  1851. }
  1852. $new_attr_item['attr_list'][] = [
  1853. 'attr_id' => $attr_model->id,
  1854. 'attr_name' => $attr_model->attr_name,
  1855. ];
  1856. }
  1857. //如果未更改售价就使用原来的价格
  1858. if ($goods->attr && $num_type) {
  1859. $new_attr_item_id = array_column($new_attr_item['attr_list'], 'attr_id');
  1860. sort($new_attr_item_id);
  1861. $old_goods_attr = json_decode($goods->attr, true);
  1862. foreach ($old_goods_attr as $old_goods_attr_item) {
  1863. $old_goods_attr_id = array_column($old_goods_attr_item['attr_list'], 'attr_id');
  1864. sort($old_goods_attr_id);
  1865. if (!array_diff($new_attr_item_id, $old_goods_attr_id)) {
  1866. $member_arr = [];
  1867. foreach ($old_goods_attr_item as $old_goods_attr_item_index => $old_goods_attr_item_item) {
  1868. if (strpos($old_goods_attr_item_index, 'member') !== false) {
  1869. $member_arr[$old_goods_attr_item_index] = $old_goods_attr_item_item;
  1870. }
  1871. }
  1872. $new_attr_item = array_merge($new_attr_item, $member_arr);
  1873. }
  1874. }
  1875. }
  1876. $new_attr[] = $new_attr_item;
  1877. }
  1878. $goods->attr = Json::encode($new_attr);
  1879. $goods->save();
  1880. return;
  1881. }
  1882. /**
  1883. * @return array
  1884. */
  1885. private function getDefaultAttr()
  1886. {
  1887. $default_attr_name = '默认';
  1888. $default_attr_group_name = '规格';
  1889. $attr = Attr::findOne([
  1890. 'attr_name' => $default_attr_name,
  1891. 'is_delete' => 0,
  1892. 'is_default' => 1,
  1893. ]);
  1894. $attr_group = null;
  1895. if (!$attr) {
  1896. $attr_group = AttrGroup::findOne([
  1897. 'attr_group_name' => $default_attr_group_name,
  1898. 'is_delete' => 0,
  1899. ]);
  1900. if (!$attr_group) {
  1901. $attr_group = new AttrGroup();
  1902. $attr_group->store_id = $this->store_id;
  1903. $attr_group->attr_group_name = $default_attr_group_name;
  1904. $attr_group->is_delete = 0;
  1905. $attr_group->save(false);
  1906. }
  1907. $attr = new Attr();
  1908. $attr->attr_group_id = $attr_group->id;
  1909. $attr->attr_name = $default_attr_name;
  1910. $attr->is_delete = 0;
  1911. $attr->is_default = 1;
  1912. $attr->save(false);
  1913. } else {
  1914. $attr_group = AttrGroup::findOne($attr->attr_group_id);
  1915. if (!$attr_group) {
  1916. $attr_group = AttrGroup::findOne([
  1917. 'attr_group_name' => $default_attr_group_name,
  1918. 'is_delete' => 0,
  1919. ]);
  1920. if (!$attr_group) {
  1921. $attr_group = new AttrGroup();
  1922. $attr_group->store_id = $this->store_id;
  1923. $attr_group->attr_group_name = $default_attr_group_name;
  1924. $attr_group->is_delete = 0;
  1925. $attr_group->save(false);
  1926. }
  1927. $attr->attr_group_id = $attr_group->id;
  1928. $attr->save();
  1929. }
  1930. }
  1931. return [$attr, $attr_group];
  1932. }
  1933. public function setAttrNum($data = [])
  1934. {
  1935. $data = $data ? $data : post_params();
  1936. $goods = Goods::findOne($data['id']);
  1937. $arrt = Json::encode($data['attr']);
  1938. if ($goods) {
  1939. $goods->attr = $arrt;
  1940. $goods_num = 0;
  1941. foreach($data['attr'] as $item) {
  1942. $goods_num += $item['num'];
  1943. }
  1944. $goods->goods_num = $goods_num;
  1945. // if ($goods->mch_id > 0) {
  1946. // $mch = Mch::findOne($goods->mch_id);
  1947. // if ($mch->is_goods_ex == 1) {
  1948. // $goods->status = 0;
  1949. // $goods->is_verify = -1;
  1950. // }
  1951. // }
  1952. $goods->is_risk = $data['is_risk'];
  1953. $res = ['code' => 1, 'msg' => '保存失败'];
  1954. if ($goods->save()) {
  1955. // 同步门店商品
  1956. queue_push(new SyncMdGoodsJob(['goods_ids' => [$goods->id]]), 0, 1);
  1957. $res = ['code' => 0, 'msg' => '保存成功'];
  1958. }
  1959. } else {
  1960. $res = ['code' => 1, 'msg' => '参数错误'];
  1961. }
  1962. return $res;
  1963. }
  1964. public function updateAttrNum()
  1965. {
  1966. $data = post_params();
  1967. $goods = Goods::findOne($data['id']);
  1968. $arrt = Json::encode($data['attr']);
  1969. if ($goods) {
  1970. $goods->attr = $arrt;
  1971. $goods_num = 0;
  1972. foreach($data['attr'] as $item) {
  1973. $goods_num += $item['num'];
  1974. }
  1975. $goods->goods_num = $goods_num;
  1976. // if ($goods->mch_id > 0) {
  1977. // $mch = Mch::findOne($goods->mch_id);
  1978. // if ($mch->is_goods_ex == 1) {
  1979. // $goods->status = 0;
  1980. // $goods->is_verify = -1;
  1981. // }
  1982. // }
  1983. $res = ['code' => 1, 'msg' => '保存失败'];
  1984. if ($goods->save()) {
  1985. // 同步门店商品
  1986. queue_push(new SyncMdGoodsJob(['goods_ids' => [$goods->id]]), 0, 1);
  1987. $res = ['code' => 0, 'msg' => '保存成功'];
  1988. }
  1989. } else {
  1990. $res = ['code' => 1, 'msg' => '参数错误'];
  1991. }
  1992. return $res;
  1993. }
  1994. // 修改商品属性
  1995. public function setType($goods_id = 0, $type = '', $value = '')
  1996. {
  1997. $type = $type ? $type : get_params('type');
  1998. $goods_id = $goods_id ? $goods_id : get_params('id');
  1999. $value = $value ? $value : get_params('value', 0);
  2000. if (!$type || !$goods_id) {
  2001. return [
  2002. 'code' => 1,
  2003. 'msg' => '参数错误'
  2004. ];
  2005. }
  2006. $goods = Goods::findOne([
  2007. 'id' => $goods_id,
  2008. // 'mch_id' => get_mch_id(),
  2009. // 'store_id' => get_store_id()
  2010. ]);
  2011. if (empty($goods)) {
  2012. return [
  2013. 'code' => 1,
  2014. 'msg' => '查询商品为空'
  2015. ];
  2016. }
  2017. if ($type == 'price' && $goods->use_attr == 1) {
  2018. return [
  2019. 'code' => 0,
  2020. 'msg' => '保存成功'
  2021. ];
  2022. }
  2023. $goods->$type = $value;
  2024. if($type == 'price') {
  2025. $goods->is_risk = get_params('is_risk');
  2026. }
  2027. if ($type == 'goods_num' && $goods->use_attr == 0) {
  2028. $attr = Json::decode($goods->attr);
  2029. $attr[0]['num'] = $value;
  2030. $goods->attr = Json::encode($attr);
  2031. }
  2032. if ($type == 'price' && $goods->use_attr == 0) {
  2033. $attr = Json::decode($goods->attr);
  2034. $attr[0]['price'] = doubleval($value);
  2035. $goods->attr = Json::encode($attr);
  2036. }
  2037. // if ($goods->mch_id > 0) {
  2038. // $mch = Mch::findOne($goods->mch_id);
  2039. // if ($mch->is_goods_ex == 1) {
  2040. // $goods->status = 0;
  2041. // $goods->is_verify = -1;
  2042. // }
  2043. // }
  2044. if ($goods->save()) {
  2045. if ($goods->cloud_goods_id) {
  2046. $cloud_is_update = Option::get('cloud_is_update', $goods->store_id, 'store')['value'];
  2047. if ($cloud_is_update) {
  2048. $this->id = $goods->cloud_goods_id;
  2049. $this->store_id = $goods->store_id;
  2050. $goodsInfo = $this->saveCloudGoods();
  2051. if (!isset($goodsInfo['code'])) {
  2052. $merchantForm = new MerchantForm();
  2053. $merchantForm->mchGoodsImport($goodsInfo['cloudBindInfo'],$goodsInfo['goods_id']);
  2054. }
  2055. }
  2056. }
  2057. // 同步门店商品
  2058. queue_push(new SyncMdGoodsJob(['goods_ids' => [$goods->id]]), 0, 1);
  2059. return [
  2060. 'code' => 0,
  2061. 'msg' => '保存成功'
  2062. ];
  2063. } else {
  2064. return [
  2065. 'code' => 1,
  2066. 'msg' => '保存失败'
  2067. ];
  2068. }
  2069. }
  2070. public function upPriceBatch($goods_id = [], $num = 0, $type) {
  2071. foreach($goods_id as $gid){
  2072. $goods = Goods::findOne($gid);
  2073. if ($type == 'add') {
  2074. $goods->price += $goods->price * ($num / 100);
  2075. $goods->original_price += $goods->original_price * ($num / 100);
  2076. } else {
  2077. $goods->price -= $goods->price * ($num / 100);
  2078. $goods->original_price -= $goods->original_price * ($num / 100);
  2079. }
  2080. $res = $this->setType($goods->id, 'price', $goods->price);
  2081. if($res['code'] != 0){
  2082. return $res;
  2083. }
  2084. $res = $this->setType($goods->id, 'original_price', $goods->original_price);
  2085. if($res['code'] != 0){
  2086. return $res;
  2087. }
  2088. $attr = json_decode($goods->attr, true);
  2089. foreach($attr as &$iattr){
  2090. if ($type == 'add') {
  2091. $iattr['price'] += $iattr['price'] * ($num / 100);
  2092. } else {
  2093. $iattr['price'] -= $iattr['price'] * ($num / 100);
  2094. }
  2095. $iattr['price'] = number_format($iattr['price'], 2, '.', '');
  2096. }
  2097. $res = $this->setAttrNum([
  2098. 'id' => $goods->id,
  2099. 'attr' => $attr,
  2100. ]);
  2101. if($res['code'] != 0){
  2102. return $res;
  2103. }
  2104. }
  2105. return [
  2106. 'code' => 0,
  2107. 'msg' => '保存成功'
  2108. ];
  2109. }
  2110. // 修改商品属性
  2111. public function updateAttribute()
  2112. {
  2113. $type = post_params('type');
  2114. $goods_id = post_params('id');
  2115. $value = post_params('value', 0);
  2116. if (!$type || !$goods_id) {
  2117. return [
  2118. 'code' => 1,
  2119. 'msg' => '参数错误'
  2120. ];
  2121. }
  2122. $goods = Goods::findOne([
  2123. 'id' => $goods_id,
  2124. 'store_id' => get_store_id()
  2125. ]);
  2126. if (empty($goods)) {
  2127. return [
  2128. 'code' => 1,
  2129. 'msg' => '查询商品为空'
  2130. ];
  2131. }
  2132. $goods->$type = $value;
  2133. if ($type == 'goods_num' && $goods->use_attr == 0) {
  2134. $attr = Json::decode($goods->attr);
  2135. $attr[0]['num'] = $value;
  2136. $goods->attr = Json::encode($attr);
  2137. }
  2138. if ($type == 'price' && $goods->use_attr == 0) {
  2139. $attr = Json::decode($goods->attr);
  2140. $attr[0]['price'] = doubleval($value);
  2141. $goods->attr = Json::encode($attr);
  2142. }
  2143. // if ($goods->mch_id > 0) {
  2144. // $mch = Mch::findOne($goods->mch_id);
  2145. // if ($mch->is_goods_ex == 1) {
  2146. // $goods->status = 0;
  2147. // $goods->is_verify = -1;
  2148. // }
  2149. // }
  2150. if ($goods->save()) {
  2151. return [
  2152. 'code' => 0,
  2153. 'msg' => '保存成功'
  2154. ];
  2155. } else {
  2156. return [
  2157. 'code' => 1,
  2158. 'msg' => '保存失败'
  2159. ];
  2160. }
  2161. }
  2162. /**
  2163. * Undocumented function
  2164. *
  2165. * @Author LGL 24963@qq.com
  2166. * @DateTime 2021-01-18
  2167. * @desc: 根据id获取商品列表
  2168. * @param array $id
  2169. * @return void
  2170. */
  2171. public static function getGoodsListById ($id = [])
  2172. {
  2173. if (empty($id) && !is_array($id)) {
  2174. return [];
  2175. }
  2176. return Goods::find()->where(['in', 'id', $id])->select('id, name, cover_pic')->asArray()->all();
  2177. }
  2178. /**
  2179. * Undocumented function
  2180. *
  2181. * @Author LGL 24963@qq.com
  2182. * @DateTime 2021-03-02
  2183. * @desc: 根据商品id获取规格属性列表
  2184. * @param [type] $id
  2185. * @return void
  2186. */
  2187. public static function getAttrByGoodsId ($id)
  2188. {
  2189. $goods = Goods::findOne(['id' => $id, 'store_id' => get_store_id(), 'mch_id' => get_mch_id()]);
  2190. if (!$goods->attr) {
  2191. return [];
  2192. }
  2193. $attr_data = json_decode($goods->attr, true);
  2194. foreach ($attr_data as $i => $attr_data_item) {
  2195. if (!isset($attr_data[$i]['no'])) {
  2196. $attr_data[$i]['no'] = '';
  2197. }
  2198. if (!isset($attr_data[$i]['pic'])) {
  2199. $attr_data[$i]['pic'] = '';
  2200. }
  2201. foreach ($attr_data[$i]['attr_list'] as $j => $attr_list) {
  2202. $attr_group = $goods->getAttrGroupByAttId($attr_data[$i]['attr_list'][$j]['attr_id']);
  2203. $t = $attr_data[$i]['attr_list'][$j]['attr_name'];
  2204. unset($attr_data[$i]['attr_list'][$j]['attr_name']);
  2205. $attr_data[$i]['attr_list'][$j]['attr_group_name'] = $attr_group ? $attr_group->attr_group_name : null;
  2206. $attr_data[$i]['attr_list'][$j]['attr_name'] = $t;
  2207. }
  2208. }
  2209. return $attr_data;
  2210. }
  2211. private function compareDate($arr): bool
  2212. {
  2213. array_multisort(array_column($arr, 'start_time'), SORT_ASC, $arr);
  2214. foreach ($arr as $k => $v){
  2215. if ($v['start_time'] >= $v['end_time'])
  2216. return false;
  2217. if ($k > 0 && $arr[$k]['start_time'] < $arr[$k-1]['end_time'])
  2218. return false;
  2219. }
  2220. return true;
  2221. }
  2222. public function getDateByInterval(int $num) :array
  2223. {
  2224. //var_dump($st, $et);die;
  2225. $returnData = [];
  2226. $i = 0;
  2227. do {
  2228. $temp = date('Y-m-d', strtotime('+' . $i . ' day', strtotime(date('Y-m-d'))));
  2229. $returnData[] = $temp;
  2230. $i++;
  2231. } while ($i < $num);
  2232. return $returnData;
  2233. }
  2234. /**
  2235. * 模块名:checkRisk
  2236. * 代码描述:商品风险检测
  2237. * 作者:WPing丶
  2238. * 请求方式:GET
  2239. * 创建时间:2024/03/18 17:42:46
  2240. * @param int id
  2241. * @param string str
  2242. * @param bool bool
  2243. */
  2244. public function checkRisk() {
  2245. foreach($this->attr as $attr_item) {
  2246. $risk_array = $this->risk($attr_item, true);
  2247. $price = $this->use_attr == 1 ? $attr_item['price'] : $this->price;
  2248. if($this->is_level) {
  2249. $level_list = Level::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'status' => 1])
  2250. ->select('level')->column();
  2251. foreach($level_list as $level) {
  2252. if($attr_item['member'.$level] > 0 && $attr_item['member'.$level] < $price) {
  2253. $price = $attr_item['member'.$level];
  2254. }
  2255. }
  2256. }
  2257. $cost_price = $this->use_attr == 1 ? $attr_item['cost_price'] : $this->cost_price;
  2258. $profit = bcsub($price,$cost_price,2);
  2259. $end_str = '(售价'.$price.')-('.'成本价'.$cost_price;
  2260. foreach($risk_array as $key => $item) {
  2261. switch ($key) {
  2262. case 'share_first_price': //一级分销
  2263. $str = $item > 0 ? ')-(一级分销'.$item : '';
  2264. break;
  2265. case 'share_second_price'://二级分销
  2266. $str = $item > 0 ? ')-(二级分销'.$item : '';
  2267. break;
  2268. case 'share_third_price'://三级分销
  2269. $str = $item > 0 ? ')-(三级分销'.$item : '';
  2270. break;
  2271. case 'dl_p_price'://省级代理
  2272. $str = $item > 0 ? ')-(省级代理'.$item : '';
  2273. break;
  2274. case 'dl_c_price'://市级代理
  2275. $str = $item > 0 ? ')-(市级代理'.$item : '';
  2276. break;
  2277. case 'dl_d_price'://区级代理
  2278. $str = $item > 0 ? ')-(区级代理'.$item : '';
  2279. break;
  2280. case 'md_price'://门店佣金
  2281. $str = $item > 0 ? ')-(门店佣金'.$item : '';
  2282. break;
  2283. case 'direct'://直推佣金
  2284. $str = $item > 0 ? ')-(直推佣金'.$item : '';
  2285. break;
  2286. case 'indirect'://间推佣金
  2287. $str = $item > 0 ? ')-(间推佣金'.$item : '';
  2288. break;
  2289. case 'max_discount_price'://总佣金
  2290. $max_discount_price = $item;
  2291. break;
  2292. }
  2293. if($key != 'max_discount_price') {
  2294. $end_str .= $str;
  2295. }
  2296. }
  2297. $end_str.= ')='.bcsub($profit,$max_discount_price,2);
  2298. $risk_array['price'] = $price;
  2299. $risk_array['real_profit'] = $risk_array['is_show_risk'] ? bcsub($profit,$max_discount_price,2) : 0;
  2300. $risk_array['cost_price'] = $cost_price;
  2301. // $risk_array['is_open_share'] = false;
  2302. // $shareOption = Option::get(
  2303. // \app\constants\OptionSetting::SHARE_MONEY_SETTING,
  2304. // $this->store_id,
  2305. // \app\constants\OptionSetting::SHARE_GROUP_NAME,
  2306. // json_encode(['commission_type' => []])
  2307. // );
  2308. // $shareOption = \json_decode($shareOption['value'], true);
  2309. // if (in_array(1, ($shareOption['commission_type'] ?: []))) {
  2310. $risk_array['is_open_share'] = true;
  2311. // }
  2312. if($profit < $max_discount_price) {
  2313. return $risk_array;
  2314. return $end_str;
  2315. }
  2316. }
  2317. return $risk_array;
  2318. return $end_str;
  2319. }
  2320. /**
  2321. * 模块名: risk
  2322. * 代码描述:风控检测
  2323. * 作者:WPing丶
  2324. * 创建时间:2024/03/15 11:03:54
  2325. * @param int attr_item 规格
  2326. * @param bool is_array 是否需要返回详细数组
  2327. */
  2328. public function risk($attr_item, $is_array = false) {
  2329. //商品金额
  2330. $price = $this->use_attr == 1 ? $attr_item['price'] : $this->price;;//默认商品金额为售价
  2331. //判断用户有没有开启会员价
  2332. if($this->is_level) {
  2333. $level_list = Level::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'status' => 1])
  2334. ->select('level')->column();
  2335. foreach($level_list as $level) {
  2336. if($attr_item['member'.$level] > 0 && $attr_item['member'.$level] < $price) {
  2337. $price = $attr_item['member'.$level];
  2338. }
  2339. }
  2340. }
  2341. //计算最大支出
  2342. $max_discount_price = 0;//固定金额
  2343. /* 股东分红 begin */
  2344. if($this->is_open == 1) {
  2345. //股东分红基础金额
  2346. if($this->rate_type == 0) {//比例
  2347. $share_holder_price = bcmul($this->price,bcdiv($this->rate,100,4),2);
  2348. } else {//固定金额
  2349. $share_holder_price = $this->rate;
  2350. }
  2351. $direct = 0;
  2352. $indirect = 0;
  2353. $k = 0;//自建一个foreach索引值,因为$this->chain_level_value不是索引数组,他的key值是会员等级
  2354. foreach($this->chain_level_value as $level => $share) {
  2355. $max_direct = $share[0] > $max_direct ? $share[0] : $max_direct;//判断最大的直推金额
  2356. if($this->chain_type == 1) {//固定金额
  2357. $max_discount_price += $share[1];//间推
  2358. $indirect += $share[1];
  2359. //判断是不是最后一个股东等级,如果是加上直推金额(直推只发一次,间推无限发放)
  2360. if($k+1 == count($this->chain_level_value)) {
  2361. $max_discount_price += $share[0];//直推
  2362. $direct += $share[0];
  2363. }
  2364. } else {//比例
  2365. $max_discount_price += bcmul($share_holder_price, bcdiv($share[1],100,4), 2);//间推
  2366. $indirect += bcmul($share_holder_price, bcdiv($share[1],100,4), 2);
  2367. //判断是不是最后一个股东等级,如果是加上直推金额(直推只发一次,间推无限发放)
  2368. if($k+1 == count($this->chain_level_value)) {
  2369. $max_discount_price += bcmul($share_holder_price, bcdiv($share[0],100,4), 2);//直推
  2370. $direct += bcmul($share_holder_price, bcdiv($share[0],100,4), 2);
  2371. }
  2372. }
  2373. $k++;
  2374. }
  2375. }
  2376. /* 股东分红 end */
  2377. /* 门店佣金 begin */
  2378. if($this->md_hx_rate > 0 || $this->md_rate > 0) {
  2379. if($this->md_hx_rate_type == 0) {
  2380. $md_hx_rate = bcmul($price,bcdiv($this->md_hx_rate,100,4),2);
  2381. } else {
  2382. $md_hx_rate = $this->md_hx_rate;
  2383. }
  2384. if($this->md_rate_type == 0) {
  2385. $md_rate = bcmul($price,bcdiv($this->md_rate,100,4),2);
  2386. } else {
  2387. $md_rate = $this->md_rate;
  2388. }
  2389. $md_price = $md_hx_rate >= $md_rate ? $md_hx_rate : $md_rate;
  2390. $max_discount_price += $md_price;
  2391. }
  2392. /* 门店佣金 end */
  2393. /* 区域代理佣金 begin */
  2394. if ($this->dl_p_rate > 0) {//省代
  2395. if($this->dl_p_rate_type == 0) {
  2396. $dl_p_price = bcmul($price,bcdiv($this->dl_p_rate,100,4),2);
  2397. } else {
  2398. $dl_p_price = $this->dl_p_rate;
  2399. }
  2400. $max_discount_price += $dl_p_price;
  2401. }
  2402. if ($this->dl_c_rate > 0) {//市代
  2403. if($this->dl_c_rate_type == 0) {
  2404. $dl_c_price = bcmul($price,bcdiv($this->dl_c_rate,100,4),2);
  2405. } else {
  2406. $dl_c_price = $this->dl_c_rate;
  2407. }
  2408. $max_discount_price += $dl_c_price;
  2409. }
  2410. if ($this->dl_d_rate > 0) {//区代
  2411. if($this->dl_d_rate_type == 0) {
  2412. $dl_d_price = bcmul($price,bcdiv($this->dl_d_rate,100,4),2);
  2413. } else {
  2414. $dl_d_price = $this->dl_d_rate;
  2415. }
  2416. $max_discount_price += $dl_d_price;
  2417. }
  2418. /* 区域代理佣金 end */
  2419. /* 分销佣金 begin */
  2420. if($this->individual_share == 1) {//商品独立分销
  2421. if($this->attr_setting_type == 0) {//普通设置
  2422. $share_first = max(json_decode($this->share_commission_new_first, true));
  2423. $share_second = max(json_decode($this->share_commission_new_second, true));
  2424. $share_third = max(json_decode($this->share_commission_new_third, true));
  2425. } else {//详细设置
  2426. $share_first = $attr_item['share_commission_new_first'][0]['value'];
  2427. $share_second = $attr_item['share_commission_new_second'][0]['value'];
  2428. $share_third = $attr_item['share_commission_new_third'][0]['value'];
  2429. }
  2430. if($share_first > 0) {//一级分销
  2431. if($this->share_type == 0) {
  2432. $share_first_price = bcmul($price,bcdiv($share_first,100,4),2);
  2433. } else {
  2434. $share_first_price = $share_first;
  2435. }
  2436. $max_discount_price += $share_first_price;
  2437. }
  2438. if($share_second > 0) {//二级分销
  2439. if($this->share_type == 0) {
  2440. $share_second_price = bcmul($price,bcdiv($share_second,100,4),2);
  2441. } else {
  2442. $share_second_price = $share_second;
  2443. }
  2444. $max_discount_price += $share_second_price;
  2445. }
  2446. if($share_third > 0) {//三级分销
  2447. if($this->share_type == 0) {
  2448. $share_third_price = bcmul($price,bcdiv($share_third,100,4),2);
  2449. } else {
  2450. $share_third_price = $share_third;
  2451. }
  2452. $max_discount_price += $share_third_price;
  2453. }
  2454. } else {//默认分销
  2455. $share_basic_setting = Option::get('share_money_setting', $this->store_id, OptionSetting::SHARE_GROUP_NAME)['value'];
  2456. $share_basic_setting = json_decode($share_basic_setting, true);
  2457. $share_first = $share_basic_setting['level_one']['value'];
  2458. if($share_first > 0) {//一级分销
  2459. $share_first_price = bcmul($price,bcdiv($share_first,100,4),2);
  2460. $max_discount_price += $share_first_price;
  2461. }
  2462. $share_second = $share_basic_setting['level_two']['value'];
  2463. if($share_second > 0) {//二级分销
  2464. $share_second_price = bcmul($price,bcdiv($share_second,100,4),2);
  2465. $max_discount_price += $share_second_price;
  2466. }
  2467. $share_third = $share_basic_setting['level_three']['value'];
  2468. if($share_third > 0) {//三级分销
  2469. $share_third_price = bcmul($price,bcdiv($share_third,100,4),2);
  2470. $max_discount_price += $share_third_price;
  2471. }
  2472. }
  2473. /* 分销佣金 end */
  2474. if($is_array) {
  2475. $is_show_risk = Option::get(OptionSetting::IS_SHOW_RISK, $this->store_id, 'store', '')['value'];
  2476. return [
  2477. 'share_first_price' => round($share_first_price, 2),//一级分销
  2478. 'share_second_price' => round($share_second_price, 2),//二级分销
  2479. 'share_third_price' => round($share_third_price, 2),//三级分销
  2480. 'dl_p_price' => round($dl_p_price, 2),//省级代理
  2481. 'dl_c_price' => round($dl_c_price, 2),//市级代理
  2482. 'dl_d_price' => round($dl_d_price, 2),//区级代理
  2483. 'md_price' => round($md_price, 2),//门店佣金
  2484. 'direct' => round($direct, 2),//直推佣金
  2485. 'indirect' => round($indirect, 2),//间推佣金
  2486. 'max_discount_price' => round($max_discount_price, 2),//总支出
  2487. 'is_show_risk' => intval($is_show_risk)
  2488. ];
  2489. }
  2490. return round($max_discount_price, 2);
  2491. }
  2492. }