| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789 |
- <?php
- namespace app\admin\controller;
- use app\admin\model\QcodeCompany;
- use app\admin\model\QcodeGsmc;
- use app\admin\model\QcodeProduct;
- use app\common\controller\Backend;
- use app\admin\model\ResetFlow;
- use app\admin\model\QcodeLarge;
- use app\admin\model\QcodeBach;
- use app\admin\model\QcodeSmall;
- use app\admin\model\QcodeLiushui;
- use fast\Arr;
- use MongoDB\BSON\ObjectId;
- use think\Db;
- use think\Session;
- class QcodeAdd extends Backend{
- /**
- * 首页展示
- */
- public function index(){
- //获取登录账号信息【厂商信息】
- $userinfo = Session::get('admin');
- $data = [
- 'nickname' => $userinfo['company_name'],
- 'postcode' => $userinfo['postcode'],
- 'mobile' => $userinfo['mobile'],
- 'printer_code' => $userinfo['printer_code'],
- 'company_address' => $userinfo['company_address']
- ];
- $this->view->assign('row',$data);
- //将对此账号创建公司唯一id,进行创建公司对应公司表名company id
- $user_company_value = Db::name('admin')->where('id', $userinfo['id'])->value('company');
- if (empty($user_company_value)) {
- $max_company = Db::name('admin')->max('company');
- $new_company_value = $max_company ? ($max_company + 1) : 1;
- Db::name('admin')->where('id', $userinfo['id'])->update(['company' => $new_company_value]);
- } else {
- $new_company_value = $user_company_value;
- }
- $tableNames = [
- $new_company_value . '_qcode_bach',
- $new_company_value . '_qcode_company',
- $new_company_value . '_qcode_large',
- $new_company_value . '_qcode_liushui',
- $new_company_value . '_qcode_small',
- $new_company_value . '_reset_flow',
- ];
- foreach ($tableNames as $tableName) {
- try {
- Db::connect('mongodb')->name($tableName)->insert(['init' => 1]);
- // 删除测试数据(可选,如果不想保留这个测试数据)
- Db::connect('mongodb')->name($tableName)->where('init', 1)->delete();
- } catch (\Exception $e) {
- echo "创建集合 {$tableName} 失败:" . $e->getMessage();
- }
- }
- return $this->view->fetch();
- }
- /**
- * 获取产品信息
- */
- public function product(){
- $params = input('');
- $page = max(1, (int)$params['page']);
- $limit = max(1, (int)$params['limit']);
- $offset = ($page - 1) * $limit;
- // 获取工单编号列表
- $db3 = Db::connect(config('database.db3'));
- $gdRows = $db3->query("SELECT DISTINCT `Gd_gdbh`, `Gd_客户代号`, `Gd_cpdh` FROM `工单_基本资料` WHERE `Gd_客户代号` = ?", ['J0031']);
- $Gd_gdbhList = array_column($gdRows, 'Gd_gdbh');
- $gdbhList = array_column($gdRows, 'Gd_cpdh');
- if (empty($gdbhList)) {
- $this->assign([
- 'data' => '',
- 'total' => '',
- ]);
- }
- // Mongo 查询
- $mongo = \think\Db::connect('mongodb');
- $where = ['成品编码' => ['in', $gdbhList],'jjcp_gdbh' => ['in', $Gd_gdbhList], 'jjcp_smb' => '末 板'];
- // $where = ['成品编码' => ['in', $gdbhList], 'jjcp_smb' => '末 板'];
- if (!empty($params['search'])) {
- $where['成品编码|成品名称|jjcp_gdbh|订单编号'] = new \MongoDB\BSON\Regex($params['search'], 'i');
- }
- // 查询符合条件的成品数据
- $al_products = $mongo->name('finished_products')
- ->where($where)
- ->order('Sys_rq', 'desc')
- ->select();
- // 查询 texts = 新增产品 的数据
- $xz_products = $mongo->name('finished_products')
- ->where('texts', '新增产品')
- ->order('Sys_rq', 'desc')
- ->select();
- // 合并数据
- $all_products = array_merge($al_products, $xz_products);
- // 分组聚合处理
- $grouped_products = [];
- foreach ($all_products as $item) {
- // 转换日期格式(如果是 d/m/Y H:i:s)
- $date = \DateTime::createFromFormat('d/m/Y H:i:s', $item['Sys_rq']);
- $item['Sys_rq'] = $date ? $date->format('Y-m-d H:i:s') : $item['Sys_rq'];
- $group_key = $item['订单编号'] . '_' . $item['jjcp_gdbh'];
- if (!isset($grouped_products[$group_key])) {
- $grouped_products[$group_key] = [
- 'Sys_rq' => $item['Sys_rq'],
- 'order_ddbh' => $item['订单编号'],
- 'gdbh' => $item['jjcp_gdbh'],
- 'cpbm' => $item['成品编码'],
- 'cpmc' => $item['成品名称'],
- 'sl' => 0,
- 'cpdh_list' => [],
- 'cpbm_list' => []
- ];
- }
- $grouped_products[$group_key]['sl'] += (int)$item['jjcp_sl'];
- if (!in_array($item['jjcp_cpdh'], $grouped_products[$group_key]['cpdh_list'])) {
- $grouped_products[$group_key]['cpdh_list'][] = $item['jjcp_cpdh'];
- }
- if (!in_array($item['成品编码'], $grouped_products[$group_key]['cpbm_list'])) {
- $grouped_products[$group_key]['cpbm_list'][] = $item['成品编码'];
- }
- }
- // 格式化列表字符串
- foreach ($grouped_products as &$group) {
- $group['cpdh'] = implode(',', $group['cpdh_list']);
- $group['cpbm'] = implode(',', $group['cpbm_list']);
- unset($group['cpdh_list'], $group['cpbm_list']);
- }
- // 聚合结果排序(按时间降序)
- $all_grouped = array_values($grouped_products);
- usort($all_grouped, function ($a, $b) {
- $timeA = strtotime($a['Sys_rq']) ?: 0;
- $timeB = strtotime($b['Sys_rq']) ?: 0;
- return $timeB <=> $timeA;
- });
- // 再分页
- $total = count($all_grouped);
- $paged_grouped = array_slice($all_grouped, $offset, $limit);
- // 查询库存并计算剩余数
- foreach ($paged_grouped as &$prod) {
- $inventory = $mongo->name('inventory_summary')->where([
- 'order_ddbh' => $prod['order_ddbh'],
- 'gdbh' => $prod['gdbh'],
- 'cpmc' => $prod['cpmc'],
- ])->find();
- $total_chu_quantity = isset($inventory['total_chu_quantity']) ? (int)$inventory['total_chu_quantity'] : 0;
- $prod['total_chu_quantity'] = $total_chu_quantity;
- $prod['remaining_quantity'] = $prod['sl'] - $total_chu_quantity;
- }
- unset($prod);
- return json([
- 'code' => 1,
- 'data' => $paged_grouped,
- 'total' => $total,
- 'page' => $page,
- 'limit' => $limit
- ]);
- }
- // public function add_bach()
- // {
- // // 1. AJAX请求验证
- // if (!$this->request->isAjax()) {
- // $this->error('请求必须为AJAX');
- // }
- //
- // // 2. 获取并解析输入数据
- // $data = input('row');
- // if (empty($data)) {
- // $this->error('请求参数不能为空');
- // }
- //
- // $data = json_decode($data, true);
- // if (json_last_error() !== JSON_ERROR_NONE) {
- // $this->error('JSON数据解析失败');
- // }
- //
- // if (empty($data['products'])) {
- // $this->error('产品数据不能为空');
- // }
- //
- // // 3. 用户会话验证
- // $userinfo = Session::get('admin');
- // if (empty($userinfo) || !isset($userinfo['company'])) {
- // $this->error('获取用户信息失败,请重新登录');
- // }
- //
- // // 4. MongoDB连接配置
- // $mongo = \think\Db::connect('mongodb');
- // $collection = $userinfo['company'] . '_qcode_bach'; // 主表
- // $bachdetails = $userinfo['company'] . '_qcode_bachdetails'; // 托盘明细表
- // $bachsummary = $userinfo['company'] . '_qcode_bachsummary'; // 批次汇总表
- //
- // // 5. 生成批次信息
- // $currentDate = date('Y-m-d');
- // $currentDateTime = date('Y-m-d H:i:s');
- // $timestamp = time();
- // $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999); // 批次号规则
- //
- // // 6. 托盘默认配置
- // $config = [
- // 'tray_num' => 6, // 每层6箱
- // 'pallet_length' => '0.9', // 托盘长度(米)
- // 'pallet_width' => '1.2', // 托盘宽度(米)
- // 'default_layer_height' => '1.35' // 默认层高(米)
- // ];
- //
- // // 7. 初始化统计容器
- // $batchStats = [
- // 'total_quantity' => 0, // 总产品数量
- // 'total_boxes' => 0, // 总箱数
- // 'total_pallets' => 0, // 总托盘数
- // 'full_pallets' => 0, // 完整托盘数
- // 'partial_pallets' => 0, // 不完整托盘数
- // 'product_varieties' => count($data['products']) // 产品种类数
- // ];
- //
- // // 8. 处理每个产品 - 分为两个阶段
- // $productDetails = []; // 产品主表数据
- // $palletDetails = []; // 托盘明细数据
- // $currentPalletNo = 1; // 托盘编号计数器
- //
- // // 第一阶段:先处理所有完整托盘
- // foreach ($data['products'] as $product) {
- // // 8.1 计算托盘配置
- // $tray_count = $product['tray_count'] ?? 18; // 默认18箱/托盘
- // $box_num = $tray_count == 24 ? 4 : 3; // 24箱时为4层,否则3层
- // $small_num = $product['items_per_box'] ?? 20; // 每箱数量,默认20
- //
- // // 8.2 处理实际数量
- // $remaining = (int)$product['remaining_quantity'];
- // $actual = isset($product['actual_quantity']) ?
- // min((int)$product['actual_quantity'], $remaining) : $remaining;
- //
- // // 8.3 计算托盘分配
- // $boxes_per_pallet = $config['tray_num'] * $box_num; // 每托盘总箱数
- // $total_boxes = ceil($actual / $small_num); // 总箱数
- // $full_pallets = floor($total_boxes / $boxes_per_pallet); // 完整托盘数
- // $remaining_boxes = $total_boxes % $boxes_per_pallet; // 剩余箱数
- //
- // // 8.4 构建产品基础信息
- // $baseInfo = [
- // 'bach_ids' => $bachNum, // 批次号
- // 'userid' => $userinfo['id'], // 操作人ID
- // 'gdbh' => $product['gdbh'], // 工单编号
- // 'order_ddbh' => $product['order_ddbh'], // 订单编号
- // 'cpbm' => $product['cpbm'], // 产品编码
- // 'cpmc' => $product['cpmc'], // 产品名称
- // 'matter_name' => $product['cpmc'], // 物料名称
- // 'remark' => $product['remark'] ?? '', // 备注
- // 'small_num' => $small_num, // 每箱数量
- // 'unit' => $product['unit'] ?? '套', // 单位
- // 'tray_num' => $config['tray_num'], // 每层箱数
- // 'box_num' => $box_num, // 层数
- // 'tray_count' => $tray_count, // 总箱数/托盘
- // 'layer_height' => $product['layer_height'] ?? $config['default_layer_height'], // 层高
- // 'pallet_length' => $config['pallet_length'], // 托盘长度
- // 'pallet_width' => $config['pallet_width'], // 托盘宽度
- // 'bach_status' => 0, // 状态(0:未处理)
- // 'sys_rq' => $currentDate, // 系统日期
- // 'created_at' => $currentDateTime, // 创建时间
- // 'create_time' => $timestamp, // 时间戳
- // 'delete_time' => '' // 删除时间
- // ];
- //
- // // 只处理完整托盘部分
- // if ($full_pallets > 0) {
- // $full_qty = $full_pallets * $boxes_per_pallet * $small_num;
- // $endNo = $currentPalletNo + $full_pallets - 1;
- //
- // $productDetails[] = array_merge($baseInfo, [
- // 'actual_quantity' => $full_qty,
- // 'total_boxes' => $full_pallets * $boxes_per_pallet,
- // 'pallet_count' => $full_pallets,
- // 'pallet_type' => 'full',
- // 'pallet_range' => "$currentPalletNo-$endNo",
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $endNo
- // ]);
- //
- // // 生成托盘明细
- // for ($i = 0; $i < $full_pallets; $i++) {
- // $palletDetails[] = [
- // 'bach_ids' => $bachNum,
- // 'product_id' => $product['gdbh'],
- // 'pallet_no' => $currentPalletNo + $i,
- // 'pallet_no_display' => $currentPalletNo + $i,
- // 'pallet_type' => 'full',
- // 'quantity' => $boxes_per_pallet * $small_num,
- // 'box_count' => $boxes_per_pallet,
- // 'layer_count' => $box_num,
- // 'bach_status' => 0,
- // 'created_at' => $currentDateTime,
- // 'delete_time' => ''
- // ];
- // }
- //
- // $batchStats['full_pallets'] += $full_pallets;
- // $batchStats['total_quantity'] += $full_qty;
- // $batchStats['total_boxes'] += $full_pallets * $boxes_per_pallet;
- // $currentPalletNo += $full_pallets;
- // $batchStats['total_pallets'] += $full_pallets;
- // }
- // }
- //
- // // 第二阶段:再处理所有不完整托盘
- // foreach ($data['products'] as $product) {
- // //每托箱数
- // $tray_count = $product['tray_count'];
- //
- // //判断:每托箱数=每层箱数*每托层数
- // if ($tray_count == 18) {
- // $box_num = 3;
- // $per_box = 6;
- // } elseif ($tray_count == 24) {
- // $box_num = 4;
- // $per_box = 6;
- // } elseif ($tray_count == 36) {
- // $box_num = 4;
- // $per_box = 9;
- // } else {
- // $this->error('请联系管理员');
- // }
- // //每托箱数
- // $boxes_per_pallet = $per_box * $box_num;
- //
- // //每箱个数
- // $small_num = $product['items_per_box'];
- //
- // //可发数量
- // $remaining = (int)$product['remaining_quantity'];
- // //实际发货数量
- // $actual = isset($product['actual_quantity']) ?
- // min((int)$product['actual_quantity'], $remaining) : $remaining;
- //
- // //实际发货数量 / 每箱个数 = 总箱数
- // $total_boxes = ceil($actual / $small_num);
- // //多少箱 / 每托箱数 = 完整托盘数
- // $full_pallets = floor($total_boxes / $boxes_per_pallet);
- // // 剩余箱数
- // $remaining_boxes = $total_boxes % $boxes_per_pallet;
- //
- // // 构建产品基础信息(需要重新构建因为baseInfo可能在循环中被修改)
- // $baseInfo = [
- // 'bach_ids' => $bachNum,
- // 'userid' => $userinfo['id'],
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'matter_name' => $product['cpmc'],
- // 'remark' => $product['remark'] ?? '',
- // 'small_num' => $small_num,
- // 'unit' => $product['unit'] ?? '套',
- // 'tray_num' => $config['tray_num'],
- // 'box_num' => $box_num,
- // 'tray_count' => $tray_count,
- // 'layer_height' => $product['layer_height'] ?? $config['default_layer_height'],
- // 'pallet_length' => $config['pallet_length'],
- // 'pallet_width' => $config['pallet_width'],
- // 'bach_status' => 0,
- // 'sys_rq' => $currentDate,
- // 'created_at' => $currentDateTime,
- // 'create_time' => $timestamp,
- // 'delete_time' => ''
- // ];
- //
- // // 只处理不完整托盘部分
- // if ($remaining_boxes > 0) {
- // $partial_qty = $remaining_boxes * $small_num;
- //
- // $productDetails[] = array_merge($baseInfo, [
- // 'actual_quantity' => $partial_qty,
- // 'total_boxes' => $remaining_boxes,
- // 'pallet_count' => 1,
- // 'pallet_type' => 'partial',
- // 'pallet_range' => (string)$currentPalletNo,
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $currentPalletNo
- // ]);
- //
- // $palletDetails[] = [
- // 'bach_ids' => $bachNum,
- // 'product_id' => $product['gdbh'],
- // 'pallet_no' => $currentPalletNo,
- // 'pallet_no_display' => $currentPalletNo,
- // 'pallet_type' => 'partial',
- // 'quantity' => $partial_qty,
- // 'box_count' => $remaining_boxes,
- // 'layer_count' => ceil($remaining_boxes / $config['tray_num']),
- // 'bach_status' => 0,
- // 'created_at' => $currentDateTime,
- // 'delete_time' => ''
- // ];
- //
- // $batchStats['partial_pallets']++;
- // $batchStats['total_quantity'] += $partial_qty;
- // $batchStats['total_boxes'] += $remaining_boxes;
- // $currentPalletNo++;
- // $batchStats['total_pallets']++;
- // }
- // }
- //
- // // 9. 构建批次汇总数据
- // $summaryData = [
- // 'bach_ids' => $bachNum,
- // 'userid' => $userinfo['id'],
- // 'total_quantity' => $batchStats['total_quantity'],
- // 'total_boxes' => $batchStats['total_boxes'],
- // 'total_pallets' => $batchStats['total_pallets'],
- // 'product_count' => $batchStats['product_varieties'],
- // 'full_pallets' => $batchStats['full_pallets'],
- // 'partial_pallets' => $batchStats['partial_pallets'],
- // 'bach_status' => 0,
- // 'sys_rq' => $currentDate,
- // 'created_at' => $currentDateTime,
- // 'create_time' => $timestamp,
- // 'delete_time' => ''
- // ];
- //die;
- // // 10. 保存所有数据
- // $mongo->name($collection)->insertAll($productDetails);
- // $mongo->name($bachdetails)->insertAll($palletDetails);
- // $mongo->name($bachsummary)->insert($summaryData);
- //
- // // 11. 更新库存记录
- // foreach ($data['products'] as $product) {
- // $where = [
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpmc' => $product['cpmc'],
- // ];
- //
- // $actual = (int)($product['actual_quantity'] ?? 0);
- // $remaining = (int)$product['remaining_quantity'];
- //
- // // 处理MongoDB查询结果
- // $existing = $mongo->name('inventory_summary')->where($where)->find();
- //
- // if ($existing) {
- // // 转换为数组处理
- // if (is_object($existing)) {
- // $existing = (array)$existing;
- // }
- //
- // // 处理多结果情况
- // if (isset($existing[0])) {
- // $existing = $existing[0];
- // }
- //
- // // 安全获取字段值
- // $current_chu = (int)($existing['total_chu_quantity'] ?? 0);
- // $current_remain = (int)($existing['remaining_quantity'] ?? 0);
- //
- // $mongo->name('inventory_summary')
- // ->where($where)
- // ->update([
- // 'total_chu_quantity' => $current_chu + $actual,
- // 'remaining_quantity' => $current_remain - $actual,
- // 'updated_at' => $currentDateTime,
- // ]);
- // } else {
- // // 新记录
- // $mongo->name('inventory_summary')->insert([
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'total_ru_quantity' => $remaining,
- // 'total_chu_quantity' => $actual,
- // 'remaining_quantity' => $remaining - $actual,
- // 'created_at' => $currentDateTime,
- // 'company' => $data['company_name'] ?? '',
- // ]);
- // }
- //
- // // 插入库存流水记录
- // $mongo->name('inventory_records')->insert([
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'total_ru_quantity' => $remaining,
- // 'total_chu_quantity' => $actual,
- // 'remaining_quantity' => $remaining - $actual,
- // 'created_at' => $currentDateTime,
- // 'company' => $data['company_name'] ?? '',
- // ]);
- // }
- //
- // $this->success('批次创建成功');
- // }
- /**
- * 添加批次功能
- *
- * 功能说明:
- * 1. 处理AJAX请求,创建产品批次
- * 2. 自动计算托盘分配(完整托盘和不完整托盘)
- * 3. 生成批次号和相关统计信息
- * 4. 更新库存记录
- * 5. 支持多种托盘配置(18箱/24箱/36箱)
- *
- * 数据流向:
- * 前端提交 -> 验证 -> 计算分配 -> 生成记录 -> 更新库存 -> 返回结果
- */
- public function add_bach()
- {
- // ==================== 1. 请求验证阶段 ====================
- // 1.1 验证必须是AJAX请求
- if (!$this->request->isAjax()) {
- $this->error('非法请求,必须使用AJAX方式提交');
- }
- // 1.2 获取并解析输入数据
- $data = input('row'); // 获取原始数据
- if (empty($data)) {
- $this->error('请求参数不能为空');
- }
- // 1.3 解析JSON数据
- $data = json_decode($data, true);
- if (json_last_error() !== JSON_ERROR_NONE) {
- $this->error('JSON数据解析失败:' . json_last_error_msg());
- }
- // 1.4 验证产品数据是否存在
- if (empty($data['products']) || !is_array($data['products'])) {
- $this->error('产品数据不能为空且必须是数组');
- }
- // ==================== 2. 用户会话验证 ====================
- $userinfo = Session::get('admin');
- if (empty($userinfo) || !isset($userinfo['company'])) {
- $this->error('获取用户信息失败,请重新登录');
- }
- // ==================== 3. 数据库准备 ====================
- // 3.1 连接MongoDB
- $mongo = \think\Db::connect('mongodb');
- // 3.2 动态生成集合名称(基于公司名称)
- $collection = $userinfo['company'] . '_qcode_bach'; // 主表
- $bachdetails = $userinfo['company'] . '_qcode_bachdetails'; // 托盘明细表
- $bachsummary = $userinfo['company'] . '_qcode_bachsummary'; // 批次汇总表
- // ==================== 4. 生成批次信息 ====================
- $currentDate = date('Y-m-d');
- $currentDateTime = date('Y-m-d H:i:s');
- $timestamp = time();
- // 批次号规则:BACH + 年月日时分秒 + 4位随机数
- $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999);
- // ==================== 5. 初始化统计容器 ====================
- $batchStats = [
- 'total_quantity' => 0, // 总产品数量
- 'total_boxes' => 0, // 总箱数
- 'total_pallets' => 0, // 总托盘数
- 'full_pallets' => 0, // 完整托盘数
- 'partial_pallets' => 0, // 不完整托盘数
- 'product_varieties' => count($data['products']) // 产品种类数
- ];
- // ==================== 6. 处理产品数据 ====================
- $productDetails = []; // 产品主表数据
- $palletDetails = []; // 托盘明细数据
- $currentPalletNo = 1; // 托盘编号计数器
- /**
- * 第一阶段:处理完整托盘
- * 逻辑:先分配完整托盘,确保托盘利用率最大化
- */
- foreach ($data['products'] as $product) {
- // 6.1 动态获取托盘配置
- $tray_count = $product['tray_count'] ?? 18; // 默认18箱/托盘
- // 6.2 根据托盘配置确定层数和每层箱数
- if ($tray_count == 18) {
- $box_num = 3; // 3层
- $per_box = 6; // 每层6箱
- } elseif ($tray_count == 24) {
- $box_num = 4; // 4层
- $per_box = 6; // 每层6箱
- } elseif ($tray_count == 36) {
- $box_num = 4; // 4层
- $per_box = 9; // 每层9箱
- } else {
- $this->error('不支持的托盘配置:' . $tray_count);
- }
- $boxes_per_pallet = $per_box * $box_num; // 每托盘总箱数
- $small_num = $product['items_per_box'] ?? 20; // 每箱数量,默认20
- $default_layer_height = $product['default_layer_height'] ?? '1.35'; // 默认层高
- // 6.3 计算实际发货数量(不超过剩余数量)
- $remaining = (int)$product['remaining_quantity'];
- $actual = isset($product['actual_quantity']) ?
- min((int)$product['actual_quantity'], $remaining) : $remaining;
- // 6.4 计算托盘分配
- $total_boxes = ceil($actual / $small_num); // 总箱数
- $full_pallets = floor($total_boxes / $boxes_per_pallet); // 完整托盘数
- $remaining_boxes = $total_boxes % $boxes_per_pallet; // 剩余箱数
- // 6.5 构建产品基础信息
- $baseInfo = [
- 'bach_ids' => $bachNum,
- 'userid' => $userinfo['id'],
- 'gdbh' => $product['gdbh'],
- 'order_ddbh' => $product['order_ddbh'],
- 'cpbm' => $product['cpbm'],
- 'cpmc' => $product['cpmc'],
- 'matter_name' => $product['cpmc'],
- 'remark' => $product['remark'] ?? '',
- 'small_num' => $small_num,
- 'unit' => $product['unit'] ?? '套',
- 'tray_num' => $per_box,
- 'box_num' => $box_num,
- 'tray_count' => $tray_count,
- 'layer_height' => $product['layer_height'] ?? $default_layer_height,
- 'pallet_length' => $product['pallet_length'] ?? '0.9',
- 'pallet_width' => $product['pallet_width'] ?? '1.2',
- 'bach_status' => 0, // 状态(0:未处理)
- 'sys_rq' => $currentDate,
- 'created_at' => $currentDateTime,
- 'create_time' => $timestamp,
- 'delete_time' => ''
- ];
- // 6.6 处理完整托盘
- if ($full_pallets > 0) {
- $full_qty = $full_pallets * $boxes_per_pallet * $small_num;
- $endNo = $currentPalletNo + $full_pallets - 1;
- $productDetails[] = array_merge($baseInfo, [
- 'actual_quantity' => $full_qty,
- 'total_boxes' => $full_pallets * $boxes_per_pallet,
- 'pallet_count' => $full_pallets,
- 'pallet_type' => 'full',
- 'pallet_range' => "$currentPalletNo-$endNo",
- 'start_pallet_no' => $currentPalletNo,
- 'end_pallet_no' => $endNo
- ]);
- // 生成托盘明细记录
- for ($i = 0; $i < $full_pallets; $i++) {
- $palletDetails[] = [
- 'bach_ids' => $bachNum,
- 'product_id' => $product['gdbh'],
- 'pallet_no' => $currentPalletNo + $i,
- 'pallet_no_display' => $currentPalletNo + $i,
- 'pallet_type' => 'full',
- 'quantity' => $boxes_per_pallet * $small_num,
- 'box_count' => $boxes_per_pallet,
- 'layer_count' => $box_num,
- 'bach_status' => 0,
- 'created_at' => $currentDateTime,
- 'delete_time' => ''
- ];
- }
- // 更新统计信息
- $batchStats['full_pallets'] += $full_pallets;
- $batchStats['total_quantity'] += $full_qty;
- $batchStats['total_boxes'] += $full_pallets * $boxes_per_pallet;
- $currentPalletNo += $full_pallets;
- $batchStats['total_pallets'] += $full_pallets;
- }
- }
- /**
- * 第二阶段:处理不完整托盘
- * 逻辑:分配剩余不能组成完整托盘的部分
- */
- foreach ($data['products'] as $product) {
- // 同上获取托盘配置
- $tray_count = $product['tray_count'] ?? 18;
- if ($tray_count == 18) {
- $box_num = 3;
- $per_box = 6;
- } elseif ($tray_count == 24) {
- $box_num = 4;
- $per_box = 6;
- } elseif ($tray_count == 36) {
- $box_num = 4;
- $per_box = 9;
- } else {
- continue; // 已在前阶段验证过,这里跳过
- }
- $boxes_per_pallet = $per_box * $box_num;
- $small_num = $product['items_per_box'] ?? 20;
- $default_layer_height = $product['default_layer_height'] ?? '1.35';
- $remaining = (int)$product['remaining_quantity'];
- $actual = isset($product['actual_quantity']) ?
- min((int)$product['actual_quantity'], $remaining) : $remaining;
- $total_boxes = ceil($actual / $small_num);
- $full_pallets = floor($total_boxes / $boxes_per_pallet);
- $remaining_boxes = $total_boxes % $boxes_per_pallet;
- $baseInfo = [
- 'bach_ids' => $bachNum,
- 'userid' => $userinfo['id'],
- 'gdbh' => $product['gdbh'],
- 'order_ddbh' => $product['order_ddbh'],
- 'cpbm' => $product['cpbm'],
- 'cpmc' => $product['cpmc'],
- 'matter_name' => $product['cpmc'],
- 'remark' => $product['remark'] ?? '',
- 'small_num' => $small_num,
- 'unit' => $product['unit'] ?? '套',
- 'tray_num' => $per_box,
- 'box_num' => $box_num,
- 'tray_count' => $tray_count,
- 'layer_height' => $product['layer_height'] ?? $default_layer_height,
- 'pallet_length' => $product['pallet_length'] ?? '0.9',
- 'pallet_width' => $product['pallet_width'] ?? '1.2',
- 'bach_status' => 0,
- 'sys_rq' => $currentDate,
- 'created_at' => $currentDateTime,
- 'create_time' => $timestamp,
- 'delete_time' => ''
- ];
- // 处理不完整托盘
- if ($remaining_boxes > 0) {
- $partial_qty = $remaining_boxes * $small_num;
- $productDetails[] = array_merge($baseInfo, [
- 'actual_quantity' => $partial_qty,
- 'total_boxes' => $remaining_boxes,
- 'pallet_count' => 1,
- 'pallet_type' => 'partial',
- 'pallet_range' => (string)$currentPalletNo,
- 'start_pallet_no' => $currentPalletNo,
- 'end_pallet_no' => $currentPalletNo
- ]);
- $palletDetails[] = [
- 'bach_ids' => $bachNum,
- 'product_id' => $product['gdbh'],
- 'pallet_no' => $currentPalletNo,
- 'pallet_no_display' => $currentPalletNo,
- 'pallet_type' => 'partial',
- 'quantity' => $partial_qty,
- 'box_count' => $remaining_boxes,
- 'layer_count' => ceil($remaining_boxes / $per_box),
- 'bach_status' => 0,
- 'created_at' => $currentDateTime,
- 'delete_time' => ''
- ];
- // 更新统计信息
- $batchStats['partial_pallets']++;
- $batchStats['total_quantity'] += $partial_qty;
- $batchStats['total_boxes'] += $remaining_boxes;
- $currentPalletNo++;
- $batchStats['total_pallets']++;
- }
- }
- // ==================== 7. 构建批次汇总数据 ====================
- $summaryData = [
- 'bach_ids' => $bachNum,
- 'userid' => $userinfo['id'],
- 'total_quantity' => $batchStats['total_quantity'],
- 'total_boxes' => $batchStats['total_boxes'],
- 'total_pallets' => $batchStats['total_pallets'],
- 'product_count' => $batchStats['product_varieties'],
- 'full_pallets' => $batchStats['full_pallets'],
- 'partial_pallets' => $batchStats['partial_pallets'],
- 'bach_status' => 0,
- 'sys_rq' => $currentDate,
- 'created_at' => $currentDateTime,
- 'create_time' => $timestamp,
- 'delete_time' => ''
- ];
- // ==================== 8. 数据存储 ====================
- // try {
- // 8.1 开启事务(如果MongoDB支持)
- // 8.2 写入产品主表
- $mongo->name($collection)->insertAll($productDetails);
- // 8.3 写入托盘明细表
- $mongo->name($bachdetails)->insertAll($palletDetails);
- // 8.4 写入批次汇总表
- $mongo->name($bachsummary)->insert($summaryData);
- // ==================== 9. 更新库存记录 ====================
- foreach ($data['products'] as $product) {
- $where = [
- 'gdbh' => $product['gdbh'],
- 'order_ddbh' => $product['order_ddbh'],
- 'cpmc' => $product['cpmc'],
- ];
- $actual = (int)($product['actual_quantity'] ?? 0);
- $remaining = (int)$product['remaining_quantity'];
- // 查询现有库存记录
- $existing = $mongo->name('inventory_summary')->where($where)->find();
- if ($existing) {
- // 处理查询结果
- if (is_object($existing)) {
- $existing = (array)$existing;
- }
- if (isset($existing[0])) {
- $existing = $existing[0];
- }
- // 更新库存
- $mongo->name('inventory_summary')
- ->where($where)
- ->update([
- 'total_chu_quantity' => ($existing['total_chu_quantity'] ?? 0) + $actual,
- 'remaining_quantity' => ($existing['remaining_quantity'] ?? 0) - $actual,
- 'updated_at' => $currentDateTime,
- ]);
- } else {
- // 新增库存记录
- $mongo->name('inventory_summary')->insert([
- 'gdbh' => $product['gdbh'],
- 'order_ddbh' => $product['order_ddbh'],
- 'cpbm' => $product['cpbm'],
- 'cpmc' => $product['cpmc'],
- 'total_ru_quantity' => $remaining,
- 'total_chu_quantity' => $actual,
- 'remaining_quantity' => $remaining - $actual,
- 'created_at' => $currentDateTime,
- 'company' => $data['company_name'] ?? '',
- ]);
- }
- // 添加库存流水记录
- $mongo->name('inventory_records')->insert([
- 'gdbh' => $product['gdbh'],
- 'order_ddbh' => $product['order_ddbh'],
- 'cpbm' => $product['cpbm'],
- 'cpmc' => $product['cpmc'],
- 'operation_type' => 'outbound',
- 'quantity' => $actual,
- 'remaining_quantity' => $remaining - $actual,
- 'operator' => $userinfo['id'],
- 'created_at' => $currentDateTime,
- 'batch_number' => $bachNum,
- 'company' => $data['company_name'] ?? '',
- ]);
- }
- // 返回成功响应
- $this->success('批次创建成功');
- // } catch (\Exception $e) {
- // 错误处理
- // $this->error('批次创建失败:' . $e->getMessage());
- // }
- }
- // public function add_bach()
- // {
- // // 1. 请求验证部分
- // if (!$this->request->isAjax()) {
- // $this->error('请求必须为AJAX');
- // }
- //
- // $data = input('row');
- // if (empty($data)) {
- // $this->error('请求参数不能为空');
- // }
- //
- // $data = json_decode($data, true);
- // if (json_last_error() !== JSON_ERROR_NONE) {
- // $this->error('JSON数据解析失败');
- // }
- //
- // if (empty($data['products'])) {
- // $this->error('产品数据不能为空');
- // }
- //
- // // 2. 用户验证
- // $userinfo = Session::get('admin');
- // if (empty($userinfo) || !isset($userinfo['company'])) {
- // $this->error('获取用户信息失败,请重新登录');
- // }
- //
- // // 3. 数据库连接
- // $mongo = \think\Db::connect('mongodb');
- // $collection = $userinfo['company'] . '_qcode_bach'; // 产品主表
- // $bachdetails = $userinfo['company'] . '_qcode_bachdetails'; // 托盘明细表
- // $bachsummary = $userinfo['company'] . '_qcode_bachsummary'; // 批次汇总表
- //
- // // 4. 生成批次信息
- // $currentDate = date('Y-m-d');
- // $currentDateTime = date('Y-m-d H:i:s');
- // $timestamp = time();
- // $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999);
- //
- // // 5. 托盘配置
- // $config = [
- // 'tray_num' => 6, // 每层6箱
- // 'small_num' => 20, // 每箱20个
- // 'pallet_length' => '0.9',
- // 'pallet_width' => '1.2',
- // 'default_layer_height' => '1.35'
- // ];
- //
- // // 6. 初始化数据容器
- // $fullPalletsData = []; // 完整托盘数据
- // $partialPalletsData = []; // 不完整托盘数据
- // $palletDetails = []; // 托盘明细数据
- // $batchStats = [
- // 'total_quantity' => 0, // 总产品数量
- // 'total_boxes' => 0, // 总箱数
- // 'total_pallets' => 0, // 总托盘数
- // 'full_pallets' => 0, // 完整托盘数
- // 'partial_pallets' => 0, // 不完整托盘数
- // 'product_varieties' => count($data['products']) // 产品种类数
- // ];
- //
- // $currentPalletNo = 1; // 全局托盘计数器
- //
- // // 7. 第一阶段:处理所有完整托盘
- // foreach ($data['products'] as $product) {
- // // 7.1 计算托盘配置
- // $tray_count = isset($product['tray_count']) ? (int)$product['tray_count'] : 18;
- // $box_num = $tray_count == 24 ? 4 : 3;
- //
- // // 7.2 处理数量 - 确保不超过剩余数量
- // $remaining_quantity = (int)$product['remaining_quantity'];
- // $actual_quantity = isset($product['actual_quantity']) ?
- // min((int)$product['actual_quantity'], $remaining_quantity) :
- // $remaining_quantity;
- //
- // // 7.3 计算托盘分配
- // $boxes_per_pallet = $config['tray_num'] * $box_num;
- // $total_boxes = ceil($actual_quantity / $config['small_num']);
- // $full_pallets = floor($total_boxes / $boxes_per_pallet);
- // $remaining_boxes = $total_boxes % $boxes_per_pallet;
- //
- // // 7.4 产品基础信息
- // $baseProductInfo = [
- // 'bach_ids' => $bachNum,
- // 'userid' => $userinfo['id'],
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'matter_name' => $product['cpmc'],
- // 'remark' => $product['remark'] ?? '',
- // 'small_num' => $config['small_num'],
- // 'tray_num' => $config['tray_num'],
- // 'box_num' => $box_num,
- // 'tray_count' => $tray_count,
- // 'layer_height' => $product['layer_height'] ?? $config['default_layer_height'],
- // 'pallet_length' => $config['pallet_length'],
- // 'pallet_width' => $config['pallet_width'],
- // 'bach_status' => 0,
- // 'sys_rq' => $currentDate,
- // 'created_at' => $currentDateTime,
- // 'create_time' => $timestamp,
- // 'delete_time' => ''
- // ];
- //
- // // 7.5 处理完整托盘
- // if ($full_pallets > 0) {
- // $full_quantity = $full_pallets * $boxes_per_pallet * $config['small_num'];
- // $endPalletNo = $currentPalletNo + $full_pallets - 1;
- //
- // $fullPalletsData[] = [
- // 'product_info' => array_merge($baseProductInfo, [
- // 'actual_quantity' => $full_quantity,
- // 'total_boxes' => $full_pallets * $boxes_per_pallet,
- // 'pallet_count' => $full_pallets,
- // 'pallet_type' => 'full',
- // 'pallet_range' => $currentPalletNo . '-' . $endPalletNo,
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $endPalletNo
- // ]),
- // 'pallet_count' => $full_pallets,
- // 'start_no' => $currentPalletNo,
- // 'boxes_per_pallet' => $boxes_per_pallet,
- // 'box_num' => $box_num
- // ];
- //
- // $batchStats['full_pallets'] += $full_pallets;
- // $batchStats['total_quantity'] += $full_quantity;
- // $batchStats['total_boxes'] += $full_pallets * $boxes_per_pallet;
- // $currentPalletNo += $full_pallets;
- // $batchStats['total_pallets'] += $full_pallets;
- // }
- // }
- //
- // // 8. 第二阶段:处理所有不完整托盘
- // foreach ($data['products'] as $product) {
- // // 8.1 计算托盘配置
- // $tray_count = isset($product['tray_count']) ? (int)$product['tray_count'] : 18;
- // $box_num = $tray_count == 24 ? 4 : 3;
- //
- // // 8.2 处理数量 - 确保不超过剩余数量
- // $remaining_quantity = (int)$product['remaining_quantity'];
- // $actual_quantity = isset($product['actual_quantity']) ?
- // min((int)$product['actual_quantity'], $remaining_quantity) :
- // $remaining_quantity;
- //
- // // 8.3 计算托盘分配
- // $boxes_per_pallet = $config['tray_num'] * $box_num;
- // $total_boxes = ceil($actual_quantity / $config['small_num']);
- // $full_pallets = floor($total_boxes / $boxes_per_pallet);
- // $remaining_boxes = $total_boxes % $boxes_per_pallet;
- //
- // // 8.4 产品基础信息
- // $baseProductInfo = [
- // 'bach_ids' => $bachNum,
- // 'userid' => $userinfo['id'],
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'matter_name' => $product['cpmc'],
- // 'remark' => $product['remark'] ?? '',
- // 'small_num' => $config['small_num'],
- // 'tray_num' => $config['tray_num'],
- // 'box_num' => $box_num,
- // 'tray_count' => $tray_count,
- // 'layer_height' => $product['layer_height'] ?? $config['default_layer_height'],
- // 'pallet_length' => $config['pallet_length'],
- // 'pallet_width' => $config['pallet_width'],
- // 'bach_status' => 0,
- // 'sys_rq' => $currentDate,
- // 'created_at' => $currentDateTime,
- // 'create_time' => $timestamp,
- // 'delete_time' => ''
- // ];
- //
- // // 8.5 处理不完整托盘
- // if ($remaining_boxes > 0) {
- // // 计算完整托盘已经处理的数量
- // $full_quantity = $full_pallets * $boxes_per_pallet * $config['small_num'];
- // // 确保不完整托盘数量不超过剩余数量
- // $partial_quantity = min($remaining_boxes * $config['small_num'], $actual_quantity - $full_quantity);
- //
- // $partialPalletsData[] = [
- // 'product_info' => array_merge($baseProductInfo, [
- // 'actual_quantity' => $partial_quantity,
- // 'total_boxes' => $remaining_boxes,
- // 'pallet_count' => 1,
- // 'pallet_type' => 'partial',
- // 'pallet_range' => (string)$currentPalletNo,
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $currentPalletNo
- // ]),
- // 'pallet_count' => 1,
- // 'start_no' => $currentPalletNo,
- // 'remaining_boxes' => $remaining_boxes
- // ];
- //
- // $batchStats['partial_pallets']++;
- // $batchStats['total_quantity'] += $partial_quantity;
- // $batchStats['total_boxes'] += $remaining_boxes;
- // $currentPalletNo++;
- // $batchStats['total_pallets']++;
- // }
- // }
- //
- // // 9. 验证总数是否正确
- // $expected_total = array_sum(array_map(function($product) {
- // return isset($product['actual_quantity']) ?
- // min((int)$product['actual_quantity'], (int)$product['remaining_quantity']) :
- // (int)$product['remaining_quantity'];
- // }, $data['products']));
- //
- // if ($batchStats['total_quantity'] != $expected_total) {
- // $this->error('计算数量不一致,预期: '.$expected_total.',实际: '.$batchStats['total_quantity']);
- // }
- //
- // // 10. 合并所有托盘数据(完整托盘在前,不完整托盘在后)
- // $allPalletData = array_merge($fullPalletsData, $partialPalletsData);
- //
- // // 11. 生成最终的产品主表数据和托盘明细数据
- // $productDetails = [];
- // $palletDetails = [];
- // $currentPalletNo = 1; // 重新开始计数
- //
- // foreach ($allPalletData as $pallet) {
- // if (isset($pallet['boxes_per_pallet'])) {
- // // 完整托盘
- // $endPalletNo = $currentPalletNo + $pallet['pallet_count'] - 1;
- //
- // $productDetails[] = array_merge($pallet['product_info'], [
- // 'pallet_range' => $currentPalletNo . '-' . $endPalletNo,
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $endPalletNo
- // ]);
- //
- // // 生成托盘明细
- // for ($i = 0; $i < $pallet['pallet_count']; $i++) {
- // $palletDetails[] = [
- // 'bach_ids' => $bachNum,
- // 'product_id' => $pallet['product_info']['gdbh'],
- // 'pallet_no' => $currentPalletNo + $i,
- // 'pallet_no_display' => $currentPalletNo + $i,
- // 'pallet_type' => 'full',
- // 'quantity' => $pallet['boxes_per_pallet'] * $config['small_num'],
- // 'box_count' => $pallet['boxes_per_pallet'],
- // 'layer_count' => $pallet['box_num'],
- // 'bach_status' => 0,
- // 'created_at' => $currentDateTime,
- // 'delete_time' => ''
- // ];
- // }
- //
- // $currentPalletNo += $pallet['pallet_count'];
- // } else {
- // // 不完整托盘
- // $productDetails[] = array_merge($pallet['product_info'], [
- // 'pallet_range' => (string)$currentPalletNo,
- // 'start_pallet_no' => $currentPalletNo,
- // 'end_pallet_no' => $currentPalletNo
- // ]);
- //
- // $palletDetails[] = [
- // 'bach_ids' => $bachNum,
- // 'product_id' => $pallet['product_info']['gdbh'],
- // 'pallet_no' => $currentPalletNo,
- // 'pallet_no_display' => $currentPalletNo,
- // 'pallet_type' => 'partial',
- // 'quantity' => $pallet['product_info']['actual_quantity'],
- // 'box_count' => $pallet['product_info']['total_boxes'],
- // 'layer_count' => ceil($pallet['product_info']['total_boxes'] / $config['tray_num']),
- // 'bach_status' => 0,
- // 'created_at' => $currentDateTime,
- // 'delete_time' => ''
- // ];
- //
- // $currentPalletNo++;
- // }
- // }
- //
- // // 12. 构建批次汇总数据
- // $summaryData = [
- // 'bach_ids' => $bachNum, // 单据编号
- // 'userid' => $userinfo['id'], // 用户ID
- // 'total_quantity' => $batchStats['total_quantity'], // 总发货数量
- // 'total_boxes' => $batchStats['total_boxes'], // 总箱数
- // 'total_pallets' => $batchStats['total_pallets'], // 总托盘数
- // 'product_count' => $batchStats['product_varieties'], // 产品数量
- // 'full_pallets' => $batchStats['full_pallets'], // 完整托盘数
- // 'partial_pallets' => $batchStats['partial_pallets'], // 不完整托盘数
- // 'bach_status' => 0, // 状态
- // 'sys_rq' => $currentDate, // 日期
- // 'created_at' => $currentDateTime, // 操作时间
- // 'create_time' => $timestamp, // 时间戳
- // 'delete_time' => '' // 删除时间
- // ];
- //
- // foreach ($data['products'] as $product) {
- // $where = [
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpmc' => $product['cpmc'],
- // ];
- //
- // // 实际出库数量
- // $actual_quantity = isset($product['actual_quantity']) ? (int)$product['actual_quantity'] : 0;
- // $remaining_quantity = isset($product['remaining_quantity']) ? (int)$product['remaining_quantity'] : 0;
- //
- // // 插入/更新字段
- // $insertData = [
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'total_ru_quantity' => $remaining_quantity, // 入库数来自当前剩余
- // 'total_chu_quantity' => $actual_quantity, // 本次出库数
- // 'remaining_quantity' => $remaining_quantity - $actual_quantity, // 计算结存
- // 'created_at' => date('Y-m-d H:i:s'),
- // 'updated_at' => '',
- // 'mod_rq' => '',
- // 'company' => $data['company_name'] ?? '',
- // ];
- //
- // // 查询是否已存在
- // $existing = $mongo->name('inventory_summary')->where($where)->find();
- //
- // if ($existing) {
- // // 累加更新
- // $new_chu = (int)$existing['total_chu_quantity'] + $actual_quantity;
- // $new_remaining = (int)$existing['remaining_quantity'] - $actual_quantity;
- //
- // $mongo->name('inventory_summary')
- // ->where($where)
- // ->update([
- // 'total_ru_quantity' => (int)$existing['total_ru_quantity'], // 保持不变或你可定义逻辑
- // 'total_chu_quantity' => $new_chu,
- // 'remaining_quantity' => $new_remaining,
- // 'updated_at' => date('Y-m-d H:i:s'),
- // ]);
- // } else {
- // // 插入新记录
- // $mongo->name('inventory_summary')->insert($insertData);
- // }
- //
- // // 插入库存明细记录
- // $mongo->name('inventory_records')->insert($insertData);
- // }
- //
- // // 13. 数据入库操作
- // try {
- // $mongo->name($collection)->insertAll($productDetails);
- // $mongo->name($bachdetails)->insertAll($palletDetails);
- // $mongo->name($bachsummary)->insert($summaryData);
- //
- //// $this->success('批次创建成功', null, [
- //// 'bach_num' => $bachNum,
- //// 'total_quantity' => $batchStats['total_quantity'],
- //// 'total_boxes' => $batchStats['total_boxes'],
- //// 'total_pallets' => $batchStats['total_pallets'],
- //// 'product_count' => $batchStats['product_varieties'],
- //// 'pallet_range' => '1-' . ($currentPalletNo - 1)
- //// ]);
- // } catch (\Exception $e) {
- // $this->error('批次创建失败:' . $e->getMessage());
- // }
- // }
- // public function add_bach()
- // {
- // if (!$this->request->isAjax()) {
- // $this->error('请求错误');
- // }
- //
- // $data = input('row');
- // if (empty($data)) {
- // $this->error('参数错误');
- // }
- //
- // $data = json_decode($data, true);
- //
- // if (json_last_error() !== JSON_ERROR_NONE) {
- // $this->error('JSON解析错误');
- // }
- //
- // if (empty($data['products'])) {
- // $this->error('产品数据不能为空');
- // }
- //
- // $userinfo = Session::get('admin');
- // if (empty($userinfo) || !isset($userinfo['company'])) {
- // $this->error('用户信息获取失败');
- // }
- //
- // $mongo = \think\Db::connect('mongodb');
- // $collection = $userinfo['company'] . '_qcode_bach';
- // $bachsummary = $userinfo['company'] . '_qcode_bachsummary';
- //
- // $insertData = [];
- // $currentday = date('Y-m-d');
- // $currentTime = date('Y-m-d H:i:s');
- // $timestamp = time();
- // $bachNum = 'BACH' . date('YmdHis') . mt_rand(1000, 9999);
- //
- // $totalQuantity = 0;
- // $totalBoxes = 0;
- // $totalPallets = 0;
- //
- // foreach ($data['products'] as $product) {
- // $small_num = 20;
- // $tray_num = 6;
- // $box_num = 3;
- // $total_boxes = $tray_num * $box_num;
- //
- // $remaining_quantity = (int)$product['remaining_quantity'];
- // $larger_num = ceil($remaining_quantity / $small_num);
- // $large_num = ceil($larger_num / $total_boxes);
- //
- // $totalQuantity += $remaining_quantity;
- // $totalBoxes += $larger_num;
- // $totalPallets += $large_num;
- //
- // $palletRange = '1-' . $large_num;
- //
- // $insertData[] = [
- // 'userid' => $userinfo['id'],
- // 'supplier_id' => $userinfo['id'],
- // 'supplier_code' => $userinfo['printer_code'],
- // 'supplier_name' => $data['company_name'],
- // 'pallet' => $palletRange,
- // 'matter_no' => $product['gdbh'],
- // 'matter_id' => $product['gdbh'],
- // 'matter_type' => '01',
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'matter_name' => $product['cpmc'],
- // 'remark' => $product['remark'],
- // 'num_danwei' => '2',
- // 'danwei' => '套',
- // 'num' => $remaining_quantity,
- // 'small_num' => $small_num,
- // 'tray_num' => $tray_num,
- // 'box_num' => $box_num,
- // 'total_boxes' => $total_boxes,
- // 'large_num' => $large_num,
- // 'larger_num' => $larger_num,
- // 'pallet_height' => '1.05',
- // 'pallet_length' => '0.9',
- // 'pallet_width' => '1.2',
- // 'l_reservation' => '',
- // 'l_flow' => '1',
- // 'l_weight' => '',
- // 's_flow' => '',
- // 's_weight' => '',
- // 's_reservation' => '',
- // 'bach_status' => 0,
- // 'bach_ids' => $bachNum,
- // 'large_endnum' => $large_num,
- // 'manufacture_date' => '',
- // 'print_date' => '',
- // 'sys_rq' => $currentday,
- // 'created_at' => $currentTime,
- // 'create_time' => $timestamp,
- // 'updated_at' => '',
- // 'sync_flag' => '0',
- // 'delete_time' => '',
- // 'delect_time' => ''
- // ];
- // }
- //
- // $insertData_bachsummary = [
- // 'bach_ids' => $bachNum,
- // 'userid' => $userinfo['id'],
- // 'supplier_id' => $userinfo['id'],
- // 'supplier_code' => $userinfo['printer_code'],
- // 'supplier_name' => $data['company_name'],
- // 'total_quantity' => $totalQuantity,
- // 'total_boxes' => $totalBoxes,
- // 'total_pallets' => $totalPallets,
- // 'product_count' => count($data['products']),
- // 'bach_status' => 0,
- // 'sys_rq' => $currentday,
- // 'created_at' => $currentTime,
- // 'create_time' => $timestamp,
- // 'updated_at' => '',
- // 'delete_time' => ''
- // ];
- //
- //echo "<pre>";
- //print_r($insertData);
- //echo "<pre>";die;
- // $mongo->name($collection)->insertAll($insertData);
- // $mongo->name($bachsummary)->insert($insertData_bachsummary);
- //
- //
- // foreach ($data['products'] as $product) {
- // $where = [
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpmc' => $product['cpmc'],
- // ];
- //
- // // 实际出库数量
- // $actual_quantity = isset($product['actual_quantity']) ? (int)$product['actual_quantity'] : 0;
- // $remaining_quantity = isset($product['remaining_quantity']) ? (int)$product['remaining_quantity'] : 0;
- //
- // // 插入/更新字段
- // $insertData = [
- // 'gdbh' => $product['gdbh'],
- // 'order_ddbh' => $product['order_ddbh'],
- // 'cpbm' => $product['cpbm'],
- // 'cpmc' => $product['cpmc'],
- // 'total_ru_quantity' => $remaining_quantity, // 入库数来自当前剩余
- // 'total_chu_quantity' => $actual_quantity, // 本次出库数
- // 'remaining_quantity' => $remaining_quantity - $actual_quantity, // 计算结存
- // 'created_at' => date('Y-m-d H:i:s'),
- // 'updated_at' => '',
- // 'mod_rq' => '',
- // 'company' => $data['company_name'] ?? '',
- // ];
- //
- // // 查询是否已存在
- // $existing = $mongo->name('inventory_summary')->where($where)->find();
- //
- // if ($existing) {
- // // 累加更新
- // $new_chu = (int)$existing['total_chu_quantity'] + $actual_quantity;
- // $new_remaining = (int)$existing['remaining_quantity'] - $actual_quantity;
- //
- // $mongo->name('inventory_summary')
- // ->where($where)
- // ->update([
- // 'total_ru_quantity' => (int)$existing['total_ru_quantity'], // 保持不变或你可定义逻辑
- // 'total_chu_quantity' => $new_chu,
- // 'remaining_quantity' => $new_remaining,
- // 'updated_at' => date('Y-m-d H:i:s'),
- // ]);
- // } else {
- // // 插入新记录
- // $mongo->name('inventory_summary')->insert($insertData);
- // }
- //
- // // 插入库存明细记录
- // $mongo->name('inventory_records')->insert($insertData);
- // }
- // $this->success('添加成功');
- //
- // }
- /**
- * 增加新批次
- */
- public function add()
- {
- $product = new QcodeProduct();
- $bach = new QcodeBach();
- $large = new QcodeLarge();
- $small = new QcodeSmall();
- $liushui = new QcodeLiushui();
- $resetFlow = new ResetFlow();
- $QcodeCompany = new QcodeCompany();
- if ($this->request->isAjax() === false){
- $this->error('请求错误');
- }
- $rows = input('row');
- if (empty($rows)){
- $this->error('参数错误');
- }
- $rows = json_decode($rows);
- $data = [];
- foreach ($rows as $value){
- foreach ($value as $k=>$v){
- $data[$k] = $v;
- }
- }
- // echo "接口获取";echo "<pre>";print_r($data);echo "<pre>";die;
- //记录库存操作
- $mongo = \think\Db::connect('mongodb');
- $where = [
- 'gdbh' => $data['gdbh'],
- 'order_ddbh' => $data['order_ddbh'],
- 'cpmc' => $data['cpmc'],
- ];
- //插入字段[inventory_summaryk库存明细]
- $insertData = [
- 'gdbh' => $data['gdbh'],
- 'order_ddbh' => $data['order_ddbh'],
- 'cpbm' => $data['cpbm'],
- 'cpmc' => $data['cpmc'],
- 'total_ru_quantity' => $data['sl'],//入库数
- 'total_chu_quantity' => $data['number'],//出库数
- 'remaining_quantity' => $data['remaining_quantity'] - $data['number'],//剩余数
- 'created_at' => date('Y-m-d H:i:s'),
- 'updated_at' => '',
- 'mod_rq' => '',
- 'company' => '',
- ];
- // 查询库存汇总表数据是否存在记录
- $list = $mongo->name('inventory_summary')->where($where)->find();
- if ($list) {
- // 如果数据存在,更新库存汇总记录
- $chu = $list['total_chu_quantity'] + $data['number'];//累计出库数量
- $jiecun = $list['remaining_quantity'] - $data['number'];//剩余结存数量
- $updateResult = $mongo->name('inventory_summary')
- ->where($where)
- ->update([
- 'total_ru_quantity' => $data['sl'],
- 'total_chu_quantity' => $chu,
- 'remaining_quantity' => $jiecun,
- 'updated_at' => date('Y-m-d H:i:s'),
- ]);
- } else {
- // 数据不存在则插入新记录
- $mongo->name('inventory_summary')->insert($insertData);
- }
- //记录库存明细
- $mongo->name('inventory_records')->insert($insertData);
- // // 调试输出
- // echo "<pre>"; print_r($list); echo "</pre>";die;
- switch ($data['danwei']) {
- case 1:
- $danwei = '个';
- break;
- case 2:
- $danwei = '套';
- break;
- case 3:
- $danwei = '张';
- break;
- default:
- $danwei = '';
- break;
- }
- $userinfo = Session::get('admin');//获取用户信息
- $arr = [
- 'batch' => $data['gdbh'],
- 'create_time' => time(),
- 'delect_time' => '',
- 'sync_flag' => 0,
- ];
- $productres = $QcodeCompany->save($arr);
- if ($productres === 0){
- $this->error('添加失败');
- }
- $batchList = [
- 'userid' => $userinfo['id'],//登录用户id
- 'supplier_id' => $userinfo['id'],//登录用户id
- 'supplier_code' => $userinfo['printer_code'],
- 'supplier_name' => $data['company_name'],//公司名称
- 'cpbm' => $data['cpbm'],//成品编码
- 'matter_name' => $data['cpmc'],//成品名称
- 'matter_no' => $data['gdbh'],//生产批次号-工单编号
- 'order_ddbh' => $data['order_ddbh'],//销售订单号
- 'matter_id' => $data['gdbh'],
- 'matter_type' => '01',
- 'manufacture_date' => (int)date('ymd',strtotime($data['manufacture_date'])),//生产日期
- 'print_date' => (int)date('ymd',strtotime($data['print_date'])),//打码日期
- 'num_danwei' => $data['danwei'],//单位
- 'danwei' => $danwei,//单位
- 'num' => $data['number'],//总数量(张/个)
- 'small_num' => $data['box_number'],//每一箱数量
- 'tray_num' => $data['tray_num'],//每层箱数【箱/层】
- 'box_num' => $data['tray_number'],//每托层数【 层/托】
- 'total_boxes' => $data['total_boxes'],//每托盘箱数【箱/托】
- 'large_num' => $data['box_num'],//本次打包托盘数
- 'larger_num' => $data['small_num'],//总箱数
- 'pallet_height' => $data['pallet_height'],//每托高度
- 'pallet_length' => $data['pallet_length'],//托盘规格
- 'pallet_width' => $data['pallet_width'],//托盘规格
- 'l_reservation' => '',
- // 处理可能为空的流水/重量字段
- 'l_flow' => $data['big_liushui'],//大件流水
- 'l_weight' => $data['big_weight'],//大件重量
- 's_flow' => $data['small_start_liushui'],//小件流水
- 's_weight' => $data['small_weight'],//小件重量
- 's_reservation' => '',
- 'bach_status' => 0,
- 'bach_num' => $data['gdbh'],//生产批次号-工单编号
- 'large_endnum' => $data['big_liushui'] + $data['box_num'] -1,
- 'create_time' => time(),//新增时间
- 'delect_time' => '',//删除时间
- ];
- $res = $bach->save($batchList);
- if ($res === 0){
- $this->error('添加失败');
- }
- $flow = [
- 'l_flow' => (int)$batchList['large_num'],
- 'bach_num' => $batchList['matter_no'],
- ];
- if ($resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_no'])->find()){
- $resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_no'])->update($flow);
- }else{
- $flow['product_id'] = $batchList['matter_no'];
- $resetFlow->save($flow);
- }
- $last_id = $bach->getLastInsID();
- if ($last_id){
- //插入大小二维码数据 二维码数据不变区域
- // echo "<pre>";print_r($batchList);echo "<pre>";die;
- $fixed_code = '';
- $fixed_code.=$this->intTochar($batchList['matter_type'],2);//2位 辅料种类编码
- $fixed_code .= $this->intTochar($batchList['supplier_code'], 21);//21位 供应商编码
- $fixed_code .= '9'; // 补0一位
- $fixed_code.=$this->intTochar($batchList['cpbm'],10);//10位 辅料编码
- $fixed_code.=$batchList['manufacture_date'];//6位 生产日期
- $print_code=$batchList['print_date'];//6位 打码日期
- $small_liushui = [
- 'onlycode' => 'AB92'.$fixed_code.$print_code,
- 'last_num' => 0,
- 'user_id' => $userinfo['company'],
- 'stype' => 2,
- 'dateTime' => time(),
- ];
- $whereSmall = [
- 'onlycode' => $small_liushui['onlycode'],
- 'user_id' => $userinfo['company'],
- ];
- if ($liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find()){
- //小件二维码存在,更新小件二维码最后流水号
- $lastNum = $liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find();
- }else{
- //小件二维码不存在,新增记录
- $liushui->save($small_liushui);
- $lastNum['last_num'] = 0;
- }
- //循环插入大件二维码数据
- for ($i=0;$i<$data['box_num'];$i++){
- $large = new QcodeLarge();
- $l_flow = $this->intTochar($batchList['l_flow']+$i,6);
- $l_weight = $this->intTochar($batchList['l_weight']*100,6);
- $l_reservation = $this->intTochar($batchList['matter_no'],10);
- $l_reservation = $l_reservation.'0000000000';
- $remainder = $batchList['num'] - $batchList['total_boxes'] * $i;//最后一托盘小件数量
- if ($remainder < $batchList['tray_num']){
- $small_n = $this->intTochar($remainder,3);//3位小件数量,不足补0
- }else{
- $small_n = $this->intTochar($batchList['tray_num'],3);
- }
- // $l_num = $small_n * $batchList['box_num'];
- $l_num = 0;
- //大件二维码数据
- $code_data = $this->CodeData('AB92',$fixed_code,$small_n,$print_code,$l_flow,$l_weight,'2',$l_reservation);
- //大码数据信息
- $l_data = [
- 'bach_id' => $last_id,
- 'code' => $code_data['code'],
- 'code_cp1' => $code_data['code_cp1'],
- 'code_cp2' => $code_data['code_cp2'],
- 'print_date' => $print_code,
- 'create_time' => time(),
- 'p_nums' => 0,
- 'userid' =>$userinfo['id'],
- 'l_weight' =>$batchList['l_weight']*100,
- 'l_num' =>$l_num,
- 'l_status' => 0,
- 'l_print' => 0
- ];
- $l_res = $large->save($l_data);
- if ($l_res === 0){
- $this->error('大件码插入失败');
- }
- $large_id = $large->getLastInsID();
- if ($large_id){
- // //小件码循环插入
- // for ($j=0;$j<$data['tray_num'] and ($j+$i*$data['tray_num'])<$batchList['small_num'];$j++){
- for ($j=0;$j<$data['total_boxes'] and ($j+$i*$data['total_boxes'])<$batchList['total_boxes'];$j++){
- $small = new QcodeSmall();
- $s_flow = $this->intTochar($batchList['s_flow']+$j+$i*$data['tray_num']+$lastNum['last_num'],6);//小件码序号从1开始
- $s_weight = $this->intTochar($batchList['s_weight'],6);
- $small_sign = '000';
- $s_reservation = $this->intTochar($batchList['bach_num'],10);
- $s_reservation = $s_reservation . '0000000000';
- //生成小件码
- $small_code_data = $this->CodeData('AB92',$fixed_code,$small_sign,$print_code,$s_flow,$s_weight,'1',$s_reservation);
- //小码数据
- $s_data = [
- 'large_id'=>$large_id,
- 'bach_id'=>$last_id,
- 'code'=>$small_code_data['code'],
- 'code_cp1'=>$small_code_data['code_cp1'],
- 'code_cp2'=>$small_code_data['code_cp2'],
- 'l_flow'=>$j+1,
- 'print_date'=>$print_code,
- 'create_time'=>time(),
- 'p_nums'=>0,
- 'userid'=>$userinfo['id'],//小码绑定用户id
- 's_weight'=>$batchList['s_weight'],//单个小件重量
- 'status' => 0,
- ];
- $s_res = $small->save($s_data);
- if ($s_res === 0){
- $this->error('小件码插入失败');
- }
- }
- }else{
- $this->error('添加失败');
- }
- }
- }
- $liushui_res = $liushui->name($userinfo['id'].'_'.'qcode_liushui')->where($whereSmall)->update(['last_num'=>$batchList['small_num']]);
- if ($liushui_res === false){
- $this->error('添加失败');
- }
- return json(['code' => 1, 'msg' => '成功', 'data' => '']);
- // $this->success('成功');
- }
- /**
- * 编码补位
- * @param $num
- * @param $len
- * @return string
- */
- function intTochar($num=0,$len){
- //规定的不足的时候自动补足零
- $code=(string)$num;
- $buwei='';
- if(strlen($code)<$len){
- for($i=strlen($code);$i<$len;$i++){
- $buwei.='0';
- }
- }
- return $buwei.$code;
- }
- /**
- * 二维码编码生成
- * @param $sign
- * @param $fixed_code
- * @param $small_num
- * @param $print_date
- * @param $flow
- * @param $weight
- * @param $large_sign
- * @param $reservation
- * @return array
- */
- function CodeData($sign,$fixed_code,$small_num,$print_date,$flow,$weight,$large_sign,$reservation){
- $code=$sign;//4 位固定标志位
- $code.=$fixed_code; // 固定字符串
- $code.=$small_num;//3位 小件数量
- $code.=$print_date;//6 位 日期
- $code.=$flow;//6位打印流水号
- $code.=$weight;//6位辅料重量
- $code.=$large_sign;//大小件标示位
- $code.=$reservation;//20 位 预留号
- //大码数据信息
- $data=[
- 'code'=>str_replace(" ","",$code),
- 'code_cp1'=>$print_date.$flow,
- 'code_cp2'=>$weight.$reservation,//20位补充
- 'print_date'=>time(),
- 'p_nums'=>0,
- ];
- return $data;
- }
- }
|