CheckService.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace App\Service;
  3. use App\Model\Construction;
  4. use App\Model\ConstructionProductInfo;
  5. use App\Model\InOutRecord;
  6. use App\Model\InvoiceOrder;
  7. use App\Model\InvoiceOrderInfo;
  8. use App\Model\ProductInventory;
  9. use App\Model\PurchaseOrder;
  10. use App\Model\PurchaseOrderInfo;
  11. use App\Model\SalesOrder;
  12. use App\Model\Setting;
  13. use Illuminate\Support\Facades\DB;
  14. class CheckService extends Service
  15. {
  16. //审批操作对应的数值
  17. const one = 1; //收货
  18. const two = 2; //发货
  19. const three = 3; //采购单
  20. const four = 4; //销售订单
  21. const five = 5; //施工单
  22. //中文对照
  23. public $map = [
  24. self::one => '收货单',
  25. self::two => '发货单',//确认后出库
  26. self::three => '采购单',//确认后入库
  27. self::four => '销售订单',
  28. self::five => '施工单',//确认后出库
  29. ];
  30. //入库操作
  31. public static $in_opt = [
  32. self::three,
  33. ];
  34. //出库操作
  35. public static $out_opt = [
  36. self::two,
  37. self::five,
  38. ];
  39. const TYPE_ONE = 1;//通过
  40. const TYPE_TWO = 2;//不通过
  41. //单据操作
  42. public static $opt_case = [
  43. self::two => 'confirmInvoiceOrder',
  44. self::three => 'confirmPurchaseOrder',
  45. self::four => 'confirmSalesOrder',
  46. self::five => 'confirmConstruction',
  47. ];
  48. //单据库存流水
  49. public static $record = [
  50. self::two => 'recordInvoiceOrder',
  51. self::three => 'recordPurchaseOrder',
  52. self::five => 'recordConstruction',
  53. ];
  54. public function confirmInvoiceOrder($data){
  55. $model = InvoiceOrder::where('id',$data['id'])
  56. ->where('del_time',0)
  57. ->first();
  58. if(empty($model)) return [false, '发货单不存在或已被删除'];
  59. if($model->state != InvoiceOrder::STATE_ZERO) return [false, '请确认发货单状态,操作失败'];
  60. InvoiceOrder::where('del_time',0)->where('id',$data['id'])
  61. ->update(['state' => InvoiceOrder::STATE_ONE]);
  62. return [true, $model->toArray()];
  63. }
  64. public function recordInvoiceOrder($data, $order){
  65. $result = InvoiceOrderInfo::where('del_time',0)
  66. ->where('order_number',$order['order_number'])
  67. ->get()->toArray();
  68. if(empty($result)) return [false,'发货单产品信息不存在或已被删除'];
  69. $insert = [];
  70. $time = time();
  71. foreach ($result as $value){
  72. if(isset($insert[$value['product_id']])){
  73. $insert[$value['product_id']]['number'] += -($value['number']);
  74. }else{
  75. $insert[$value['product_id']] = [
  76. 'product_id' => $value['product_id'],
  77. 'number' => -($value['number']),
  78. 'order_type' => InvoiceOrder::prefix,
  79. 'order_number' => $order['order_number'],
  80. 'crt_time' => $time
  81. ];
  82. }
  83. }
  84. $insert = array_values($insert);
  85. $bool = InOutRecord::insert($insert);
  86. if(! $bool) return [false,'流水写入失败'];
  87. return [true,''];
  88. }
  89. public function confirmPurchaseOrder($data){
  90. $model = PurchaseOrder::where('id',$data['id'])
  91. ->where('del_time',0)
  92. ->first();
  93. if(empty($model)) return [false, '采购订单不存在或已被删除'];
  94. if($model->state != PurchaseOrder::STATE_ZERO) return [false, '请确认采购订单状态,操作失败'];
  95. PurchaseOrder::where('del_time',0)->where('id',$data['id'])
  96. ->update(['state' => PurchaseOrder::STATE_ONE]);
  97. return [true, $model->toArray()];
  98. }
  99. public function recordPurchaseOrder($data, $order){
  100. $result = PurchaseOrderInfo::where('del_time',0)
  101. ->where('order_number',$order['order_number'])
  102. ->get()->toArray();
  103. if(empty($result)) return [false,'采购单产品信息不存在或已被删除'];
  104. $insert = [];
  105. $time = time();
  106. foreach ($result as $value){
  107. if(isset($insert[$value['product_id']])){
  108. $insert[$value['product_id']]['number'] += $value['number'];
  109. }else{
  110. $insert[$value['product_id']] = [
  111. 'product_id' => $value['product_id'],
  112. 'number' => $value['number'],
  113. 'order_type' => PurchaseOrder::prefix,
  114. 'order_number' => $order['order_number'],
  115. 'crt_time' => $time
  116. ];
  117. }
  118. }
  119. $insert = array_values($insert);
  120. $bool = InOutRecord::insert($insert);
  121. if(! $bool) return [false,'流水写入失败'];
  122. return [true,''];
  123. }
  124. public function confirmSalesOrder($data){
  125. $model = SalesOrder::where('id',$data['id'])->where('del_time',0)->first();
  126. if(empty($model)) return [false, '销售订单不存在或已被删除'];
  127. if($data['type'] == self::TYPE_ONE){
  128. if($model->state == SalesOrder::State_one) return [false,'已锁定,操作失败!'];
  129. $model->state = SalesOrder::State_one;
  130. }else{
  131. if($model->state == SalesOrder::State_zero) return [false,'未锁定,操作失败!'];
  132. $model->state = SalesOrder::State_zero;
  133. }
  134. $model->save();
  135. return [true,$model->toArray()];
  136. }
  137. public function confirmConstruction($data){
  138. $model = Construction::where('id',$data['id'])
  139. ->where('del_time',0)
  140. ->first();
  141. if(empty($model)) return [false, '施工单不存在或已被删除'];
  142. if($model->state != Construction::STATE_ZERO) return [false, '请确认施工单状态,操作失败'];
  143. Construction::where('del_time',0)->where('id',$data['id'])
  144. ->update(['state' => Construction::STATE_ONE]);
  145. return [true, $model->toArray()];
  146. }
  147. public function recordConstruction($data, $order){
  148. $result = ConstructionProductInfo::where('del_time',0)
  149. ->where('construction_id',$order['id'])
  150. ->get()->toArray();
  151. if(empty($result)) return [false,'施工单产品信息不存在或已被删除'];
  152. $insert = [];
  153. $time = time();
  154. foreach ($result as $value){
  155. if(isset($insert[$value['product_id']])){
  156. $insert[$value['product_id']]['number'] += -($value['number']);
  157. }else{
  158. $insert[$value['product_id']] = [
  159. 'product_id' => $value['product_id'],
  160. 'number' => -($value['number']),
  161. 'order_type' => Construction::$prefix[$order['model_type']] ?? '',
  162. 'order_number' => $order['order_number'],
  163. 'crt_time' => $time
  164. ];
  165. }
  166. }
  167. $insert = array_values($insert);
  168. $bool = InOutRecord::insert($insert);
  169. if(! $bool) return [false,'流水写入失败'];
  170. return [true,''];
  171. }
  172. public function checkAll($data,$user){
  173. if(empty($data['id']) || empty($data['opt_case'])) return [false,'必传参数不能为空或者参数值错误!'];
  174. //具体方法
  175. $function = self::$opt_case[$data['opt_case']] ?? "";
  176. $record = self::$record[$data['opt_case']] ?? "";
  177. try{
  178. DB::beginTransaction();
  179. list($bool,$msg) = $this->$function($data);
  180. if(! $bool){
  181. DB::rollBack();
  182. return [false, $msg];
  183. }
  184. $order = $msg;
  185. if($record) {
  186. //流水
  187. $bool = $this->$record($data, $order);
  188. if(! $bool) {
  189. DB::rollBack();
  190. return [false, $msg];
  191. }
  192. //库存
  193. $bool = $this->changeInventory($data, $order);
  194. if(! $bool) {
  195. DB::rollBack();
  196. return [false, $msg];
  197. }
  198. }
  199. DB::commit();
  200. return [true, ''];
  201. }catch (\Throwable $exception){
  202. DB::rollBack();
  203. return [false, $exception->getMessage()];
  204. }
  205. }
  206. //更新库存
  207. public function changeInventory($data,$order){
  208. $number_symbol = ">";
  209. if(in_array($data['opt_case'],self::$in_opt)){
  210. $number_symbol = ">";
  211. }elseif (in_array($data['opt_case'],self::$out_opt)){
  212. $number_symbol = "<";
  213. }
  214. //获取单据最新数据时间 正常审核的数据
  215. $latest = InOutRecord::where('del_time',0)
  216. ->where('order_number',$order['order_number'])
  217. ->where('number',$number_symbol,0)
  218. ->select('crt_time')
  219. ->orderBy('crt_time', 'desc')
  220. ->first();
  221. $model = InOutRecord::where('del_time',0)
  222. ->where('order_number',$order['order_number'])
  223. ->where('number',$number_symbol,0)
  224. ->select(DB::raw("sum(number) as number"),'crt_time','product_id');
  225. if(! empty($latest)) {
  226. $t = $latest->toArray();
  227. $model->where('crt_time',$t['crt_time']);
  228. }
  229. $result = $model->get()->toArray();
  230. if (empty($result)) return [false,'流水记录不存在'];
  231. //是否锁定
  232. $setting_map = Setting::where('setting_name','lock_number')
  233. ->pluck('setting_value','setting_name')->toArray();
  234. foreach ($result as $key => $value){
  235. $m = ProductInventory::where('product_id',$value['product_id'])
  236. ->select('product_id','number')
  237. ->first();
  238. if(empty($m)){
  239. ProductInventory::insert($result[$key]);
  240. }else{
  241. $lock_number = 0;
  242. if(! empty($setting_map['lock_number']) && in_array($data['opt_case'],self::$out_opt)) $lock_number = $value['number'];
  243. ProductInventory::where('product_id',$m->product_id)
  244. ->lockForUpdate()
  245. ->update([
  246. 'number' => DB::raw('number + ('. $value['number'] . ')'),
  247. 'lock_number' => DB::raw('lock_number + ('. $lock_number . ')')
  248. ]);
  249. }
  250. }
  251. return [true,''];
  252. }
  253. }