Easyui 实现订单拆分开票功能
需求
1、实现一个订单开具多分发票功能;
2、支持拆行;
3、支持拆数量;
流程设计
1、操作页面展示订订单头信息,订单明细信息
2、点击新增发票按钮弹出一个弹出框用于创建一张拆分发票,弹出框可以选择商品明细输入数量。每次添加一张
3、点击弹出框的保存功能实现订单拆分
4、提交到后台之后,生成多张发票
页面设计依次如下
核心代码如下
<!-- 新增发票按钮-->
<span class="span_title"><a href="javascript:void(0)" style="color: red;font-weight: bold" onclick="addTicketDialog()">新增发票</a></span><!-- tablesContainer为添加发票的容器 -->
<div id="extInfoBtn" class="div_detail_margin_left_right div_button div_button_detail"><div class="div_button_title"><span id="extInfoTitle" class="spanTitleImgOpen" onClick="hideshow('extInfo','extInfoTitle','divExtInfoBtn')"/></div><div class="div_button_title"><span class="span_title">开票明细</span></div>
</div>
<div id="extInfo" class="div_detail_margin_left_right"><div style="margin-top:10px;margin-bottom:10px;"><div id="tablesContainer" ></div></div>
</div><!-- 弹出框 -->
<div id="addDialog" class="easyui-dialog" style="width:70%;height:500px" data-options="title:'拆分开票',toolbar:'#addToolbar',buttons:'#bb',modal:true,closed: true"><table class="easyui-datagrid" id="addTable" style="width:100%;height:365px;"data-options="singleSelect:true,collapsible:true,fitColumns:true"><thead><tr><th data-options="field:'id',width:80" formatter="formatOpt">操作</th><th data-options="field:'customerLineItem',width:80">项目行号</th><th data-options="field:'taxCode',width:120" formatter="formatTaxCode">税收编码</th><th data-options="field:'projectName',width:300" formatter="formatterProjectName">商品发票名称</th><th data-options="field:'model',width:120" formatter="formatterModel">发票型号</th><th data-options="field:'quantity',width:50,align:'right'">订单数量</th><th data-options="field:'thisTimeQuantity',width:50,align:'right'">本次开票数量</th><th data-options="field:'productUnit',width:50">单位</th><th data-options="field:'feeSku',width:80,align:'right'">含税单价</th><th data-options="field:'tax',width:80,align:'right'" formatter="formatterTax">税率</th><th data-options="field:'feeTotal',width:80">含税总价</th></tr></thead></table><div id="addRemark" style="padding:2px 5px;">开票栏备注: <input class="easyui-textbox" id="remark" class="remark" name="remark" style="width:90%"></div>
</div>
<div id="bb" style="font-size: 12px;"><div style="float: left">订单金额:<input id="orderAmount" class="easyui-textbox" disabled/>发票金额:<input id="invoiceAmount" class="easyui-textbox" disabled/></div><a href="javascript:void(0)" onclick="saveOne()" class="easyui-linkbutton">保存</a><a href="javascript:void(0)" class="easyui-linkbutton">关闭</a>
</div>
<div id="addToolbar" style="padding:2px 5px;font-size: 12px;">开票商品: <select class="easyui-combobox" id="addItem" style="width:300px"></select>可开票数量: <input class="easyui-numberbox" id="maxQty" disabled panelHeight="auto" style="width:110px"></input>本次开票数量: <input class="easyui-numberbox" id="quantity" name="qty" style="width:110px" data-options="min:0,precision:0"/><a href="javascript:void(0)" class="easyui-linkbutton" onclick="addRow()" iconCls="icon-add">添加</a>
</div>
js核心代码
/*新增发票编辑窗口*/
function addTicketDialog(){endEdit();orderItems = $('#detailTable').datagrid('getRows');orderItems = orderItems.map(item => ({...item, leftQuantity: item.quantity }));// 设置值$('#addItem').combobox({valueField: 'customerLineItem',textField: 'projectName',data:orderItems,panelHeight:'auto',onSelect:handleOnSelect});$("#orderAmount").textbox('setValue',invoice.orderFee)$('#addDialog').dialog('open');
}function handleOnSelect(rec){$('#maxQty').numberbox('setValue',rec.leftQuantity);$('#quantity').numberbox({ max:rec.leftQuantity });selectedRow = rec
}/*添加行*/
function addRow(){let dg = $('#addTable');let rows = dg.datagrid('getRows');let thisTimeQuantity = $('#quantity').numberbox('getValue');if(thisTimeQuantity == null || thisTimeQuantity == 0){$.messager.alert('操作提示','请输入本次开票数量','info')return;}if(rows.some(item => item.itemId === selectedRow.itemId)){$.messager.alert('操作提示','此商品已添加,如需修改数量请删除后重新添加','info')return;}selectedRow.thisTimeQuantity = thisTimeQuantityselectedRow.thisTimeAmount = thisTimeQuantity * selectedRow.feeSkuselectedRow.leftQuantity = selectedRow.leftQuantity - thisTimeQuantity// 插入行dg.datagrid('insertRow',{index:rows.length+1,row:selectedRow});// 设置发票金额rows = dg.datagrid('getRows');let invoiceAmount = rows.reduce((acc, current) => acc + current.feeSku * current.thisTimeQuantity, 0)$("#invoiceAmount").textbox('setValue',invoiceAmount)// 更新列表展示$('#detailTable').datagrid('loadData',orderItems);
}/*删除行*/
function deleteRow(index){let dg = $('#addTable');// 从数据源中删除该行数据let dataSource = dg.datagrid('getData');let deleteOne = dataSource.rows[index]updateOrderItems(deleteOne,true);dataSource.rows.splice(index, 1);dg.datagrid('loadData', dataSource);// 重新设置formatter相关逻辑,更新索引dg.datagrid('getColumnOption', 'id').formatter = function(value, row, index){return '<a href="javascript:void(0)" οnclick="deleteRow('+index+')"><font color="blue" style="text-decoration:underline">删除</font></a> ';};$('#detailTable').datagrid('loadData',orderItems);
}function updateOrderItems(one,isAdd){let newArray = [];for(let i=0;i<orderItems.length;i++){let item = orderItems[i]if(one.itemId === item.itemId){if(isAdd){item.leftQuantity = item.leftQuantity + one.thisTimeQuantity}else{item.leftQuantity = item.leftQuantity - one.thisTimeQuantity}}newArray.push(item)}orderItems = newArray;
}/**保存一个**/
function saveOne(){let dg = $('#addTable');// 从数据源中删除该行数据let dataSource = dg.datagrid('getRows');if(dataSource === null || dataSource.length ===0){$.messager.alert('操作提示','请您添加开票明细!','info')return;}//获取数据let one = {}one.id = splitList.length;one.items = dataSourceone.remark = $('#remark').textbox('getValue');splitList.push(one);// 清除数据dg.datagrid('loadData', []);drewTables();// 清空内容$('#remark').textbox('setValue','')$('#quantity').numberbox('setValue',null)$('#addDialog').dialog('close');
}/**绘制表格**/
function drewTables(){let container = $('#tablesContainer');container.empty();if(splitList.length ===0){return;}for(let i=0;i<splitList.length;i++){let one = splitList[i];let j = i+1;let mainDivStart = '<div id="ip-'+i+'" style="margin-bottom: 10px;border: 1px solid #cccccc;padding: 2px;">'let deleteButton = '发票'+j+' <span style="color: red;font-weight: bold;cursor: pointer" οnclick="removeInvoice('+i+')">删除此发票</span>'let table = '<table class="easyui-datagrid" id="ip-table-'+i+'" style="width:100%;" data-options="singleSelect:true,collapsible:true,fitColumns:true">'+ '<thead>'+ '<tr>'+ '<th data-options="field:\'customerLineItem\',width:80">项目行号</th>'+ '<th data-options="field:\'skuCodeProj\',width:150">项目商品编码</th>'+ '<th data-options="field:\'skuNameProj\',width:300">商品名称</th>'+ '<th data-options="field:\'specificationInvoice\',width:120">商品型号</th>'+ '<th data-options="field:\'taxCode\',width:120" formatter="formatTaxCode">税收编码</th>'+ '<th data-options="field:\'projectName\',width:300" formatter="formatterProjectName">商品发票名称</th>'+ '<th data-options="field:\'model\',width:120" formatter="formatterModel">发票型号</th>'+ '<th data-options="field:\'thisTimeQuantity\',width:50,align:\'right\'">数量</th>'+ '<th data-options="field:\'productUnit\',width:50">单位</th>'+ '<th data-options="field:\'feeSku\',width:80,align:\'right\'">含税单价</th>'+ '<th data-options="field:\'tax\',width:80,align:\'right\'" formatter="formatterTax">税率</th>'+ '<th data-options="field:\'thisTimeAmount\',width:80">含税总价</th>'+'</tr>'+'</thead>'+'</table>'let remark = '<div style="padding:2px 5px;">开票栏备注: <input class="easyui-textbox" class="remark" disabled name="remark" value="'+one.remark+'" style="width:90%"></div>'let mainDivEnd = '</div>'let $allHtml = mainDivStart + deleteButton + table + remark + mainDivEndcontainer.append($allHtml);let oneTable = $('#ip-table-' + i);oneTable.datagrid({ data:one.items });}
}function removeInvoice(index){// 删除元素$.messager.confirm('删除提示', '您确认要删除此发票吗?', function(r){if (r){splitList.splice(index, 1);let newArray = []for(let i=0;i<splitList.length;i++){let one = splitList[i];one.id = inewArray.push(one)}splitList = newArray;//重新渲染drewTables();}});}function endEdit(){// 取消编辑if (lastIndex !== null) {$('#detailTable').datagrid('endEdit', lastIndex);lastIndex = null;}
}
总结
此方案的优势就是在单独弹出框处理拆分,然后动态的渲染表格,新增一个表格然后再表格中进行行编辑要简单许多