StoreItemService.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. namespace App\Services;
  3. use App\OracleDOCASNDetail;
  4. use App\Owner;
  5. use App\Services\common\BatchUpdateService;
  6. use App\Services\common\DataHandlerService;
  7. use App\Store;
  8. use App\StoreItem;
  9. use App\Traits\ServiceAppAop;
  10. use Illuminate\Database\Eloquent\Builder;
  11. use Illuminate\Database\Eloquent\Model;
  12. use Illuminate\Support\Facades\DB;
  13. class StoreItemService
  14. {
  15. use ServiceAppAop;
  16. protected $modelClass=StoreItem::class;
  17. public function storeItemCreateByWms($asnHerders)
  18. {
  19. if (!$asnHerders) return null;
  20. $asnDetails = $this->getAsnDetailsByAsnHerder($asnHerders);
  21. $this->createStoreItem($asnDetails);
  22. }
  23. public function storeItemUpdateByWms($asnHerders)
  24. {
  25. if (!$asnHerders) return null;
  26. $asnDetails = $this->getAsnDetailsByAsnHerder($asnHerders);
  27. $this->updateStoreItem($asnDetails);
  28. }
  29. public function getAsnDetailsByAsnHerder($asnHerders)
  30. {
  31. $asnnos = collect();
  32. foreach ($asnHerders as $asnHerder) {
  33. $asnnos->add($asnHerder->asnno);
  34. }
  35. $asnnos = $asnnos->unique()->toArray();
  36. return OracleDOCASNDetail::query()
  37. ->with(['lineStatus', 'qualityStatus'])
  38. ->whereIn('asnno',$asnnos)
  39. ->select('asnno','asnlineno','customerid','sku','skudescrc','linestatus','lotatt08','lotatt05','receivedqty','expectedqty','addtime','edittime')
  40. ->get();
  41. }
  42. public function createStoreItem($asnDetails)
  43. {
  44. if ($asnDetails->isEmpty()) return null;
  45. $stores = Store::query()->whereIn('asn_code', array_unique(data_get($asnDetails, '*.asnno')))->get();
  46. $store_asn_code_map = [];
  47. foreach ($stores as $store) {
  48. $store_asn_code_map[$store->asn_code] = $store;
  49. }
  50. $params = $this->getParamsByAsnDetails($asnDetails, $store_asn_code_map);
  51. if (count($params) > 0) $this->insertStoreItem($params);
  52. }
  53. public function getParamsByAsnDetails($asnDetails, $store_asn_code_map): array
  54. {
  55. /**
  56. * @var DataHandlerService $dataHandlerService
  57. * @var CommodityService $commodityService
  58. * @var OwnerService $ownerService
  59. */
  60. $dataHandlerService = app(DataHandlerService::class);
  61. $commodityService = app(CommodityService::class);
  62. $ownerService = app(OwnerService::class);
  63. $owners = $ownerService->getOwnerByCodes(array_unique(data_get($asnDetails,'*.customerid')));
  64. $stores = Store::query()->whereIn('asn_code', array_unique(data_get($asnDetails, '*.asnno')))->get();
  65. $owner_map=[];
  66. $store_map=[];
  67. foreach ($owners as $owner){
  68. $owner_map[$owner->code]=$owner->id;
  69. }
  70. foreach ($stores as $store){
  71. $store_map[$store->asn_code]=$store->id;
  72. }
  73. $maps = [];
  74. foreach ($asnDetails as $asnDetail) {
  75. $value = [
  76. 'owner_code' => $asnDetail->customerid,
  77. 'sku' => $asnDetail->sku,
  78. ];
  79. $maps[json_encode($value)] = $value;
  80. }
  81. $commodities=$commodityService->getCommoditiesByMaps($maps);
  82. $commodities_map= $dataHandlerService->dataHeader(['owner_id','sku'], $commodities);
  83. $storeItems = $this->getByWms($asnDetails);
  84. $storeItem_map = $dataHandlerService->dataHeader(['store_id', 'asn_line_code', 'commodity_id'], $storeItems);
  85. $params = [];
  86. foreach ($asnDetails as $asnDetail) {
  87. $commodity=$dataHandlerService->getKeyValue(['owner_id'=>$owner_map[$asnDetail->customerid],'sku'=>$asnDetail->sku],$commodities_map);
  88. if (!$commodity)continue;
  89. $storeItem = $dataHandlerService
  90. ->getKeyValue(['store_id' => $store_map[$asnDetail->asnno], 'asn_line_code' => $asnDetail->asnlineno, 'commodity_id' => $commodity->id], $storeItem_map);
  91. if ($storeItem ?? false) continue;
  92. $status = null;
  93. if ($asnDetail->lineStatus && $asnDetail->lineStatus->codename_c == '完全收货') $status = '已入库';
  94. if ($asnDetail->lineStatus && $asnDetail->lineStatus->codename_c == '订单创建') $status = '未入库';
  95. //if (empty($store_asn_code_map[$asnDetail->asnno])) continue;
  96. $params[] = [
  97. 'store_id' => $store_asn_code_map[$asnDetail->asnno]['id'],
  98. 'asn_line_code' => (string)$asnDetail->asnlineno,
  99. 'commodity_id' => $commodity->id,
  100. 'name' => $asnDetail->skudescrc,
  101. 'sku' => $asnDetail->sku,
  102. 'amount' => $asnDetail->receivedqty ?? 0,
  103. 'expected_amount' => $asnDetail->expectedqty ?? 0,
  104. 'quality' => $asnDetail->qualityStatus ? $asnDetail->qualityStatus->codename_c :'',
  105. 'status' => $status ? $status : $asnDetail->lineStatus->codename_c,
  106. 'created_at' => $asnDetail->addtime ?? null,
  107. 'updated_at' => $asnDetail->edittime ?? null,
  108. ];
  109. }
  110. return $params;
  111. }
  112. public function insertStoreItem(array $params)
  113. {
  114. if (count($params) === 0) return;
  115. foreach (array_chunk($params, 1000) as $item) {
  116. try {
  117. $bool = $this->insert($item);
  118. if ($bool) {
  119. app('LogService')->log(__METHOD__, __FUNCTION__, "批量创建 store_item success " . count($item) . ' || ' . json_encode($item));
  120. } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 store_item FAILED " . ' || ' . json_encode($item));
  121. } catch (\Exception $e) {
  122. app('LogService')->log(__METHOD__, __FUNCTION__, "批量添加 store_item ERROR " . ' || ' . json_encode($params) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
  123. }
  124. }
  125. }
  126. public function updateStoreItem($asnDetails)
  127. {
  128. if (!$asnDetails || $asnDetails->count() == 0) return null;
  129. /**
  130. * @var DataHandlerService $dataHandlerService
  131. * @var CommodityService $commodityService
  132. * @var OwnerService $ownerService
  133. */
  134. $dataHandlerService = app(DataHandlerService::class);
  135. $commodityService = app(CommodityService::class);
  136. $ownerService = app(OwnerService::class);
  137. $owners = $ownerService->getOwnerByCodes(array_unique(data_get($asnDetails,'*.customerid')));
  138. $owner_map=[];
  139. foreach ($owners as $owner){
  140. $owner_map[$owner->id]=$owner->code;
  141. }
  142. $maps = [];
  143. foreach ($asnDetails as $asnDetail) {
  144. $value = [
  145. 'owner_code' => $asnDetail->customerid,
  146. 'sku' => $asnDetail->sku,
  147. ];
  148. $maps[json_encode($value)] = $value;
  149. }
  150. $commodities=$commodityService->getCommoditiesByMaps($maps);
  151. $commodities_map= $dataHandlerService->dataHeader(['id'], $commodities);
  152. $storeItems = $this->getByWms($asnDetails);
  153. $asnDetails_map = $dataHandlerService->dataHeader(['asnno', 'asnlineno','customerid','sku'], $asnDetails);
  154. $updateParams = [[
  155. 'id', 'store_id', 'asn_line_code', 'name', 'sku', 'barcode', 'amount','expected_amount', 'quality', 'status', 'created_at', 'updated_at'
  156. ]];
  157. $delete_storeItems = [];
  158. foreach ($storeItems as $storeItem) {
  159. $commodity= $dataHandlerService->getKeyValue(['id'=>$storeItem->commodity_id],$commodities_map);if (!$commodity) continue;
  160. $asnDetail = $dataHandlerService
  161. ->getKeyValue(['asnno' => $storeItem->store->asn_code ?? '', 'asnlineno' => $storeItem->asn_line_code,'customerid'=>$owner_map[$commodity->owner_id],'sku' => $commodity->sku], $asnDetails_map);
  162. if (!$asnDetail) {
  163. array_push($delete_storeItems, $storeItem);
  164. continue;
  165. }
  166. $status = null;
  167. if ($asnDetail['lineStatus'] && $asnDetail['lineStatus']['codename_c'] == '完全收货') $status = '已入库';
  168. if ($asnDetail['lineStatus'] && $asnDetail['lineStatus']['codename_c'] == '订单创建') $status = '未入库';
  169. if ($storeItem->updated_at != $asnDetail['edittime']
  170. // || $storeItem->expected_amount!=$asnDetail['expectedqty']
  171. ) {
  172. $updateParams[] = [
  173. 'id' => $storeItem->id,
  174. 'store_id' => $storeItem->store->id,
  175. 'asn_line_code' => (string)$asnDetail['asnlineno'],
  176. 'name' => $asnDetail['skudescrc'],
  177. 'sku' => $asnDetail['sku'],
  178. 'barcode' => $asnDetail['basSku'] ? $asnDetail['basSku']['alternate_sku1'] : '',
  179. 'amount' => $asnDetail['receivedqty'] ?? 0,
  180. 'expected_amount' => $asnDetail['expectedqty'] ?? 0,
  181. 'quality' => $asnDetail['qualityStatus'] ? $asnDetail['qualityStatus']['codename_c'] : '',
  182. 'status' => $status ? $status : $asnDetail['lineStatus']['codename_c'],
  183. 'created_at' => $asnDetail['addtime'] ?? null,
  184. 'updated_at' => $asnDetail['edittime'],
  185. ];
  186. }
  187. }
  188. if (count($updateParams) > 1) $this->batchUpdate($updateParams);
  189. if (count($delete_storeItems) > 0) $this->deleteStoreItem($delete_storeItems);
  190. unset($updateParams, $asnDetails, $delete_storeItems);
  191. }
  192. public function batchUpdate($params)
  193. {
  194. return app(BatchUpdateService::class)->batchUpdate('store_items', $params);
  195. }
  196. public function getByWms($asnDetails)
  197. {
  198. if (!$asnDetails) {
  199. return null;
  200. }
  201. return StoreItem::query()->with('store')->whereIn('store_id', function ($query) use ($asnDetails) {
  202. $query->from('stores')->select('id')->whereIn('asn_code', array_unique(data_get($asnDetails, '*.asnno')));
  203. })->get();
  204. }
  205. public function deleteStoreItem(array $delete_storeItems)
  206. {
  207. $storeItemIds = [];
  208. foreach ($delete_storeItems as $delete_storeItem) {
  209. array_push($storeItemIds, $delete_storeItem->id);
  210. }
  211. try {
  212. StoreItem::query()->whereIn('id', $storeItemIds)->delete();
  213. LogService::log(__METHOD__, __FUNCTION__, '删除多余StoreItems ' . count($delete_storeItems) . json_encode($delete_storeItems), null);
  214. } catch (\Exception $e) {
  215. LogService::log(__METHOD__, __FUNCTION__, '删除多余StoreItems error' . count($delete_storeItems) . json_encode($delete_storeItems) . $e->getMessage() . $e->getTraceAsString(), null);
  216. }
  217. }
  218. /**
  219. * 获取最大可上架数的详情项
  220. *
  221. * @param string $asn
  222. * @param string $barCode
  223. *
  224. * @return StoreItem|Model|null
  225. */
  226. public function getMaxAvailableDetail(string $asn,string $barCode):?StoreItem
  227. {
  228. $sql = <<<SQL
  229. SELECT DOC_ASN_DETAILS.ASNLINENO,SUM(TSK_TASKLISTS.FMQTY) QTY FROM DOC_ASN_DETAILS LEFT JOIN TSK_TASKLISTS ON DOC_ASN_DETAILS.ASNNO = TSK_TASKLISTS.DOCNO AND DOC_ASN_DETAILS.ASNLINENO = TSK_TASKLISTS.DOCLINENO
  230. LEFT JOIN BAS_SKU ON DOC_ASN_DETAILS.SKU = BAS_SKU.SKU AND DOC_ASN_DETAILS.CUSTOMERID = BAS_SKU.CUSTOMERID
  231. WHERE DOC_ASN_DETAILS.ASNNO = ? AND DOC_ASN_DETAILS.LINESTATUS IN ('30','40')
  232. AND (BAS_SKU.ALTERNATE_SKU1 = ? OR ALTERNATE_SKU2 = ? AND ALTERNATE_SKU3 = ?)
  233. AND TSK_TASKLISTS.TASKTYPE = 'PA' AND TASKPROCESS = '00'
  234. GROUP BY (DOC_ASN_DETAILS.ASNLINENO,DOC_ASN_DETAILS.ASNNO) ORDER BY QTY DESC
  235. SQL;
  236. $detail = DB::connection("oracle")->selectOne(DB::raw($sql),[$asn,$barCode,$barCode,$barCode]);
  237. if (!$detail)return null;
  238. return StoreItem::query()->whereHas("store",function (Builder $query)use($asn){
  239. $query->where("asn_code",$asn);
  240. })->where("asn_line_code",$detail->asnlineno)->first();
  241. }
  242. }