CommodityService.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. <?php
  2. namespace App\Services;
  3. use App\Commodity;
  4. use App\Http\Controllers\CommodityController;
  5. use App\CommodityBarcode;
  6. use App\OracleBasSKU;
  7. use App\Owner;
  8. use App\Services\common\BatchUpdateService;
  9. use App\Services\common\DataHandlerService;
  10. use App\ValueStore;
  11. use Carbon\Carbon;
  12. use Illuminate\Database\Eloquent\Builder;
  13. use Illuminate\Database\Eloquent\Collection;
  14. use Illuminate\Support\Facades\Cache;
  15. use App\Traits\ServiceAppAop;
  16. class CommodityService
  17. {
  18. use ServiceAppAop;
  19. protected $modelClass=Commodity::class;
  20. /**
  21. * @var CacheService $cacheService
  22. * @var OwnerService $ownerService
  23. */
  24. private $cacheService;
  25. private $ownerService;
  26. function __construct()
  27. {
  28. $this->cacheService = app('CacheService');
  29. $this->ownerService = app('OwnerService');
  30. }
  31. public function firstOrCreate($param, $column = null): Commodity
  32. {
  33. if ($column) return Commodity::query()->firstOrCreate($param, $column);
  34. return Commodity::query()->firstOrCreate($param);
  35. }
  36. public function updateOrCreate($param, $column = null)
  37. {
  38. if ($column) return Commodity::query()->updateOrCreate($param, $column);
  39. return Commodity::query()->updateOrCreate($param);
  40. }
  41. public function first(array $params, $with = null)
  42. {
  43. $commodity = Commodity::query();
  44. if ($with) $commodity->with($with);
  45. foreach ($params as $column => $value) {
  46. if (!is_array($value)) $commodity->where($column, $value);
  47. else $commodity->whereIn($column, $value);
  48. }
  49. return $commodity->first();
  50. }
  51. public function get(array $params)
  52. {
  53. $query = Commodity::query()->with('barcodes');
  54. if ($params["owner_id"] ?? false) {
  55. $query->where("owner_id", $params["owner_id"]);
  56. }
  57. if ($params["sku"] ?? false) {
  58. if (!is_array($params["sku"])) $params["sku"] = [$params["sku"]];
  59. $query->whereIn('sku', $params["sku"]);
  60. }
  61. return $query->get();
  62. }
  63. public function getOwnerCommodities(array $params)
  64. {
  65. $query = Commodity::query();
  66. foreach ($params as $column => $value) {
  67. if (!is_array($value)) $query->where($column, $value);
  68. else $query->whereIn($column, $value);
  69. }
  70. return $query->get();
  71. }
  72. /* 批量更新 */
  73. public function batchUpdate(array $params)
  74. {
  75. return app(BatchUpdateService::class)->batchUpdate('commodities', $params);
  76. }
  77. /* 根据货主条形码查找商品 */
  78. private function ownerBarcodeSeekCommodityQuery(Builder $query, array $ownerParam, $barcode)
  79. {
  80. $query->whereHas('owner', function ($builder) use ($ownerParam) {
  81. foreach ($ownerParam as $column => $param) {
  82. $builder->where($column, $param);
  83. }
  84. });
  85. $query->whereHas('barcodes', function ($builder) use ($barcode) {
  86. if (is_array($barcode)) $builder->whereIn('code', $barcode);
  87. else $builder->where('code', $barcode);
  88. });
  89. // haozi 2020-12-14
  90. // $query->whereIn('id', function ($builder) use ($barcode) {
  91. // if (is_array($barcode)) $builder->from('commodity_barcodes')->select('commodity_id')->whereIn('code', $barcode);
  92. // else $builder->from('commodity_barcodes')->select('commodity_id')->where('code', $barcode);
  93. // });
  94. return $query;
  95. }
  96. public function ownerBarcodeSeekCommodityFirst(array $ownerParam, $barcode, $with = null)
  97. {
  98. $commodity = Commodity::query();
  99. if ($with) $commodity->with($with);
  100. $commodity = $this->ownerBarcodeSeekCommodityQuery($commodity, $ownerParam, $barcode);
  101. return $commodity->first();
  102. }
  103. public function ownerBarcodeSeekCommodityGet(array $ownerParam, $barcode, $isNullSku = false)
  104. {
  105. $commodities = Commodity::query()->with('barcodes');
  106. if ($isNullSku) $commodities->whereNull('sku');
  107. $commodities = $this->ownerBarcodeSeekCommodityQuery($commodities, $ownerParam, $barcode);
  108. return $commodities->get();
  109. }
  110. /* 通过货主代码与条形码寻找FLUX商品补充至WMS 单条*/
  111. public function ownerAndBarcodeFirstOrCreate(Owner $owner, $barcode)
  112. {
  113. $wmsCommodity = app('OracleBasSkuService')->first(['customerid' => $owner->code, 'barcode' => $barcode]);
  114. if (!$wmsCommodity) return null;
  115. $commodity = $this->firstOrCreate(['owner_id' => $owner->id, 'sku' => $wmsCommodity->sku], [
  116. "name" => $wmsCommodity->descr_c,
  117. "sku" => $wmsCommodity->sku,
  118. "owner_id" => $owner->id,
  119. "length" => $wmsCommodity->skulength,
  120. "width" => $wmsCommodity->skuwidth,
  121. "height" => $wmsCommodity->skuhigh,
  122. "volumn" => $wmsCommodity->cube,
  123. "pack_spec" => $wmsCommodity->packid == 'STANDARD' ? 0 : explode("/",$wmsCommodity->packid)[1],
  124. "remark" => $wmsCommodity->notes,
  125. ]);
  126. if ($wmsCommodity->alternate_sku1) app('CommodityBarcodeService')->first([
  127. 'commodity_id' => $commodity->id,
  128. 'code' => $wmsCommodity->alternate_sku1,
  129. ]);
  130. if ($wmsCommodity->alternate_sku2) app('CommodityBarcodeService')->first([
  131. 'commodity_id' => $commodity->id,
  132. 'code' => $wmsCommodity->alternate_sku2,
  133. ]);
  134. return $commodity;
  135. }
  136. public function create(array $params)
  137. {
  138. return Commodity::query()->create($params);
  139. }
  140. public function getByWmsOrders($orderHeaders)
  141. {
  142. if (!$orderHeaders) return null;
  143. $customerId_sku_map = [];
  144. foreach ($orderHeaders as $orderHeader) {
  145. $oracleDOCOrderDetails = $orderHeader->oracleDOCOrderDetails;
  146. foreach ($oracleDOCOrderDetails as $oracleDOCOrderDetail) {
  147. $value = [
  148. 'owner_code' => $oracleDOCOrderDetail->customerid,
  149. 'sku' => $oracleDOCOrderDetail->sku
  150. ];
  151. if (!in_array($value, $customerId_sku_map)) {
  152. $customerId_sku_map[] = $value;
  153. }
  154. }
  155. }
  156. $owner_codes = array_diff(array_unique(data_get($customerId_sku_map, '*.owner_code')), ['', '*', null]);
  157. if (!$owner_codes) return null;
  158. $owners = Owner::query()->whereIn('code', $owner_codes)->get();
  159. $owners_code_map = [];
  160. $owners_id_map = [];
  161. foreach ($owners as $owner) {
  162. $owners_code_map[$owner->code] = $owner;
  163. $owners_id_map[$owner->id] = $owner;
  164. }
  165. $orderHeader_sku = array_diff(array_unique(data_get($customerId_sku_map, '*.sku')), ['', '*', null]);
  166. $commodities = Commodity::query()
  167. ->whereIn('owner_id', data_get($owners, '*.id'))
  168. ->whereIn('sku', $orderHeader_sku)
  169. ->get();
  170. if ($commodities->count() < count($customerId_sku_map)) {
  171. $commoditiesInWAS索引_sku = [];
  172. foreach ($commodities as $commodityInWms) {
  173. $owner = $owners_id_map[$commodityInWms->owner_id] ?? '';
  174. if (!$owner) continue;
  175. $key = 'owner_cod=' . $owner['code'] . ' sku=' . $commodityInWms->sku;
  176. $commoditiesInWAS索引_sku[$key] = $commodityInWms;
  177. }
  178. $commodities需要新增 = [];
  179. foreach ($customerId_sku_map as $commodityInWms) {
  180. $key = 'owner_cod=' . $commodityInWms['owner_code'] . ' sku=' . $commodityInWms['sku'];
  181. if ($commoditiesInWAS索引_sku[$key] ?? false) continue;
  182. $commodities需要新增[$key] = $commodityInWms;
  183. }
  184. $commodity_set = $this->createCommodities($commodities需要新增, $owners_code_map);
  185. $commodities = $commodities->concat($commodity_set);
  186. }
  187. return $commodities;
  188. }
  189. public function createCommodities($params, $owners_code_map)
  190. {
  191. if (!$params) return [];
  192. $bas_sku_arr = OracleBasSKU::query()
  193. ->selectRaw('customerid,sku,descr_c,skulength,skuwidth,skuhigh,cube')
  194. ->whereIn('CustomerID', data_get($params, '*.owner_code'))
  195. ->whereIn('Sku', data_get($params, '*.sku'))
  196. ->get();
  197. $insert_params = [];
  198. $created_at = Carbon::now()->format('Y-m-d H:i:s');
  199. foreach ($bas_sku_arr as $bas_sku) {
  200. $owner = $owners_code_map[$bas_sku->customerid] ?? '';
  201. if (!$owner) continue;
  202. if ($bas_sku->sku == null) continue;
  203. if ($bas_sku->descr_c == '') continue;
  204. $insert_params[] = [
  205. 'owner_id' => $owner->id,
  206. 'sku' => $bas_sku->sku,
  207. 'name' => $bas_sku->descr_c,
  208. 'created_at' => $created_at,
  209. 'length' => $bas_sku->skulength,
  210. 'width' => $bas_sku->skuwidth,
  211. 'height' => $bas_sku->skuhigh,
  212. 'volumn' => $bas_sku->cube,
  213. "pack_spec" => $bas_sku->packid == 'STANDARD' ? 0 : explode("/",$bas_sku->packid)[1],
  214. "remark" => $bas_sku->notes,
  215. ];
  216. }
  217. if (count($insert_params) > 0) {
  218. try {
  219. $this->insert($insert_params);
  220. app('LogService')->log(__METHOD__, __FUNCTION__, '批量添加 commodity ' . count($insert_params) . json_encode($insert_params));
  221. } catch (\Exception $e) {
  222. app('LogService')->log(__METHOD__, __FUNCTION__, '批量添加 commodity error' . json_encode($insert_params) . "||" . $e->getMessage() . '||' . $e->getTraceAsString());
  223. }
  224. }
  225. return Commodity::query()
  226. ->whereIn('owner_id', data_get($owners_code_map, '*.id'))
  227. ->whereIn('sku', data_get($params, '*.sku'))
  228. ->get();
  229. }
  230. public function createTemporaryCommodity(array $params)
  231. {
  232. $params["type"] = "临时";
  233. return Commodity::query()->create($params);
  234. }
  235. public function syncBarcodes($barcodesStr, $ownerId, $sku): Commodity
  236. {
  237. $barcodes = (function () use ($barcodesStr) {
  238. $barcodes = rtrim($barcodesStr, ',');
  239. $barcodes = explode(',', $barcodes);
  240. foreach ($barcodes as $k => $barcode) {
  241. if (!trim($barcode)) unset($barcodes[$k]);
  242. }
  243. return $barcodes;
  244. })();
  245. //
  246. // $commodities=$this->get_([$ownerId],[$sku],[],true);
  247. // if ($commodities->first()){
  248. // $commodity=$commodities->first();
  249. // }else{
  250. $commodity = $this->firstOrCreate(['owner_id' => $ownerId, 'sku' => $sku]);
  251. // }
  252. $commodityBarcodes = $commodity['barcodes'] ?? new Collection();
  253. /** @var CommodityBarcodeService $commodityBarcodeService */
  254. $commodityBarcodeService = app('CommodityBarcodeService');
  255. $redundantCommodityBarcodes = new Collection();
  256. foreach ($commodityBarcodes as $commodityBarcode) {//清除数组中 已经在商品有的条码,清除商品条码中,不在数组中的条码
  257. $hasMatch = false;
  258. foreach ($barcodes as $key => $barcode) {
  259. if ($barcodes[$key] == $commodityBarcode['code']) {
  260. $hasMatch = true;
  261. unset($barcodes[$key]);
  262. break;
  263. }
  264. }
  265. if (!$hasMatch) {
  266. $redundantCommodityBarcodes->push($commodityBarcode);
  267. }
  268. }
  269. if (!empty($redundantCommodityBarcodes)) {
  270. $commodityBarcodeService->destroyCollections($redundantCommodityBarcodes);
  271. }
  272. if (!empty($barcodes)) {
  273. $commodityBarcodeService->insertMany_onCommodities([['commodity_id' => $commodity['id'], 'barcodes' => $barcodes]]);
  274. }
  275. return $commodity;
  276. }
  277. public function destroyWithOffspring(Commodity $commodity)
  278. {
  279. $barcodesIds = $commodity->barcodes->map(function ($barcode) {
  280. return $barcode['id'];
  281. });
  282. CommodityBarcode::destroy($barcodesIds);
  283. $commodity->delete();
  284. }
  285. public function syncWMSOrderCode($owner, $skus)
  286. {
  287. $basSku = OracleBasSKU::query()->whereIn('SKU', $skus)->where('CustomerID', $owner->code)->get();
  288. $inner_params = [];
  289. $created_at = new Carbon();
  290. $basSku->each(function ($bas_sku) use (&$inner_params, $owner, $created_at) {
  291. $inner_params[] = [
  292. 'owner_id' => $owner->id,
  293. 'sku' => $bas_sku->sku,
  294. 'name' => $bas_sku->descr_c,
  295. 'created_at' => $created_at,
  296. 'length' => $bas_sku->skulength,
  297. 'width' => $bas_sku->skuwidth,
  298. 'height' => $bas_sku->skuhigh,
  299. 'volumn' => $bas_sku->cube,
  300. "pack_spec" => $bas_sku->packid == 'STANDARD' ? 0 : explode("/",$bas_sku->packid)[1],
  301. "remark" => $bas_sku->notes,
  302. ];
  303. });
  304. if (count($inner_params) > 0) {
  305. try {
  306. $this->insert($inner_params);
  307. app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($inner_params));
  308. } catch (\Exception $e) {
  309. app('LogService')->log(__METHOD__, 'Error ' . __FUNCTION__, json_encode($inner_params) . ' || ' . $e->getMessage());
  310. }
  311. }
  312. }
  313. //获取箱规
  314. public function getPack($owner_id, $sku)
  315. {
  316. $that = $this;
  317. return app("CacheService")->getOrExecute("pack_{$owner_id}_{$sku}", function () use ($owner_id, $sku, $that) {
  318. $commodity = $that->first([
  319. "owner_id" => $owner_id,
  320. "sku" => $sku
  321. ]);
  322. if (!$commodity || $commodity->pack_spec === null) {
  323. $owner = app("OwnerService")->find($owner_id);
  324. $action = new CommodityController();
  325. $action->syncOwnerCommodities($owner->id, $owner->code, $sku);
  326. }
  327. return $that->first([
  328. "owner_id" => $owner_id,
  329. "sku" => $sku
  330. ])->pack_spec;
  331. });
  332. }
  333. //是否存在
  334. public function isExist(array $params)
  335. {
  336. $query = Commodity::query();
  337. if ($params["barcode"] ?? false) {
  338. $query->whereHas("barcodes", function ($query) use ($params) {
  339. /** @var Builder $query */
  340. $query->where("code", $params["barcode"]);
  341. });
  342. unset($params["barcode"]);
  343. }
  344. foreach ($params as $column => $param) {
  345. $query->where($column, $param);
  346. }
  347. if ($query->count() > 0) return true;
  348. return false;
  349. }
  350. public function getParamsByBasSku($basSku, $owner = null)
  351. {
  352. if (empty($owner)) {
  353. $owner = app('OwnerService')->getOwnerByCode($basSku['customerid']);
  354. }
  355. return [
  356. 'owner_id' => $owner['id'] ?? '',
  357. 'sku' => $basSku['sku'],
  358. 'name' => $basSku['descr_c'],
  359. 'length' => $basSku['skulength'],
  360. 'width' => $basSku['skuwidth'],
  361. 'height' => $basSku['skuhigh'],
  362. 'volumn' => $basSku['cube'],
  363. "pack_spec" => $basSku['packid'] == 'STANDARD' ? 0 : explode("/",$basSku['packid'])[1],
  364. "remark" => $basSku['notes'],
  365. ];
  366. }
  367. public function syncCommodityCreated()
  368. {
  369. $created_at = config('sync.commodity_sync.created_at');
  370. $create_set = config('sync.commodity_sync.cache_prefix.create_set');
  371. $create_keys = config('sync.commodity_sync.cache_prefix.create_keys');
  372. $create_key = config('sync.commodity_sync.cache_prefix.create');
  373. ini_set('memory_limit', '512M');
  374. /** @var OracleBasSkuService $oracleBasSkuService */
  375. $oracleBasSkuService = app(OracleBasSkuService::class);
  376. $last_time = $this->getCommodityLastSyncAt($created_at, 'create');
  377. $basSkus = $oracleBasSkuService->getWmsCreatedCommodities($last_time);
  378. $last_time = $basSkus->first()['addtime'];
  379. $last_records = $basSkus->where('addtime', $last_time);
  380. if (!$basSkus) return;
  381. $this->syncCreateCommodity($basSkus);
  382. $this->deleteCacheKey($create_set, $create_keys);
  383. $this->setLastRecordsByRedis($create_key, $create_set, $create_keys, $last_records);
  384. $this->setCommodityLastSyncAt($created_at, $last_time);
  385. }
  386. public function syncCommodityUpdated()
  387. {
  388. $updated_at = config('sync.commodity_sync.updated_at');
  389. $update_set = config('sync.commodity_sync.cache_prefix.update_set');
  390. $update_keys = config('sync.commodity_sync.cache_prefix.update_keys');
  391. $update_key = config('sync.commodity_sync.cache_prefix.update');
  392. ini_set('memory_limit', '1200M');
  393. /** @var OracleBasSkuService $oracleBasSkuService */
  394. $oracleBasSkuService = app(OracleBasSkuService::class);
  395. $last_time = $this->getCommodityLastSyncAt($updated_at, 'update');
  396. $basSkus = $oracleBasSkuService->getWmsUpdatedCommodities($last_time);
  397. $last_time = $basSkus->first()['edittime'];
  398. $last_records = $basSkus->where('edittime', $last_time);
  399. if (!$basSkus) return;
  400. set_time_limit(500);
  401. $basSkus=$basSkus->chunk(2000);
  402. foreach ($basSkus as $basSku){
  403. $this->syncUpdateCommodity($basSku);
  404. }
  405. $this->deleteCacheKey($update_set, $update_keys);
  406. $this->setLastRecordsByRedis($update_key, $update_set, $update_keys, $last_records);
  407. $this->setCommodityLastSyncAt($updated_at, $last_time);
  408. }
  409. public function syncCreateCommodity($addBasSkus)
  410. {
  411. if (count($addBasSkus) < 1) return null;
  412. $insert_params = $this->getParamsByBasSkus($addBasSkus);
  413. if (!$insert_params) return;
  414. $this->insertCommodities($insert_params);
  415. /** @var CommodityBarcodeService $commodityBarcodeService */
  416. $commodityBarcodeService = app(CommodityBarcodeService::class);
  417. if (count($insert_params) > 0) $commodityBarcodeService->createBarcodeByWms($addBasSkus);
  418. }
  419. public function insertCommodities($insert_params)
  420. {
  421. if (count($insert_params) < 1) return;
  422. $ownerIds = array_unique(data_get($insert_params, '*.owner_id'));
  423. //sort($ownerIds);
  424. $skus = array_unique(data_get($insert_params, '*.sku'));
  425. //sort($skus);
  426. try {
  427. $bool = $this->insert($insert_params,false,false,false);
  428. if ($bool) {
  429. app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 Commodity Success " . count($insert_params) . ' || ' . json_encode($insert_params));
  430. $commodities = Commodity::query()->whereIn('owner_id', $ownerIds)->whereIn('sku', $skus)->get();
  431. //$md5 = md5(json_encode([$skus, $ownerIds]));
  432. //if (Cache::has('commodity_' . $md5)) Cache::forget('commodity_' . $md5);
  433. if(count($commodities)>0) $this->pushToCache($commodities);
  434. } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 Commodity FAILED " . ' || ' . json_encode($insert_params));
  435. } catch (\Exception $e) {
  436. app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 Commodity ERROR " . ' || ' . json_encode($insert_params) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
  437. }
  438. }
  439. public function getParamsByBasSkus($addBasSkus)
  440. {
  441. $owner_sku_map = [];
  442. $sku = [];
  443. $owner_code = [];
  444. $owner_codes = [];
  445. $addBasSkus->each(function ($addBasSku) use (&$owner_sku_map, &$sku, &$owner_codes, &$owner_code) {
  446. if (!empty($addBasSku['customerid']) && !empty($addBasSku['sku'])) {
  447. $key = "owner_code_{$addBasSku['customerid']}_sku_{$addBasSku['sku']}";
  448. $owner_sku_map[$key] = ['owner_code' => $addBasSku['customerid'], 'sku' => $addBasSku['sku']];
  449. $sku[] = $addBasSku['sku'];
  450. $owner_code[] = $addBasSku['customerid'];
  451. $owner_codes[$addBasSku['customerid']] = $addBasSku['customerid'];
  452. }
  453. });
  454. /** @var OwnerService $ownerService */
  455. $ownerService = app(OwnerService::class);
  456. $owner_id = (function () use ($ownerService, $owner_codes) {
  457. $owners = $ownerService->getOwnerByCodes($owner_codes);
  458. $map = [];
  459. $owners->each(function ($owner) use (&$map) {
  460. $map[] = $owner['id'];
  461. });
  462. return $map;
  463. })();
  464. $owner_map = (function () use ($ownerService, $owner_codes) {
  465. $owners = $ownerService->getOwnerByCodes($owner_codes);
  466. $map = [];
  467. $owners->each(function ($owner) use (&$map) {
  468. $map[$owner['code']] = $owner['id'];
  469. });
  470. return $map;
  471. })();
  472. if (count($owner_sku_map) == 0) return null;
  473. $commodities = Commodity::query()
  474. ->whereIn('owner_id', array_unique($owner_id))
  475. ->whereIn('sku', array_unique($sku))
  476. ->get();
  477. $unexists = [];
  478. foreach ($owner_sku_map as $item) {
  479. $commodity = Cache::get("owner_code_{$item['owner_code']}_sku_{$item['sku']}");
  480. if ($commodity) continue;
  481. $commodity = $commodities->where('sku', $item['sku'])->where('owner_id', $owner_map[$item['owner_code']])->first();
  482. if ($commodity) continue;
  483. $items = [
  484. 'owner_code' => $item['owner_code'],
  485. 'sku' => $item['sku']
  486. ];
  487. $unexists[json_encode($items)] = true;
  488. }
  489. if (count($unexists) == 0) return null;
  490. $BasSKUs = $addBasSkus->filter(function ($bas_sku) use ($unexists) {
  491. $arr = [
  492. 'owner_code' => $bas_sku['customerid'],
  493. 'sku' => $bas_sku['sku']
  494. ];
  495. return $unexists[json_encode($arr)] ?? false;
  496. });
  497. $inner_params = (function () use ($BasSKUs, $owner_map) {
  498. $map = [];
  499. $BasSKUs->each(function ($basSku) use (&$map, $owner_map) {
  500. $key = $basSku['sku'].$owner_map[$basSku['customerid']];
  501. if ($basSku->sku&&$basSku->descr_c&&$basSku->customerid){ //只添加有sku 有name 有货主的商品
  502. $map[$key] = [
  503. 'owner_id' => $owner_map[$basSku['customerid']] ?? '',
  504. 'sku' => $basSku->sku,
  505. 'name' => $basSku->descr_c,
  506. 'length' => $basSku->skulength,
  507. 'width' => $basSku->skuwidth,
  508. 'height' => $basSku->skuhigh,
  509. 'volumn' => $basSku->cube,
  510. 'created_at' => $basSku->addtime,
  511. 'updated_at' => $basSku->edittime,
  512. 'pack_spec' => $basSku->packid == 'STANDARD' ? 0 : explode("/", $basSku->packid)[1],
  513. 'remark' => $basSku->notes,
  514. ];
  515. }
  516. });
  517. return $map;
  518. })();
  519. if (count($inner_params) == 0) return null;
  520. return $inner_params;
  521. }
  522. public function syncUpdateCommodity($addBasSkus)
  523. {
  524. $sku = [];
  525. $owner_codes = [];
  526. $addBasSkus->each(function ($addBasSku) use (&$sku, &$owner_codes) {
  527. if (!empty($addBasSku['customerid']) && !empty($addBasSku['sku'])) {
  528. $sku[] = $addBasSku['sku'];
  529. $owner_codes[$addBasSku['customerid']] = $addBasSku['customerid'];
  530. }
  531. });
  532. /**
  533. * @var OwnerService $ownerService
  534. * @var DataHandlerService $dataHandlerService
  535. */
  536. $ownerService = app(OwnerService::class);
  537. $dataHandlerService = app(DataHandlerService::class);
  538. $owner_map = (function () use ($ownerService, $owner_codes) {
  539. $owners = $ownerService->getOwnerByCodes($owner_codes);
  540. $map = [];
  541. $owners->each(function ($owner) use (&$map) {
  542. $map[$owner['code']] = $owner['id'];
  543. });
  544. return $map;
  545. })();
  546. $owner_id = (function () use ($ownerService, $owner_codes) {
  547. $owners = $ownerService->getOwnerByCodes($owner_codes);
  548. $map = [];
  549. $owners->each(function ($owner) use (&$map) {
  550. $map[] = $owner['id'];
  551. });
  552. return $map;
  553. })();
  554. $commodities = Commodity::query()
  555. ->whereIn('owner_id', array_unique($owner_id))
  556. ->whereIn('sku', array_unique($sku))
  557. ->get();
  558. $commodities_map = $dataHandlerService->dataHeader(['owner_id', 'sku'], $commodities);
  559. $updateParams = [[
  560. 'id', 'name', 'sku', 'owner_id', 'length', 'width', 'height', 'volumn', 'pack_spec', 'remark', 'updated_at', 'created_at'
  561. ]];
  562. $insert_params = [];
  563. $updateBasSkus=collect();
  564. foreach ($addBasSkus as $basSku) {
  565. $commodity = Cache::get("owner_code_{$basSku['customerid']}_sku_{$basSku['sku']}");
  566. if (!$commodity) $commodity = $dataHandlerService->getKeyValue(['owner_id' => $owner_map[$basSku['customerid']], 'sku' => $basSku['sku']], $commodities_map);
  567. if (!$commodity) {
  568. if (!$basSku->sku||! $basSku->descr_c ||!$basSku->customerid)continue;//只添加有sku 有name 有货主的商品
  569. $updateBasSkus->add($basSku);
  570. $key = $basSku['sku'].$owner_map[$basSku['customerid']];
  571. $insert_params[$key] = [
  572. 'owner_id' => $owner_map[$basSku['customerid']] ?? '',
  573. 'sku' => $basSku->sku,
  574. 'name' => $basSku->descr_c,
  575. 'length' => $basSku->skulength,
  576. 'width' => $basSku->skuwidth,
  577. 'height' => $basSku->skuhigh,
  578. 'volumn' => $basSku->cube,
  579. 'remark' => $basSku->notes,
  580. 'created_at' => $basSku->addtime,
  581. 'updated_at' => $basSku->edittime,
  582. 'pack_spec' => $basSku->packid == 'STANDARD' ? 0 : explode("/", $basSku->packid)[1],
  583. ];
  584. continue;
  585. } else if (
  586. $commodity->sku != $basSku->sku ||
  587. $commodity->name != $basSku->descr_c ||
  588. $commodity->length != $basSku->skulength ||
  589. $commodity->width != $basSku->skuwidth ||
  590. $commodity->height != $basSku->skuhigh ||
  591. $commodity->volumn != $basSku->cube ||
  592. $commodity->remark != $basSku->notes ||
  593. $commodity->created_at != $basSku->addtime ||
  594. $commodity->pack_spec != $basSku->pickid ||
  595. $commodity->updated_at != $basSku->edittime
  596. ) {
  597. $updateBasSkus->add($basSku);
  598. $updateParams[] = [
  599. 'id' => $commodity->id,
  600. 'owner_id' => $owner_map[$basSku['customerid']] ?? '',
  601. 'sku' => $basSku->sku,
  602. 'name' => $basSku->descr_c,
  603. 'length' => $basSku->skulength,
  604. 'width' => $basSku->skuwidth,
  605. 'height' => $basSku->skuhigh,
  606. 'volumn' => $basSku->cube,
  607. 'remark' => $basSku->notes,
  608. 'created_at' => $basSku->addtime,
  609. 'updated_at' => $basSku->edittime,
  610. 'pack_spec' => $basSku->packid == 'STANDARD' ? 0 : explode("/", $basSku->packid)[1],
  611. ];
  612. }
  613. }
  614. if (count($insert_params) > 0) $this->insertCommodities($insert_params);
  615. if (count($updateParams) > 0) $this->updateCommodities($updateParams);
  616. /** @var CommodityBarcodeService $commodityBarcodeService */
  617. $commodityBarcodeService = app(CommodityBarcodeService::class);
  618. if (count($updateParams) > 0) $commodityBarcodeService->updateBarcodeByWms($updateBasSkus);
  619. }
  620. private function pushToCache($commodities)
  621. {
  622. $owners=Owner::query()->whereIn('id',array_unique(data_get($commodities,'*.owner_id')))->get();
  623. $owner_map=[];
  624. foreach ($owners as $owner){
  625. $owner_map[$owner->id]=$owner->code;
  626. }
  627. if (count($commodities) < 1) return null;
  628. foreach ($commodities as $commodity) {
  629. $commodity_key = "owner_code_{$owner_map[$commodity['owner_id']]}_sku_{$commodity['sku']}";
  630. Cache::put($commodity_key, $commodity);
  631. }
  632. }
  633. public function getCommodityLastSyncAt($key, $type)
  634. {
  635. $last_time = ValueStore::query()->where('name', $key)->value('value');
  636. if ($last_time) return $last_time;
  637. if ($type == 'create') {
  638. $store = Commodity::query()->orderByDesc('created_at')->first();
  639. if ($store) return $store->created_at;
  640. } else {
  641. $store = Commodity::query()->orderByDesc('updated_at')->first();
  642. if ($store) return $store->updated_at;
  643. }
  644. return Carbon::now()->subSeconds(65);
  645. }
  646. public function setCommodityLastSyncAt($key, $last_time)
  647. {
  648. $asnLastSyncAt = ValueStore::query()->updateOrCreate([
  649. 'name' => $key,
  650. ], [
  651. 'name' => $key,
  652. 'value' => $last_time,
  653. ]);
  654. LogService::log(__METHOD__, __FUNCTION__, '修改或更新' . $key . json_encode($asnLastSyncAt));
  655. return $asnLastSyncAt;
  656. }
  657. public function deleteCacheKey($set, $keys)
  658. {
  659. if (Cache::get($set)) {
  660. $cacheKeys = Cache::get($keys);
  661. if (!$cacheKeys) return;
  662. foreach ($cacheKeys as $cacheKey) {
  663. Cache::forget($cacheKey);
  664. }
  665. Cache::forget($keys);
  666. }
  667. }
  668. public function setLastRecordsByRedis($prefixKey, $set, $keys, $last_records)
  669. {
  670. $cacheKeys = [];
  671. foreach ($last_records as $last_record) {
  672. Cache::put($prefixKey . $last_record->customerid . '_' . $last_record->sku, true);
  673. array_push($cacheKeys, $prefixKey . $last_record->customerid . '_' . $last_record->sku);
  674. }
  675. Cache::put($keys, $cacheKeys);
  676. Cache::put($set, true);
  677. }
  678. function updateCommodities($updateParams)
  679. {
  680. if (count($updateParams) < 1) return;
  681. $ownerIds = array_unique(data_get($updateParams, '*.owner_id'));
  682. // sort($ownerIds);
  683. $skus = array_unique(data_get($updateParams, '*.sku'));
  684. // sort($skus);
  685. $this->batchUpdate($updateParams);
  686. // $md5 = md5(json_encode([$skus, $ownerIds]));
  687. // if (Cache::has('commodity_' . $md5)) Cache::forget('commodity_' . $md5);
  688. $commodities = Commodity::query()->whereIn('owner_id', $ownerIds)->whereIn('sku', $skus)->get();
  689. if(count($commodities)>0) $this->pushToCache($commodities);
  690. }
  691. /**
  692. * @param array $ownerIds
  693. * @param array $skus
  694. * @param array $barcodes
  695. * @param bool $isSyncWms 是否开启同步wms数据 开启则必须给定 $ownerIds 和 $skus
  696. * @param int $paginate 分页只对 货主$ownerIds 条件
  697. * @param int $page
  698. * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|mixed|null
  699. */
  700. function get_(array $ownerIds = [], array $skus = [], array $barcodes = [], $isSyncWms = false, $paginate = 100, $page = 1)
  701. {
  702. if ($paginate < 100 || fmod($paginate, 100) != 0) return null; //$paginate小于100,或取余数100不为0,异常 //取余函数fmod()
  703. $time = config('cache.expirations.forever');
  704. $status = null;
  705. if ($ownerIds && !$skus && !$barcodes) $status = '只有货主条件';
  706. if ($skus) $status = '有SKU';
  707. if ($barcodes && !$skus) $status = '有条码没SKU';
  708. if (!$status) return null;
  709. switch ($status) {
  710. case $status == '有SKU':
  711. if ($isSyncWms) {
  712. if (!$ownerIds) return null;
  713. return $this->getCommoditiesByOwnerIdsAndSKu($ownerIds,$skus);
  714. }
  715. sort($skus);
  716. //在取出的记录用 $ownerIds和$barcodes筛选
  717. $commodities = Commodity::query()
  718. ->whereIn('sku', $skus)->get();
  719. if ($ownerIds) {
  720. sort($ownerIds);
  721. // $md5 = md5(json_encode([$skus, $ownerIds]));
  722. // return Cache::remember('commodity_' . $md5, $time, function () use ($skus, $ownerIds, $commodities) {
  723. return $commodities->whereIn('owner_id', $ownerIds);
  724. // });
  725. }
  726. if ($barcodes && !$ownerIds) {
  727. sort($barcodes);
  728. $md5 = md5(json_encode([$skus, $barcodes]));
  729. return Cache::remember('commodity_' . $md5, $time, function () use ($skus, $barcodes) {
  730. return Commodity::query()
  731. ->whereIn('id', function ($query) use ($barcodes) {
  732. $query->from('commodity_barcodes')->select('commodity_id')->whereIn('code', $barcodes);
  733. })
  734. ->whereIn('sku', $skus)->get();
  735. });
  736. }
  737. return $commodities;
  738. case $status == '有条码没SKU':
  739. sort($barcodes);
  740. $commodities = Commodity::query()
  741. ->whereIn('id', function ($query) use ($barcodes) {
  742. $query->from('commodity_barcodes')->select('commodity_id')->whereIn('code', $barcodes);
  743. })->get();
  744. if ($ownerIds) {
  745. sort($ownerIds);
  746. $barcodes_ownerIds_md5 = md5(json_encode([$barcodes, $ownerIds]));
  747. return Cache::remember('commodity_' . $barcodes_ownerIds_md5, $time, function () use ($ownerIds) {
  748. return Commodity::query()->whereIn('owner_id', $ownerIds);
  749. });
  750. }
  751. return $commodities;
  752. case $status == '只有货主条件':
  753. sort($ownerIds);
  754. $md5 = md5(json_encode([$ownerIds, $paginate, $page]));
  755. $key = 'commodity_' . $md5;
  756. $commodities = Cache::get($key);
  757. if (is_null($commodities))//如果缓存已失效或者无缓存则重新缓存
  758. {
  759. $commodities = Commodity::query()
  760. ->whereIn('owner_id', $ownerIds)
  761. ->orderBy('owner_id', 'asc')
  762. ->paginate($paginate, '*', 'page', $page);
  763. Cache::add($key, $commodities->items());
  764. return $commodities;
  765. }
  766. return $commodities;
  767. }
  768. }
  769. public function getCommoditiesByOwnerIdsAndSKu($owner_ids, $skus)
  770. {
  771. $owner_codes = Owner::query()->whereIn('id', $owner_ids)->get()->map(function ($owner) {return $owner->code;});
  772. $basSkus = OracleBasSKU::query()->whereIn('sku', $skus)->whereIn('customerid', $owner_codes)
  773. ->select('customerid', 'sku', 'descr_c', 'alternate_sku1', 'alternate_sku2', 'alternate_sku3', 'skulength', 'skuwidth', 'skuhigh', 'cube', 'packid', 'addtime', 'edittime')->get();
  774. $maps = [];
  775. foreach ($basSkus as $basSku) {
  776. $value = [
  777. 'owner_code' => $basSku['customerid'],
  778. 'sku' => $basSku['sku']
  779. ];
  780. $maps[json_encode($value)] = $value;
  781. }
  782. return $this->getCommoditiesByMaps($maps, $basSkus);
  783. }
  784. /**
  785. * @param $maps
  786. * @param null $basSkus
  787. * @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
  788. * 参数maps格式 $maps[json_encode(['owner_code' => $basSku['customerid'],'sku' => $basSku['sku']])]=['owner_code' => $basSku['customerid'],'sku' => $basSku['sku']];
  789. */
  790. public function getCommoditiesByMaps($maps, $basSkus = null)
  791. {
  792. $commodities = $this->getCommodityByCacheMaps($maps);
  793. if (count($maps) == 0) return $commodities;
  794. $commoditiesInDB=$this->getCommodityByMaps($maps);
  795. $commodities = $commodities->concat($commoditiesInDB);
  796. if (count($maps) == 0) return $commodities;
  797. $owners = Owner::query()->whereIn('code', array_unique(data_get($maps, '*.owner_code')))->get();
  798. $owner_map = [];
  799. $owner_id_map = [];
  800. foreach ($owners as $owner) {
  801. $owner_map[$owner->id] = $owner->code;
  802. $owner_id_map[$owner->code] = $owner->id;
  803. }
  804. $mapOwnerCodes = [];
  805. $mapSkus = [];
  806. foreach ($maps as $map) {
  807. $mapSkus[] = $map['sku'];
  808. $mapOwnerCodes[] = $map['owner_code'];
  809. }
  810. $basSkus = OracleBasSKU::query()->whereIn('sku', $mapSkus)->whereIn('customerid', $mapOwnerCodes)
  811. ->select('customerid', 'sku', 'descr_c', 'alternate_sku1', 'alternate_sku2', 'alternate_sku3', 'skulength', 'skuwidth', 'skuhigh', 'cube', 'packid', 'addtime', 'edittime')->get();
  812. if (count($basSkus) < 1) return $commodities;
  813. $insert_params = [];
  814. $owner_ids = [];
  815. $skus = [];
  816. foreach ($basSkus as $basSku) {
  817. $commodity = Cache::get("owner_code_{$basSku['customerid']}_sku_{$basSku['sku']}");
  818. if ($commodity) continue;
  819. if ($basSku->sku=='NOSKU')continue;
  820. $owner_id = $owner_id_map[$basSku['customerid']] ?? '';
  821. $owner_ids[] = $owner_id;
  822. $skus[] = $basSku->sku;
  823. $insert_params[] = [
  824. 'owner_id' => $owner_id,
  825. 'sku' => $basSku->sku,
  826. 'name' => $basSku->descr_c,
  827. 'length' => $basSku->skulength,
  828. 'width' => $basSku->skuwidth,
  829. 'height' => $basSku->skuhigh,
  830. 'volumn' => $basSku->cube,
  831. 'remark' => $basSku->notes,
  832. 'created_at' => $basSku->addtime,
  833. 'updated_at' => $basSku->edittime,
  834. 'pack_spec' => $basSku->packid == 'STANDARD' ? 0 : explode("/", $basSku->packid)[1],
  835. ];
  836. }
  837. $this->insert($insert_params);
  838. app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 Commodity Success " . count($insert_params) . ' || ' . json_encode($insert_params));
  839. $insertCommodities = Commodity::query()->whereIn('owner_id',array_unique($owner_ids))->whereIn('sku',array_unique($skus))->get();
  840. if(count($insertCommodities)>0) $this->pushToCache($insertCommodities);
  841. $commodities = $commodities->concat($insertCommodities);
  842. return $commodities;
  843. }
  844. public function getCommodityByCacheMaps(&$maps)
  845. {
  846. $commodities = collect();
  847. foreach ($maps as $key => $map) {
  848. $commodity = Cache::get("owner_code_{$map['owner_code']}_sku_{$map['sku']}");
  849. if (isset($commodity)) {
  850. $commodities->push($commodity);
  851. unset($maps[$key]);
  852. }
  853. }
  854. return $commodities;
  855. }
  856. public function getCommodityByMaps(&$maps, $owners = null)
  857. {
  858. $count=count($maps);
  859. if ($owners == null) $owners = Owner::query()->whereIn('code', array_unique(data_get($maps, '*.owner_code')))->get();
  860. $owner_map=[];
  861. foreach ($owners as $owner){
  862. $owner_map[$owner->id]=$owner->code;
  863. }
  864. $commodities = Commodity::query()
  865. ->whereIn('owner_id', data_get($owners, '*.id'))
  866. ->whereIn('sku', array_unique(data_get($maps, '*.sku')))
  867. ->get();
  868. foreach ($commodities as $commodity) {
  869. $key = json_encode(['owner_code'=>$owner_map[$commodity->owner_id],'sku'=>$commodity->sku]);
  870. if(isset($maps[$key]))unset($maps[$key]);
  871. }
  872. if(count($maps)!=$count) $this->pushToCache($commodities);
  873. return $commodities;
  874. }
  875. /**
  876. * 不存在则创建
  877. *
  878. * @param integer $ownerId
  879. * @param array $sku
  880. */
  881. public function notExistToCreate($ownerId,array $sku)
  882. {
  883. $map = [];
  884. foreach ($sku as $item){
  885. $map[$item] = true;
  886. }
  887. $commodities = Commodity::query()->where("owner_id",$ownerId)->whereIn("sku",$sku)->get();
  888. $commodities->each(function ($commodity)use(&$map){
  889. unset($map[$commodity->sku]);
  890. });
  891. $sku = array_keys($map);
  892. if ($sku)$this->syncWMSOrderCode($ownerId,$sku);
  893. }
  894. public function getCommodityBy($owner,$sku)
  895. {
  896. $commodity = Commodity::query()->where('owner_id',$owner->id)->where('sku',$sku)->first();
  897. if ($commodity) return $commodity;
  898. $barcode = CommodityBarcode::query()->with('commodity')->where('code',$sku)->whereHas('commodity',function ($query)use($owner){
  899. /** @var Builder $query */
  900. $query->where('id',$owner->id);
  901. })->first();
  902. if ($barcode) return $barcode->commodity;
  903. return false;
  904. }
  905. }