CheckService.php 68 KB

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