Easyui 实现订单拆分开票功能
需求
1、实现一个订单开具多分发票功能;
2、支持拆行;
3、支持拆数量;
流程设计
1、操作页面展示订订单头信息,订单明细信息
2、点击新增发票按钮弹出一个弹出框用于创建一张拆分发票,弹出框可以选择商品明细输入数量。每次添加一张
3、点击弹出框的保存功能实现订单拆分
4、提交到后台之后,生成多张发票
页面设计依次如下
核心代码如下
html
<!-- 新增发票按钮-->
<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核心代码
javascript
/*新增发票编辑窗口*/
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 = thisTimeQuantity
selectedRow.thisTimeAmount = thisTimeQuantity * selectedRow.feeSku
selectedRow.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 = dataSource
one.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 + mainDivEnd
container.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 = i
newArray.push(one)
}
splitList = newArray;
//重新渲染
drewTables();
}
});
}
function endEdit(){
// 取消编辑
if (lastIndex !== null) {
$('#detailTable').datagrid('endEdit', lastIndex);
lastIndex = null;
}
}
总结
此方案的优势就是在单独弹出框处理拆分,然后动态的渲染表格,新增一个表格然后再表格中进行行编辑要简单许多