ReportFormsService.php 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. <?php
  2. namespace App\Service;
  3. use App\Model\DispatchSub;
  4. use App\Model\Employee;
  5. use App\Model\OrdersProduct;
  6. use App\Model\OrdersProductProcess;
  7. use App\Model\Process;
  8. use App\Model\ReportWorkingDetail;
  9. use App\Model\Scrapp;
  10. use App\Model\ScrappCount;
  11. use App\Model\SystemL;
  12. use App\Model\Team;
  13. use Illuminate\Support\Facades\DB;
  14. /**
  15. * 设备相关设置报表
  16. * Class ReportFormsService
  17. * @package App\Service
  18. */
  19. class ReportFormsService extends Service
  20. {
  21. /**
  22. * 生产进度
  23. * @param $data
  24. * @return array
  25. */
  26. public function productionReport($data){
  27. if(empty($data['production_time'][0]) || empty($data['production_time'][1])) return [false, '生产订单时间必须选择!'];
  28. //检索条件 生产订单主表----------------
  29. $model = OrdersProduct::where('del_time',0)->select('id','production_time','production_no','out_order_no','out_order_no_time','customer_no','customer_name','table_header_mark','order_quantity','production_quantity');
  30. $model->whereBetween('production_time',[$data['production_time'][0],$data['production_time'][1]]);
  31. if(! empty($data['production_no'])) $model->where('production_no', 'LIKE', '%'.$data['production_no'].'%');
  32. if(! empty($data['out_order_no_time'][0]) && ! empty($data['out_order_no_time'][1])) $model->whereBetween('out_order_no_time',[$data['out_order_no_time'][0],$data['out_order_no_time'][1]]);
  33. if(! empty($data['out_order_no'])) $model->where('out_order_no', 'LIKE', '%'.$data['out_order_no'].'%');
  34. if(! empty($data['customer_no'])) $model->where('customer_no', 'LIKE', '%'.$data['customer_no'].'%');
  35. if(! empty($data['customer_name'])) $model->where('customer_name', 'LIKE', '%'.$data['customer_name'].'%');
  36. $orderList = $model->get()->toArray();
  37. //生产订单主表----------------
  38. $id = array_column($orderList,'id');
  39. //分组以后的订单列表
  40. $list = [];
  41. foreach ($orderList as $value){
  42. if(! isset($list[$value['production_no']])){
  43. $list[$value['production_no']] = $value;
  44. }else{
  45. $list[$value['production_no']]['order_quantity'] += $value['order_quantity'];
  46. $list[$value['production_no']]['production_quantity'] += $value['production_quantity'];
  47. }
  48. }unset($orderList);
  49. $detail = [];
  50. $dispatchList = DispatchSub::where('del_time',0)
  51. ->whereIn('order_product_id',$id)
  52. ->select('order_product_id','process_id',DB::raw('SUM(dispatch_quantity) as dispatch_count'),DB::raw('SUM(finished_num) as finish_count'))
  53. ->groupBy('order_product_id','process_id')
  54. ->get()->toArray();//派工和完工数据
  55. foreach ($dispatchList as $t){
  56. $keys = $t['order_product_id'] . "|" .$t['process_id'];
  57. if(isset($detail[$keys])){
  58. $detail[$keys]['dispatch_count'] += $t['dispatch_count'];
  59. $detail[$keys]['finish_count'] += $t['finish_count'];
  60. }else{
  61. $detail[$keys] = $t;
  62. }
  63. }
  64. //返回统计数据
  65. foreach ($list as $key => $value) {
  66. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  67. $list[$key]['out_order_no_time'] = $value['out_order_no_time'] ? date('Y-m-d',$value['out_order_no_time']) : '';
  68. $detail_key = $value['id'] . "|";
  69. foreach ($detail as $key_son => $value_son) {
  70. if (strpos($key_son, $detail_key) !== false) {
  71. $value_son['production_no'] = $value['production_no'];
  72. $dispatch_count = $value_son['dispatch_count'];
  73. $finish_count = $value_son['finish_count'];
  74. $value_son['dispatch_count'] = $dispatch_count;
  75. $value_son['finish_count'] = $finish_count;
  76. $value_son['rate'] = number_format($value_son['finish_count'] / $value['order_quantity'] * 100, 2);
  77. $list[$key]['process'][] = $value_son;
  78. }
  79. }
  80. if(empty($list[$key]['process'])) unset($list[$key]);
  81. }
  82. return [true,array_values($list)];
  83. }
  84. private function checkSameQuarter($timestamps) {
  85. $quarters = $out_time = [];
  86. foreach ($timestamps as $timestamp) {
  87. $date = date('Ym', $timestamp);
  88. $year = intval(date('Y', $timestamp));
  89. $quarter = ceil(intval(date('n', $timestamp)) / 3);
  90. if(! isset($quarters[$year]) || ! in_array($quarter,$quarters[$year])){
  91. $quarters[$year][] = $quarter;
  92. $out_time[] = $date;
  93. }
  94. }
  95. return $out_time;
  96. }
  97. public function teamReport($data){
  98. if(empty($data['finish_time'][0]) || empty($data['finish_time'][1])) return [false, '完工时间必须选择!'];
  99. //班组
  100. $team_id = $data['team_id'] ?? [];
  101. $result = DispatchSub::where('del_time',0)
  102. ->where('finished_num','>',0)
  103. ->whereBetween('upd_time', [$data['finish_time'][0], $data['finish_time'][1]])
  104. ->when(!empty($team_id), function ($query) use ($team_id) {
  105. return $query->whereIn('team_id', $team_id);
  106. })
  107. ->select('team_id','upd_time as finished_time','finished_num','order_product_id')
  108. ->get()->toArray();
  109. if(empty($result)) return [true , []];
  110. //组织数据
  111. $team_map = Team::whereIn('id',array_unique(array_column($result,'team_id')))
  112. ->pluck('title','id')
  113. ->toArray();
  114. $return_team = $return_team_time_tmp = $return_team_time= [];
  115. foreach ($result as $value){
  116. if(isset($return_team[$value['team_id']])){
  117. $num = bcadd($value['finished_num'], $return_team[$value['team_id']]['num'],3);
  118. $return_team[$value['team_id']]['num'] = $num;
  119. if(! in_array($value['order_product_id'], $return_team[$value['team_id']]['production_no'])) {
  120. $return_team[$value['team_id']]['production_no'] = array_merge_recursive($return_team[$value['team_id']]['production_no'],[$value['order_product_id']]);
  121. }
  122. }else{
  123. $return_team[$value['team_id']] = [
  124. 'num' => $value['finished_num'],
  125. 'team_name' => $team_map[$value['team_id']] ?? '',
  126. 'production_no' => [$value['order_product_id']]
  127. ];
  128. }
  129. $tmp = date("Y-m-d",$value['finished_time']);
  130. if(isset($return_team_time_tmp[$tmp][$value['team_id']])){
  131. $num = bcadd($value['finished_num'],$return_team_time_tmp[$tmp][$value['team_id']]['num'],3);
  132. $return_team_time_tmp[$tmp][$value['team_id']]['num'] = $num;
  133. }else{
  134. $return_team_time_tmp[$tmp][$value['team_id']] = [
  135. 'time' => $tmp,
  136. 'num' => $value['finished_num'],
  137. 'team_name' => $team_map[$value['team_id']] ?? '',
  138. ];
  139. }
  140. }ksort($return_team_time_tmp);unset($result);
  141. $all_team_map = Team::where('del_time',0)
  142. ->pluck('title','id')
  143. ->toArray();
  144. foreach ($return_team_time_tmp as $key => $value){
  145. $t_k = array_keys($value);
  146. foreach ($all_team_map as $k => $v){
  147. if(! in_array($k,$t_k)){
  148. $return_team_time_tmp[$key][$k] = [
  149. 'time' => $key,
  150. 'num' => 0,
  151. 'team_name' => $v,
  152. ];
  153. }
  154. }
  155. ksort($return_team_time_tmp[$key]);
  156. $tmp = [];
  157. $tmp['time'] = $key;
  158. $tmp['sub'] = array_values($return_team_time_tmp[$key]);
  159. $return_team_time[] = $tmp;
  160. }unset($return_team_time_tmp);
  161. foreach ($return_team as $key => $value){
  162. $return_team[$key]['num'] = $value['num'];
  163. }
  164. foreach ($return_team_time as $key => $value){
  165. foreach ($value['sub'] as $k => $v){
  166. $return_team_time[$key]['sub'][$k]['num'] = $v['num'];
  167. }
  168. }
  169. //列表数据 图表数据
  170. return [true,['list'=>array_values($return_team),'chart'=>$return_team_time]];
  171. }
  172. /**
  173. * 班组
  174. * @param $data
  175. * @return array
  176. */
  177. public function teamReport1($data){
  178. if(empty($data['finish_time'][0]) || empty($data['finish_time'][1])) return [false, '完工时间必须选择!'];
  179. //班组
  180. $team_id = $data['team_id'] ?? [];
  181. //根据完工时间 扩大时间戳范围前后三个月
  182. $new_finish_time = $this->increaseTimeArea($data['finish_time']);
  183. //根据时间戳范围 获取分表的时间
  184. $return_time = $this->getTimeAreaData($new_finish_time);
  185. //检索分表数据
  186. $batchSize = 1000; // 每次处理的数据量
  187. $result = $team = [];
  188. foreach ($return_time as $value){
  189. $offset = 0;
  190. $hasMoreData = true;
  191. while ($hasMoreData) {
  192. // 子表搜索
  193. $models = new OrdersProductProcess(['channel' => $value]);
  194. $tmp = $models->where('del_time', 0)
  195. ->whereBetween('finished_time', [$data['finish_time'][0], $data['finish_time'][1]])
  196. ->where('status', 2)
  197. ->when(!empty($team_id), function ($query) use ($team_id) {
  198. return $query->whereIn('team_id', $team_id);
  199. })
  200. ->skip($offset) // 跳过前面的数据
  201. ->take($batchSize) // 获取固定数量的数据
  202. ->select('team_id', 'finished_time', 'production_no')
  203. ->get()->toArray(); // 完工数据
  204. if (empty($tmp)) {
  205. $hasMoreData = false;
  206. } else {
  207. $result = array_merge_recursive($result, $tmp);
  208. $team = array_merge_recursive($team, array_unique(array_column($tmp, 'team_id')));
  209. $offset += $batchSize;
  210. }
  211. }
  212. // //子表搜索
  213. // $models = new OrdersProductProcess(['channel' => $value]);
  214. // $tmp = $models->where('del_time',0)
  215. // ->whereBetween('finished_time',[$data['finish_time'][0], $data['finish_time'][1]])
  216. // ->where('status',2)
  217. // ->when(!empty($team_id), function ($query) use ($team_id) {
  218. // return $query->whereIn('team_id', $team_id);
  219. // })
  220. // ->select('team_id','finished_time','production_no')
  221. // ->get()->toArray();//完工数据
  222. // $result = array_merge_recursive($result,$tmp);
  223. // $team = array_merge_recursive($team,array_unique(array_column($tmp,'team_id')));
  224. }
  225. if(empty($result)) return [true , []];
  226. //组织数据
  227. $team_map = Team::whereIn('id',array_unique($team))
  228. ->pluck('title','id')
  229. ->toArray();
  230. $return_team = $return_team_time_tmp = $return_team_time= [];
  231. foreach ($result as $value){
  232. if(isset($return_team[$value['team_id']])){
  233. $return_team[$value['team_id']]['num'] += 1;
  234. if(! in_array($value['production_no'], $return_team[$value['team_id']]['production_no'])) {
  235. $return_team[$value['team_id']]['production_no'] = array_merge_recursive($return_team[$value['team_id']]['production_no'],[$value['production_no']]);
  236. }
  237. }else{
  238. $return_team[$value['team_id']] = [
  239. 'num' => 1,
  240. 'team_name' => $team_map[$value['team_id']] ?? '',
  241. 'production_no' => [$value['production_no']]
  242. ];
  243. }
  244. $tmp = date("Y-m-d",$value['finished_time']);
  245. if(isset($return_team_time_tmp[$tmp][$value['team_id']])){
  246. $return_team_time_tmp[$tmp][$value['team_id']]['num'] += 1;
  247. }else{
  248. $return_team_time_tmp[$tmp][$value['team_id']] = [
  249. 'time' => $tmp,
  250. 'num' => 1,
  251. 'team_name' => $team_map[$value['team_id']] ?? '',
  252. ];
  253. }
  254. }ksort($return_team_time_tmp);unset($result);
  255. $all_team_map = Team::where('del_time',0)
  256. ->pluck('title','id')
  257. ->toArray();
  258. foreach ($return_team_time_tmp as $key => $value){
  259. $t_k = array_keys($value);
  260. foreach ($all_team_map as $k => $v){
  261. if(! in_array($k,$t_k)){
  262. $return_team_time_tmp[$key][$k] = [
  263. 'time' => $key,
  264. 'num' => 0,
  265. 'team_name' => $v,
  266. ];
  267. }
  268. }
  269. ksort($return_team_time_tmp[$key]);
  270. $tmp = [];
  271. $tmp['time'] = $key;
  272. $tmp['sub'] = array_values($return_team_time_tmp[$key]);
  273. $return_team_time[] = $tmp;
  274. }unset($return_team_time_tmp);
  275. foreach ($return_team as $key => $value){
  276. $return_team[$key]['num'] = bcdiv($value['num'],1000,3);
  277. }
  278. foreach ($return_team_time as $key => $value){
  279. foreach ($value['sub'] as $k => $v){
  280. $return_team_time[$key]['sub'][$k]['num'] = bcdiv($v['num'],1000,3);
  281. }
  282. }
  283. //列表数据 图表数据
  284. return [true,['list'=>array_values($return_team),'chart'=>$return_team_time]];
  285. }
  286. /**
  287. * 时间特殊处理
  288. * @param $time_area
  289. * @return array
  290. */
  291. private function increaseTimeArea($time_area){
  292. // 增加三个月的时间戳
  293. $newStartTimestamp = strtotime('-3 months', $time_area[0]);
  294. $newEndTimestamp = strtotime('+3 months', $time_area[1]);
  295. return [$time_area[0],$time_area[1]];
  296. }
  297. /**
  298. * 获取时间区间数据
  299. * @param $time_area
  300. * @return array
  301. */
  302. private function getTimeAreaData($time_area){
  303. $startYear = date('Y', $time_area[0]);
  304. $endYear = date('Y', $time_area[1]);
  305. $return = [];
  306. for ($year = $startYear; $year <= $endYear; $year++) {
  307. for ($quarter = 1; $quarter <= 4; $quarter++) {
  308. $quarterStart = strtotime($year . '-' . (($quarter - 1) * 3 + 1) . '-01');
  309. $quarterEnd = strtotime($year . '-' . ($quarter * 3) . '-01') - 1;
  310. if ($quarterStart <= $time_area[1] && $quarterEnd >= $time_area[0]) {
  311. // $tmp = $year . sprintf('%02d', $quarter);//年季度
  312. $return[] = $year .sprintf('%02d',($quarter - 1) * 3 + 1);
  313. }
  314. }
  315. }
  316. return $return;
  317. }
  318. /**
  319. * 班组 详情
  320. * @param $data
  321. * @return array
  322. */
  323. public function teamReportDetail($data){
  324. if(empty($data['production_no'])) return [false,'生产订单号不能为空!'];
  325. $list = OrdersProduct::whereIn('id',$data['production_no'])
  326. ->select('production_time','production_no','customer_no','customer_name','table_header_mark','product_no','product_title','product_size','product_unit','dispatch_complete_quantity','finished_num','technology_material','technology_name','wood_name','process_mark','table_body_mark')
  327. ->get()->toArray();
  328. foreach ($list as $key => $value) {
  329. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  330. }
  331. return [true,$list];
  332. }
  333. /**
  334. * 不良品
  335. * @param $data
  336. * @return array
  337. */
  338. public function badGoodsReport($data){
  339. if(empty($data['production_time'][0]) || empty($data['production_time'][1])) return [false, '生产订单时间必须选择!'];
  340. //检索条件 生产订单主表----------------
  341. $model = OrdersProduct::where('del_time',0)->select('production_time','production_no','out_order_no','out_order_no_time','customer_no','customer_name','table_header_mark','order_quantity','production_quantity','out_crt_man','id');
  342. $model->whereBetween('production_time',[$data['production_time'][0],$data['production_time'][1]]);
  343. if(! empty($data['production_no'])) $model->where('production_no', 'LIKE', '%'.$data['production_no'].'%');
  344. if(! empty($data['out_order_no_time'][0]) && ! empty($data['out_order_no_time'][1])) $model->whereBetween('out_order_no_time',[$data['out_order_no_time'][0],$data['out_order_no_time'][1]]);
  345. if(! empty($data['out_order_no'])) $model->where('out_order_no', 'LIKE', '%'.$data['out_order_no'].'%');
  346. if(! empty($data['customer_no'])) $model->where('customer_no', 'LIKE', '%'.$data['customer_no'].'%');
  347. if(! empty($data['customer_name'])) $model->where('customer_name', 'LIKE', '%'.$data['customer_name'].'%');
  348. if(! empty($data['out_crt_man'])) $model->where('out_crt_man', 'LIKE', '%'.$data['out_crt_man'].'%');
  349. $orderList = $model->get()->toArray();
  350. //生产订单主表----------------
  351. //筛选出制单日期 分表的依据
  352. $out_order_no_time = array_unique(array_column($orderList,'out_order_no_time'));
  353. //制单日期
  354. $out_time = $this->checkSameQuarter($out_order_no_time);
  355. //分组以后的订单列表
  356. $list = [];
  357. foreach ($orderList as $value){
  358. if(! isset($list[$value['id']])){
  359. $list[$value['id']] = $value;
  360. }else{
  361. $list[$value['id']]['order_quantity'] += $value['order_quantity'];
  362. $list[$value['id']]['production_quantity'] += $value['production_quantity'];
  363. }
  364. }unset($orderList);
  365. //查询分表数据
  366. $production_id = array_keys($list);
  367. $detail = [];
  368. // foreach ($out_time as $value){
  369. // //子表搜索
  370. // $models = new OrdersProductProcess(['channel' => $value]);
  371. // $tmp = $models->whereIn('order_product_id',$production_id)
  372. // ->where('del_time',0)
  373. // ->where('status',4)
  374. // ->select('order_product_id',DB::raw('COUNT(id) as bad_goods_num'))
  375. // ->groupBy('order_product_id')
  376. // ->get()->toArray();//不良品数据
  377. //
  378. // foreach ($tmp as $t){
  379. // if(isset($detail[$t['order_product_id']])){
  380. // $detail[$t['order_product_id']]['bad_goods_num'] += $t['bad_goods_num'];
  381. // }else{
  382. // $detail[$t['order_product_id']] = $t['bad_goods_num'];
  383. // }
  384. // }
  385. // }
  386. $scrapp = ScrappCount::where('del_time',0)
  387. ->whereIn('order_product_id',$production_id)
  388. ->select('order_product_id','scrapp_num as bad_goods_num')
  389. ->get()->toArray();
  390. foreach ($scrapp as $value){
  391. if(isset($detail[$value['order_product_id']])){
  392. $tmp = bcadd($detail[$value['order_product_id']],$value['bad_goods_num'],3);
  393. $detail[$value['order_product_id']] = $tmp;
  394. }else{
  395. $detail[$value['order_product_id']] = $value['bad_goods_num'];
  396. }
  397. }
  398. //返回统计数据
  399. foreach ($list as $key => $value) {
  400. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  401. $list[$key]['out_order_no_time'] = $value['out_order_no_time'] ? date('Y-m-d',$value['out_order_no_time']) : '';
  402. $del_num = $detail[$value['id']] ?? 0;
  403. $list[$key]['bad_goods_num'] = $del_num;
  404. $list[$key]['rate'] = bcdiv($del_num ,$value['production_quantity'], 2);
  405. }
  406. return [true,array_values($list)];
  407. }
  408. /**
  409. * 不良品 详情
  410. * @param $data
  411. * @return array
  412. */
  413. public function badGoodsReportDetail($data){
  414. if(empty($data['production_no'])) return [false,'生产订单号不能为空!'];
  415. $list = OrdersProduct::where('production_no',$data['production_no'])
  416. ->select('id','production_time','production_no','out_order_no','out_order_no_time','customer_no','customer_name','table_header_mark','product_no','product_title','product_size','product_unit','dispatch_complete_quantity','finished_num','technology_material','technology_name','wood_name','process_mark','table_body_mark','out_crt_man','production_quantity','order_quantity')
  417. ->get()->toArray();
  418. //筛选出制单日期 分表的依据
  419. $out_order_no_time = array_unique(array_column($list,'out_order_no_time'));
  420. //制单日期
  421. $out_time = $this->checkSameQuarter($out_order_no_time);
  422. $detail = $detail_scrapp = [];
  423. $order_product_id = array_column($list,'id');
  424. $scrapp = ScrappCount::where('del_time',0)
  425. ->whereIn('order_product_id',$order_product_id)
  426. ->select('order_product_id','scrapp_num as bad_goods_num','scrapp_id')
  427. ->get()->toArray();
  428. foreach ($scrapp as $value){
  429. if(isset($detail[$value['order_product_id']])){
  430. $tmp = bcadd($detail[$value['order_product_id']],$value['bad_goods_num'],3);
  431. $detail[$value['order_product_id']] = $tmp;
  432. }else{
  433. $detail[$value['order_product_id']] = $value['bad_goods_num'];
  434. }
  435. if(isset($detail_scrapp[$value['order_product_id']])){
  436. $detail_scrapp[$value['order_product_id']] .= "," . $value['scrapp_id'];
  437. }else{
  438. $detail_scrapp[$value['order_product_id']] = $value['scrapp_id'];
  439. }
  440. }
  441. // foreach ($out_time as $value){
  442. // //子表搜索
  443. // $models = new OrdersProductProcess(['channel' => $value]);
  444. // $tmp = $models->whereIn('order_product_id',$order_product_id)
  445. // ->where('del_time',0)
  446. // ->where('status',4)
  447. // ->select('order_product_id',DB::raw('COUNT(id) as bad_goods_num'), DB::raw("GROUP_CONCAT(DISTINCT scrapp_id ORDER BY scrapp_id SEPARATOR ',') as scrapp_ids"))
  448. // ->groupBy('order_product_id')
  449. // ->get()
  450. // ->toArray();//不良品数据
  451. //
  452. // foreach ($tmp as $v){
  453. // if(isset($detail[$v['order_product_id']])){
  454. // $detail[$v['order_product_id']] += $v['bad_goods_num'];
  455. // }else{
  456. // $detail[$v['order_product_id']] = $v['bad_goods_num'];
  457. // }
  458. // if(isset($detail_scrapp[$v['order_product_id']])){
  459. // $detail_scrapp[$v['order_product_id']] .= "," . $v['scrapp_ids'];
  460. // }else{
  461. // $detail_scrapp[$v['order_product_id']] = $v['scrapp_ids'];
  462. // }
  463. // }
  464. // }
  465. $scrapp_map = Scrapp::where('del_time',0)->pluck('title','id')->toArray();
  466. foreach ($list as $key => $value) {
  467. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  468. $list[$key]['out_order_no_time'] = $value['out_order_no_time'] ? date('Y-m-d',$value['out_order_no_time']) : '';
  469. $list[$key]['bad_goods_num'] = $detail[$value['id']] ?? 0;
  470. $list[$key]['rate'] = number_format($list[$key]['bad_goods_num'] / $value['production_quantity'], 2);
  471. $scrapp = $detail_scrapp[$value['id']] ?? '';
  472. $tmp_str = '';
  473. if(! empty($scrapp)){
  474. $tmp = explode(',',$scrapp);
  475. foreach ($tmp as $vv){
  476. $tmp_str .= ($scrapp_map[$vv] ? $scrapp_map[$vv] . ',' : '');
  477. }
  478. }
  479. $list[$key]['scrapp_name'] = rtrim($tmp_str,',');
  480. }
  481. return [true, $list];
  482. }
  483. /**
  484. * 不良品原因
  485. * @param $data
  486. * @return array
  487. */
  488. public function badGoodsReasonReport($data){
  489. if(empty($data['production_time'][0]) || empty($data['production_time'][1])) return [false, '生产订单时间必须选择!'];
  490. //检索条件 生产订单主表----------------
  491. $model = OrdersProduct::where('del_time',0)->select('production_time','production_no','out_order_no','out_order_no_time','customer_no','customer_name','table_header_mark','order_quantity','production_quantity','out_crt_man','id');
  492. $model->whereBetween('production_time',[$data['production_time'][0],$data['production_time'][1]]);
  493. if(! empty($data['production_no'])) $model->where('production_no', 'LIKE', '%'.$data['production_no'].'%');
  494. if(! empty($data['out_order_no_time'][0]) && ! empty($data['out_order_no_time'][1])) $model->whereBetween('out_order_no_time',[$data['out_order_no_time'][0],$data['out_order_no_time'][1]]);
  495. if(! empty($data['out_order_no'])) $model->where('out_order_no', 'LIKE', '%'.$data['out_order_no'].'%');
  496. if(! empty($data['customer_no'])) $model->where('customer_no', 'LIKE', '%'.$data['customer_no'].'%');
  497. if(! empty($data['customer_name'])) $model->where('customer_name', 'LIKE', '%'.$data['customer_name'].'%');
  498. if(! empty($data['out_crt_man'])) $model->where('out_crt_man', 'LIKE', '%'.$data['out_crt_man'].'%');
  499. $orderList = $model->get()->toArray();
  500. //生产订单主表----------------
  501. //筛选出制单日期 分表的依据
  502. $out_order_no_time = array_unique(array_column($orderList,'out_order_no_time'));
  503. //制单日期
  504. $out_time = $this->checkSameQuarter($out_order_no_time);
  505. //分组以后的订单列表
  506. $list = [];
  507. foreach ($orderList as $value){
  508. if(! isset($list[$value['id']])){
  509. $list[$value['id']] = $value;
  510. }else{
  511. $list[$value['id']]['order_quantity'] += $value['order_quantity'];
  512. $list[$value['id']]['production_quantity'] += $value['production_quantity'];
  513. }
  514. }unset($orderList);
  515. //查询分表数据
  516. $production_id = array_keys($list);
  517. $detail = [];
  518. $scrapp = ScrappCount::where('del_time',0)
  519. ->whereIn('order_product_id',$production_id)
  520. ->select('order_product_id','scrapp_num as bad_goods_num')
  521. ->get()->toArray();
  522. foreach ($scrapp as $value){
  523. if(isset($detail[$value['order_product_id']])){
  524. $tmp = bcadd($detail[$value['order_product_id']],$value['bad_goods_num'],3);
  525. $detail[$value['order_product_id']] = $tmp;
  526. }else{
  527. $detail[$value['order_product_id']] = $value['bad_goods_num'];
  528. }
  529. }
  530. // foreach ($out_time as $value){
  531. // //子表搜索
  532. // $models = new OrdersProductProcess(['channel' => $value]);
  533. // $tmp = $models->whereIn('order_product_id',$production_id)
  534. // ->where('del_time',0)
  535. // ->where('status',4)
  536. // ->select('order_product_id',DB::raw('COUNT(id) as bad_goods_num'))
  537. // ->groupBy('order_product_id')
  538. // ->get()->toArray();//不良品数据
  539. //
  540. // foreach ($tmp as $t){
  541. // if(isset($detail[$t['order_product_id']])){
  542. // $detail[$t['order_product_id']] += $t['bad_goods_num'];
  543. // }else{
  544. // $detail[$t['order_product_id']] = $t['bad_goods_num'];
  545. // }
  546. // }
  547. // }
  548. //返回统计数据
  549. foreach ($list as $key => $value) {
  550. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  551. $list[$key]['out_order_no_time'] = $value['out_order_no_time'] ? date('Y-m-d',$value['out_order_no_time']) : '';
  552. $del_num = $detail[$value['id']] ?? 0;
  553. $list[$key]['bad_goods_num'] = $del_num;
  554. $list[$key]['rate'] = bcdiv($del_num ,$value['production_quantity'], 2);
  555. }
  556. return [true,array_values($list)];
  557. }
  558. //不良品原因 详情
  559. public function badGoodsReasonReportDetail($data){
  560. if(empty($data['production_no'])) return [false,'生产订单号不能为空!'];
  561. $list = OrdersProduct::where('production_no',$data['production_no'])
  562. ->select('id','production_time','production_no','out_order_no','out_order_no_time','customer_no','customer_name','table_header_mark','product_no','product_title','product_size','product_unit','dispatch_complete_quantity','finished_num','technology_material','technology_name','wood_name','process_mark','table_body_mark','out_crt_man','production_quantity')
  563. ->get()->toArray();
  564. //筛选出制单日期 分表的依据
  565. $out_order_no_time = array_unique(array_column($list,'out_order_no_time'));
  566. //制单日期
  567. $out_time = $this->checkSameQuarter($out_order_no_time);
  568. $detail = $scrapp_id = $team = $man = [];
  569. $order_product_id = array_column($list,'id');
  570. $scrapp = ScrappCount::where('del_time',0)
  571. ->whereIn('order_product_id',$order_product_id)
  572. ->select('order_product_id','scrapp_num as bad_goods_num','scrapp_id','team_id','finished_id')
  573. ->get()->toArray();
  574. foreach ($scrapp as $value){
  575. if(isset($detail[$value['order_product_id']])){
  576. foreach ($detail[$value['order_product_id']] as $k => $d){
  577. if($k == $value['scrapp_id']){
  578. $t = bcadd($detail[$value['order_product_id']][$k]['bad_goods_num'], $value['bad_goods_num'],3);
  579. $detail[$value['order_product_id']][$k]['bad_goods_num'] = $t;
  580. }else{
  581. $detail[$value['order_product_id']][$value['scrapp_id']] = $value;
  582. }
  583. }
  584. }else{
  585. $detail[$value['order_product_id']][$value['scrapp_id']] = $value;
  586. }
  587. if(! in_array($value['scrapp_id'], $scrapp_id)) $scrapp_id[] = $value['scrapp_id'];
  588. if(! in_array($value['team_id'], $team)) $team[] = $value['team_id'];
  589. if(! in_array($value['finished_id'], $man)) $man[] = $value['finished_id'];
  590. }
  591. // foreach ($out_time as $value){
  592. // //子表搜索
  593. // $models = new OrdersProductProcess(['channel' => $value]);
  594. // $tmp = $models->where('order_product_id',$order_product_id)
  595. // ->where('del_time',0)
  596. // ->where('status',4)
  597. // ->select('order_product_id','scrapp_id','team_id','finished_id',DB::raw('COUNT(id) as bad_goods_num'))
  598. // ->groupBy('order_product_id','scrapp_id')
  599. // ->get()->toArray();//不良品数据
  600. //
  601. // foreach ($tmp as $v){
  602. // if(! in_array($v['scrapp_id'], $scrapp_id)) $scrapp_id[] = $v['scrapp_id'];
  603. // if(! in_array($v['team_id'], $team)) $team[] = $v['team_id'];
  604. // if(! in_array($v['finished_id'], $man)) $man[] = $v['finished_id'];
  605. // if(isset($detail[$v['order_product_id']])){
  606. // foreach ($detail[$v['order_product_id']] as $k => $d){
  607. // if($k == $v['scrapp_id']){
  608. // $detail[$v['order_product_id']][$k]['bad_goods_num'] += $v['bad_goods_num'];
  609. // }else{
  610. // $detail[$v['order_product_id']][$v['scrapp_id']] = $v;
  611. // }
  612. // }
  613. // }else{
  614. // $detail[$v['order_product_id']][$v['scrapp_id']] = $v;
  615. // }
  616. // }
  617. // }
  618. //次品原因 班组 人员
  619. $map = Scrapp::whereIn('id',$scrapp_id)
  620. ->pluck('title','id')
  621. ->toArray();
  622. $map1 = Team::whereIn('id',$team)
  623. ->pluck('title','id')
  624. ->toArray();
  625. $map2 = Employee::whereIn('id',$man)
  626. ->pluck('emp_name','id')
  627. ->toArray();
  628. foreach ($list as $key => $value) {
  629. $list[$key]['production_time'] = $value['production_time'] ? date('Y-m-d',$value['production_time']) : '';
  630. $list[$key]['out_order_no_time'] = $value['out_order_no_time'] ? date('Y-m-d',$value['out_order_no_time']) : '';
  631. $sum = 0;
  632. $d_t = $detail[$value['id']] ?? [];
  633. if(! empty($d_t)) $sum = array_sum(array_column($d_t,'bad_goods_num'));
  634. $list[$key]['rate'] = bcdiv($sum ,$value['production_quantity'], 2) * 100 ."%";
  635. foreach ($d_t as $dk => $dv){
  636. $d_t[$dk]['rate'] = bcdiv($dv['bad_goods_num'] ,$value['production_quantity'], 2) * 100 . "%";
  637. $d_t[$dk]['scrapp_name'] = $map[$dv['scrapp_id']] ?? '';
  638. $d_t[$dk]['team_name'] = $map1[$dv['team_id']] ?? '';
  639. $d_t[$dk]['man_name'] = $map2[$dv['finished_id']] ?? '';
  640. }
  641. $list[$key]['bad_goods'] = array_values($d_t);
  642. }
  643. return [true, $list];
  644. }
  645. //设备统计报表
  646. public function deviceStatisticsReport($data){
  647. if(empty($data['time'][0]) || empty($data['time'][1])) return [false, '时间必须选择!'];
  648. $day = $this->returnDays($data['time']);
  649. if($day > 10) return [false, '设备数据查询时间仅支持范围区间在10天内'];
  650. $model = SystemL::where('time','>=',$data['time'][0])
  651. ->where('time','<',$data['time'][1]);
  652. if(! empty($data['title'])) $model->whereIn('device_name',$data['title']);
  653. $result = $model->select('device_name','time','value','data_point_name')
  654. ->get()
  655. ->toArray();
  656. if(empty($result)) return [true,[]];
  657. $device_name = array_values(array_unique(array_column($result,'device_name')));
  658. //运行时间 工作时间 故障
  659. $run_time = $process_time = $fault = [];
  660. foreach ($result as $value){
  661. if($value['data_point_name'] == SystemL::run || $value['data_point_name'] == SystemL::standBy){
  662. //运行次数
  663. if(isset($run_time[$value['device_name']])){
  664. $run_time[$value['device_name']] += 1;
  665. }else{
  666. $run_time[$value['device_name']] = 1;
  667. }
  668. }
  669. if($value['data_point_name'] == SystemL::standBy){
  670. //工作次数
  671. if(isset($process_time[$value['device_name']])){
  672. $process_time[$value['device_name']] += 1;
  673. }else{
  674. $process_time[$value['device_name']] = 1;
  675. }
  676. }
  677. if($value['data_point_name'] == SystemL::stop){
  678. //设备故障次数
  679. if(isset($fault[$value['device_name']])){
  680. $fault[$value['device_name']] += 1;
  681. }else{
  682. $fault[$value['device_name']] = 1;
  683. }
  684. }
  685. }
  686. foreach ($device_name as $key => $value){
  687. //运行次数
  688. $run_num = $run_time[$value] ?? 0;
  689. //工作次数
  690. $process_num = $process_time[$value] ?? 0;
  691. //故障次数
  692. $fault_tmp = $fault[$value] ?? 0;
  693. //运行时间
  694. $run_time_tmp = $this->calTimeReturnMin($run_num);
  695. //工作时间
  696. $process_time_tmp = $this->calTimeReturnMin($process_num);
  697. //故障时间
  698. $fault_time_tmp = $this->calTimeReturnMin($fault_tmp);
  699. //待机时间
  700. $standby_time_tmp = number_format($run_time_tmp - $process_time_tmp,2);
  701. //计划运行时间 工作时间 - 计划停机 (没有计划停机)
  702. //实际运行时间 计划运行时间 -故障停机 - 设备调整(没有设备调整
  703. $true_process_time = $process_time_tmp - $fault_time_tmp;
  704. //有效率 实际/计划运行 时间
  705. $efficient = $process_time_tmp > 0 ? number_format($true_process_time / $process_time_tmp,2) : 0;
  706. //表现性 加工数量/实际运行时间
  707. $expressive = $true_process_time > 0 ? number_format($process_num / $true_process_time,2) : 0;
  708. //质量指数 加工数量- 废品数量 / 加工数量
  709. $quality_index = $process_num > 0 ? number_format(($process_num - $fault_tmp) / $process_num,2) : 0;
  710. //OEE
  711. $oee = number_format($efficient * $expressive * $quality_index,2);
  712. $device_name[$key] = [
  713. 'device_name' => $value,
  714. 'run_time' => $run_time_tmp,
  715. 'process_time' => $process_time_tmp,
  716. 'standby_time' => $standby_time_tmp,
  717. 'process_num' => $process_num,
  718. 'fault_num' => $fault_tmp,
  719. 'oee' => $oee,
  720. // 'e' => $efficient,
  721. // 'ex' => $expressive,
  722. // 'true_process_time' => $true_process_time,
  723. // 'qua' => $quality_index
  724. ];
  725. }
  726. return [true,$device_name];
  727. }
  728. public function deviceStatisticsReportDetail($data){
  729. if(empty($data['device_name']) || empty($data['time'][0]) || empty($data['time'][0])) return [false,'参数不能为空!'];
  730. $day = $this->returnDays($data['time']);
  731. if($day > 10) return [false, '设备数据查询时间仅支持范围区间在10天内'];
  732. $result = SystemL::where('time','>=',$data['time'][0])
  733. ->where('time','<',$data['time'][1])
  734. ->where('device_name',$data['device_name'])
  735. ->select('device_name','time','data_point_name')
  736. ->get()->toArray();
  737. $return = [
  738. 'run' => [],
  739. 'work' => [],
  740. 'stop' => [],
  741. 'stand_by' => [],
  742. ];
  743. foreach ($result as $key => $value){
  744. $time = date('Y-m-d H:i:s',$value['time'] / 1000);
  745. $stop_time = date('Y-m-d H:i:s',$value['time'] / 1000 + rand(10,40));
  746. if($value['data_point_name'] == SystemL::run || $value['data_point_name'] == SystemL::standBy){
  747. $return['run'][] = [
  748. 'time' => $time,
  749. 'stop_time' => $stop_time
  750. ];
  751. }
  752. if($value['data_point_name'] == SystemL::standBy){
  753. $return['work'][] = [
  754. 'time' => $time,
  755. 'stop_time' => $stop_time
  756. ];
  757. }
  758. if($value['data_point_name'] == SystemL::stop){
  759. $return['stop'][] = [
  760. 'time' => $time,
  761. 'stop_time' => $stop_time
  762. ];
  763. }
  764. }
  765. return [true, $return];
  766. }
  767. /**
  768. * 数据分析图
  769. * @param $data
  770. * @return array
  771. */
  772. public function deviceStatisticsReportChart($data){
  773. if(empty($data['time'][0]) || empty($data['time'][1])) return [false, '时间必须选择!'];
  774. $day = $this->returnDays($data['time'], false);
  775. if($day > 31) return [false, '查询时间仅支持范围区间在31天内'];
  776. $process_time = [];
  777. $device = (new EquipmentService())->getDeviceList();
  778. $result = SystemL::where('time','>=',$data['time'][0])
  779. ->where('time','<',$data['time'][1])
  780. ->where('data_point_name',SystemL::standBy)
  781. ->whereIn('device_name',array_keys($device))
  782. ->select('device_name','time','value')
  783. ->get()->toArray();
  784. //所有的时间
  785. $time_all = [];
  786. foreach ($result as $value){
  787. $time = date('Y-m-d',$value['time'] / 1000);
  788. //工作 运行次数
  789. if(isset($process_time[$value['device_name']][$time])){
  790. $process_time[$value['device_name']][$time] += 1;
  791. }else{
  792. $process_time[$value['device_name']][$time] = 1;
  793. }
  794. if(! in_array($time, $time_all)) $time_all[] = $time;
  795. }
  796. sort($time_all);
  797. //数据结构模型
  798. foreach ($device as $k => $v){
  799. if(isset($process_time[$k])){
  800. foreach ($time_all as $t){
  801. if(! isset($process_time[$k][$t])){
  802. $process_time[$k][$t] = 0;
  803. }
  804. }
  805. }else{
  806. foreach ($time_all as $t){
  807. $process_time[$k][$t] = 0;
  808. }
  809. }
  810. }
  811. $return = [];
  812. foreach ($process_time as $key => $value){
  813. $tmp['title'] = $key;
  814. $tmp['list'] = [];
  815. foreach ($value as $k => $v){
  816. $tmp['list'][] = [
  817. 'time' => $k,
  818. 'num' => $v
  819. ];
  820. }
  821. $return[] = $tmp;
  822. }
  823. return [true, $return];
  824. }
  825. /**
  826. * 数据OEE分析图
  827. * @param $data
  828. * @return array
  829. */
  830. public function deviceStatisticsReportOEEChart($data){
  831. if(empty($data['time'][0]) || empty($data['time'][1])) return [false, '时间必须选择!'];
  832. $day = $this->returnDays($data['time'], false);
  833. if($day > 31) return [false, '查询时间仅支持范围区间在31天内'];
  834. $device = (new EquipmentService())->getDeviceList();
  835. $device_name = array_keys($device);
  836. //获取数据
  837. $result = SystemL::where('time','>=',$data['time'][0])
  838. ->where('time','<',$data['time'][1])
  839. ->whereIn('device_name', $device_name)
  840. ->select('device_name','time','value','data_point_name')
  841. ->get()->toArray();
  842. if(empty($result)) return [true,[]];
  843. $run_time = $process_time = $fault = $time_all = [];
  844. foreach ($result as $value){
  845. $time = date("Y-m-d",$value['time'] / 1000);
  846. if($value['data_point_name'] == SystemL::run || $value['data_point_name'] == SystemL::standBy){
  847. //运行次数
  848. if(isset($run_time[$value['device_name']][$time])){
  849. $run_time[$value['device_name']][$time] += 1;
  850. }else{
  851. $run_time[$value['device_name']][$time] = 1;
  852. }
  853. }
  854. if($value['data_point_name'] == SystemL::standBy){
  855. //工作次数
  856. if(isset($process_time[$value['device_name']][$time])){
  857. $process_time[$value['device_name']][$time] += 1;
  858. }else{
  859. $process_time[$value['device_name']][$time] = 1;
  860. }
  861. }
  862. if($value['data_point_name'] == SystemL::stop){
  863. //故障次数
  864. if(isset($fault[$value['device_name']][$time])){
  865. $fault[$value['device_name']][$time] += 1;
  866. }else{
  867. $fault[$value['device_name']][$time] = 1;
  868. }
  869. }
  870. if(! in_array($time, $time_all)) $time_all[] = $time;
  871. }
  872. sort($time_all);
  873. //组织模型 返回大致的数据结构
  874. $models = [];
  875. foreach ($device as $k => $v){
  876. foreach ($time_all as $t){
  877. $models[$k][$t] = 0;
  878. }
  879. }
  880. //填充模型里的数据
  881. foreach ($device_name as $value){//设备名
  882. foreach ($time_all as $d_val){
  883. //运行次数
  884. $run_num = $run_time[$value][$d_val] ?? 0;
  885. //工作次数
  886. $process_num = $process_time[$value][$d_val] ?? 0;
  887. //故障次数
  888. $fault_tmp = $fault[$value][$d_val] ?? 0;
  889. //运行时间
  890. $run_time_tmp = $this->calTimeReturnMin($run_num);
  891. //工作时间
  892. $process_time_tmp = $this->calTimeReturnMin($process_num);
  893. //故障时间
  894. $fault_time_tmp = $this->calTimeReturnMin($fault_tmp);
  895. //计划运行时间 工作时间 - 计划停机
  896. //实际运行时间 计划运行时间 -故障停机 - 设备调整
  897. $true_process_time = $process_time_tmp - $fault_time_tmp;
  898. //有效率 实际/计划运行 时间
  899. $efficient = $process_time_tmp > 0 ? number_format($true_process_time / $process_time_tmp,2) : 0;
  900. //表现性 加工数量/实际运行时间
  901. $expressive = $true_process_time > 0 ? number_format($process_num / $true_process_time,2) : 0;
  902. //质量指数 加工数量- 废品数量 / 加工数量
  903. $quality_index = $process_num > 0 ? number_format(($process_num - $fault_tmp) / $process_num,2) : 0;
  904. //OEE
  905. $oee = number_format($efficient * $expressive * $quality_index,2);
  906. //模型里赋值
  907. if(isset($models[$value][$d_val])){
  908. $models[$value][$d_val] = $oee;
  909. }
  910. }
  911. }
  912. //返回结果
  913. $final = [];
  914. foreach ($models as $key => $value){
  915. $tmp['title'] = $key;
  916. $tmp['list'] = [];
  917. foreach ($value as $k => $v){
  918. $tmp['list'][] = [
  919. 'time' => $k,
  920. 'num' => $v
  921. ];
  922. }
  923. $final[] = $tmp;
  924. }
  925. return [true,$final];
  926. }
  927. /**
  928. * 用于计算时间
  929. * @param $minute
  930. * @return string
  931. */
  932. public function calTimeReturnMin($minute){
  933. return number_format($minute * 1.5 / 60,2);
  934. }
  935. /**
  936. * 报工
  937. * @param $data
  938. * @return array
  939. */
  940. public function statisticsReportWorkingChart($data){
  941. if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '报工单生成时间必须选择!'];
  942. //人员
  943. $finished_id = $data['finished_id'] ?? [];
  944. //工序
  945. $process_id = $data['process_id'] ?? [];
  946. $result = ReportWorkingDetail::where('del_time',0)
  947. ->where('crt_time',">=",$data['crt_time'][0])
  948. ->where('crt_time',"<=",$data['crt_time'][1])
  949. ->when(! empty($finished_id), function ($query) use ($finished_id) {
  950. return $query->whereIn('finished_id', $finished_id);
  951. })
  952. ->when(! empty($process_id), function ($query) use ($process_id) {
  953. return $query->whereIn('process_id', $process_id);
  954. })
  955. ->get()->toArray();
  956. if(empty($result)) return [true, []];
  957. $emp_map = Employee::whereIn('id',array_unique(array_column($result,'finished_id')))
  958. ->pluck('emp_name','id')
  959. ->toArray();
  960. $process_map = Process::whereIn('id',array_unique(array_column($result,'process_id')))
  961. ->pluck('title','id')
  962. ->toArray();
  963. //派工单
  964. $d = DispatchSub::where('del_time',0)
  965. ->whereIn('id', array_unique(array_column($result,'data_id')))
  966. ->select('id', 'dispatch_no as order_no', 'product_title','technology_name','product_no','product_unit','price')
  967. ->get()->toArray();
  968. $d_tmp = array_column($d,null,'id');
  969. $return = [];
  970. foreach ($result as $value){
  971. $tmp = $d_tmp[$value['data_id']] ?? [];
  972. if(empty($tmp)) continue;
  973. $string = $value['finished_id'] . $value['process_id'];
  974. if(isset($return[$string])){
  975. $quantity = bcadd($value['quantity'], $return[$string]['quantity'], 3);
  976. $return[$string]['quantity'] = $quantity;
  977. if(! in_array($value['id'], $return[$string]['report_id'])){
  978. $id = array_merge_recursive($return[$string]['report_id'], [$value['id']]);
  979. $return[$string]['report_id'] = $id;
  980. }
  981. }else{
  982. $return[$string] = [
  983. 'finished_id' => $value['finished_id'],
  984. 'finished_title' => $emp_map[$value['finished_id']] ?? "",
  985. 'process_id' => $value['process_id'],
  986. 'process_title' => $process_map[$value['process_id']] ?? "",
  987. 'quantity' => $value['quantity'],
  988. 'report_id' => [$value['id']],
  989. ];
  990. }
  991. }
  992. return [true, array_values($return)];
  993. }
  994. public function statisticsReportWorkingChartDetail($data){
  995. if(empty($data['report_id'])) return [false, '报工单数据必须选择!'];
  996. $result = ReportWorkingDetail::where('del_time',0)
  997. ->whereIn('id', $data['report_id'])
  998. ->get()->toArray();
  999. if(empty($result)) return [false, '报工单数据不存在或已被删除'];
  1000. //派工单
  1001. $d = DispatchSub::where('del_time',0)
  1002. ->whereIn('id', array_unique(array_column($result,'data_id')))
  1003. ->select('id', 'dispatch_no as order_no', 'product_title','technology_name','product_no','product_unit','price')
  1004. ->get()->toArray();
  1005. $d_tmp = array_column($d,null,'id');
  1006. $return = [];
  1007. foreach ($result as $value){
  1008. $tmp = $d_tmp[$value['data_id']] ?? [];
  1009. if(empty($tmp)) continue;
  1010. $string = $tmp['id'] . $tmp['product_no'] . $tmp['technology_name'];
  1011. if(isset($return[$string])){
  1012. $return[$string]['quantity'] += $value['quantity'];
  1013. }else{
  1014. $return[$string] = [
  1015. 'order_no' => $tmp['order_no'] ?? "",
  1016. 'product_title' => $tmp["product_title"] ?? "",
  1017. 'product_no' => $tmp["product_no"] ?? "",
  1018. 'product_unit' => $tmp["product_unit"] ?? "",
  1019. 'technology_name' => $tmp['technology_name'] ?? "",
  1020. 'wood_name' => $tmp['wood_name'] ?? "",
  1021. 'quantity' => $value['quantity'],
  1022. ];
  1023. }
  1024. }
  1025. return [true, array_values($return)];
  1026. }
  1027. }