CheckService.php 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664
  1. <?php
  2. namespace App\Service;
  3. use App\Model\Construction;
  4. use App\Model\ConstructionProductInfo;
  5. use App\Model\Customer;
  6. use App\Model\Depart;
  7. use App\Model\Employee;
  8. use App\Model\InOutRecord;
  9. use App\Model\InvoiceOrder;
  10. use App\Model\InvoiceOrderInfo;
  11. use App\Model\OrderOperation;
  12. use App\Model\PaymentReceipt;
  13. use App\Model\PaymentReceiptInfo;
  14. use App\Model\ProductInventory;
  15. use App\Model\ProductInventorySet;
  16. use App\Model\PurchaseOrder;
  17. use App\Model\PurchaseOrderInfo;
  18. use App\Model\PurchaseOrderSpecial;
  19. use App\Model\PurchaseOrderSpecialInfo;
  20. use App\Model\ReturnExchangeOrder;
  21. use App\Model\ReturnExchangeOrderProductInfo;
  22. use App\Model\SalesOrder;
  23. use App\Model\SalesOrderInfo;
  24. use App\Model\SalesOrderOtherFee;
  25. use App\Model\SalesOrderProductInfo;
  26. use App\Model\SeeRange;
  27. use App\Model\SportsBag;
  28. use App\Model\Storehouse;
  29. use App\Model\Supplier;
  30. use App\Service\OaService;
  31. use Illuminate\Support\Facades\DB;
  32. class CheckService extends Service
  33. {
  34. //特殊操作数
  35. const minus_one = -1;//跳出库存流水
  36. //审批操作对应的数值
  37. const one = 1; //收货
  38. const two = 2; //发货
  39. const three = 3; //采购单入库
  40. const four = 4; //合同公司完结
  41. const five = 5; //施工单
  42. const six = 6; //退换货单
  43. const seven = 7; //采购单确认
  44. const eight = 8; //合同确认
  45. const nine = 9; //合同客户完结
  46. const ten = 10; //收付款确认
  47. const eve = 11; //接受派单
  48. const twl = 12; //活动包
  49. //中文对照
  50. public $map = [
  51. self::one => '收货单',
  52. self::two => '发货单',//确认后出库
  53. self::three => '采购单入库',//确认后入库
  54. self::four => '公司完结', // 安装件 合同完结
  55. self::five => '施工单',//确认后出库
  56. self::six => '退换货单',//确认后出库或出库入库
  57. self::seven => '采购单确认',
  58. self::eight => '合同确认',
  59. self::nine => '合同客户完结',
  60. self::ten => '收付款确认',
  61. self::eve => '接受门店派单',
  62. self::twl => '活动包',
  63. ];
  64. //入库操作
  65. public static $in_opt = [
  66. self::three,
  67. ];
  68. //出库操作
  69. public static $out_opt = [
  70. self::two,
  71. self::five,
  72. ];
  73. const TYPE_ONE = 1;//通过
  74. const TYPE_TWO = 2;//不通过
  75. const TYPE_THREE = 3;//通过后驳回
  76. //改为待审核状态 校验
  77. public static $opt_1case_check = [
  78. self::five => 'checkConstruction',//施工单
  79. ];
  80. //改为待审核状态
  81. public static $opt_1case = [
  82. self::two => 'waitInvoice',//发货单
  83. // self::three => 'waitPurchase',//采购单 入库
  84. self::five => 'waitConstruction',//施工单
  85. self::six => 'waitReturnExchange',//退换货单
  86. self::seven => 'waitPurchaseConfirm', //采购单确认
  87. self::eight => 'waitSales', // 合同安装件 合同确认
  88. self::ten => 'waitPaymentReceipt', //收付款确认
  89. self::twl => 'waitSportsBag', //活动包确认
  90. ];
  91. public static $finished = [
  92. self::three => 'confirmPurchaseOrder',//采购单 入库
  93. self::four => 'settleSalesOrder', // 合同 安装件 合同公司完结
  94. self::nine => 'settleSalesOrderCustomer', // 合同 安装件 合同客户完结
  95. self::eve => 'settleSalesOrderConfirm', // 合同 安装件 合同接收
  96. ];
  97. //单据操作
  98. public static $opt_case = [
  99. self::two => 'confirmInvoiceOrder',
  100. // self::three => 'confirmPurchaseOrder',
  101. self::five => 'confirmConstruction',
  102. self::six => 'confirmReturnExchangeOrder',
  103. self::seven => 'confirmPurchaseOrderState',
  104. self::eight => 'confirmSales', // 合同 安装件 合同确认
  105. self::ten => 'confirmPaymentReceipt', // 确认收付款单
  106. self::twl => 'confirmSportsBag', // 确认活动包
  107. ];
  108. //单据库存流水
  109. public static $record = [
  110. self::two => 'recordInvoiceOrder',
  111. self::three => 'recordPurchaseOrder',
  112. self::five => 'recordConstruction',
  113. self::six => 'recordReturnExchangeOrder'
  114. ];
  115. //自动生成
  116. public static $create = [
  117. self::seven => 'createPurchaseOrderSales', //分社合同生成
  118. self::four => 'createPurchaseOrder', // 派给分社的合同 公司完结以后生成虚拟采购单
  119. ];
  120. //自动生成的删除
  121. public static $create_del = [
  122. self::seven => 'delCreatePurchaseOrderSales', //分社合同生成(删除)
  123. // self::four => 'delCreatePurchaseOrder', // 派给分社的合同确认以后生成虚拟采购单
  124. ];
  125. //审核通过后 弃审
  126. public static $opt_case_reject = [
  127. self::four => 'reject_sales', // 合同
  128. // self::three => 'reject_purchase', //采购入库
  129. self::seven => 'reject_purchase_confirm', //采购确认驳回
  130. self::five => 'reject_construction',//施工单
  131. self::six => 'reject_return_exchange',//退换货
  132. self::ten => 'reject_payment_receipt',//收付款单
  133. self::twl => 'reject_sports_bag',//活动包
  134. ];
  135. //审核通过后 驳回 产生流水
  136. public static $reject_record = [
  137. self::five => 'reject_record_construction', //施工单驳回
  138. self::three => 'reject_record_purchase', //采购
  139. self::six => 'reject_record_return_exchange',//退换货
  140. ];
  141. //旅程日志 同意
  142. public static $operation_order = [
  143. self::eight => OrderOperation::three, //合同确认
  144. self::two => OrderOperation::eight, //发货单确认
  145. self::six => OrderOperation::nine, //退换货审核
  146. self::five => OrderOperation::eve, //施工单
  147. self::seven => OrderOperation::thi,//采购单确认
  148. self::three => OrderOperation::fourteen,//采购单入库
  149. self::ten => OrderOperation::twenty_one,//收付款单
  150. self::twl => OrderOperation::twenty_one,//收付款单
  151. ];
  152. //旅程日志 驳回
  153. public static $operation_order_reject = [
  154. self::four => OrderOperation::four, //合同弃审
  155. self::six => OrderOperation::ten, //退换货弃审
  156. self::five => OrderOperation::twl, //施工单弃审
  157. self::three => OrderOperation::fif,//采购单入库弃审
  158. self::seven => OrderOperation::twenty,//采购单确认弃审
  159. self::ten => OrderOperation::twenty_two,//收付款单
  160. self::twl => OrderOperation::twenty_eight,//活动包
  161. ];
  162. //校验
  163. public function checkConstruction($data, $user){
  164. $order = Construction::where('del_time',0)
  165. ->where('order_number',$data['order_number'])
  166. ->first();
  167. if(empty($order)) return [false,'施工单不存在或已被删除'];
  168. $order = $order->toArray();
  169. //总社id
  170. $head = $user['head'] ?? [];
  171. $head = $head['id'] ?? 0;
  172. //分社自己的施工单 直接返回
  173. if($order['top_depart_id'] != $head) return [true, ''];
  174. //不校验库存
  175. if($user['is_check_stock'] == ProductInventorySet::type_two) return [true,''];
  176. //施工单产品
  177. $sub = ConstructionProductInfo::where('construction_id',$order['id'])
  178. ->where('del_time',0)
  179. ->get()->toArray();
  180. if(empty($sub)) return [false,'施工单产品不存在或已被删除'];
  181. $product_submit = $product_id = [];
  182. foreach ($sub as $value){
  183. $product_id[] = $value['product_id'];
  184. $key = $value['product_id'] . ',' . $value['storehouse_id'];
  185. if(isset($product_save[$key])){
  186. $product_submit[$key] += $value['number'];
  187. }else{
  188. $product_submit[$key] = $value['number'];
  189. }
  190. }
  191. //比较库存
  192. list($status,$msg) = (new ProductInventoryService())->compareStock($user,$product_id, $product_submit, []);
  193. if(! $status) return [false, $msg];
  194. //锁定库存
  195. ProductInventoryService::changeLockNumber($user,$product_submit);
  196. return [true, ''];
  197. }
  198. //改为待审核---------------------------------
  199. public function waitInvoice($data){
  200. $model = InvoiceOrder::where('id',$data['id'])
  201. ->where('del_time',0)
  202. ->first();
  203. if(empty($model)) return [false, '发货单不存在或已被删除'];
  204. if($model->state != InvoiceOrder::STATE_ZERO) return [false, '请确认发货单状态,操作失败'];
  205. InvoiceOrder::where('del_time',0)->where('id',$data['id'])
  206. ->update(['state' => InvoiceOrder::STATE_ONE]);
  207. return [true, $model->toArray()];
  208. }
  209. public function waitPurchaseConfirm($data){
  210. $model = PurchaseOrder::where('id',$data['id'])
  211. ->where('del_time',0)
  212. ->first();
  213. if(empty($model)) return [false,'采购单不存在或已被删除'];
  214. if(! in_array($model->state, [PurchaseOrder::State_minus_one,PurchaseOrder::STATE_ZERO])) return [false, '请确认采购单状态,操作失败'];
  215. //待确认
  216. PurchaseOrder::where('id',$data['id'])->update(['state' => PurchaseOrder::STATE_ONE]);
  217. return [true, $model->toArray()];
  218. }
  219. public function waitPurchase($data){
  220. $model = PurchaseOrder::where('id',$data['id'])
  221. ->where('del_time',0)
  222. ->first();
  223. if(empty($model)) return [false, '采购订单不存在或已被删除'];
  224. if($model->state != PurchaseOrder::STATE_TWO) return [false, '请确认采购订单状态,操作失败'];
  225. //待入库
  226. PurchaseOrder::where('del_time',0)->where('id',$data['id'])
  227. ->update(['state' => PurchaseOrder::STATE_Three]);
  228. return [true, $model->toArray()];
  229. }
  230. public function waitConstruction($data){
  231. $model = Construction::where('id',$data['id'])
  232. ->where('del_time',0)
  233. ->first();
  234. if(empty($model)) return [false, '施工单不存在或已被删除'];
  235. if(! in_array($model->state, [Construction::State_minus_one,Construction::STATE_ZERO])) return [false, '请确认施工单状态,操作失败'];
  236. //待确认
  237. Construction::where('del_time',0)->where('id',$data['id'])
  238. ->update(['state' => Construction::STATE_ONE]);
  239. return [true, $model->toArray()];
  240. }
  241. public function waitReturnExchange($data){
  242. $model = ReturnExchangeOrder::where('id',$data['id'])
  243. ->where('del_time',0)
  244. ->first();
  245. if(empty($model)) return [false, '退换货单不存在或已被删除'];
  246. if(! in_array($model->state, [ReturnExchangeOrder::State_minus_one,ReturnExchangeOrder::State_zero])) return [false, '请确认退换货单状态,操作失败'];
  247. //待确认
  248. ReturnExchangeOrder::where('del_time',0)->where('id',$data['id'])
  249. ->update(['state' => ReturnExchangeOrder::State_one]);
  250. return [true, $model->toArray()];
  251. }
  252. public function waitSales($data){
  253. $model = SalesOrder::where('id', $data['id'])
  254. ->where('del_time',0)
  255. ->first();
  256. if(empty($model)) return [false, '合同不存在或已被删除'];
  257. //安装件
  258. if(! in_array($model->state, [SalesOrder::State_minus_one,SalesOrder::State_zero])) return [false, '请确认合同状态,操作失败'];
  259. SalesOrder::where('del_time',0)->where('id',$data['id'])
  260. ->update(['state' => SalesOrder::State_one]);
  261. return [true, $model->toArray()];
  262. }
  263. public function waitPaymentReceipt($data){
  264. $model = PaymentReceipt::where('id', $data['id'])
  265. ->where('del_time',0)
  266. ->first();
  267. if(empty($model)) return [false, '收付款单不存在或已被删除'];
  268. if(! in_array($model->state, [PaymentReceipt::State_minus_one,PaymentReceipt::STATE_ZERO])) return [false, '请确认收付款单状态,操作失败'];
  269. PaymentReceipt::where('del_time',0)->where('id',$data['id'])
  270. ->update(['state' => PaymentReceipt::STATE_ONE]);
  271. return [true, $model->toArray()];
  272. }
  273. public function waitSportsBag($data){
  274. $model = SportsBag::where('id', $data['id'])
  275. ->where('del_time',0)
  276. ->first();
  277. if(empty($model)) return [false, '活动包不存在或已被删除'];
  278. if(! in_array($model->state, [SportsBag::State_minus_one,SportsBag::STATE_ZERO])) return [false, '请确认活动包状态,操作失败'];
  279. SportsBag::where('del_time',0)->where('id',$data['id'])
  280. ->update(['state' => PaymentReceipt::STATE_ONE]);
  281. return [true, $model->toArray()];
  282. }
  283. //改为待审核---------------------------------
  284. //自动生成-----------------------------------
  285. //总社派给分社的合同 完成生成虚拟采购单
  286. public function createPurchaseOrder($order,$user){
  287. //快递件
  288. if($order['sales_order_type'] == SalesOrder::Order_type_two) return [true,''];
  289. //不是总公司的合同
  290. $head = $user['head'] ?? [];
  291. $head = $head['id'] ?? 0; //总社id
  292. if($head != $order['top_depart_id']) return [true, ''];
  293. $see = SeeRange::where('del_time',0)
  294. ->where('data_id',$order['id'])
  295. ->where('data_type',SeeRange::type_seven)
  296. ->where('type',SeeRange::data_three)
  297. ->first();
  298. if(empty($see)) return [false, '未找到指派分社信息'];
  299. $depart_id = $see->param_id;//指派的分社
  300. //总社指派给自己
  301. if($depart_id == $head) return [true, ''];
  302. //获取指派分社时候的金额
  303. $fee = SalesOrderOtherFee::where('del_time',0)
  304. ->where('sales_order_id',$order['id'])
  305. ->first();
  306. if(empty($fee)) return [false, '未找到指派分社时填写的金额'];
  307. $fee = $fee->toArray();
  308. $order_number = (new OrderNoService())->createOrderNumber(PurchaseOrderSpecial::prefix);
  309. $storehouse = Storehouse::where('depart_id',$head)->value('id');
  310. $product = SalesOrderProductInfo::where('del_time',0)
  311. ->where('sales_order_id',$order['id'])
  312. ->select('product_id','number','retail_price')
  313. ->get()->toArray();
  314. $product_map = $rate = [];
  315. $total = 0;
  316. foreach ($product as $value){
  317. $total += $value['number'] * $value['retail_price'];
  318. if(isset($product_map[$value['product_id']])){
  319. $product_map[$value['product_id']] += $value['retail_price'] * $value['number'];
  320. }else{
  321. $product_map[$value['product_id']] = $value['retail_price'] * $value['number'];
  322. }
  323. }
  324. foreach ($product_map as $key => $value){
  325. $rate[$key] = bcdiv($value / $total, 2);
  326. }
  327. try {
  328. DB::beginTransaction();
  329. $model = new PurchaseOrderSpecial();
  330. $model->order_number = $order_number;
  331. $model->sales_order_id = $order['id'];
  332. $model->supplier = $depart_id;
  333. $model->type = $order['type'];
  334. $model->depart_id = $head;
  335. $model->top_depart_id = $head;
  336. $model->crt_id = Employee::SPECIAL_ADMIN;
  337. $model->purchase_id = Employee::SPECIAL_ADMIN;
  338. $model->purchase_total = $fee['other_fee_1'] ?? 0;
  339. $model->storehouse_id = $storehouse ?? 0;
  340. $model->save();
  341. if(empty($model->id)) return [false,'采购单主信息生成失败'];
  342. $purchase_order_id = $model->id;
  343. $insert = [];$product_total = 0;
  344. foreach ($product as $value){
  345. $rate_tmp = $rate[$value['product_id']] ?? 0;
  346. $price = bcdiv(bcmul($rate_tmp, $fee['other_fee_1'],2),$value['number'],2);
  347. $product_total += $price * $value['number'];
  348. $insert[] = [
  349. 'purchase_order_special_id' => $purchase_order_id,
  350. 'product_id' => $value['product_id'],
  351. 'order_number' => $order_number,
  352. 'number' => $value['number'],
  353. 'price' => $price,
  354. 'storehouse_id' => $storehouse,
  355. ];
  356. }
  357. PurchaseOrderSpecialInfo::insert($insert);
  358. PurchaseOrderSpecial::where('id',$purchase_order_id)->update(['total' => $product_total]);
  359. DB::commit();
  360. }catch (\Throwable $exception){
  361. DB::rollBack();
  362. if (str_contains($exception->getMessage(), '1062') || str_contains($exception->getMessage(), 'Duplicate entry')) {
  363. return [false, '网络波动,请重新操作!'];
  364. }
  365. return [false, $exception->getMessage()];
  366. }
  367. return [true, ''];
  368. }
  369. //分社向总社采购 生成 分社订货合同
  370. public function createPurchaseOrderSales($order,$user){
  371. //没有供应商 不创建合同
  372. if(empty($order['supplier'])) return [true, ''];
  373. //总公司的采购单 不创建合同
  374. $head = $user['head'] ?? [];
  375. $head = $head['id'] ?? 0; //总社id
  376. if($head == $order['top_depart_id']) return [true, ''];
  377. //分社公司的采购单 不向总供应商采购 不创建合同
  378. $is_create = Supplier::where('id',$order['supplier'])->value('is_main');
  379. if(empty($is_create)) return [true, ''];
  380. // $customer_short_name = Depart::where('id',$order['top_depart_id'])->value('id') ?? "";
  381. $prefix = SalesOrder::$prefix[SalesOrder::Model_type_two];
  382. $order_number = OrderNoService::createSalesOrderNumber($prefix);
  383. $product = PurchaseOrderInfo::where('del_time',0)
  384. ->where('purchase_order_id',$order['id'])
  385. ->get()->toArray();
  386. if(empty($product)) return [false, '采购订单产品数据不能为空'];
  387. try{
  388. DB::beginTransaction();
  389. $time = time();
  390. $model = new SalesOrder();
  391. $model->model_type = SalesOrder::Model_type_two;
  392. $model->sales_order_type = SalesOrder::Order_type_two;
  393. $model->customer_id = Customer::special_id;
  394. $model->order_number = $order_number;
  395. $model->crt_id = $order['crt_id'];
  396. $model->depart_id = $head;
  397. $model->top_depart_id = $head;
  398. $model->other_fee = $order['other_fee'];
  399. $model->discount_fee = $order['discount_fee'];
  400. $model->contract_fee = $order['purchase_total'];
  401. $model->contact_order_no = $order['order_number'];
  402. $model->sign_time = $time;
  403. $model->save();
  404. $sales_order_id = $model->id;
  405. //产品字典
  406. $product_map = (new ProductService())->getProductDetail(array_column($product,'product_id'));
  407. $insert = [];
  408. $product_total = 0;
  409. foreach ($product as $value){
  410. $tmp = $product_map[$value['product_id']] ?? [];
  411. $product_total += $value['price'] * $value['number'];
  412. $insert[] = [
  413. 'sales_order_id' => $sales_order_id,
  414. 'product_id' => $value['product_id'],
  415. 'number' => $value['number'],
  416. 'basic_type_id' => $value['basic_type_id'],
  417. 'price' => $value['price'],
  418. 'cost' => $tmp['cost'] ?? 0,
  419. 'retail_price' => $tmp['retail_price'] ?? 0,
  420. 'final_amount' => $value['price'] * $value['number'],
  421. ];
  422. }
  423. $bool = SalesOrderProductInfo::insert($insert);
  424. if(! $bool) return [false,'合同生成失败!'];
  425. //反写数据
  426. $tmp = $product_total + $order['other_fee'];
  427. $tmp = $tmp > 0 ? $tmp : 1;
  428. $rate = ($product_total + $order['other_fee'] - $order['discount_fee']) / $tmp;
  429. SalesOrder::where('id',$sales_order_id)->update([
  430. 'product_total' => $product_total,
  431. 'rate' => $rate
  432. ]);
  433. //生成付款单
  434. $model = new PaymentReceipt();
  435. $model->order_number = (new OrderNoService())->createOrderNumber(PaymentReceipt::prefix);
  436. $model->data_type = PaymentReceipt::data_type_one;
  437. $model->type = PaymentReceipt::type_one;
  438. $model->crt_id = $user['id'];
  439. $model->depart_id = $head;
  440. $model->top_depart_id = $head;
  441. $model->save();
  442. $insert = [];
  443. $insert[] = [
  444. 'payment_receipt_id' => $model->id,
  445. 'data_type' => PaymentReceipt::type_one,
  446. 'data_order_no' => $order_number,
  447. 'data_order_type' => PaymentReceipt::data_type_one,
  448. 'amount' => $order['purchase_total'],
  449. 'type' => PaymentReceiptInfo::type_three,
  450. 'crt_time' => $time,
  451. ];
  452. PaymentReceiptInfo::insert($insert);
  453. DB::commit();
  454. }catch (\Throwable $exception){
  455. DB::rollBack();
  456. if (str_contains($exception->getMessage(), '1062') || str_contains($exception->getMessage(), 'Duplicate entry')) {
  457. return [false, '网络波动,请重新操作!'];
  458. }
  459. return [false ,$exception->getMessage()];
  460. }
  461. return [true,''];
  462. }
  463. //自动生成-----------------------------------
  464. //自动生成删除
  465. //分社订货合同删除
  466. public function delCreatePurchaseOrderSales($data, $order){
  467. $sale_order = SalesOrder::where('del_time',0)
  468. ->where('contact_order_no',$order['order_number'])
  469. ->select('id','order_number')
  470. ->get()->toArray();
  471. if(empty($sale_order)) return [true,''];
  472. foreach ($sale_order as $value){
  473. list($status, $msg) = (new SalesOrderService())->salesOrderDel(['id' => $value['id']]);
  474. if(! $status) return [false,$msg];
  475. list($status, $msg) = (new PaymentReceiptService())->customerDel(['id' => $value['id']]);
  476. if(! $status) return [false,$msg];
  477. }
  478. return [true, ''];
  479. }
  480. //自动生成删除
  481. public function confirmSportsBag($data){
  482. $model = SportsBag::where('order_number',$data['order_number'])
  483. ->where('del_time',0)
  484. ->first();
  485. if(empty($model)) return [false, '活动包不存在或已被删除'];
  486. if($model->state != SportsBag::STATE_ONE) return [false, '请确认活动包状态,操作失败'];
  487. if($data['type'] == self::TYPE_ONE){
  488. //通过
  489. $model->state = SportsBag::STATE_TWO;
  490. $model->save();
  491. }else{
  492. //驳回
  493. $model->state = SportsBag::State_minus_one;
  494. $model->save();
  495. }
  496. return [true, $model->toArray()];
  497. }
  498. public function confirmPaymentReceipt($data){
  499. $model = PaymentReceipt::where('order_number',$data['order_number'])
  500. ->where('del_time',0)
  501. ->first();
  502. if(empty($model)) return [false, '收付款单不存在或已被删除'];
  503. if($model->state != PaymentReceipt::STATE_ONE) return [false, '请确认收付款单状态,操作失败'];
  504. if($data['type'] == self::TYPE_ONE){
  505. //通过
  506. $model->state = PaymentReceipt::STATE_TWO;
  507. $model->save();
  508. }else{
  509. //驳回
  510. $model->state = PaymentReceipt::State_minus_one;
  511. $model->save();
  512. }
  513. return [true, $model->toArray()];
  514. }
  515. public function confirmInvoiceOrder($data){
  516. $model = InvoiceOrder::where('order_number',$data['order_number'])
  517. ->where('del_time',0)
  518. ->first();
  519. if(empty($model)) return [false, '发货单不存在或已被删除'];
  520. if($model->state != InvoiceOrder::STATE_ONE) return [false, '请确认发货单状态,操作失败'];
  521. if($data['type'] == self::TYPE_ONE){
  522. //通过
  523. $model->state = InvoiceOrder::STATE_TWO;
  524. $model->save();
  525. $sale = SalesOrder::where('id',$model->sales_order_id)->first();
  526. if($sale['sales_order_type'] == SalesOrder::Order_type_one){
  527. //安装件更新发货状态
  528. SalesOrder::where('id',$model->sales_order_id)
  529. ->update(['invoice_state' => SalesOrder::invoice_one]);
  530. }else{
  531. //快递件更新 单据状态 发货状态
  532. SalesOrder::where('id',$model->sales_order_id)
  533. ->update([
  534. 'state' => SalesOrder::State2_one,
  535. 'invoice_state' => SalesOrder::invoice_one
  536. ]);
  537. }
  538. //分社采购单更新发货状态
  539. if(! empty($sale->contact_order_no)) PurchaseOrder::where('order_number',$sale->contact_order_no)->update(['invoice_state' => PurchaseOrder::invoice_state_one]);
  540. }else{
  541. //驳回
  542. $model->state = InvoiceOrder::STATE_ZERO;
  543. $model->save();
  544. }
  545. return [true, $model->toArray()];
  546. }
  547. public function recordInvoiceOrder($data, $order){
  548. $result = InvoiceOrderInfo::where('del_time',0)
  549. ->where('order_number',$order['order_number'])
  550. ->get()->toArray();
  551. if(empty($result)) return [false,'发货单产品信息不存在或已被删除'];
  552. $insert = [];
  553. $time = time();
  554. foreach ($result as $value){
  555. $key = $value['product_id'] . $value['storehouse_id'];
  556. if(isset($insert[$key])){
  557. $insert[$key]['number'] += -($value['number']);
  558. }else{
  559. $insert[$key] = [
  560. 'product_id' => $value['product_id'],
  561. 'number' => -($value['number']),
  562. 'order_type' => InvoiceOrder::prefix,
  563. 'order_number' => $order['order_number'],
  564. 'crt_time' => $time,
  565. 'storehouse_id' => $value['storehouse_id'],
  566. 'depart_id' => $order['depart_id'],
  567. 'top_depart_id' => $order['top_depart_id'],
  568. 'price' => $value['price'],
  569. ];
  570. }
  571. }
  572. $insert = array_values($insert);
  573. $bool = InOutRecord::insert($insert);
  574. if(! $bool) return [false,'流水写入失败'];
  575. return [true,''];
  576. }
  577. public function confirmPurchaseOrderState($data){
  578. $model = PurchaseOrder::where('order_number',$data['order_number'])
  579. ->where('del_time',0)
  580. ->first();
  581. if(empty($model)) return [false,'采购单不存在或已被删除'];
  582. if($model->state != PurchaseOrder::STATE_ONE) return [false,'请确认采购单状态,操作失败'];
  583. if($data['type'] == self::TYPE_ONE){
  584. $model->state = PurchaseOrder::STATE_TWO;
  585. $model->save();
  586. }else{
  587. //驳回
  588. $model->state = PurchaseOrder::State_minus_one;
  589. $model->save();
  590. }
  591. return [true, $model->toArray()];
  592. }
  593. public function confirmPurchaseOrder($data,$user){
  594. $model = PurchaseOrder::where('order_number',$data['order_number'])
  595. ->where('del_time',0)
  596. ->first();
  597. if(empty($model)) return [false, '采购订单不存在或已被删除'];
  598. if($model->state != PurchaseOrder::STATE_TWO) return [false, '请确认采购订单状态,操作失败'];
  599. $model->state = PurchaseOrder::STATE_Four;
  600. $model->save();
  601. return [true, $model->toArray()];
  602. }
  603. public function recordPurchaseOrder($data, $order){
  604. $result = PurchaseOrderInfo::where('del_time',0)
  605. ->where('order_number',$order['order_number'])
  606. ->get()->toArray();
  607. if(empty($result)) return [false,'采购单产品信息不存在或已被删除'];
  608. $insert = [];
  609. $time = time();
  610. foreach ($result as $value){
  611. $key = $value['product_id'] . $value['storehouse_id'];
  612. if(isset($insert[$key])){
  613. $insert[$key]['number'] += $value['number'];
  614. }else{
  615. $insert[$key] = [
  616. 'product_id' => $value['product_id'],
  617. 'number' => $value['number'],
  618. 'order_type' => PurchaseOrder::prefix,
  619. 'order_number' => $order['order_number'],
  620. 'crt_time' => $time,
  621. 'storehouse_id' => $value['storehouse_id'],
  622. 'depart_id' => $order['depart_id'],
  623. 'top_depart_id' => $order['top_depart_id'],
  624. 'price' => $value['price'],
  625. ];
  626. }
  627. }
  628. $insert = array_values($insert);
  629. $bool = InOutRecord::insert($insert);
  630. if(! $bool) return [false,'流水写入失败'];
  631. return [true,''];
  632. }
  633. public function confirmConstruction($data){
  634. $model = Construction::where('order_number',$data['order_number'])
  635. ->where('del_time',0)
  636. ->first();
  637. if(empty($model)) return [false, '施工单不存在或已被删除'];
  638. if($model->state != Construction::STATE_ONE) return [false, '请确认施工单状态,操作失败'];
  639. if($data['type'] == self::TYPE_ONE){
  640. $model->state = Construction::STATE_TWO;
  641. $model->save();
  642. //已下施工
  643. SalesOrder::where('id',$model->sales_order_id)->update(['state' => SalesOrder::State_five]);
  644. }else{
  645. //驳回
  646. $model->state = Construction::State_minus_one;
  647. $model->save();
  648. }
  649. return [true, $model->toArray()];
  650. }
  651. public function recordConstruction($data, $order){
  652. //仅施工不需要库存流水
  653. if($order['model_type'] == Construction::Model_type_two) return [true, self::minus_one];
  654. $result = ConstructionProductInfo::where('del_time',0)
  655. ->where('construction_id',$order['id'])
  656. ->get()->toArray();
  657. if(empty($result)) return [false,'施工单产品信息不存在或已被删除'];
  658. $insert = [];
  659. $time = time();
  660. foreach ($result as $value){
  661. $key = $value['product_id'] . $value['storehouse_id'];
  662. if(isset($insert[$key])){
  663. $insert[$key]['number'] += -($value['number']);
  664. }else{
  665. $insert[$key] = [
  666. 'product_id' => $value['product_id'],
  667. 'number' => -($value['number']),
  668. 'order_type' => Construction::$prefix[$order['model_type']] ?? '',
  669. 'order_number' => $order['order_number'],
  670. 'crt_time' => $time,
  671. 'storehouse_id' => $value['storehouse_id'],
  672. 'depart_id' => $order['depart_id'],
  673. 'top_depart_id' => $order['top_depart_id'],
  674. 'price' => $value['price'],
  675. ];
  676. }
  677. }
  678. $insert = array_values($insert);
  679. $bool = InOutRecord::insert($insert);
  680. if(! $bool) return [false,'流水写入失败'];
  681. return [true,''];
  682. }
  683. public function confirmReturnExchangeOrder($data){
  684. $model = ReturnExchangeOrder::where('order_number',$data['order_number'])
  685. ->where('del_time',0)
  686. ->first();
  687. if(empty($model)) return [false, '退换货单不存在或已被删除'];
  688. if($model->state != ReturnExchangeOrder::State_one) return [false, '请确认退换货单状态,操作失败'];
  689. if($data['type'] == self::TYPE_ONE){
  690. $model->state = ReturnExchangeOrder::State_two;
  691. $model->save();
  692. // if($model->data_type == ReturnExchangeOrder::Order_type){
  693. // SalesOrder::where('id', $model->data_id)->update([
  694. // 'state' => SalesOrder::State_six
  695. // ]);
  696. // }
  697. }else{
  698. //驳回
  699. $model->state = ReturnExchangeOrder::State_minus_one;
  700. $model->save();
  701. }
  702. return [true, $model->toArray()];
  703. }
  704. public function recordReturnExchangeOrder($data, $order){
  705. if($order['model_type'] == ReturnExchangeOrder::Model_type_three) return [true, self::minus_one];
  706. // if($order['type'] == ReturnExchangeOrder::Order_type){
  707. // //快递件不记录流水
  708. // $sales_order_type = SalesOrder::where('id',$order['data_id'])->value('sales_order_type');
  709. // if($sales_order_type == SalesOrder::Order_type_two) return [true, self::minus_one];
  710. // }
  711. //合同 退货
  712. $construction_pro = [];
  713. if($order['type'] == ReturnExchangeOrder::Order_type){
  714. //查找合同下 已经下施工的产品
  715. $construction_id = Construction::where('del_time',0)
  716. ->where('sales_order_id', $order['data_id'])
  717. ->select('id')
  718. ->get()->toArray();
  719. $construction_id = array_column($construction_id,'id');
  720. $product = ConstructionProductInfo::where('del_time',0)
  721. ->whereIn('construction_id',$construction_id)
  722. ->select('product_id','number')
  723. ->get()->toArray();
  724. foreach ($product as $value){
  725. if(isset($construction_pro[$value['product_id']])){
  726. $construction_pro[$value['product_id']] += $value['number'];
  727. }else{
  728. $construction_pro[$value['product_id']] = $value['number'];
  729. }
  730. }
  731. }
  732. $result = ReturnExchangeOrderProductInfo::where('del_time',0)
  733. ->where('return_exchange_id',$order['id'])
  734. ->get()->toArray();
  735. if(empty($result)) return [false,'退换货单产品信息不存在或已被删除'];
  736. $insert = [];
  737. $time = time();
  738. foreach ($result as $value){
  739. $key = $value['product_id'] . $value['storehouse_id'];
  740. $prefix = ReturnExchangeOrder::$prefix[$value['return_or_exchange']] ?? '';
  741. if($value['return_or_exchange'] == ReturnExchangeOrderProductInfo::type_one){
  742. //退货
  743. if($order['type'] == ReturnExchangeOrder::Order_type){
  744. //合同
  745. $c_number = $construction_pro[$value['product_id']] ?? 0;
  746. if($c_number == 0) {
  747. //未下施工 这个退货不需要加回来 不需要流水
  748. continue;
  749. }else{
  750. if($c_number >= $value['number']) {
  751. //加回来退货的数据
  752. $number = $value['number'];
  753. }else{
  754. //加回来施工的数量
  755. $number = $c_number;
  756. }
  757. }
  758. }else{
  759. // 采购
  760. $number = -($value['number']);
  761. }
  762. if(isset($insert[$key])){
  763. $insert[$key]['number'] += $number;
  764. }else{
  765. $insert[$key] = [
  766. 'product_id' => $value['product_id'],
  767. 'number' => $number,
  768. 'order_type' => $prefix,
  769. 'order_number' => $order['order_number'],
  770. 'crt_time' => $time,
  771. 'storehouse_id' => $value['storehouse_id'],
  772. 'depart_id' => $order['depart_id'],
  773. 'top_depart_id' => $order['top_depart_id'],
  774. 'price' => $value['return_exchange_price'],
  775. ];
  776. }
  777. }
  778. }
  779. $insert = array_values($insert);
  780. if(empty($insert)) return [true, self::minus_one];
  781. $bool = InOutRecord::insert($insert);
  782. if(! $bool) return [false,'流水写入失败'];
  783. return [true,''];
  784. }
  785. public function settleSalesOrder($data,$user){
  786. $model = SalesOrder::where('order_number', $data['order_number'])
  787. ->where('del_time',0)
  788. ->first();
  789. if(empty($model)) return [false, '合同不存在或已被删除'];
  790. //安装件
  791. if($model->state <= SalesOrder::State_four || $model->state >= SalesOrder::State_seven) return [false, '请确认合同状态,操作失败'];
  792. SalesOrder::where('del_time',0)->where('order_number',$data['order_number'])
  793. ->update(['state' => SalesOrder::State_seven]);
  794. return [true, $model->toArray()];
  795. }
  796. public function settleSalesOrderCustomer($data,$user){
  797. $model = SalesOrder::where('order_number', $data['order_number'])
  798. ->where('del_time',0)
  799. ->first();
  800. if(empty($model)) return [false, '合同不存在或已被删除'];
  801. if(empty($data['img'])) return [false,'图片不能为空'];
  802. //安装件
  803. if($model->state != SalesOrder::State_seven) return [false, '请确认合同状态,操作失败'];
  804. SalesOrder::where('del_time',0)->where('order_number',$data['order_number'])
  805. ->update(['state' => SalesOrder::State_eight]);
  806. SalesOrderInfo::insert([
  807. 'sales_order_id' => $model->id,
  808. 'type' => SalesOrderInfo::type_six,
  809. 'file' => $data['img'],
  810. 'crt_time' => time(),
  811. ]);
  812. return [true, $model->toArray()];
  813. }
  814. public function settleSalesOrderConfirm($data,$user){
  815. $model = SalesOrder::where('order_number', $data['order_number'])
  816. ->where('del_time',0)
  817. ->first();
  818. if(empty($model)) return [false, '合同不存在或已被删除'];
  819. //安装件
  820. if($model->state != SalesOrder::State_four) return [false, '请确认合同状态,操作失败'];
  821. $model->is_confirm = 1;
  822. $model->save();
  823. $emp_name = Employee::where('id',$user['id'])->value('emp_name');
  824. $take_id = $model->dispatch_time_second_id ?? 0;
  825. $send_data = [];
  826. if(! empty($take_id)){
  827. $send_data[] = [
  828. 'employee_id' => $take_id,
  829. 'type' => 2,
  830. 'state' => 0,
  831. 'menu_id' => 37,
  832. 'order_number' => $model->order_number,
  833. 'tmp_data' => [
  834. $model->order_number,
  835. "派单合同",
  836. "接收派单成功",
  837. $emp_name,
  838. date('Y-m-d H:i:s'),
  839. ],
  840. ];
  841. (new OaService())->sendWxOaCheckMessage($send_data);
  842. }
  843. return [true, $model->toArray()];
  844. }
  845. public function confirmSales($data){
  846. $model = SalesOrder::where('order_number', $data['order_number'])
  847. ->where('del_time',0)
  848. ->first();
  849. if(empty($model)) return [false, '合同不存在或已被删除'];
  850. if($model->state != SalesOrder::State_one) return [false, '请确认合同状态,操作失败'];
  851. if($data['type'] == self::TYPE_ONE){
  852. $state = SalesOrder::State_three;
  853. if(in_array($model->model_type,[SalesOrder::Model_type_four,SalesOrder::Model_type_seven])){
  854. //线上订单 补贴订单
  855. $state = SalesOrder::State_two;
  856. }
  857. $model->state = $state;
  858. $model->save();
  859. }else{
  860. $model->state = SalesOrder::State_minus_one;
  861. $model->save();
  862. }
  863. return [true, $model->toArray()];
  864. }
  865. public function reject_sales($data){
  866. $model = SalesOrder::where('order_number', $data['order_number'])
  867. ->where('del_time',0)
  868. ->first();
  869. if(empty($model)) return [false, '合同不存在或已被删除'];
  870. //安装件
  871. if(in_array($model->model_type,[SalesOrder::Model_type_four,SalesOrder::Model_type_seven])){
  872. //线上订单 补贴订单
  873. if($model->state != SalesOrder::State_two) return [false, '请确认合同状态,操作失败'];
  874. }else{
  875. //除线上订单 补贴订单 之外
  876. if($model->state != SalesOrder::State_three) return [false, '请确认合同状态,操作失败'];
  877. }
  878. //未确认
  879. $model->state = SalesOrder::State_zero;
  880. $model->save();
  881. return [true, $model->toArray()];
  882. }
  883. public function reject_purchase($data){
  884. $model = PurchaseOrder::where('order_number', $data['order_number'])
  885. ->where('del_time',0)
  886. ->first();
  887. if(empty($model)) return [false, '采购单不存在或已被删除'];
  888. //安装件
  889. if($model->state != PurchaseOrder::STATE_Four) return [false, '请确认采购单状态,操作失败'];
  890. $model->state = PurchaseOrder::STATE_TWO;
  891. $model->save();
  892. return [true, $model->toArray()];
  893. }
  894. public function reject_purchase_confirm($data){
  895. $model = PurchaseOrder::where('order_number', $data['order_number'])
  896. ->where('del_time',0)
  897. ->first();
  898. if(empty($model)) return [false, '采购单不存在或已被删除'];
  899. //安装件
  900. if($model->state != PurchaseOrder::STATE_TWO) return [false, '请确认采购单状态,操作失败'];
  901. $model->state = PurchaseOrder::STATE_ZERO;
  902. $model->save();
  903. return [true, $model->toArray()];
  904. }
  905. public function reject_construction($data){
  906. $model = Construction::where('order_number', $data['order_number'])
  907. ->where('del_time',0)
  908. ->first();
  909. if(empty($model)) return [false, '施工单不存在或已被删除'];
  910. //安装件
  911. if($model->state != Construction::STATE_TWO) return [false, '请确认施工单状态,操作失败'];
  912. $model->state = Construction::STATE_ZERO;
  913. $model->save();
  914. return [true, $model->toArray()];
  915. }
  916. public function reject_payment_receipt($data){
  917. $model = PaymentReceipt::where('order_number', $data['order_number'])
  918. ->where('del_time',0)
  919. ->first();
  920. if(empty($model)) return [false, '收付款单不存在或已被删除'];
  921. if($model->state != PaymentReceipt::STATE_TWO) return [false, '请确认收付款单状态,操作失败'];
  922. $model->state = PaymentReceipt::STATE_ZERO;
  923. $model->save();
  924. return [true, $model->toArray()];
  925. }
  926. public function reject_sports_bag($data){
  927. $model = SportsBag::where('order_number', $data['order_number'])
  928. ->where('del_time',0)
  929. ->first();
  930. if(empty($model)) return [false, '活动包不存在或已被删除'];
  931. if($model->state != SportsBag::STATE_TWO) return [false, '请确认活动包状态,操作失败'];
  932. $model->state = SportsBag::STATE_ZERO;
  933. $model->save();
  934. return [true, $model->toArray()];
  935. }
  936. public function reject_return_exchange($data){
  937. $model = ReturnExchangeOrder::where('order_number', $data['order_number'])
  938. ->where('del_time',0)
  939. ->first();
  940. if(empty($model)) return [false, '退换货单不存在或已被删除'];
  941. if($model->state != ReturnExchangeOrder::State_two) return [false, '请确认退换货单状态,操作失败'];
  942. $model->state = ReturnExchangeOrder::State_zero;
  943. $model->save();
  944. return [true, $model->toArray()];
  945. }
  946. public function reject_record_construction($data,$order){
  947. //仅施工不需要库存流水
  948. if($order['model_type'] == Construction::Model_type_two) return [true, self::minus_one];
  949. //获取单据最新数据时间 正常施工数据
  950. $crt_time = 0;
  951. $latest = InOutRecord::where('del_time',0)
  952. ->where('order_number',$data['order_number'])
  953. ->where('number','<',0)
  954. ->select('crt_time')
  955. ->orderBy('crt_time', 'desc')
  956. ->first();
  957. if(! empty($latest)) $crt_time = $latest->crt_time;
  958. $result = InOutRecord::where('del_time',0)
  959. ->where('crt_time',$crt_time)
  960. ->where('order_number',$data['order_number'])
  961. ->where('number','<',0)
  962. ->select('product_id','storehouse_id','number','depart_id','order_number','top_depart_id','order_type','price')
  963. ->get()->toArray();
  964. if(empty($result)) return [false,'施工出库流水数据未找到'];
  965. //生成对冲数据
  966. $time = time();
  967. foreach ($result as $key => $value){
  968. $result[$key]['number'] = abs($value['number']);
  969. $result[$key]['crt_time'] = $time;
  970. }
  971. $bool = InOutRecord::insert($result);
  972. if(! $bool) return [false,'流水写入失败'];
  973. //写入流水
  974. return [true, ''];
  975. }
  976. public function reject_record_purchase($data,$order){
  977. //获取单据最新数据时间 正常采购入库数据
  978. $crt_time = 0;
  979. $latest = InOutRecord::where('del_time',0)
  980. ->where('order_number',$data['order_number'])
  981. ->where('number','>',0)
  982. ->select('crt_time')
  983. ->orderBy('crt_time', 'desc')
  984. ->first();
  985. if(! empty($latest)) $crt_time = $latest->crt_time;
  986. $result = InOutRecord::where('del_time',0)
  987. ->where('crt_time',$crt_time)
  988. ->where('order_number',$data['order_number'])
  989. ->where('number','>',0)
  990. ->select('product_id','storehouse_id','number','depart_id','order_number','top_depart_id','order_type','price')
  991. ->get()->toArray();
  992. if(empty($result)) return [false,'采购入库流水数据未找到'];
  993. //生成对冲数据
  994. $time = time();
  995. foreach ($result as $key => $value){
  996. $result[$key]['number'] = - $value['number'];
  997. $result[$key]['crt_time'] = $time;
  998. }
  999. $bool = InOutRecord::insert($result);
  1000. if(! $bool) return [false,'流水写入失败'];
  1001. //写入流水
  1002. return [true, ''];
  1003. }
  1004. public function reject_record_return_exchange($data,$order){
  1005. if($order['model_type'] == ReturnExchangeOrder::Model_type_three) return [true, self::minus_one];
  1006. //获取单据最新数据时间 正常退换货流水数据
  1007. $crt_time = 0;
  1008. $latest = InOutRecord::where('del_time',0)
  1009. ->where('order_number',$data['order_number'])
  1010. ->select('crt_time')
  1011. ->orderBy('crt_time', 'desc')
  1012. ->first();
  1013. if(! empty($latest)) $crt_time = $latest->crt_time;
  1014. $result = InOutRecord::where('del_time',0)
  1015. ->where('crt_time',$crt_time)
  1016. ->where('order_number',$data['order_number'])
  1017. ->select('product_id','storehouse_id','number','depart_id','order_number','top_depart_id','order_type','price')
  1018. ->get()->toArray();
  1019. if(empty($result)) return [false,'退换货流水数据未找到'];
  1020. //生成对冲数据
  1021. $time = time();
  1022. foreach ($result as $key => $value){
  1023. $result[$key]['number'] = - $value['number'];
  1024. $result[$key]['crt_time'] = $time;
  1025. }
  1026. $bool = InOutRecord::insert($result);
  1027. if(! $bool) return [false, '流水写入失败'];
  1028. //写入流水
  1029. return [true, ''];
  1030. }
  1031. public function getOrderDetail($data,$user){
  1032. if(empty($data['order_number'])) return [false,'必传参数不能为空'];
  1033. $array = [];
  1034. foreach (Construction::$prefix as $value){
  1035. $array[$value] = "\App\Service\\ConstructionService";
  1036. }
  1037. foreach (ReturnExchangeOrder::$prefix as $value){
  1038. $array[$value] = "\App\Service\\ReturnExchangeOrderService";
  1039. }
  1040. foreach (SalesOrder::$prefix as $value){
  1041. $array[$value] = "\App\Service\\SalesOrderService";
  1042. }
  1043. $status = true;
  1044. $msg = [];
  1045. foreach ($array as $key => $value){
  1046. if(strpos($data['order_number'],$key) !== false) {
  1047. list($status, $msg) = (new $value)->detail($data);
  1048. return [$status, $msg];
  1049. }
  1050. }
  1051. if(strpos($data['order_number'],PurchaseOrder::prefix) !== false){
  1052. $service = "\App\Service\\PurchaseOrderService";
  1053. list($status, $msg) = (new $service)->detail($data,$user);
  1054. return [$status, $msg];
  1055. }
  1056. return [$status, $msg];
  1057. }
  1058. public function checkAll($data,$user){
  1059. if(empty($data['id']) || empty($data['order_number'])|| empty($data['opt_case'])) return [false,'必传参数不能为空或者参数值错误!'];
  1060. list($status,$msg) = $this->limitingSendRequestBackgExpire($data['order_number'].$data['opt_case']);
  1061. if(! $status) return [false,$msg];
  1062. //走审批流 单据校验
  1063. $function_check = self::$opt_1case_check[$data['opt_case']] ?? '';
  1064. //走审批流 单据状态改为待审批方法
  1065. $function = self::$opt_1case[$data['opt_case']] ?? '';
  1066. //单据不走审批流
  1067. $function2 = self::$finished[$data['opt_case']] ?? '';
  1068. try{
  1069. DB::beginTransaction();
  1070. //不走审批流,更新完直接返回
  1071. if($function2) {
  1072. list($bool,$msg) = $this->$function2($data,$user);
  1073. if($bool) {
  1074. $order = $msg;
  1075. list($bool,$err) = $this->createRecordAndInventoryMy($data,$user,$order);
  1076. if($bool){
  1077. DB::commit();
  1078. return [true, ''];
  1079. }else{
  1080. DB::rollBack();
  1081. return [false, $err];
  1082. }
  1083. }else{
  1084. DB::rollBack();
  1085. return [false, $msg];
  1086. }
  1087. }
  1088. //需要审批流,校验
  1089. if($function_check){
  1090. list($bool,$msg) = $this->$function_check($data, $user);
  1091. if(! $bool){
  1092. DB::rollBack();
  1093. return [false, $msg];
  1094. }
  1095. }
  1096. //需要审批流,从未审核变成待审核
  1097. if($function){
  1098. list($bool,$msg) = $this->$function($data);
  1099. if(! $bool){
  1100. DB::rollBack();
  1101. return [false, $msg];
  1102. }
  1103. //创建审批流
  1104. $args = [
  1105. 'order_no' => $data['order_number'],
  1106. 'menu_id' => $data['menu_id'] ?? 0,
  1107. 'opt_case' => $data['opt_case'],
  1108. 'order' => $msg,
  1109. ];
  1110. $oa = new OaService($user);
  1111. list($bool,$msg) = $oa->createOaOrder($args);
  1112. if(! $bool) {
  1113. DB::rollBack();
  1114. if($msg) return [false,$msg];
  1115. }
  1116. }
  1117. DB::commit();
  1118. return [true, ''];
  1119. }catch (\Throwable $exception){
  1120. DB::rollBack();
  1121. return [false, $exception->getMessage() . $exception->getFile(). $exception->getLine()];
  1122. }
  1123. }
  1124. //更新库存
  1125. public function changeInventory($data,$order,$user){
  1126. $number_symbol = "";
  1127. if(in_array($data['opt_case'],self::$in_opt)){
  1128. $number_symbol = ">";
  1129. }elseif (in_array($data['opt_case'],self::$out_opt)){
  1130. $number_symbol = "<";
  1131. }
  1132. //获取单据最新数据时间 正常审核的数据
  1133. $latest = InOutRecord::where('del_time',0)
  1134. ->where('order_number',$order['order_number'])
  1135. ->when(! empty($number_symbol), function ($query) use ($number_symbol) {
  1136. return $query->where('number', $number_symbol,0);
  1137. })
  1138. ->select('crt_time')
  1139. ->orderBy('crt_time', 'desc')
  1140. ->first();
  1141. $model = InOutRecord::where('del_time',0)
  1142. ->where('order_number',$order['order_number'])
  1143. ->when(! empty($number_symbol), function ($query) use ($number_symbol) {
  1144. return $query->where('number', $number_symbol,0);
  1145. })
  1146. ->select('number','crt_time','product_id','storehouse_id','top_depart_id');
  1147. if(! empty($latest)) {
  1148. $t = $latest->toArray();
  1149. $model->where('crt_time',$t['crt_time']);
  1150. }
  1151. $record = $model->get()->toArray();
  1152. if (empty($record)) return [false,'流水记录不存在'];
  1153. $top_depart_id = Storehouse::where('id', $order['storehouse_id'])->value('top_depart_id');
  1154. $result = $lock_number = [];
  1155. foreach ($record as $value){
  1156. $key = $value['product_id'] . $value['storehouse_id'];
  1157. if(isset($result[$key])){
  1158. $result[$key]['number'] += $value['number'];
  1159. }else{
  1160. $result[$key] = [
  1161. 'product_id' => $value['product_id'],
  1162. 'number' => $value['number'],
  1163. 'crt_time' => $value['crt_time'],
  1164. 'storehouse_id' => $value['storehouse_id'],
  1165. 'top_depart_id' => $top_depart_id,
  1166. ];
  1167. }
  1168. if($value['number'] < 0){
  1169. if(isset($lock_number[$key])){
  1170. $lock_number[$key] += $value['number'];
  1171. }else{
  1172. $lock_number[$key] = $value['number'];
  1173. }
  1174. }
  1175. }
  1176. //是否校验库存 是的话锁定数量要更新(根据当前操作人所在门店是否校验库存)
  1177. $lock = $user['is_check_stock'];
  1178. $result = array_values($result);
  1179. foreach ($result as $key => $value){
  1180. $keys = $value['product_id'] . $value['storehouse_id'];
  1181. $m = ProductInventory::where('product_id',$value['product_id'])
  1182. ->where('storehouse_id',$value['storehouse_id'])
  1183. ->select('product_id','number','storehouse_id')
  1184. ->first();
  1185. if(empty($m)){
  1186. ProductInventory::insert($result[$key]);
  1187. }else{
  1188. //锁定数量
  1189. $lock_number_tmp = 0;
  1190. if($lock && ! empty($lock_number[$keys])) $lock_number_tmp = $lock_number[$keys];
  1191. ProductInventory::where('product_id',$m->product_id)
  1192. ->where('storehouse_id',$m->storehouse_id)
  1193. ->lockForUpdate()
  1194. ->update([
  1195. 'number' => DB::raw('number + ('. $value['number'] . ')'),
  1196. 'lock_number' => DB::raw('lock_number + ('. $lock_number_tmp . ')')
  1197. ]);
  1198. }
  1199. }
  1200. return [true,''];
  1201. }
  1202. //业务单据审批通过后 驳回 更新库存
  1203. public function changeInventoryReject($data,$order,$user){
  1204. $number_symbol = "";
  1205. if(in_array($data['opt_case'],self::$in_opt)){
  1206. $number_symbol = "<";
  1207. }elseif (in_array($data['opt_case'],self::$out_opt)){
  1208. $number_symbol = ">";
  1209. }
  1210. //获取单据最新数据时间 正常审核的数据
  1211. $latest = InOutRecord::where('del_time',0)
  1212. ->where('order_number',$order['order_number'])
  1213. ->when(! empty($number_symbol), function ($query) use ($number_symbol) {
  1214. return $query->where('number', $number_symbol,0);
  1215. })
  1216. ->select('crt_time')
  1217. ->orderBy('crt_time', 'desc')
  1218. ->first();
  1219. $model = InOutRecord::where('del_time',0)
  1220. ->where('order_number',$order['order_number'])
  1221. ->when(! empty($number_symbol), function ($query) use ($number_symbol) {
  1222. return $query->where('number', $number_symbol,0);
  1223. })
  1224. ->select('number','crt_time','product_id','storehouse_id','top_depart_id');
  1225. if(! empty($latest)) {
  1226. $t = $latest->toArray();
  1227. $model->where('crt_time',$t['crt_time']);
  1228. }
  1229. $record = $model->get()->toArray();
  1230. if (empty($record)) return [false,'流水记录不存在'];
  1231. $top_depart_id = Storehouse::where('id', $order['storehouse_id'])->value('top_depart_id');
  1232. $result = $lock_number = [];
  1233. foreach ($record as $value){
  1234. $key = $value['product_id'] . $value['storehouse_id'];
  1235. if(isset($result[$key])){
  1236. $result[$key]['number'] += $value['number'];
  1237. }else{
  1238. $result[$key] = [
  1239. 'product_id' => $value['product_id'],
  1240. 'number' => $value['number'],
  1241. 'crt_time' => $value['crt_time'],
  1242. 'storehouse_id' => $value['storehouse_id'],
  1243. 'top_depart_id' => $top_depart_id,
  1244. ];
  1245. }
  1246. if($value['number'] > 0){
  1247. if(isset($lock_number[$key])){
  1248. $lock_number[$key] += $value['number'];
  1249. }else{
  1250. $lock_number[$key] = $value['number'];
  1251. }
  1252. }
  1253. }
  1254. //是否校验库存 是的话锁定数量要更新(根据当前操作人所在门店是否校验库存)
  1255. $lock = $user['is_check_stock'];
  1256. $result = array_values($result);
  1257. foreach ($result as $key => $value){
  1258. $keys = $value['product_id'] . $value['storehouse_id'];
  1259. $m = ProductInventory::where('product_id',$value['product_id'])
  1260. ->where('storehouse_id',$value['storehouse_id'])
  1261. ->select('product_id','number','storehouse_id')
  1262. ->first();
  1263. if(empty($m)){
  1264. ProductInventory::insert($result[$key]);
  1265. }else{
  1266. //锁定数量
  1267. $lock_number_tmp = 0;
  1268. if($lock && ! empty($lock_number[$keys])) $lock_number_tmp = $lock_number[$keys];
  1269. ProductInventory::where('product_id',$m->product_id)
  1270. ->where('storehouse_id',$m->storehouse_id)
  1271. ->lockForUpdate()
  1272. ->update([
  1273. 'number' => DB::raw('number + ('. $value['number'] . ')'),
  1274. 'lock_number' => DB::raw('lock_number + ('. $lock_number_tmp . ')')
  1275. ]);
  1276. }
  1277. }
  1278. return [true,''];
  1279. }
  1280. public function createRecordAndInventory($data = []){
  1281. if(empty($data['type']) || empty($data['opt_case']) || empty($data['order_number'])) return [false, '传递参数缺少'];
  1282. $user = $data['user_data'] ?? [];
  1283. if($data['type'] == self::TYPE_THREE){
  1284. //通过后弃审
  1285. if(! isset(self::$opt_case_reject[$data['opt_case']])) return [false, '该操作不存在'];
  1286. //具体方法
  1287. $function = self::$opt_case_reject[$data['opt_case']];
  1288. //流水
  1289. $function2 = self::$reject_record[$data['opt_case']] ?? '';
  1290. //自动生成删除
  1291. $function3 = self::$create_del[$data['opt_case']] ?? '';
  1292. try{
  1293. DB::beginTransaction();
  1294. //更新单据的状态
  1295. list($bool,$msg) = $this->$function($data);
  1296. if(! $bool){
  1297. DB::rollBack();
  1298. return [false, $msg];
  1299. }
  1300. $order = $msg;
  1301. if($function3){
  1302. list($boolean,$msg) = $this->$function3($data,$order);
  1303. if(! $boolean) {
  1304. DB::rollBack();
  1305. return [false, $msg];
  1306. }
  1307. }
  1308. if($function2) {
  1309. //流水
  1310. list($boolean,$msg) = $this->$function2($data,$order);
  1311. if(! $boolean) {
  1312. DB::rollBack();
  1313. return [false, $msg];
  1314. }
  1315. if($msg != self::minus_one){
  1316. //库存
  1317. list($bool,$msg) = $this->changeInventoryReject($data,$order,$user);
  1318. if(! $bool){
  1319. DB::rollBack();
  1320. return [false, $msg];
  1321. }
  1322. }
  1323. }
  1324. if(! empty(self::$operation_order_reject[$data['opt_case']])){
  1325. $type = self::$operation_order_reject[$data['opt_case']];
  1326. (new OrderOperationService())->add([
  1327. 'order_number' => $order['order_number'],
  1328. 'msg' => OrderOperation::$type[$type],
  1329. 'type' => $type
  1330. ],$user);
  1331. }
  1332. DB::commit();
  1333. return [true, ''];
  1334. }catch (\Throwable $exception){
  1335. DB::rollBack();
  1336. return [false, $exception->getMessage() . $exception->getLine() . $exception->getFile()];
  1337. }
  1338. }else{
  1339. //具体方法
  1340. $function = self::$opt_case[$data['opt_case']] ?? "";
  1341. $record = self::$record[$data['opt_case']] ?? "";
  1342. $create = self::$create[$data['opt_case']] ?? "";
  1343. try{
  1344. DB::beginTransaction();
  1345. list($bool,$msg) = $this->$function($data);
  1346. if(! $bool){
  1347. DB::rollBack();
  1348. return [false, $msg];
  1349. }
  1350. $order = $msg;
  1351. if($data['type'] == self::TYPE_ONE){
  1352. if($record) {
  1353. //流水
  1354. list($bool,$msg) = $this->$record($data, $order);
  1355. if(! $bool) {
  1356. DB::rollBack();
  1357. return [false, $msg];
  1358. }
  1359. if($msg != self::minus_one){
  1360. //库存
  1361. list($bool,$msg) = $this->changeInventory($data, $order, $user);
  1362. if(! $bool) {
  1363. DB::rollBack();
  1364. return [false, $msg];
  1365. }
  1366. }
  1367. }
  1368. if($create) {
  1369. list($bool,$msg) = $this->$create($order,$user);
  1370. if(! $bool) {
  1371. DB::rollBack();
  1372. return [false, $msg];
  1373. }
  1374. }
  1375. }
  1376. if(! empty(self::$operation_order[$data['opt_case']])){
  1377. $user = $data['user_data'] ?? [];
  1378. $type = self::$operation_order[$data['opt_case']];
  1379. (new OrderOperationService())->add([
  1380. 'order_number' => $order['order_number'],
  1381. 'msg' => OrderOperation::$type[$type],
  1382. 'type' => $type
  1383. ],$user);
  1384. }
  1385. DB::commit();
  1386. return [true, ''];
  1387. }catch (\Throwable $exception){
  1388. DB::rollBack();
  1389. return [false, $exception->getMessage() . $exception->getLine() . $exception->getFile()];
  1390. }
  1391. }
  1392. }
  1393. //不需要走审批流 直接调用
  1394. public function createRecordAndInventoryMy($data = [],$user = [],$order = []){
  1395. if(! empty($data['type']) && $data['type'] == self::TYPE_THREE){
  1396. }else{
  1397. //具体方法
  1398. $record = self::$record[$data['opt_case']] ?? "";
  1399. $create = self::$create[$data['opt_case']] ?? "";
  1400. try{
  1401. DB::beginTransaction();
  1402. if($record) {
  1403. //流水
  1404. list($bool,$msg) = $this->$record($data, $order);
  1405. if(! $bool) {
  1406. DB::rollBack();
  1407. return [false, $msg];
  1408. }
  1409. if($msg != self::minus_one){
  1410. //库存
  1411. list($bool,$msg) = $this->changeInventory($data, $order, $user);
  1412. if(! $bool) {
  1413. DB::rollBack();
  1414. return [false, $msg];
  1415. }
  1416. }
  1417. }
  1418. if($create) {
  1419. list($bool,$msg) = $this->$create($order,$user);
  1420. if(! $bool) {
  1421. DB::rollBack();
  1422. return [false, $msg];
  1423. }
  1424. }
  1425. if(! empty(self::$operation_order[$data['opt_case']])){
  1426. $type = self::$operation_order[$data['opt_case']];
  1427. (new OrderOperationService())->add([
  1428. 'order_number' => $order['order_number'],
  1429. 'msg' => OrderOperation::$type[$type],
  1430. 'type' => $type
  1431. ],$user);
  1432. }
  1433. DB::commit();
  1434. return [true, ''];
  1435. }catch (\Throwable $exception){
  1436. DB::rollBack();
  1437. return [false, $exception->getMessage() . $exception->getLine() . $exception->getFile()];
  1438. }
  1439. }
  1440. }
  1441. }