StoreService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. namespace App\Services;
  3. use App\Jobs\StoreCreateInstantBill;
  4. use App\Order;
  5. use App\OwnerFeeDetail;
  6. use App\Services\common\BatchUpdateService;
  7. use App\Services\common\DataHandlerService;
  8. use App\Services\common\QueryService;
  9. use App\Store;
  10. use App\StoreRejected;
  11. use App\ValueStore;
  12. use Carbon\Carbon;
  13. use Illuminate\Support\Facades\Cache;
  14. use App\Traits\ServiceAppAop;
  15. class StoreService
  16. {
  17. use ServiceAppAop;
  18. protected $modelClass=Store::class;
  19. private function conditionQuery(array $params)
  20. {
  21. $stores = Store::query()->with(['storeItems.store', 'warehouse', 'owner'])->where('is_fast_stored', '无')->orderBy('id', 'DESC');
  22. $columnQueryRules = [
  23. 'asn_code' => ['like' => ''],
  24. 'remark' => ['like' => '','timeLimit' => 15],
  25. 'created_at_start' => ['alias' => 'created_at', 'startDate' => ' 00:00:00'],
  26. 'created_at_end' => ['alias' => 'created_at', 'endDate' => ' 23:59:59'],
  27. 'owner_id' => ['multi' => ','],
  28. 'warehouse_id' => ['multi' => ','],
  29. 'status' => ['multi' => ','],
  30. 'stored_method' => ['multi' => ','],
  31. 'id' => ['multi' => ',']
  32. ];
  33. $stores = app(QueryService::class)->query($params, $stores, $columnQueryRules, 'stores');
  34. return $stores;
  35. }
  36. public function paginate(array $params)
  37. {
  38. return $this->conditionQuery($params)->paginate($params['paginate'] ?? 50);
  39. }
  40. public function create(array $params)
  41. {
  42. return Store::query()->create($params);
  43. }
  44. public function storeCreateByWms()
  45. {
  46. $created_at = config('sync.asn_sync.created_at');
  47. $create_set = config('sync.asn_sync.cache_prefix.create_set');
  48. $create_keys = config('sync.asn_sync.cache_prefix.create_keys');
  49. $create_key = config('sync.asn_sync.cache_prefix.create');
  50. /** @var OracleDocAsnHerderService $oracleDocAsnHerderService */
  51. $oracleDocAsnHerderService = app(OracleDocAsnHerderService::class);
  52. $last_time = $this->getAsnLastSyncAt($created_at, 'create');
  53. $asnHerders = $oracleDocAsnHerderService->getWmsAsnOnStartDateCreate($last_time);
  54. if (count($asnHerders)<1) return;
  55. $last_time = $asnHerders->first()['addtime'];
  56. $last_records = $asnHerders->where('addtime', $last_time);
  57. $this->createStore($asnHerders);
  58. $this->createStoreRejected($asnHerders);
  59. $this->deleteCacheKey($create_set, $create_keys);
  60. $this->setLastRecordsByRedis($create_key, $create_set, $create_keys, $last_records);
  61. $this->setAsnLastSyncAt($created_at, $last_time);
  62. }
  63. public function storeUpdateByWms()
  64. {
  65. $updated_at = config('sync.asn_sync.updated_at');
  66. $update_set = config('sync.asn_sync.cache_prefix.update_set');
  67. $update_keys = config('sync.asn_sync.cache_prefix.update_keys');
  68. $update_key = config('sync.asn_sync.cache_prefix.update');
  69. /** @var OracleDocAsnHerderService $oracleDocAsnHerderService */
  70. $oracleDocAsnHerderService = app(OracleDocAsnHerderService::class);
  71. $last_time = $this->getAsnLastSyncAt($updated_at, 'update');
  72. $asnHerders = $oracleDocAsnHerderService->getWmsAsnOnStartDateEdit($last_time);
  73. if (count($asnHerders)<1) return;
  74. $last_time = $asnHerders->first()['edittime'];
  75. $last_records = $asnHerders->where('edittime', $last_time);
  76. $this->createStore($asnHerders);
  77. $this->updateStore($asnHerders);
  78. $this->createStoreRejected($asnHerders);
  79. $this->deleteCacheKey($update_set, $update_keys);
  80. $this->setLastRecordsByRedis($update_key, $update_set, $update_keys, $last_records);
  81. $this->setAsnLastSyncAt($updated_at, $last_time);
  82. }
  83. public function createStore($asnHerders)
  84. {
  85. if (!$asnHerders) return null;
  86. /**
  87. * @var OwnerService $ownerService
  88. * @var WarehouseService $wareHouseService
  89. */
  90. $ownerService = app(OwnerService::class);
  91. $wareHouseService = app(WarehouseService::class);
  92. $owner_codes = [];
  93. $warehouse_codes = [];
  94. foreach ($asnHerders as $asnHerder) {
  95. if (!empty($asnHerder['customerid']))
  96. $owner_codes[$asnHerder['customerid']] = $asnHerder['customerid'];
  97. if (!empty($asnHerder['warehouseid']))
  98. $warehouse_codes[$asnHerder['warehouseid']] = $asnHerder['warehouseid'];
  99. }
  100. $owners = $ownerService->getOwnerByCodes($owner_codes);
  101. $warehouses = $wareHouseService->getWareHouseByCodes($warehouse_codes);
  102. $owners_code_map=[];
  103. foreach ($owners as $owner) {
  104. $owners_code_map[$owner->code] = $owner;
  105. }
  106. $warehouses_code_map=[];
  107. foreach ($warehouses as $warehouse) {
  108. $warehouses_code_map[$warehouse->code] = $warehouse;
  109. }
  110. $params = $this->getParamsByAsnHeader($asnHerders, $owners_code_map, $warehouses_code_map);
  111. if (count($params) > 0) $this->insertStore($params);
  112. /** @var StoreItemService $storeItemService */
  113. $storeItemService = app(StoreItemService::class);
  114. $storeItemService->storeItemCreateByWms($asnHerders);
  115. /** @var RejectedBillService $rejectedBillService */
  116. $rejectedBillService = app(RejectedBillService::class);
  117. $rejectedBillService->syncLoadedStatusByAsnHerder($asnHerders);
  118. $this->pushJob($asnHerders);
  119. unset($asnHerders, $owners_code_map, $warehouses_code_map);
  120. }
  121. public function getParamsByAsnHeader($asnHerders, $owners_code_map, $warehouses_code_map)
  122. {
  123. $params = [];
  124. $stores = Store::query()->whereIn('asn_code', data_get($asnHerders, '*.asnno'))->get();
  125. $store_asn_code_map = [];
  126. foreach ($stores as $store) {
  127. $store_asn_code_map[$store->asn_code] = $store;
  128. }
  129. foreach ($asnHerders as $asnHerder) {
  130. if ($store_asn_code_map[$asnHerder->asnno] ?? false) continue;
  131. $owner = $owners_code_map[$asnHerder->customerid] ?? null;
  132. $warehouse = $warehouses_code_map[$asnHerder->warehouseid] ?? null;
  133. $status = null;
  134. if ($asnHerder->asnStatus && $asnHerder->asnStatus->codename_c == '完全收货') $status = '已入库';
  135. if ($asnHerder->asnStatus && $asnHerder->asnStatus->codename_c == '订单创建') $status = '未入库';
  136. $params[] = [
  137. 'asn_code' => $asnHerder->asnno,
  138. 'warehouse_id' => $warehouse->id ?? null,
  139. 'owner_id' => $owner->id ?? null,
  140. 'stored_method' => $asnHerder->asnType ? $asnHerder->asnType->codename_c : '',
  141. 'status' => $status ? $status : $asnHerder->asnStatus->codename_c,
  142. 'remark' => $asnHerder->notes ?? null,
  143. 'created_at' => $asnHerder->addtime ?? null,
  144. 'updated_at' => $asnHerder->edittime ?? null,
  145. ];
  146. }
  147. return $params;
  148. }
  149. public function insertStore(array $params)
  150. {
  151. if (count($params) === 0) return;
  152. foreach (array_chunk($params, 1000) as $item) {
  153. try {
  154. $bool = $this->insert($item);
  155. if ($bool) {
  156. app('LogService')->log(__METHOD__, __FUNCTION__, "批量创建 store success " . count($item) . ' || ' . json_encode($item));
  157. } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 store FAILED " . ' || ' . json_encode($item));
  158. } catch (\Exception $e) {
  159. app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 store ERROR " . ' || ' . json_encode($params) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
  160. }
  161. }
  162. }
  163. public function updateStore($asnHerders)
  164. {
  165. if (!$asnHerders || $asnHerders->count() == 0) return null;
  166. /**
  167. * @var DataHandlerService $dataHandlerService
  168. * @var OwnerService $ownerService
  169. * @var WarehouseService $wareHouseService
  170. */
  171. $ownerService = app(OwnerService::class);
  172. $wareHouseService = app(WarehouseService::class);
  173. $dataHandlerService = app(DataHandlerService::class);
  174. $stores = $this->getByWms($asnHerders);
  175. $store_asn_code_map = $dataHandlerService->dataHeader(['asn_code'], $stores);
  176. $owners = $ownerService->getOwnerByCodes(array_unique(data_get($asnHerders,'*.customerid')));
  177. $warehouses = $wareHouseService->getWareHouseByCodes(array_unique(data_get($asnHerders,'*.warehouseid')));
  178. $owner_code_map = $dataHandlerService->dataHeader(['code'], $owners);
  179. $warehouses_map = $dataHandlerService->dataHeader(['code'], $warehouses);
  180. $updateParams = [[
  181. 'id', 'asn_code', 'warehouse_id', 'owner_id', 'stored_method', 'status', 'remark', 'updated_at'
  182. ]];
  183. foreach ($asnHerders as $asnHerder) {
  184. $store = $dataHandlerService->getKeyValue(['asn_code' => $asnHerder->asnno], $store_asn_code_map);
  185. if (!$store) continue;
  186. $owner = $dataHandlerService->getKeyValue(['code' => $asnHerder->customerid], $owner_code_map);
  187. $warehouse = $dataHandlerService->getKeyValue(['code' => $asnHerder->warehouseid], $warehouses_map);
  188. $owner_id = $owner->id ?? null;
  189. $warehouse_id = $warehouse->id ?? null;
  190. $status = null;
  191. if ($asnHerder->asnStatus && $asnHerder->asnStatus->codename_c == '完全收货') $status = '已入库';
  192. if ($asnHerder->asnStatus && $asnHerder->asnStatus->codename_c == '订单创建') $status = '未入库';
  193. if ($store->asn_code != $asnHerder->asnno ||
  194. $store->warehouse_id != $warehouse_id ||
  195. $store->owner_id != $owner_id ||
  196. $store->stored_method != ($asnHerder->asnType->codename_c ??'')||
  197. $store->status != ($asnHerder->asnStatus->codename_c ?? '')||
  198. $store->remark != $asnHerder->notes ||
  199. $store->updated_at != $asnHerder->edittime) {
  200. $updateParams[] = [
  201. 'id' => $store->id,
  202. 'asn_code' => $asnHerder->asnno,
  203. 'warehouse_id' => $warehouse_id,
  204. 'owner_id' => $owner_id,
  205. 'stored_method' => $asnHerder->asnType ? $asnHerder->asnType->codename_c : '',
  206. 'status' => $status ? $status : $asnHerder->asnStatus->codename_c,
  207. 'remark' => $asnHerder->notes,
  208. 'updated_at' => $asnHerder->edittime,
  209. ];
  210. }
  211. }
  212. if (count($updateParams) > 1) {
  213. foreach (array_chunk($updateParams, 1000) as $item) {
  214. try {
  215. $bool=$this->batchUpdate($item);
  216. if ($bool) {
  217. app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store success " . count($item) . ' || ' . json_encode($item));
  218. } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store FAILED " . ' || ' . json_encode($item));
  219. } catch (\Exception $e) {
  220. app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store ERROR " . ' || ' . json_encode($updateParams) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
  221. }
  222. }
  223. }
  224. /** @var StoreItemService $storeItemService */
  225. $storeItemService = app(StoreItemService::class);
  226. $storeItemService->storeItemUpdateByWms($asnHerders);
  227. /** @var RejectedBillService $rejectedBillService */
  228. $rejectedBillService = app(RejectedBillService::class);
  229. $rejectedBillService->syncLoadedStatusByAsnHerder($asnHerders);
  230. $this->pushJob($asnHerders);
  231. unset($updateParams, $asnHerders);
  232. }
  233. public function pushJob($asnHerders){
  234. $stores = Store::query()->with(["storeItems"])->where('status','已入库')->whereIn('asn_code', data_get($asnHerders,'*.asnno'))->get();
  235. $stores->each(function($store){
  236. dispatch(new StoreCreateInstantBill($store));
  237. });
  238. }
  239. public function insert($params)
  240. {
  241. return Store::query()->insert($params);
  242. }
  243. public function batchUpdate($params)
  244. {
  245. return app(BatchUpdateService::class)->batchUpdate('stores', $params);
  246. }
  247. public function getByWms($asnHerders)
  248. {
  249. if (!$asnHerders) {
  250. return null;
  251. }
  252. $asn_nos = array_unique(data_get($asnHerders, '*.asnno'));
  253. return Store::query()->whereIn('asn_code', $asn_nos)->get();
  254. }
  255. public function getAsnLastSyncAt($key, $type)
  256. {
  257. $last_time = ValueStore::query()->where('name', $key)->value('value');
  258. if ($last_time) return $last_time;
  259. if ($type == 'create') {
  260. $store = Store::query()->orderByDesc('created_at')->first();
  261. if ($store) return $store->created_at;
  262. } else {
  263. $store = Store::query()->orderByDesc('updated_at')->first();
  264. if ($store) return $store->updated_at;
  265. }
  266. return Carbon::now()->subSeconds(65);
  267. }
  268. public function setAsnLastSyncAt($key, $last_time)
  269. {
  270. $asnLastSyncAt = ValueStore::query()->updateOrCreate([
  271. 'name' => $key,
  272. ], [
  273. 'name' => $key,
  274. 'value' => $last_time,
  275. ]);
  276. LogService::log(__METHOD__, __FUNCTION__, '修改或更新' . $key . json_encode($asnLastSyncAt));
  277. return $asnLastSyncAt;
  278. }
  279. public function deleteCacheKey($set, $keys)
  280. {
  281. if (Cache::get($set)) {
  282. $cacheKeys = Cache::get($keys);
  283. if (!$cacheKeys) return;
  284. foreach ($cacheKeys as $cacheKey) {
  285. Cache::forget($cacheKey);
  286. }
  287. Cache::forget($keys);
  288. }
  289. }
  290. public function setLastRecordsByRedis($prefixKey, $set, $keys, $last_records)
  291. {
  292. $cacheKeys = [];
  293. foreach ($last_records as $last_record) {
  294. Cache::put($prefixKey . $last_record->customerid . '_' . $last_record->asnno, true);
  295. array_push($cacheKeys, $prefixKey . $last_record->customerid . '_' . $last_record->asnno);
  296. }
  297. Cache::put($keys, $cacheKeys);
  298. Cache::put($set, true);
  299. }
  300. public function createInstantBill(Store $store): bool
  301. {
  302. if (!$store || $store->status != "已入库") return false;
  303. if (OwnerFeeDetail::query()->where("outer_table_name","stores")->where("outer_id",$store->id)->first())return false;
  304. $store->loadMissing("storeItems");
  305. /** @var OwnerPriceOperationService $service */
  306. $service = app("OwnerPriceOperationService");
  307. $mapping = ["packages" => "storeItems", "商品名称" => "name", "订单类型" => "stored_method", "订单数"=>"amount"];
  308. $result = $service->matching($store, $mapping, $store->owner_id, "入库");
  309. if (app("OwnerFeeDetailService")->create([
  310. "owner_id" => $store->owner_id,
  311. "worked_at" => $store->created_at,
  312. "type" => "收货",
  313. "operation_bill" => $store->asn_code,
  314. "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
  315. "work_fee" => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
  316. "owner_price_operation_id" => is_array($result) ? $result["id"] : null,
  317. "created_at" => date('Y-m-d H:i:s'),
  318. "outer_id" => $store->id,
  319. "outer_table_name" => "stores",
  320. ])) return true;
  321. return false;
  322. }
  323. public function createStoreRejected($asnHerders){
  324. if (!$asnHerders) return null;
  325. $stores = $this->getByWms($asnHerders);
  326. $orders = Order::query()->whereIn('client_code', data_get($asnHerders, '*.asnreference2'))->get();
  327. $store_rejecteds=StoreRejected::query()->whereIn('order_id',data_get($orders,'*.id'))->whereIn('store_id',data_get($stores,'*.id'))->get();
  328. /** @var DataHandlerService $dataHandlerService */
  329. $dataHandlerService = app(DataHandlerService::class);
  330. $order_map = $dataHandlerService->dataHeader(['client_code'], $orders);
  331. $store_map = $dataHandlerService->dataHeader(['asn_code'], $stores);
  332. $store_rejected_map=$dataHandlerService->dataHeader(['store_id','order_id','logistic_number_return'],$store_rejecteds);
  333. $insert_param=[];
  334. foreach ($asnHerders as $asnHerder){
  335. if (!$asnHerder->asnreference2) continue;
  336. $order=$dataHandlerService->getKeyValue(['client_code'=>$asnHerder->asnreference2],$order_map);
  337. $store=$dataHandlerService->getKeyValue(['asn_code'=>$asnHerder->asnno],$store_map);
  338. if (!$order || !$store)continue;
  339. $store_rejected=$dataHandlerService->getKeyValue(['store_id'=>$store->id,'order_id'=>$order->id,'logistic_number_return'=>$asnHerder->asnreference3],$store_rejected_map);
  340. if ($store_rejected) continue;
  341. $insert_param[]=[
  342. 'store_id'=>$store->id,
  343. 'order_id'=>$order->id,
  344. 'logistic_number_return'=>$asnHerder->asnreference3 ?? '',
  345. 'created_at'=>Carbon::now()->toDateTimeString(),
  346. ];
  347. }
  348. if (count($insert_param)>0) StoreRejected::query()->insert($insert_param);
  349. }
  350. }