QcodeAdd.php 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. <?php
  2. namespace app\admin\controller;
  3. use app\admin\model\QcodeCompany;
  4. use app\admin\model\QcodeGsmc;
  5. use app\admin\model\QcodeProduct;
  6. use app\common\controller\Backend;
  7. use app\admin\model\ResetFlow;
  8. use app\admin\model\QcodeLarge;
  9. use app\admin\model\QcodeBach;
  10. use app\admin\model\QcodeSmall;
  11. use app\admin\model\QcodeLiushui;
  12. use fast\Arr;
  13. use MongoDB\BSON\ObjectId;
  14. use think\Db;
  15. use think\Session;
  16. class QcodeAdd extends Backend{
  17. /**
  18. * 首页展示
  19. */
  20. public function index(){
  21. //获取登录账号信息【厂商信息】
  22. $userinfo = Session::get('admin');
  23. $data = [
  24. 'nickname' => $userinfo['company_name'],
  25. 'postcode' => $userinfo['postcode'],
  26. 'mobile' => $userinfo['mobile'],
  27. 'printer_code' => $userinfo['printer_code'],
  28. 'company_address' => $userinfo['company_address']
  29. ];
  30. $this->view->assign('row',$data);
  31. //将对此账号创建公司唯一id,进行创建公司对应公司表名company id
  32. $user_company_value = Db::name('admin')->where('id', $userinfo['id'])->value('company');
  33. if (empty($user_company_value)) {
  34. $max_company = Db::name('admin')->max('company');
  35. $new_company_value = $max_company ? ($max_company + 1) : 1;
  36. Db::name('admin')->where('id', $userinfo['id'])->update(['company' => $new_company_value]);
  37. } else {
  38. $new_company_value = $user_company_value;
  39. }
  40. $tableNames = [
  41. $new_company_value . '_qcode_bach',
  42. $new_company_value . '_qcode_company',
  43. $new_company_value . '_qcode_large',
  44. $new_company_value . '_qcode_liushui',
  45. $new_company_value . '_qcode_small',
  46. $new_company_value . '_reset_flow',
  47. ];
  48. foreach ($tableNames as $tableName) {
  49. try {
  50. Db::connect('mongodb')->name($tableName)->insert(['init' => 1]);
  51. // 删除测试数据(可选,如果不想保留这个测试数据)
  52. Db::connect('mongodb')->name($tableName)->where('init', 1)->delete();
  53. } catch (\Exception $e) {
  54. echo "创建集合 {$tableName} 失败:" . $e->getMessage();
  55. }
  56. }
  57. return $this->view->fetch();
  58. }
  59. /**
  60. * 获取产品信息
  61. */
  62. public function product(){
  63. $params = input('');
  64. $page = max(1, (int)$params['page']);
  65. $limit = max(1, (int)$params['limit']);
  66. $offset = ($page - 1) * $limit;
  67. // 获取工单编号列表
  68. $db3 = Db::connect(config('database.db3'));
  69. $gdRows = $db3->query("SELECT DISTINCT `Gd_gdbh`, `Gd_客户代号`, `Gd_cpdh` FROM `工单_基本资料` WHERE `Gd_客户代号` = ?", ['J0031']);
  70. $Gd_gdbhList = array_column($gdRows, 'Gd_gdbh');
  71. $gdbhList = array_column($gdRows, 'Gd_cpdh');
  72. if (empty($gdbhList)) {
  73. $this->assign([
  74. 'data' => '',
  75. 'total' => '',
  76. ]);
  77. }
  78. // Mongo 查询
  79. $mongo = \think\Db::connect('mongodb');
  80. $where = ['成品编码' => ['in', $gdbhList],'jjcp_gdbh' => ['in', $Gd_gdbhList], 'jjcp_smb' => '末 板'];
  81. // $where = ['成品编码' => ['in', $gdbhList], 'jjcp_smb' => '末 板'];
  82. if (!empty($params['search'])) {
  83. $where['成品编码|成品名称|jjcp_gdbh|订单编号'] = new \MongoDB\BSON\Regex($params['search'], 'i');
  84. }
  85. // 查询符合条件的成品数据
  86. $al_products = $mongo->name('finished_products')
  87. ->where($where)
  88. ->order('Sys_rq', 'desc')
  89. ->select();
  90. // 查询 texts = 新增产品 的数据
  91. $xz_products = $mongo->name('finished_products')
  92. ->where('texts', '新增产品')
  93. ->order('Sys_rq', 'desc')
  94. ->select();
  95. // 合并数据
  96. $all_products = array_merge($al_products, $xz_products);
  97. // 分组聚合处理
  98. $grouped_products = [];
  99. foreach ($all_products as $item) {
  100. // 转换日期格式(如果是 d/m/Y H:i:s)
  101. $date = \DateTime::createFromFormat('d/m/Y H:i:s', $item['Sys_rq']);
  102. $item['Sys_rq'] = $date ? $date->format('Y-m-d H:i:s') : $item['Sys_rq'];
  103. $group_key = $item['订单编号'] . '_' . $item['jjcp_gdbh'];
  104. if (!isset($grouped_products[$group_key])) {
  105. $grouped_products[$group_key] = [
  106. 'Sys_rq' => $item['Sys_rq'],
  107. 'order_ddbh' => $item['订单编号'],
  108. 'gdbh' => $item['jjcp_gdbh'],
  109. 'cpbm' => $item['成品编码'],
  110. 'cpmc' => $item['成品名称'],
  111. 'sl' => 0,
  112. 'cpdh_list' => [],
  113. 'cpbm_list' => []
  114. ];
  115. }
  116. $grouped_products[$group_key]['sl'] += (int)$item['jjcp_sl'];
  117. if (!in_array($item['jjcp_cpdh'], $grouped_products[$group_key]['cpdh_list'])) {
  118. $grouped_products[$group_key]['cpdh_list'][] = $item['jjcp_cpdh'];
  119. }
  120. if (!in_array($item['成品编码'], $grouped_products[$group_key]['cpbm_list'])) {
  121. $grouped_products[$group_key]['cpbm_list'][] = $item['成品编码'];
  122. }
  123. }
  124. // 格式化列表字符串
  125. foreach ($grouped_products as &$group) {
  126. $group['cpdh'] = implode(',', $group['cpdh_list']);
  127. $group['cpbm'] = implode(',', $group['cpbm_list']);
  128. unset($group['cpdh_list'], $group['cpbm_list']);
  129. }
  130. // 聚合结果排序(按时间降序)
  131. $all_grouped = array_values($grouped_products);
  132. usort($all_grouped, function ($a, $b) {
  133. $timeA = strtotime($a['Sys_rq']) ?: 0;
  134. $timeB = strtotime($b['Sys_rq']) ?: 0;
  135. return $timeB <=> $timeA;
  136. });
  137. // 再分页
  138. $total = count($all_grouped);
  139. $paged_grouped = array_slice($all_grouped, $offset, $limit);
  140. // 查询库存并计算剩余数
  141. foreach ($paged_grouped as &$prod) {
  142. $inventory = $mongo->name('inventory_summary')->where([
  143. 'order_ddbh' => $prod['order_ddbh'],
  144. 'gdbh' => $prod['gdbh'],
  145. 'cpmc' => $prod['cpmc'],
  146. ])->find();
  147. $total_chu_quantity = isset($inventory['total_chu_quantity']) ? (int)$inventory['total_chu_quantity'] : 0;
  148. $prod['total_chu_quantity'] = $total_chu_quantity;
  149. $prod['remaining_quantity'] = $prod['sl'] - $total_chu_quantity;
  150. }
  151. unset($prod);
  152. return json([
  153. 'code' => 1,
  154. 'data' => $paged_grouped,
  155. 'total' => $total,
  156. 'page' => $page,
  157. 'limit' => $limit
  158. ]);
  159. }
  160. public function add_bach()
  161. {
  162. if (!$this->request->isAjax()) {
  163. $this->error('请求错误');
  164. }
  165. $data = input('row');
  166. if (empty($data)) {
  167. $this->error('参数错误');
  168. }
  169. $data = json_decode($data, true);
  170. if (json_last_error() !== JSON_ERROR_NONE) {
  171. $this->error('JSON解析错误');
  172. }
  173. if (empty($data['products'])) {
  174. $this->error('产品数据不能为空');
  175. }
  176. $userinfo = Session::get('admin');
  177. if (empty($userinfo) || !isset($userinfo['company'])) {
  178. $this->error('用户信息获取失败');
  179. }
  180. $mongo = \think\Db::connect('mongodb');
  181. $collection = $userinfo['company'] . '_qcode_bach';
  182. $bachsummary = $userinfo['company'] . '_qcode_bachsummary';
  183. $insertData = [];
  184. $currentday = date('Y-m-d');
  185. $currentTime = date('Y-m-d H:i:s');
  186. $timestamp = time();
  187. $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999);
  188. $totalQuantity = 0;
  189. $totalBoxes = 0;
  190. $totalPallets = 0;
  191. $palletSequence = 1; // 全局托盘序号计数器
  192. foreach ($data['products'] as $product) {
  193. $small_num = 20;
  194. $tray_num = 6;
  195. $box_num = 3;
  196. $total_boxes = $tray_num * $box_num;
  197. $remaining_quantity = (int)$product['remaining_quantity'];
  198. $larger_num = ceil($remaining_quantity / $small_num);
  199. $large_num = ceil($larger_num / $total_boxes);
  200. $totalQuantity += $remaining_quantity;
  201. $totalBoxes += $larger_num;
  202. $totalPallets += $large_num;
  203. // 计算完整托盘数和剩余箱数
  204. $full_pallets = floor($larger_num / $total_boxes);
  205. $remaining_boxes = $larger_num % $total_boxes;
  206. // 为每个托盘创建记录
  207. for ($i = 1; $i <= $large_num; $i++) {
  208. $is_full_pallet = ($i <= $full_pallets) || ($i == $full_pallets + 1 && $remaining_boxes == $total_boxes);
  209. $boxes_in_pallet = $is_full_pallet ? $total_boxes : ($i == $full_pallets + 1 ? $remaining_boxes : 0);
  210. $insertData[] = [
  211. // 用户信息相关字段
  212. 'userid' => $userinfo['id'], // 用户ID
  213. 'supplier_id' => $userinfo['id'], // 供应商ID (同用户ID)
  214. 'supplier_code' => $userinfo['printer_code'], // 供应商编码/打印机编码
  215. 'supplier_name' => $data['company_name'], // 供应商名称/公司名称
  216. // 托盘信息相关字段
  217. 'pallet' => $palletSequence, // 托盘编号 (全局唯一序号)
  218. 'pallet_sequence' => $palletSequence, // 托盘序号 (同pallet字段,冗余设计)
  219. 'pallet_type' => $is_full_pallet ? 'full' : 'partial', // 托盘类型: full-整托/partial-部分托
  220. // 产品基本信息
  221. 'matter_no' => $product['gdbh'], // 产品编号/工单编号
  222. 'matter_id' => $product['gdbh'], // 产品ID (同工单编号)
  223. 'matter_type' => '01', // 产品类型 (固定值01)
  224. 'order_ddbh' => $product['order_ddbh'], // 订单编号
  225. 'cpbm' => $product['cpbm'], // 产品编码
  226. 'matter_name' => $product['cpmc'], // 产品名称
  227. 'remark' => $product['remark'], // 备注信息
  228. // 数量单位信息
  229. 'num_danwei' => '2', // 数量单位类型 (固定值2)
  230. 'danwei' => '套', // 单位名称 (套)
  231. // 数量计算相关字段
  232. 'num' => $i <= $full_pallets ? $small_num * $total_boxes : ($i == $full_pallets + 1 ? $small_num * $remaining_boxes : 0), // 本托盘实际产品数量
  233. 'small_num' => $small_num, // 每箱产品数量 (固定20)
  234. 'tray_num' => $tray_num, // 每层箱数 (固定6)
  235. 'box_num' => $box_num, // 每托盘层数 (固定3)
  236. 'total_boxes' => $total_boxes, // 每托盘总箱数 (tray_num * box_num)
  237. 'boxes_in_pallet' => $boxes_in_pallet, // 本托盘实际箱数 (full时为18,partial时为余数)
  238. // 托盘汇总信息
  239. 'large_num' => $large_num, // 本产品总托盘数
  240. 'larger_num' => $larger_num, // 本产品总箱数
  241. // 托盘尺寸规格
  242. 'pallet_height' => '1.05', // 托盘高度(米)
  243. 'pallet_length' => '0.9', // 托盘长度(米)
  244. 'pallet_width' => '1.2', // 托盘宽度(米)
  245. // 物流相关字段 (当前为空)
  246. 'l_reservation' => '', // 物流预留字段
  247. 'l_flow' => '1', // 物流流向 (固定值1)
  248. 'l_weight' => '', // 物流重量
  249. 's_flow' => '', // 备用流向字段
  250. 's_weight' => '', // 备用重量字段
  251. 's_reservation' => '', // 备用预留字段
  252. // 状态信息
  253. 'bach_status' => 0, // 批次状态 (0-初始状态)
  254. 'bach_ids' => $bachNum, // 批次编号 (唯一标识)
  255. 'large_endnum' => $large_num, // 本产品结束托盘号 (同large_num)
  256. // 日期相关字段
  257. 'manufacture_date' => '', // 生产日期 (空)
  258. 'print_date' => '', // 打印日期 (空)
  259. 'sys_rq' => $currentday, // 系统日期 (YYYY-MM-DD)
  260. 'created_at' => $currentTime, // 创建时间 (YYYY-MM-DD HH:MM:SS)
  261. 'create_time' => $timestamp, // 创建时间戳 (Unix timestamp)
  262. 'updated_at' => '', // 更新时间 (空)
  263. // 系统标志字段
  264. 'sync_flag' => '0', // 同步标志 (0-未同步)
  265. // 删除相关字段
  266. 'delete_time' => '', // 删除时间 (空)
  267. 'delect_time' => '' // 删除时间 (拼写错误,同delete_time)
  268. ];
  269. $palletSequence++; // 递增全局托盘序号
  270. }
  271. }
  272. $insertData_bachsummary = [
  273. 'bach_ids' => $bachNum,
  274. 'userid' => $userinfo['id'],
  275. 'supplier_id' => $userinfo['id'],
  276. 'supplier_code' => $userinfo['printer_code'],
  277. 'supplier_name' => $data['company_name'],
  278. 'total_quantity' => $totalQuantity,
  279. 'total_boxes' => $totalBoxes,
  280. 'total_pallets' => $totalPallets,
  281. 'full_pallets' => $totalPallets - count(array_filter($insertData, function($item) { return $item['pallet_type'] === 'partial'; })),
  282. 'partial_pallets' => count(array_filter($insertData, function($item) { return $item['pallet_type'] === 'partial'; })),
  283. 'product_count' => count($data['products']),
  284. 'bach_status' => 0,
  285. 'sys_rq' => $currentday,
  286. 'created_at' => $currentTime,
  287. 'create_time' => $timestamp,
  288. 'updated_at' => '',
  289. 'delete_time' => ''
  290. ];
  291. //echo "<pre>";
  292. //print_r($insertData);
  293. //echo "<pre>";die;
  294. // 插入数据
  295. $mongo->name($collection)->insertAll($insertData);
  296. $mongo->name($bachsummary)->insert($insertData_bachsummary);
  297. //die;
  298. // 更新库存信息
  299. foreach ($data['products'] as $product) {
  300. $where = [
  301. 'gdbh' => $product['gdbh'],
  302. 'order_ddbh' => $product['order_ddbh'],
  303. 'cpmc' => $product['cpmc'],
  304. ];
  305. $actual_quantity = isset($product['actual_quantity']) ? (int)$product['actual_quantity'] : 0;
  306. $remaining_quantity = isset($product['remaining_quantity']) ? (int)$product['remaining_quantity'] : 0;
  307. $insertData = [
  308. 'gdbh' => $product['gdbh'],
  309. 'order_ddbh' => $product['order_ddbh'],
  310. 'cpbm' => $product['cpbm'],
  311. 'cpmc' => $product['cpmc'],
  312. 'total_ru_quantity' => $remaining_quantity,
  313. 'total_chu_quantity' => $actual_quantity,
  314. 'remaining_quantity' => $remaining_quantity - $actual_quantity,
  315. 'created_at' => date('Y-m-d H:i:s'),
  316. 'updated_at' => '',
  317. 'mod_rq' => '',
  318. 'company' => $data['company_name'] ?? '',
  319. ];
  320. $existing = $mongo->name('inventory_summary')->where($where)->find();
  321. if ($existing) {
  322. $new_chu = (int)$existing['total_chu_quantity'] + $actual_quantity;
  323. $new_remaining = (int)$existing['remaining_quantity'] - $actual_quantity;
  324. $mongo->name('inventory_summary')
  325. ->where($where)
  326. ->update([
  327. 'total_ru_quantity' => (int)$existing['total_ru_quantity'],
  328. 'total_chu_quantity' => $new_chu,
  329. 'remaining_quantity' => $new_remaining,
  330. 'updated_at' => date('Y-m-d H:i:s'),
  331. ]);
  332. } else {
  333. $mongo->name('inventory_summary')->insert($insertData);
  334. }
  335. $mongo->name('inventory_records')->insert($insertData);
  336. }
  337. $this->success('添加成功');
  338. }
  339. // public function add_bach()
  340. // {
  341. // if (!$this->request->isAjax()) {
  342. // $this->error('请求错误');
  343. // }
  344. //
  345. // $data = input('row');
  346. // if (empty($data)) {
  347. // $this->error('参数错误');
  348. // }
  349. //
  350. // $data = json_decode($data, true);
  351. //
  352. // if (json_last_error() !== JSON_ERROR_NONE) {
  353. // $this->error('JSON解析错误');
  354. // }
  355. //
  356. // if (empty($data['products'])) {
  357. // $this->error('产品数据不能为空');
  358. // }
  359. //
  360. // $userinfo = Session::get('admin');
  361. // if (empty($userinfo) || !isset($userinfo['company'])) {
  362. // $this->error('用户信息获取失败');
  363. // }
  364. //
  365. // $mongo = \think\Db::connect('mongodb');
  366. // $collection = $userinfo['company'] . '_qcode_bach';
  367. // $bachsummary = $userinfo['company'] . '_qcode_bachsummary';
  368. //
  369. // $insertData = [];
  370. // $currentday = date('Y-m-d');
  371. // $currentTime = date('Y-m-d H:i:s');
  372. // $timestamp = time();
  373. // $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999);
  374. //
  375. // $totalQuantity = 0;
  376. // $totalBoxes = 0;
  377. // $totalPallets = 0;
  378. //
  379. // foreach ($data['products'] as $product) {
  380. // $small_num = 20;
  381. // $tray_num = 6;
  382. // $box_num = 3;
  383. // $total_boxes = $tray_num * $box_num;
  384. //
  385. // $remaining_quantity = (int)$product['remaining_quantity'];
  386. // $larger_num = ceil($remaining_quantity / $small_num);
  387. // $large_num = ceil($larger_num / $total_boxes);
  388. //
  389. // $totalQuantity += $remaining_quantity;
  390. // $totalBoxes += $larger_num;
  391. // $totalPallets += $large_num;
  392. //
  393. // $palletRange = '1-' . $large_num;
  394. //
  395. // $insertData[] = [
  396. // 'userid' => $userinfo['id'],
  397. // 'supplier_id' => $userinfo['id'],
  398. // 'supplier_code' => $userinfo['printer_code'],
  399. // 'supplier_name' => $data['company_name'],
  400. // 'pallet' => $palletRange,
  401. // 'matter_no' => $product['gdbh'],
  402. // 'matter_id' => $product['gdbh'],
  403. // 'matter_type' => '01',
  404. // 'order_ddbh' => $product['order_ddbh'],
  405. // 'cpbm' => $product['cpbm'],
  406. // 'matter_name' => $product['cpmc'],
  407. // 'remark' => $product['remark'],
  408. // 'num_danwei' => '2',
  409. // 'danwei' => '套',
  410. // 'num' => $remaining_quantity,
  411. // 'small_num' => $small_num,
  412. // 'tray_num' => $tray_num,
  413. // 'box_num' => $box_num,
  414. // 'total_boxes' => $total_boxes,
  415. // 'large_num' => $large_num,
  416. // 'larger_num' => $larger_num,
  417. // 'pallet_height' => '1.05',
  418. // 'pallet_length' => '0.9',
  419. // 'pallet_width' => '1.2',
  420. // 'l_reservation' => '',
  421. // 'l_flow' => '1',
  422. // 'l_weight' => '',
  423. // 's_flow' => '',
  424. // 's_weight' => '',
  425. // 's_reservation' => '',
  426. // 'bach_status' => 0,
  427. // 'bach_ids' => $bachNum,
  428. // 'large_endnum' => $large_num,
  429. // 'manufacture_date' => '',
  430. // 'print_date' => '',
  431. // 'sys_rq' => $currentday,
  432. // 'created_at' => $currentTime,
  433. // 'create_time' => $timestamp,
  434. // 'updated_at' => '',
  435. // 'sync_flag' => '0',
  436. // 'delete_time' => '',
  437. // 'delect_time' => ''
  438. // ];
  439. // }
  440. //
  441. // $insertData_bachsummary = [
  442. // 'bach_ids' => $bachNum,
  443. // 'userid' => $userinfo['id'],
  444. // 'supplier_id' => $userinfo['id'],
  445. // 'supplier_code' => $userinfo['printer_code'],
  446. // 'supplier_name' => $data['company_name'],
  447. // 'total_quantity' => $totalQuantity,
  448. // 'total_boxes' => $totalBoxes,
  449. // 'total_pallets' => $totalPallets,
  450. // 'product_count' => count($data['products']),
  451. // 'bach_status' => 0,
  452. // 'sys_rq' => $currentday,
  453. // 'created_at' => $currentTime,
  454. // 'create_time' => $timestamp,
  455. // 'updated_at' => '',
  456. // 'delete_time' => ''
  457. // ];
  458. //
  459. //echo "<pre>";
  460. //print_r($insertData);
  461. //echo "<pre>";die;
  462. // $mongo->name($collection)->insertAll($insertData);
  463. // $mongo->name($bachsummary)->insert($insertData_bachsummary);
  464. //
  465. //
  466. // foreach ($data['products'] as $product) {
  467. // $where = [
  468. // 'gdbh' => $product['gdbh'],
  469. // 'order_ddbh' => $product['order_ddbh'],
  470. // 'cpmc' => $product['cpmc'],
  471. // ];
  472. //
  473. // // 实际出库数量
  474. // $actual_quantity = isset($product['actual_quantity']) ? (int)$product['actual_quantity'] : 0;
  475. // $remaining_quantity = isset($product['remaining_quantity']) ? (int)$product['remaining_quantity'] : 0;
  476. //
  477. // // 插入/更新字段
  478. // $insertData = [
  479. // 'gdbh' => $product['gdbh'],
  480. // 'order_ddbh' => $product['order_ddbh'],
  481. // 'cpbm' => $product['cpbm'],
  482. // 'cpmc' => $product['cpmc'],
  483. // 'total_ru_quantity' => $remaining_quantity, // 入库数来自当前剩余
  484. // 'total_chu_quantity' => $actual_quantity, // 本次出库数
  485. // 'remaining_quantity' => $remaining_quantity - $actual_quantity, // 计算结存
  486. // 'created_at' => date('Y-m-d H:i:s'),
  487. // 'updated_at' => '',
  488. // 'mod_rq' => '',
  489. // 'company' => $data['company_name'] ?? '',
  490. // ];
  491. //
  492. // // 查询是否已存在
  493. // $existing = $mongo->name('inventory_summary')->where($where)->find();
  494. //
  495. // if ($existing) {
  496. // // 累加更新
  497. // $new_chu = (int)$existing['total_chu_quantity'] + $actual_quantity;
  498. // $new_remaining = (int)$existing['remaining_quantity'] - $actual_quantity;
  499. //
  500. // $mongo->name('inventory_summary')
  501. // ->where($where)
  502. // ->update([
  503. // 'total_ru_quantity' => (int)$existing['total_ru_quantity'], // 保持不变或你可定义逻辑
  504. // 'total_chu_quantity' => $new_chu,
  505. // 'remaining_quantity' => $new_remaining,
  506. // 'updated_at' => date('Y-m-d H:i:s'),
  507. // ]);
  508. // } else {
  509. // // 插入新记录
  510. // $mongo->name('inventory_summary')->insert($insertData);
  511. // }
  512. //
  513. // // 插入库存明细记录
  514. // $mongo->name('inventory_records')->insert($insertData);
  515. // }
  516. // $this->success('添加成功');
  517. //
  518. // }
  519. // public function add_bach()
  520. // {
  521. // if ($this->request->isAjax() === false) {
  522. // $this->error('请求错误');
  523. // }
  524. //
  525. // $data = input('row');
  526. // if (empty($data)) {
  527. // $this->error('参数错误');
  528. // }
  529. //
  530. // $data = json_decode($data, true); // 解码为关联数组
  531. //
  532. // if (json_last_error() !== JSON_ERROR_NONE) {
  533. // $this->error('JSON解析错误');
  534. // }
  535. //
  536. // if (!isset($data['products']) || empty($data['products'])) {
  537. // $this->error('产品数据不能为空');
  538. // }
  539. //
  540. // $userinfo = Session::get('admin'); // 获取用户信息
  541. // if (empty($userinfo) || !isset($userinfo['company'])) {
  542. // $this->error('用户信息获取失败');
  543. // }
  544. //
  545. // $mongo = \think\Db::connect('mongodb');
  546. // $collection = $userinfo['company'] . '_qcode_bach';
  547. // $bachsummary = $userinfo['company'] . '_qcode_bachsummary';
  548. //
  549. // $insertData = [];
  550. // $currentday = date('Y-m-d');
  551. // $currentTime = date('Y-m-d H:i:s');
  552. //
  553. // foreach ($data['products'] as $product) {
  554. //
  555. // // 计算相关数量
  556. // $small_num = 20; // 每一箱数量
  557. // $tray_num = 6; // 每层箱数【箱/层】
  558. // $box_num = 3; // 每托层数【层/托】
  559. // $total_boxes = $tray_num * $box_num; // 每托盘箱数【箱/托】= 6*3=18
  560. //
  561. // // 计算总箱数和托盘数
  562. // $remaining_quantity = (int)$product['remaining_quantity'];
  563. // $larger_num = ceil($remaining_quantity / $small_num); // 总箱数 = 剩余数量/每箱数量(向上取整)
  564. // $large_num = ceil($larger_num / $total_boxes); // 本次打包托盘数 = 总箱数/每托盘箱数(向上取整)
  565. //
  566. // $insertData[] = [
  567. // //登录用户字段信息
  568. // 'userid' => $userinfo['id'],//用户id
  569. // 'supplier_id' => $userinfo['id'],//用户id
  570. // 'supplier_code' => $userinfo['printer_code'],//供应商编码
  571. // 'supplier_name' => $data['company_name'],//公司名称
  572. //
  573. // // 产品字段信息
  574. // 'pallet' => '1-'.$large_num,//托盘序号
  575. // 'matter_no' => $product['gdbh'],//生产批次号-工单编号
  576. // 'matter_id' => $product['gdbh'],
  577. // 'matter_type' => '01',
  578. // 'order_ddbh' => $product['order_ddbh'],//销售订单号
  579. // 'cpbm' => $product['cpbm'],//成品编码
  580. // 'matter_name' => $product['cpmc'],//成品名称
  581. // 'remark' => $product['remark'],
  582. //
  583. // 'num_danwei' => '2',//单位
  584. // 'danwei' => '套',//单位
  585. // 'num' => $remaining_quantity,//总数量(张/个)
  586. // 'small_num' => $small_num,//每一箱数量
  587. // 'tray_num' => $tray_num,//每层箱数【箱/层】
  588. // 'box_num' => $box_num,//每托层数【 层/托】
  589. // 'total_boxes' => $total_boxes,//每托盘箱数【箱/托】
  590. // 'large_num' => $large_num,//本次打包托盘数
  591. // 'larger_num' => $larger_num,//总箱数
  592. // 'pallet_height' => '1.05',//每托高度
  593. // 'pallet_length' => '0.9',//托盘规格
  594. // 'pallet_width' => '1.2',//托盘规格
  595. //
  596. // 'l_reservation' => '',
  597. // 'l_flow' => '1',//大件流水
  598. // 'l_weight' => '',//大件重量
  599. // 's_flow' => '',//小件流水
  600. // 's_weight' => '',//小件重量
  601. // 's_reservation' => '',
  602. // 'bach_status' => 0,
  603. // 'bach_num' => $product['gdbh'],//生产批次号-工单编号
  604. // 'large_endnum' => $large_num,
  605. //
  606. // // 其他字段信息
  607. // 'manufacture_date' => '',//生产日期
  608. // 'print_date' => '',//打码日期
  609. // 'sys_rq' => $currentday,//新增日期
  610. // 'created_at' => $currentTime,//新增时间
  611. // 'create_time' => time(),//新增时间
  612. // 'updated_at' => '',
  613. // 'sync_flag' => '0',
  614. // 'delete_time' => '',
  615. // 'delect_time' => ''//删除时间
  616. // ];
  617. // }
  618. //echo "<pre>";
  619. //print_r($insertData_bachsummary);
  620. //echo "<pre>";die;
  621. //
  622. //
  623. // if (!empty($insertData)) {
  624. // //汇总数据
  625. // $mongo->name($bachsummary)->insertAll($insertData_bachsummary);
  626. // //明细数据
  627. // $mongo->name($collection)->insertAll($insertData);
  628. // $this->success('添加成功');
  629. // } else {
  630. // $this->error('没有有效数据可添加');
  631. // }
  632. //
  633. // }
  634. /**
  635. * 增加新批次
  636. */
  637. public function add()
  638. {
  639. $product = new QcodeProduct();
  640. $bach = new QcodeBach();
  641. $large = new QcodeLarge();
  642. $small = new QcodeSmall();
  643. $liushui = new QcodeLiushui();
  644. $resetFlow = new ResetFlow();
  645. $QcodeCompany = new QcodeCompany();
  646. if ($this->request->isAjax() === false){
  647. $this->error('请求错误');
  648. }
  649. $rows = input('row');
  650. if (empty($rows)){
  651. $this->error('参数错误');
  652. }
  653. $rows = json_decode($rows);
  654. $data = [];
  655. foreach ($rows as $value){
  656. foreach ($value as $k=>$v){
  657. $data[$k] = $v;
  658. }
  659. }
  660. //打印信息
  661. // echo "接口获取";echo "<pre>";print_r($data);echo "<pre>";die;
  662. //记录库存操作
  663. $mongo = \think\Db::connect('mongodb');
  664. $where = [
  665. 'gdbh' => $data['gdbh'],
  666. 'order_ddbh' => $data['order_ddbh'],
  667. 'cpmc' => $data['cpmc'],
  668. ];
  669. //插入字段[inventory_summaryk库存明细]
  670. $insertData = [
  671. 'gdbh' => $data['gdbh'],
  672. 'order_ddbh' => $data['order_ddbh'],
  673. 'cpbm' => $data['cpbm'],
  674. 'cpmc' => $data['cpmc'],
  675. 'total_ru_quantity' => $data['sl'],//入库数
  676. 'total_chu_quantity' => $data['number'],//出库数
  677. 'remaining_quantity' => $data['remaining_quantity'] - $data['number'],//剩余数
  678. 'created_at' => date('Y-m-d H:i:s'),
  679. 'updated_at' => '',
  680. 'mod_rq' => '',
  681. 'company' => '',
  682. ];
  683. // 查询库存汇总表数据是否存在记录
  684. $list = $mongo->name('inventory_summary')->where($where)->find();
  685. if ($list) {
  686. // 如果数据存在,更新库存汇总记录
  687. $chu = $list['total_chu_quantity'] + $data['number'];//累计出库数量
  688. $jiecun = $list['remaining_quantity'] - $data['number'];//剩余结存数量
  689. $updateResult = $mongo->name('inventory_summary')
  690. ->where($where)
  691. ->update([
  692. 'total_ru_quantity' => $data['sl'],
  693. 'total_chu_quantity' => $chu,
  694. 'remaining_quantity' => $jiecun,
  695. 'updated_at' => date('Y-m-d H:i:s'),
  696. ]);
  697. } else {
  698. // 数据不存在则插入新记录
  699. $mongo->name('inventory_summary')->insert($insertData);
  700. }
  701. //记录库存明细
  702. $mongo->name('inventory_records')->insert($insertData);
  703. // // 调试输出
  704. // echo "<pre>"; print_r($list); echo "</pre>";die;
  705. // if ($data['danwei'] == 1){
  706. // $num = $data['number'];
  707. // $tray_num = $data['tray_num'];
  708. // $box_number = $data['box_number'];
  709. // //$small_num = (int)ceil((int)总数量(张/个)/(int)张数);
  710. // $small_num = (int)ceil((int)$data['number']/(int)$data['box_number']);
  711. // $large_num = (int)ceil($small_num/$tray_num);
  712. // }else{
  713. // $num = 0;
  714. // $tray_num = $data['volume_num'];
  715. // $small_num = $data['small_num'];
  716. // $large_num = (int)ceil($small_num/$tray_num);
  717. // $box_number = 1;
  718. // $tray_num1 = 1;
  719. // }
  720. switch ($data['danwei']) {
  721. case 1:
  722. $danwei = '个';
  723. break;
  724. case 2:
  725. $danwei = '套';
  726. break;
  727. case 3:
  728. $danwei = '张';
  729. break;
  730. default:
  731. $danwei = '';
  732. break;
  733. }
  734. $userinfo = Session::get('admin');//获取用户信息
  735. $arr = [
  736. 'batch' => $data['gdbh'],
  737. 'create_time' => time(),
  738. 'delect_time' => '',
  739. 'sync_flag' => 0,
  740. ];
  741. $productres = $QcodeCompany->save($arr);
  742. if ($productres === 0){
  743. $this->error('添加失败');
  744. }
  745. $batchList = [
  746. 'userid' => $userinfo['id'],//登录用户id
  747. 'supplier_id' => $userinfo['id'],//登录用户id
  748. 'supplier_code' => $userinfo['printer_code'],
  749. 'supplier_name' => $data['company_name'],//公司名称
  750. 'cpbm' => $data['cpbm'],//成品编码
  751. 'matter_name' => $data['cpmc'],//成品名称
  752. 'matter_no' => $data['gdbh'],//生产批次号-工单编号
  753. 'order_ddbh' => $data['order_ddbh'],//销售订单号
  754. 'matter_id' => $data['gdbh'],
  755. 'matter_type' => '01',
  756. 'manufacture_date' => (int)date('ymd',strtotime($data['manufacture_date'])),//生产日期
  757. 'print_date' => (int)date('ymd',strtotime($data['print_date'])),//打码日期
  758. 'num_danwei' => $data['danwei'],//单位
  759. 'danwei' => $danwei,//单位
  760. 'num' => $data['number'],//总数量(张/个)
  761. 'small_num' => $data['box_number'],//每一箱数量
  762. 'tray_num' => $data['tray_num'],//每层箱数【箱/层】
  763. 'box_num' => $data['tray_number'],//每托层数【 层/托】
  764. 'total_boxes' => $data['total_boxes'],//每托盘箱数【箱/托】
  765. 'large_num' => $data['box_num'],//本次打包托盘数
  766. 'larger_num' => $data['small_num'],//总箱数
  767. 'pallet_height' => $data['pallet_height'],//每托高度
  768. 'pallet_length' => $data['pallet_length'],//托盘规格
  769. 'pallet_width' => $data['pallet_width'],//托盘规格
  770. 'l_reservation' => '',
  771. // 处理可能为空的流水/重量字段
  772. 'l_flow' => $data['big_liushui'],//大件流水
  773. 'l_weight' => $data['big_weight'],//大件重量
  774. 's_flow' => $data['small_start_liushui'],//小件流水
  775. 's_weight' => $data['small_weight'],//小件重量
  776. 's_reservation' => '',
  777. 'bach_status' => 0,
  778. 'bach_num' => $data['gdbh'],//生产批次号-工单编号
  779. 'large_endnum' => $data['big_liushui'] + $data['box_num'] -1,
  780. 'create_time' => time(),//新增时间
  781. 'delect_time' => '',//删除时间
  782. ];
  783. $res = $bach->save($batchList);
  784. if ($res === 0){
  785. $this->error('添加失败');
  786. }
  787. $flow = [
  788. 'l_flow' => (int)$batchList['large_num'],
  789. 'bach_num' => $batchList['matter_no'],
  790. ];
  791. if ($resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_no'])->find()){
  792. $resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_no'])->update($flow);
  793. }else{
  794. $flow['product_id'] = $batchList['matter_no'];
  795. $resetFlow->save($flow);
  796. }
  797. $last_id = $bach->getLastInsID();
  798. if ($last_id){
  799. //插入大小二维码数据 二维码数据不变区域
  800. // echo "<pre>";print_r($batchList);echo "<pre>";die;
  801. $fixed_code = '';
  802. $fixed_code.=$this->intTochar($batchList['matter_type'],2);//2位 辅料种类编码
  803. $fixed_code .= $this->intTochar($batchList['supplier_code'], 21);//21位 供应商编码
  804. $fixed_code .= '9'; // 补0一位
  805. $fixed_code.=$this->intTochar($batchList['cpbm'],10);//10位 辅料编码
  806. $fixed_code.=$batchList['manufacture_date'];//6位 生产日期
  807. $print_code=$batchList['print_date'];//6位 打码日期
  808. $small_liushui = [
  809. 'onlycode' => 'AB92'.$fixed_code.$print_code,
  810. 'last_num' => 0,
  811. 'user_id' => $userinfo['company'],
  812. 'stype' => 2,
  813. 'dateTime' => time(),
  814. ];
  815. $whereSmall = [
  816. 'onlycode' => $small_liushui['onlycode'],
  817. 'user_id' => $userinfo['company'],
  818. ];
  819. if ($liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find()){
  820. //小件二维码存在,更新小件二维码最后流水号
  821. $lastNum = $liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find();
  822. }else{
  823. //小件二维码不存在,新增记录
  824. $liushui->save($small_liushui);
  825. $lastNum['last_num'] = 0;
  826. }
  827. //循环插入大件二维码数据
  828. for ($i=0;$i<$data['box_num'];$i++){
  829. $large = new QcodeLarge();
  830. $l_flow = $this->intTochar($batchList['l_flow']+$i,6);
  831. $l_weight = $this->intTochar($batchList['l_weight']*100,6);
  832. $l_reservation = $this->intTochar($batchList['matter_no'],10);
  833. $l_reservation = $l_reservation.'0000000000';
  834. $remainder = $batchList['num'] - $batchList['total_boxes'] * $i;//最后一托盘小件数量
  835. if ($remainder < $batchList['tray_num']){
  836. $small_n = $this->intTochar($remainder,3);//3位小件数量,不足补0
  837. }else{
  838. $small_n = $this->intTochar($batchList['tray_num'],3);
  839. }
  840. // $l_num = $small_n * $batchList['box_num'];
  841. $l_num = 0;
  842. //大件二维码数据
  843. $code_data = $this->CodeData('AB92',$fixed_code,$small_n,$print_code,$l_flow,$l_weight,'2',$l_reservation);
  844. //大码数据信息
  845. $l_data = [
  846. 'bach_id' => $last_id,
  847. 'code' => $code_data['code'],
  848. 'code_cp1' => $code_data['code_cp1'],
  849. 'code_cp2' => $code_data['code_cp2'],
  850. 'print_date' => $print_code,
  851. 'create_time' => time(),
  852. 'p_nums' => 0,
  853. 'userid' =>$userinfo['id'],
  854. 'l_weight' =>$batchList['l_weight']*100,
  855. 'l_num' =>$l_num,
  856. 'l_status' => 0,
  857. 'l_print' => 0
  858. ];
  859. $l_res = $large->save($l_data);
  860. if ($l_res === 0){
  861. $this->error('大件码插入失败');
  862. }
  863. $large_id = $large->getLastInsID();
  864. if ($large_id){
  865. // //小件码循环插入
  866. // for ($j=0;$j<$data['tray_num'] and ($j+$i*$data['tray_num'])<$batchList['small_num'];$j++){
  867. for ($j=0;$j<$data['total_boxes'] and ($j+$i*$data['total_boxes'])<$batchList['total_boxes'];$j++){
  868. $small = new QcodeSmall();
  869. $s_flow = $this->intTochar($batchList['s_flow']+$j+$i*$data['tray_num']+$lastNum['last_num'],6);//小件码序号从1开始
  870. $s_weight = $this->intTochar($batchList['s_weight'],6);
  871. $small_sign = '000';
  872. $s_reservation = $this->intTochar($batchList['bach_num'],10);
  873. $s_reservation = $s_reservation . '0000000000';
  874. //生成小件码
  875. $small_code_data = $this->CodeData('AB92',$fixed_code,$small_sign,$print_code,$s_flow,$s_weight,'1',$s_reservation);
  876. //小码数据
  877. $s_data = [
  878. 'large_id'=>$large_id,
  879. 'bach_id'=>$last_id,
  880. 'code'=>$small_code_data['code'],
  881. 'code_cp1'=>$small_code_data['code_cp1'],
  882. 'code_cp2'=>$small_code_data['code_cp2'],
  883. 'l_flow'=>$j+1,
  884. 'print_date'=>$print_code,
  885. 'create_time'=>time(),
  886. 'p_nums'=>0,
  887. 'userid'=>$userinfo['id'],//小码绑定用户id
  888. 's_weight'=>$batchList['s_weight'],//单个小件重量
  889. 'status' => 0,
  890. ];
  891. $s_res = $small->save($s_data);
  892. if ($s_res === 0){
  893. $this->error('小件码插入失败');
  894. }
  895. }
  896. }else{
  897. $this->error('添加失败');
  898. }
  899. }
  900. }
  901. $liushui_res = $liushui->name($userinfo['id'].'_'.'qcode_liushui')->where($whereSmall)->update(['last_num'=>$batchList['small_num']]);
  902. if ($liushui_res === false){
  903. $this->error('添加失败');
  904. }
  905. return json(['code' => 1, 'msg' => '成功', 'data' => '']);
  906. // $this->success('成功');
  907. }
  908. /**
  909. * 编码补位
  910. * @param $num
  911. * @param $len
  912. * @return string
  913. */
  914. function intTochar($num=0,$len){
  915. //规定的不足的时候自动补足零
  916. $code=(string)$num;
  917. $buwei='';
  918. if(strlen($code)<$len){
  919. for($i=strlen($code);$i<$len;$i++){
  920. $buwei.='0';
  921. }
  922. }
  923. return $buwei.$code;
  924. }
  925. /**
  926. * 二维码编码生成
  927. * @param $sign
  928. * @param $fixed_code
  929. * @param $small_num
  930. * @param $print_date
  931. * @param $flow
  932. * @param $weight
  933. * @param $large_sign
  934. * @param $reservation
  935. * @return array
  936. */
  937. function CodeData($sign,$fixed_code,$small_num,$print_date,$flow,$weight,$large_sign,$reservation){
  938. $code=$sign;//4 位固定标志位
  939. $code.=$fixed_code; // 固定字符串
  940. $code.=$small_num;//3位 小件数量
  941. $code.=$print_date;//6 位 日期
  942. $code.=$flow;//6位打印流水号
  943. $code.=$weight;//6位辅料重量
  944. $code.=$large_sign;//大小件标示位
  945. $code.=$reservation;//20 位 预留号
  946. //大码数据信息
  947. $data=[
  948. 'code'=>str_replace(" ","",$code),
  949. 'code_cp1'=>$print_date.$flow,
  950. 'code_cp2'=>$weight.$reservation,//20位补充
  951. 'print_date'=>time(),
  952. 'p_nums'=>0,
  953. ];
  954. return $data;
  955. }
  956. }