OwnerService.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <?php
  2. namespace App\Services;
  3. use App\Authority;
  4. use App\OracleBasCustomer;
  5. use App\Owner;
  6. use App\OwnerPriceDirectLogistic;
  7. use App\OwnerPriceExpress;
  8. use App\OwnerPriceLogistic;
  9. use App\OwnerPriceOperation;
  10. use App\OwnerPriceSystem;
  11. use App\OwnerStoragePriceModel;
  12. use App\Services\common\BatchUpdateService;
  13. use App\User;
  14. use Carbon\Carbon;
  15. use Doctrine\DBAL\Exception\DatabaseObjectExistsException;
  16. use Illuminate\Database\Eloquent\Builder;
  17. use Illuminate\Database\Eloquent\Model;
  18. use Illuminate\Support\Collection;
  19. use Illuminate\Support\Facades\Auth;
  20. use Illuminate\Support\Facades\Cache;
  21. use Illuminate\Support\Facades\DB;
  22. use App\Traits\ServiceAppAop;
  23. class OwnerService
  24. {
  25. use ServiceAppAop;
  26. protected $modelClass=Owner::class;
  27. /** @var CacheService $cacheService */
  28. private $cacheService;
  29. function __construct(){
  30. $this->instant($this->cacheService,'CacheService');
  31. }
  32. /*
  33. * array | string $column
  34. * 默认一些select字段,可传递string 或 array来指定select字段
  35. */
  36. public function getIntersectPermitting(array $column = ['id', 'name'])
  37. {
  38. $ownerIds=app('UserService')->getPermittingOwnerIds(Auth::user());
  39. return $this->cacheService->getOrExecute('OwnersAll_IdName'.md5(json_encode($column).json_encode($ownerIds)),function()use($column,$ownerIds){
  40. if(empty($ownerIds))return new Collection();
  41. return Owner::query()->select($column)->whereIn('id', $ownerIds)->whereNull('deleted_at')->get();
  42. },config('cache.expirations.owners'));
  43. }
  44. public function getSelection($column = ['id'])
  45. {
  46. return $this->cacheService->getOrExecute('OwnersAll_'.md5(json_encode($column)),function()use($column){
  47. return Owner::filterAuthorities()->select($column)->get();
  48. },config('cache.expirations.owners'));
  49. }
  50. /**
  51. *同步WMS全部货主至WAS
  52. */
  53. public function syncOwnersData()
  54. {
  55. $basCustomers = OracleBasCustomer::query()
  56. ->select('CUSTOMERID', 'DESCR_C')
  57. ->where('DESCR_C', 'not like', '%换ERP%')
  58. ->where('DESCR_C', 'not like', '%退仓%')
  59. ->where('CUSTOMER_TYPE', 'OW')
  60. ->get();
  61. $ownerCount = Owner::query()->count();
  62. if (count($basCustomers) == $ownerCount) return null;
  63. foreach ($basCustomers as $basCustomer) {
  64. $owner = Owner::query()->where('code', $basCustomer['customerid'])->first();
  65. if (!isset($owner)){
  66. Owner::query()->create([
  67. 'code' => $basCustomer['customerid'],
  68. 'name' => $basCustomer['descr_c'],
  69. 'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
  70. ]);
  71. continue;
  72. }
  73. if ($owner['name']!=$basCustomer['descr_c']){
  74. $owner->update([
  75. 'code' => $basCustomer['customerid'],
  76. 'name' => $basCustomer['descr_c'],
  77. ]);
  78. }
  79. }
  80. $owners = Owner::query()->select('id', 'name')->get();
  81. return $owners;
  82. }
  83. public function first(array $params, array $rules =[]){
  84. return $this->cacheService->getOrExecute('OwnersFirst'.md5(json_encode($params),json_encode($rules)),function()use($params,$rules){
  85. $owner = Owner::query();
  86. foreach ($params as $column => $value){
  87. if (!isset($rules[$column]))$owner->where($column, $value);
  88. else{
  89. switch ($rules[$column]){
  90. case "or":
  91. $owner->orWhere($column, $value);
  92. break;
  93. }
  94. }
  95. }
  96. return $owner->first();
  97. },config('cache.expirations.rarelyChange'));
  98. }
  99. public function find($id, $with = [])
  100. {
  101. return Owner::query()->with($with)->find($id);
  102. }
  103. public function update(Owner $owner, array $values, array $related = [])
  104. {
  105. if ($related["ownerStoragePriceModels"] ?? false)$owner->ownerStoragePriceModels()->sync($related["ownerStoragePriceModels"]);
  106. return $owner->update($values);
  107. }
  108. public function create(array $params, array $related = []){
  109. /** @var Owner $owner */
  110. $owner = Owner::query()->create($params);
  111. if ($related["ownerStoragePriceModels"] ?? false)$owner->ownerStoragePriceModels()->syncWithoutDetaching($related["ownerStoragePriceModels"]);
  112. return $owner;
  113. }
  114. public function firstOrCreate(array $params, array $values = null){
  115. if (!$values) return Owner::query()->firstOrCreate($params);
  116. return Owner::query()->firstOrCreate($params,$values);
  117. }
  118. public function 获取订单跟踪的货主(){
  119. return Owner::query()->with('orderTrackingOwner')->whereHas('orderTrackingOwner',function($query){
  120. $query->where('status','启用');
  121. })->get();
  122. }
  123. public function getByWmsOrders($orderHeaders){
  124. $customerIds = array_unique(data_get($orderHeaders,'*.customerid'));
  125. $customerIds = array_diff($customerIds,[null,'','*']);
  126. $owners = Owner::query()->whereIn('code',$customerIds)->get();
  127. if($owners->count() < count($customerIds)){
  128. $customerIds = array_diff($customerIds,data_get($owners,'*.code'));
  129. $owner_list = $this->createByWmsCustomerIds($customerIds);
  130. $owners=$owners->concat($owner_list);
  131. }
  132. return $owners;
  133. }
  134. public function createByWmsCustomerIds($codes){
  135. if(!$codes) {return [];}
  136. $basCustomer = OracleBasCustomer::query()
  137. ->where('Customer_Type','OW')
  138. ->whereIn('CustomerID', $codes)
  139. ->get();
  140. $insert_params = [];
  141. $created_at = Carbon::now()->format('Y-m-d H:i:s');
  142. foreach ($basCustomer as $item) {
  143. $insert_params[] = [
  144. 'code' => $item->customerid,
  145. 'name' => $item->descr_c,
  146. 'created_at' => $created_at,
  147. ];
  148. }
  149. try {
  150. if (count($insert_params) > 0) {
  151. $this->insert($insert_params);
  152. app('LogService')->log(__METHOD__, __FUNCTION__, '批量创建 owner ' . count($insert_params) . json_encode($insert_params) );
  153. }
  154. } catch (\Exception $e) {
  155. app('LogService')->log(__METHOD__, __FUNCTION__, '批量创建 owner error' . json_encode($insert_params) . '||' . $e->getMessage() . '||' . $e->getTraceAsString());
  156. } finally {
  157. return Owner::query()->whereIn('code', $codes)->get();
  158. }
  159. }
  160. public function insert($fillables){
  161. return Owner::query()->insert($fillables);
  162. }
  163. public function getAuthorizedOwners(){
  164. $user = Auth::user();
  165. return Owner::query()->whereIn('id',app('UserService')->getPermittingOwnerIds($user)??[])->get();
  166. }
  167. public function get(array $params, array $withs = null, bool $authority = true, bool $notShowSoftDelete = false, $user = null)
  168. {
  169. /** @var User $user */
  170. if ($user==null)$user = Auth::user();
  171. return Cache::remember(
  172. 'owner_'.md5(json_encode($params).json_encode($withs).$authority.$notShowSoftDelete.json_encode($user))
  173. ,config('cache.expirations.rarelyChange')
  174. ,function()use($params,$withs,$authority,$notShowSoftDelete,$user){
  175. $query = Owner::query();
  176. if ($withs)$query->with($withs);
  177. if ($authority&&$user){
  178. $ids = $user->getPermittingOwnerIdsAttribute();
  179. $query->whereIn("id",$ids);
  180. }
  181. if ($notShowSoftDelete) $query->whereNull('deleted_at');
  182. $query = $this->query($query,$params);
  183. return $query->get();
  184. });
  185. }
  186. public function paginate(array $params, array $withs = null, bool $authority = true, bool $notShowSoftDelete = false)
  187. {
  188. /** @var User $user */
  189. $user = Auth::user();
  190. $query = Owner::query();
  191. if ($withs)$query->with($withs);
  192. if ($authority){
  193. $ids = $user->getPermittingOwnerIdsAttribute();
  194. $query->whereIn("id",$ids);
  195. }
  196. if ($notShowSoftDelete) $query->whereNull('deleted_at');
  197. $query = $this->query($query,$params)->orderByDesc("id");
  198. return $query->paginate($params["paginate"] ?? 50);
  199. }
  200. private function query(Builder $builder, array $params)
  201. {
  202. foreach ($params as $column => $param){
  203. if ($column == 'paginate' || $column == 'page' || !$param)continue;
  204. if ($param === true){
  205. $builder->whereNotNull($column);
  206. continue;
  207. }
  208. if ($param === false){
  209. $builder->whereNull($column);
  210. continue;
  211. }
  212. if ($column == 'created_at_start'){
  213. $builder->where("created_at",">=",$param.":00");
  214. continue;
  215. }
  216. if ($column == 'created_at_end'){
  217. $builder->where("created_at","<=",$param.":59");
  218. continue;
  219. }
  220. if ($column == 'contract_number'){
  221. $builder->whereHas("contracts",function ($query)use($param){
  222. /** @var Builder $query */
  223. $query->where("contract_number","like",$param."%");
  224. });
  225. continue;
  226. }
  227. if ($column == 'using_type'){
  228. $builder->whereHas("ownerStoragePriceModels",function ($query)use($param){
  229. /** @var Builder $query */
  230. $query->where("using_type",$param);
  231. });
  232. continue;
  233. }
  234. if ($column == 'customers'){
  235. if (is_array($param))$builder->whereIn('customer_id',$param);
  236. else $builder->where('customer_id',$param);
  237. continue;
  238. }
  239. if ($column == 'ids'){
  240. if (is_array($param))$builder->whereIn('id',$param);
  241. else $builder->where('id',$param);
  242. continue;
  243. }
  244. if ($column == 'owners'){
  245. if (is_array($param))$builder->whereIn('owner_id',$param);
  246. else $builder->where('owner_id',$param);
  247. continue;
  248. }
  249. if ($column == 'user_work_group'){
  250. $builder->where("user_workgroup_id",$param);
  251. continue;
  252. }
  253. if (is_array($param))$builder->whereIn($column,$param);
  254. else $builder->where($column,$param);
  255. }
  256. return $builder;
  257. }
  258. public function getOwnerByCodes($codes)
  259. {
  260. $collect = collect();
  261. if(count($codes) == 0)return $collect;
  262. foreach ($codes as $code) {
  263. $collect = $collect->push($this->getOwnerByCode($code));
  264. }
  265. return $collect;
  266. }
  267. public function getOwnerByCode($code){
  268. return Cache::remember("getOwnerByCode_{$code}", config('cache.expirations.owners'), function ()use($code){
  269. $owner = Owner::query()->where('code',$code)->first();
  270. if($owner) return $owner;
  271. $basCustomer = app('OracleBasCustomerService')->first(['Customer_Type'=>'OW','CustomerID'=>$code]);
  272. if(!$basCustomer)return null;
  273. if($basCustomer && $basCustomer['active_flag']=='Y') return Owner::query()
  274. ->create(['name'=>$basCustomer['descr_c'],'code'=>$basCustomer['customerid']]);
  275. $deleted_at=Carbon::now()->toDateTimeString();
  276. if($basCustomer && $basCustomer['active_flag']=='N') return Owner::query()
  277. ->create(['name'=>$basCustomer['descr_c'],'code'=>$basCustomer['customerid'],'deleted_at'=>$deleted_at]);
  278. });
  279. }
  280. public function codeGetOwner($code)
  281. {
  282. return app(CacheService::class)->getOrExecute("owner_".$code,function ()use($code){
  283. return Owner::query()->firstOrCreate(["code"=>$code],["code"=>$code,"name"=>$code]);
  284. });
  285. }
  286. /**
  287. * 向FLUX同步推送WAS本地录入信息
  288. *
  289. * @param array|Owner|integer $owner
  290. * @return bool
  291. */
  292. public function syncPush($owner)
  293. {
  294. if (is_array($owner)){
  295. $owner = new Owner();
  296. foreach ($owner as $column=>$value){
  297. $owner[$column] = $value;
  298. }
  299. }
  300. if (is_numeric($owner)){
  301. $owner = Owner::query()->find($owner);
  302. if (!$owner)return false;
  303. }
  304. $wms = DB::connection("oracle")->selectOne(DB::raw("SELECT CUSTOMERID FROM BAS_CUSTOMER WHERE CUSTOMER_TYPE = ? AND CUSTOMERID = ?"),["OW",$owner->code]);
  305. if (!$wms && $owner->code){
  306. $query = DB::raw(<<<sql
  307. INSERT INTO BAS_CUSTOMER(CUSTOMERID,CUSTOMER_TYPE,DESCR_C,ADDTIME,EDITTIME,ADDWHO)
  308. VALUES(?,?,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?)
  309. sql
  310. );
  311. $date = date('Y-m-d H:i:s');
  312. DB::connection("oracle")->insert($query,[$owner->code,'OW',$owner->name,$date,$date,'WAS-'.(Auth::user() ? Auth::user()['name'] : 'SYSTEM')]);
  313. }
  314. return true;
  315. }
  316. public function syncUpdate($owner)
  317. {
  318. if (is_array($owner)){
  319. $owner = new Owner();
  320. foreach ($owner as $column=>$value){
  321. $owner[$column] = $value;
  322. }
  323. }
  324. if (is_numeric($owner)){
  325. $owner = Owner::query()->find($owner);
  326. if (!$owner)return false;
  327. }
  328. $sql = DB::raw(<<<sql
  329. update BAS_CUSTOMER set ACTIVE_FLAG = ?,EDITTIME = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),EDITWHO = ? where CUSTOMERID = ? and CUSTOMER_TYPE = ?
  330. sql
  331. );
  332. $date = date('Y-m-d H:i:s');
  333. if ($owner && $owner->deleted_at){
  334. DB::connection("oracle")->update($sql,['N',$date,'WAS-'.(Auth::user() ? Auth::user()['name'] : 'SYSTEM'),$owner->code,'OW']);
  335. }
  336. if ($owner && $owner->deleted_at==null) {
  337. DB::connection("oracle")->update($sql,['Y',$date,'WAS-'.(Auth::user() ? Auth::user()['name'] : 'SYSTEM'),$owner->code,'OW']);
  338. }
  339. return true;
  340. }
  341. /**
  342. * 同步货主时创建权限
  343. *
  344. * @param array|Owner $owner
  345. */
  346. public function createAuthority($owner)
  347. {
  348. Authority::query()->create([
  349. 'name' => "_{$owner['id']}",
  350. 'alias_name' => "(货主:{$owner['name']})",
  351. 'remark' => "(key: _{$owner['id']})",
  352. ]);
  353. }
  354. /**
  355. * 停用货主时删除权限
  356. *
  357. * @param array|Owner $owner
  358. */
  359. public function deleteAuthority($owner)
  360. {
  361. $authorities = Authority::query()->where('name',"_{$owner['id']}")
  362. ->where("alias_name","like","(货主%")
  363. ->get(["id"]);
  364. $ids = array_column($authorities->toArray(),"id");
  365. DB::table("authority_role")->whereIn("id_authority",$ids)->delete();
  366. Authority::destroy($ids);
  367. }
  368. /**
  369. * 计费模型变动时更新货主中关联属性
  370. *
  371. * @param integer $ownerId
  372. *
  373. */
  374. public function refreshRelevance($ownerId)
  375. {
  376. $relevance = [];
  377. $sql = <<<sql
  378. SELECT 1 FROM owner_storage_price_models a
  379. LEFT JOIN owner_storage_price_model_owner b ON a.id = b.owner_storage_price_model_id
  380. LEFT JOIN owners c ON b.owner_id = c.id
  381. WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
  382. sql;
  383. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 0;
  384. $sql = <<<sql
  385. SELECT 1 FROM owner_price_operations a
  386. LEFT JOIN owner_price_operation_owner b ON a.id = b.owner_price_operation_id
  387. LEFT JOIN owners c ON b.owner_id = c.id
  388. WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
  389. sql;
  390. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 1;
  391. $sql = <<<sql
  392. SELECT 1 FROM owner_price_expresses a
  393. LEFT JOIN owner_price_express_owner b ON a.id = b.owner_price_express_id
  394. LEFT JOIN owners c ON b.owner_id = c.id
  395. WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
  396. sql;
  397. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 2;
  398. $sql = <<<sql
  399. SELECT 1 FROM owner_price_logistics a
  400. LEFT JOIN owner_price_logistic_owner b ON a.id = b.owner_price_logistic_id
  401. LEFT JOIN owners c ON b.owner_id = c.id
  402. WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
  403. sql;
  404. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 3;
  405. $sql = <<<sql
  406. SELECT 1 FROM owner_price_direct_logistics a
  407. LEFT JOIN owner_price_direct_logistic_owner b ON a.id = b.owner_price_direct_logistic_id
  408. LEFT JOIN owners c ON b.owner_id = c.id
  409. WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
  410. sql;
  411. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 4;
  412. $sql = <<<sql
  413. SELECT 1 FROM owner_price_systems a LEFT JOIN owners b ON a.owner_id = b.id
  414. WHERE b.id = ? LIMIT 1
  415. sql;
  416. if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 5;
  417. Owner::query()->where("id",$ownerId)->update(["relevance"=>$relevance]);
  418. }
  419. /**
  420. * 税率变更时附加税率
  421. *
  422. * @param Owner|\stdClass $owner
  423. */
  424. public function attachTaxRate(Owner $owner)
  425. {
  426. OwnerStoragePriceModel::query()->whereHas("owners",function (Builder $query)use($owner){
  427. $query->where("id",$owner->id);
  428. })->whereNull("tax_rate_id")->update(["tax_rate_id"=>$owner->tax_rate_id]);
  429. OwnerPriceOperation::query()->whereHas("owners",function (Builder $query)use($owner){
  430. $query->where("id",$owner->id);
  431. })->whereNull("tax_rate_id")->update(["tax_rate_id"=>$owner->tax_rate_id]);
  432. OwnerPriceExpress::query()->whereHas("owners",function (Builder $query)use($owner){
  433. $query->where("id",$owner->id);
  434. })->whereNull("tax_rate_id")->update(["tax_rate_id"=>$owner->tax_rate_id]);
  435. OwnerPriceLogistic::query()->whereHas("owners",function (Builder $query)use($owner){
  436. $query->where("id",$owner->id);
  437. })->whereNull("tax_rate_id")->update(["tax_rate_id"=>$owner->tax_rate_id]);
  438. OwnerPriceDirectLogistic::query()->whereHas("owners",function (Builder $query)use($owner){
  439. $query->where("id",$owner->id);
  440. })->whereNull("tax_rate_id")->update(["tax_rate_id"=>$owner->tax_rate_id]);
  441. OwnerPriceSystem::query()->where("owner_id",$owner->id)->whereNull("tax_rate_id")
  442. ->update(["tax_rate_id"=>$owner->tax_rate_id]);
  443. }
  444. /**
  445. * 税率变更时取消税率
  446. *
  447. * @param Owner|\stdClass $owner
  448. */
  449. public function removeTaxRate(Owner $owner)
  450. {
  451. OwnerStoragePriceModel::query()->whereHas("owners",function (Builder $query)use($owner){
  452. $query->where("id",$owner->id);
  453. })->update(["tax_rate_id"=>null]);
  454. OwnerPriceOperation::query()->whereHas("owners",function (Builder $query)use($owner){
  455. $query->where("id",$owner->id);
  456. })->update(["tax_rate_id"=>null]);
  457. OwnerPriceExpress::query()->whereHas("owners",function (Builder $query)use($owner){
  458. $query->where("id",$owner->id);
  459. })->update(["tax_rate_id"=>null]);
  460. OwnerPriceLogistic::query()->whereHas("owners",function (Builder $query)use($owner){
  461. $query->where("id",$owner->id);
  462. })->update(["tax_rate_id"=>null]);
  463. OwnerPriceDirectLogistic::query()->whereHas("owners",function (Builder $query)use($owner){
  464. $query->where("id",$owner->id);
  465. })->update(["tax_rate_id"=>null]);
  466. OwnerPriceSystem::query()->where("owner_id",$owner->id)
  467. ->update(["tax_rate_id"=>null]);
  468. }
  469. /**
  470. * 获取税率 或 税费
  471. *
  472. * @param Model|\stdClass $model
  473. * @param int $ownerId
  474. * @param float|null $money
  475. *
  476. * @return float|null
  477. */
  478. public function getTaxRateFee(Model $model, int $ownerId, ?float $money = null):?float
  479. {
  480. $taxRate = null;
  481. if ($model->tax_rate_id){
  482. $model->loadMissing("taxRate");
  483. $taxRate = $model->taxRate;
  484. }
  485. if (!$taxRate){
  486. /** @var Model|\stdClass $owner */
  487. $owner = new Owner();
  488. $owner->id = $ownerId;
  489. $owner->load("taxRate");
  490. $taxRate = $owner->taxRate;
  491. }
  492. if (!$taxRate)return null;
  493. if ($money===null)return $taxRate->value;
  494. return $money*($taxRate->value/100);
  495. }
  496. public function changeManualBackStatus($id,$isManual)
  497. {
  498. $owner=Owner::query()->find($id);
  499. if ($isManual==0)$owner->update(['is_manual_back'=>1]);
  500. else $owner->update(['is_manual_back'=>0]);
  501. return $owner;
  502. }
  503. public function changeIntervalTime($id,$intervalTime)
  504. {
  505. $owner=Owner::query()->find($id);
  506. $owner->update(['interval_time'=>$intervalTime]);
  507. return $owner;
  508. }
  509. }