fix:开票单信息调整,开票单导出Excel
parent
c410d4e2e3
commit
53b84e0c9b
|
|
@ -0,0 +1,259 @@
|
|||
function escapeHtml(value) {
|
||||
return String(value == null ? "" : value)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function formatCurrency(value) {
|
||||
const num = Number(value);
|
||||
if (Number.isNaN(num)) {
|
||||
return "0.00";
|
||||
}
|
||||
return num.toFixed(2);
|
||||
}
|
||||
|
||||
function getProductTypeLabel(value) {
|
||||
const map = {
|
||||
"1": "软件",
|
||||
"2": "电子计算机",
|
||||
"3": "信息系统服务"
|
||||
};
|
||||
return map[String(value)] || "";
|
||||
}
|
||||
|
||||
function convertCurrency(money) {
|
||||
const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
|
||||
const cnIntRadice = ["", "拾", "佰", "仟"];
|
||||
const cnIntUnits = ["", "万", "亿", "兆"];
|
||||
const cnDecUnits = ["角", "分", "毫", "厘"];
|
||||
const cnInteger = "整";
|
||||
const cnIntLast = "元";
|
||||
|
||||
let integerNum;
|
||||
let decimalNum;
|
||||
let chineseStr = "";
|
||||
let parts;
|
||||
|
||||
if (money === "") return "";
|
||||
money = parseFloat(money);
|
||||
if (money >= 999999999999) return "";
|
||||
if (money === 0) return cnNums[0] + cnIntLast + cnInteger;
|
||||
|
||||
let prefix = "";
|
||||
if (money < 0) {
|
||||
prefix = "(负数)";
|
||||
money = Math.abs(money);
|
||||
}
|
||||
|
||||
money = money.toString();
|
||||
if (money.indexOf(".") === -1) {
|
||||
integerNum = money;
|
||||
decimalNum = "";
|
||||
} else {
|
||||
parts = money.split(".");
|
||||
integerNum = parts[0];
|
||||
decimalNum = parts[1].substr(0, 4);
|
||||
}
|
||||
|
||||
if (parseInt(integerNum, 10) > 0) {
|
||||
let zeroCount = 0;
|
||||
const intLen = integerNum.length;
|
||||
for (let i = 0; i < intLen; i++) {
|
||||
const n = integerNum.substr(i, 1);
|
||||
const p = intLen - i - 1;
|
||||
const q = Math.floor(p / 4);
|
||||
const m = p % 4;
|
||||
if (n === "0") {
|
||||
zeroCount++;
|
||||
} else {
|
||||
if (zeroCount > 0) chineseStr += cnNums[0];
|
||||
zeroCount = 0;
|
||||
chineseStr += cnNums[parseInt(n, 10)] + cnIntRadice[m];
|
||||
}
|
||||
if (m === 0 && zeroCount < 4) chineseStr += cnIntUnits[q];
|
||||
}
|
||||
chineseStr += cnIntLast;
|
||||
}
|
||||
|
||||
if (decimalNum !== "") {
|
||||
const decLen = decimalNum.length;
|
||||
for (let i = 0; i < decLen; i++) {
|
||||
const n = decimalNum.substr(i, 1);
|
||||
if (n !== "0") chineseStr += cnNums[Number(n)] + cnDecUnits[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (chineseStr === "") chineseStr += cnNums[0] + cnIntLast + cnInteger;
|
||||
else if (decimalNum === "") chineseStr += cnInteger;
|
||||
return prefix + chineseStr;
|
||||
}
|
||||
|
||||
function getInvoiceTypeLabel(invoiceType) {
|
||||
const map = {
|
||||
"1": "增值税专用发票",
|
||||
"2": "增值税普通发票",
|
||||
"3": "电子发票"
|
||||
};
|
||||
return map[String(invoiceType)] || (invoiceType || "");
|
||||
}
|
||||
|
||||
function buildItemRows(items) {
|
||||
if (!items || items.length === 0) {
|
||||
return `
|
||||
<tr>
|
||||
<td class="cell center" colspan="12" style="height: 28px;">暂无明细</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
return items.map((item) => `
|
||||
<tr>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${escapeHtml(getProductTypeLabel(item.productType))}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${escapeHtml(item.productName)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.productModel)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.unit)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.quantity)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${formatCurrency(item.price)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${formatCurrency(item.allPrice)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.taxRate)}</td>
|
||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${formatCurrency(item.taxAmount)}</td>
|
||||
</tr>
|
||||
`).join("");
|
||||
}
|
||||
|
||||
function buildSummaryRow(items) {
|
||||
let allPriceTotal = 0;
|
||||
let taxTotal = 0;
|
||||
(items || []).forEach((item) => {
|
||||
allPriceTotal += Number(item.allPrice) || 0;
|
||||
taxTotal += Number(item.taxAmount) || 0;
|
||||
});
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="8">合计</td>
|
||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">¥${allPriceTotal.toFixed(2)}</td>
|
||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;">-</td>
|
||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;">¥${taxTotal.toFixed(2)}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
function buildInvoiceExcelHtml(invoice) {
|
||||
const detailItems = invoice.detailItemList || [];
|
||||
const totalAmountNumber = detailItems.reduce((sum, item) => sum + (Number(item.allPrice) || 0), 0).toFixed(2);
|
||||
const totalAmountChinese = convertCurrency(totalAmountNumber);
|
||||
const invoiceTypeLabel = getInvoiceTypeLabel(invoice.invoiceType);
|
||||
|
||||
return `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8" />
|
||||
<!--[if gte mso 9]><xml>
|
||||
<x:ExcelWorkbook>
|
||||
<x:ExcelWorksheets>
|
||||
<x:ExcelWorksheet>
|
||||
<x:Name>开票信息</x:Name>
|
||||
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>
|
||||
</x:ExcelWorksheet>
|
||||
</x:ExcelWorksheets>
|
||||
</x:ExcelWorkbook>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
table { border-collapse: collapse; width: 1200px; font-family: "Microsoft YaHei", Arial, sans-serif; color: #8B4513; }
|
||||
td { border: 1px solid #8B4513; padding: 6px; font-size: 12px; vertical-align: middle; mso-vertical-align: middle; mso-wrap-style: none; }
|
||||
.no-border { border: none !important; }
|
||||
.title { font-size: 26px; font-weight: bold; text-align: center; border: none !important; padding: 12px 0; }
|
||||
.sub-title { font-size: 18px; font-weight: bold; text-align: center; border: none !important; padding-bottom: 8px; }
|
||||
.label { width: 120px; font-weight: bold; text-align: center; }
|
||||
.center { text-align: center; mso-horizontal-align: center; }
|
||||
.right { text-align: right; mso-horizontal-align: right; }
|
||||
.bold { font-weight: bold; }
|
||||
.section-head { font-weight: bold; text-align: center; background: #f8f5f0; }
|
||||
.cell { height: 26px; }
|
||||
.total-main { font-weight: bold; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width:100px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:80px;" />
|
||||
<col style="width:80px;" />
|
||||
<col style="width:80px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:100px;" />
|
||||
<col style="width:80px;" />
|
||||
<col style="width:100px;" />
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td class="no-border" colspan="2"></td>
|
||||
<td class="title" colspan="8">电子发票(${escapeHtml(invoiceTypeLabel)})</td>
|
||||
<td class="no-border" colspan="2" style="text-align: left; vertical-align: middle;">
|
||||
<div><span class="bold">发票号码:</span>----------</div>
|
||||
<div><span class="bold">开票日期:</span>----------</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="section-head" colspan="2" rowspan="2">购买方信息</td>
|
||||
<td class="label" colspan="4">名称:${escapeHtml(invoice.buyerName)}</td>
|
||||
<td class="section-head" colspan="2" rowspan="2">销售方信息</td>
|
||||
<td class="label" colspan="4">名称:${escapeHtml(invoice.sellerName)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" colspan="4">纳税人识别号:${escapeHtml(invoice.buyerCreditCode)}</td>
|
||||
<td class="label" colspan="4">纳税人识别号:${escapeHtml(invoice.sellerCreditCode)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="section-head" colspan="2">税收大类</td>
|
||||
<td class="section-head" colspan="2">项目名称</td>
|
||||
<td class="section-head">规格型号</td>
|
||||
<td class="section-head">单位</td>
|
||||
<td class="section-head">数量</td>
|
||||
<td class="section-head">单价</td>
|
||||
<td class="section-head" colspan="2">金额</td>
|
||||
<td class="section-head">税率%</td>
|
||||
<td class="section-head">税额</td>
|
||||
</tr>
|
||||
${buildItemRows(detailItems)}
|
||||
${buildSummaryRow(detailItems)}
|
||||
<tr>
|
||||
<td class="label total-main" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">价税合计(大写)</td>
|
||||
<td class="total-main center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="6">⊗ ${escapeHtml(totalAmountChinese)}</td>
|
||||
<td class="label total-main" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">(小写)</td>
|
||||
<td class="total-main center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">¥${formatCurrency(totalAmountNumber)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" colspan="2">备注</td>
|
||||
<td colspan="10">${escapeHtml(invoice.remark)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" colspan="2">信息说明</td>
|
||||
<td colspan="10">${escapeHtml(invoice.informationNote)}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
export function exportInvoiceInfoToExcel(invoiceData, fileName) {
|
||||
const content = buildInvoiceExcelHtml(invoiceData || {});
|
||||
const blob = new Blob(["\ufeff", content], {
|
||||
type: "application/vnd.ms-excel;charset=utf-8;"
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = fileName || "开票单.xls";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
|
@ -58,6 +58,14 @@
|
|||
@click="exportPDF"
|
||||
:loading="pdfExporting"
|
||||
>导出PDF</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="el-icon-document"
|
||||
style="margin-right: 10px;"
|
||||
@click="exportExcel"
|
||||
:loading="excelExporting"
|
||||
>导出Excel</el-button>
|
||||
</div>
|
||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
||||
|
|
@ -95,6 +103,7 @@ import { listCompletedFlows } from "@/api/flow";
|
|||
import ReceivableInvoiceDetail from "../components/ReceivableInvoiceDetail";
|
||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
||||
import { exportInvoiceInfoToExcel } from "@/views/approve/finance/invoiceExcelUtils";
|
||||
|
||||
export default {
|
||||
name: "ReceivableInvoiceApproved",
|
||||
|
|
@ -121,7 +130,8 @@ export default {
|
|||
form: {},
|
||||
approveLogs: [],
|
||||
currentInvoiceId: null,
|
||||
pdfExporting: false
|
||||
pdfExporting: false,
|
||||
excelExporting: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -184,6 +194,23 @@ export default {
|
|||
} finally {
|
||||
this.pdfExporting = false;
|
||||
}
|
||||
},
|
||||
exportExcel() {
|
||||
if (!this.form || !this.form.invoiceBillCode) {
|
||||
this.$modal.msgWarning("暂无可导出的开票信息");
|
||||
return;
|
||||
}
|
||||
this.excelExporting = true;
|
||||
try {
|
||||
const fileName = `开票单-${this.form.invoiceBillCode || ""}.xls`;
|
||||
exportInvoiceInfoToExcel(this.form, fileName);
|
||||
this.$modal.msgSuccess("Excel导出成功");
|
||||
} catch (error) {
|
||||
console.error("Excel导出失败:", error);
|
||||
this.$modal.msgError("Excel导出失败,请稍后重试");
|
||||
} finally {
|
||||
this.excelExporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -70,6 +70,14 @@
|
|||
@click="exportPDF"
|
||||
:loading="pdfExporting"
|
||||
>导出PDF</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="el-icon-document"
|
||||
style="margin-right: 10px;"
|
||||
@click="exportExcel"
|
||||
:loading="excelExporting"
|
||||
>导出Excel</el-button>
|
||||
</div>
|
||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
||||
|
|
@ -122,6 +130,7 @@ import { approveTask, listCompletedFlows } from "@/api/flow";
|
|||
import ReceivableInvoiceDetail from "./components/ReceivableInvoiceDetail";
|
||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
||||
import { exportInvoiceInfoToExcel } from "@/views/approve/finance/invoiceExcelUtils";
|
||||
|
||||
export default {
|
||||
name: "ReceivableInvoiceApprove",
|
||||
|
|
@ -159,7 +168,8 @@ export default {
|
|||
processKey: 'finance_invoice_approve',
|
||||
taskId: null,
|
||||
currentInvoiceId: null,
|
||||
pdfExporting: false
|
||||
pdfExporting: false,
|
||||
excelExporting: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -271,6 +281,23 @@ export default {
|
|||
} finally {
|
||||
this.pdfExporting = false;
|
||||
}
|
||||
},
|
||||
exportExcel() {
|
||||
if (!this.form || !this.form.invoiceBillCode) {
|
||||
this.$modal.msgWarning("暂无可导出的开票信息");
|
||||
return;
|
||||
}
|
||||
this.excelExporting = true;
|
||||
try {
|
||||
const fileName = `开票单-${this.form.invoiceBillCode || ""}.xls`;
|
||||
exportInvoiceInfoToExcel(this.form, fileName);
|
||||
this.$modal.msgSuccess("Excel导出成功");
|
||||
} catch (error) {
|
||||
console.error("Excel导出失败:", error);
|
||||
this.$modal.msgError("Excel导出失败,请稍后重试");
|
||||
} finally {
|
||||
this.excelExporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -90,16 +90,31 @@
|
|||
show-summary
|
||||
:summary-method="getSummaries"
|
||||
>
|
||||
<el-table-column label="项目名称" prop="productName" align="center">
|
||||
<el-table-column label="税收大类" prop="productType" align="center" width="140">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productName" size="mini" placeholder="请输入" class="no-border-input"
|
||||
:disabled="!!scope.row.productCode"/>
|
||||
<el-select
|
||||
v-model="scope.row.productType"
|
||||
size="mini"
|
||||
placeholder="请选择"
|
||||
class="no-border-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in productTypeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="项目名称" prop="productDescView" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productDescView" size="mini" placeholder="请输入" class="no-border-input"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格型号" prop="productModel" align="center" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productModel" size="mini" placeholder="型号" class="no-border-input"
|
||||
:disabled="!!scope.row.productCode"/>
|
||||
<el-input v-model="scope.row.productModel" size="mini" placeholder="型号" class="no-border-input"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" prop="unit" align="center" width="60">
|
||||
|
|
@ -173,6 +188,13 @@
|
|||
class="no-border-textarea"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="remark-row">
|
||||
<div class="remark-label">信息说明</div>
|
||||
<div class="remark-content">
|
||||
<el-input type="textarea" :rows="1" v-model="form.informationNote" readonly
|
||||
class="no-border-textarea"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-form>
|
||||
|
|
@ -209,6 +231,11 @@ export default {
|
|||
return {
|
||||
loading: false,
|
||||
companyOptions: [],
|
||||
productTypeOptions: [
|
||||
{ value: '1', label: '软件' },
|
||||
{ value: '2', label: '电子计算机' },
|
||||
{ value: '3', label: '信息系统服务' }
|
||||
],
|
||||
form: {
|
||||
invoiceType: this.rowData.invoiceType || '2',
|
||||
buyerName: undefined,
|
||||
|
|
@ -219,12 +246,15 @@ export default {
|
|||
sellerCreditCode: undefined,
|
||||
sellerBank: undefined,
|
||||
sellerBankAccount: undefined,
|
||||
informationNote: '默认开票',
|
||||
remark: undefined,
|
||||
invoiceBillCode: this.rowData.invoiceBillCode,
|
||||
id: this.rowData.id,
|
||||
detailItemList: [
|
||||
{
|
||||
projectName: '',
|
||||
productType: '',
|
||||
productDescView: '',
|
||||
productModel: '',
|
||||
unit: '',
|
||||
unitPrice: '',
|
||||
|
|
@ -240,7 +270,8 @@ export default {
|
|||
buyerName: [{required: true, message: "必填", trigger: "blur"}],
|
||||
buyerCreditCode: [{required: true, message: "必填", trigger: "blur"}],
|
||||
sellerName: [{required: true, message: "必填", trigger: "blur"}]
|
||||
}
|
||||
},
|
||||
originalDetailSignature: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -266,6 +297,15 @@ export default {
|
|||
this.reset();
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
'form.detailItemList': {
|
||||
handler() {
|
||||
if (!this.visible || !this.form || !Array.isArray(this.form.detailItemList)) {
|
||||
return;
|
||||
}
|
||||
this.updateInformationNote();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -290,9 +330,11 @@ export default {
|
|||
sellerCreditCode: undefined,
|
||||
sellerBank: undefined,
|
||||
sellerBankAccount: undefined,
|
||||
informationNote: '默认开票',
|
||||
remark: undefined,
|
||||
detailItemList: []
|
||||
};
|
||||
this.originalDetailSignature = '';
|
||||
this.resetForm("form");
|
||||
},
|
||||
initData() {
|
||||
|
|
@ -337,8 +379,10 @@ export default {
|
|||
id: item.id,
|
||||
orderCode: item.orderCode,
|
||||
productCode: item.productCode,
|
||||
productType: item.productType != null ? String(item.productType) : '',
|
||||
productModel: item.productModel, // Mapping projectCode to productModel as requested
|
||||
productName: item.productName, // Mapping projectCode to productModel as requested
|
||||
productName: item.productName,
|
||||
productDescView: item.productDesc || item.productName || '',
|
||||
unit: item.unit || '',
|
||||
quantity: quantity,
|
||||
unitPrice: item.price, // Mapping price to unitPrice
|
||||
|
|
@ -350,12 +394,15 @@ export default {
|
|||
// this.calculateAmount(row);
|
||||
return row;
|
||||
});
|
||||
this.setOriginalDetailSignature();
|
||||
} else {
|
||||
this.addDetailRow(); // Default empty row if no data
|
||||
this.setOriginalDetailSignature();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.addDetailRow();
|
||||
this.setOriginalDetailSignature();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -381,6 +428,8 @@ export default {
|
|||
addDetailRow() {
|
||||
this.form.detailItemList.push({
|
||||
projectName: '',
|
||||
productType: '',
|
||||
productDescView: '',
|
||||
productModel: '',
|
||||
unit: '',
|
||||
unitPrice: '',
|
||||
|
|
@ -436,6 +485,24 @@ export default {
|
|||
});
|
||||
return sums;
|
||||
},
|
||||
normalizeDetailItem(item) {
|
||||
return {
|
||||
productType: item.productType || '',
|
||||
productDescView: item.productDescView || '',
|
||||
productModel: item.productModel || ''
|
||||
};
|
||||
},
|
||||
buildDetailSignature(list) {
|
||||
return JSON.stringify((list || []).map(item => this.normalizeDetailItem(item)));
|
||||
},
|
||||
updateInformationNote() {
|
||||
const currentSignature = this.buildDetailSignature(this.form.detailItemList);
|
||||
this.form.informationNote = currentSignature !== this.originalDetailSignature ? '手改开票' : '默认开票';
|
||||
},
|
||||
setOriginalDetailSignature() {
|
||||
this.originalDetailSignature = this.buildDetailSignature(this.form.detailItemList);
|
||||
this.form.informationNote = '默认开票';
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
|
|
@ -446,6 +513,7 @@ export default {
|
|||
}
|
||||
for (let i = 0; i < this.form.detailItemList.length; i++) {
|
||||
const item = this.form.detailItemList[i];
|
||||
item.productName = item.productDescView;
|
||||
if (!item.productName || !item.productModel || isNaN(item.quantity) || !item.unit || !item.unitPrice || !item.amount || !item.taxAmount || !item.taxRate) {
|
||||
this.$modal.msgError(`表格第 ${i + 1} 行数据不完整,请填写所有必填字段`);
|
||||
return;
|
||||
|
|
@ -735,6 +803,16 @@ export default {
|
|||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.no-border-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.no-border-select ::v-deep .el-input__inner {
|
||||
border: none;
|
||||
text-align: center;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.table-icon {
|
||||
cursor: pointer;
|
||||
color: #8B4513;
|
||||
|
|
@ -784,19 +862,26 @@ export default {
|
|||
.remark-row {
|
||||
display: flex;
|
||||
min-height: 60px;
|
||||
padding: 0 10px;
|
||||
color: #8B4513;
|
||||
border-top: 1px solid #8B4513;
|
||||
}
|
||||
|
||||
.remark-label {
|
||||
width: 120px;
|
||||
padding-top: 10px;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
border-right: 1px solid #8B4513;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.remark-content {
|
||||
flex: 1;
|
||||
padding: 5px 0;
|
||||
padding: 5px 10px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.no-border-textarea ::v-deep .el-textarea__inner {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
<!-- 表格区域 -->
|
||||
<div class="items-table-container">
|
||||
<el-table :data="data.detailItemList" border class="invoice-table" show-summary :summary-method="getSummaries">
|
||||
<el-table-column label="税收大类" prop="productType" align="center" width="140" :formatter="(row) => getProductTypeLabel(row.productType)"></el-table-column>
|
||||
<el-table-column label="项目名称" prop="productName" align="center"></el-table-column>
|
||||
<el-table-column label="规格型号" prop="productModel" align="center" width="120"></el-table-column>
|
||||
<el-table-column label="单位" prop="unit" align="center" width="60"></el-table-column>
|
||||
|
|
@ -82,6 +83,10 @@
|
|||
<div class="remark-label">备注</div>
|
||||
<div class="remark-content">{{ data.remark }}</div>
|
||||
</div>
|
||||
<div class="remark-row">
|
||||
<div class="remark-label">信息说明</div>
|
||||
<div class="remark-content">{{ data.informationNote }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -114,6 +119,14 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getProductTypeLabel(value) {
|
||||
const map = {
|
||||
'1': '软件',
|
||||
'2': '电子计算机',
|
||||
'3': '信息系统服务'
|
||||
};
|
||||
return map[String(value)] || '';
|
||||
},
|
||||
getSummaries(param) {
|
||||
const { columns, data } = param;
|
||||
const sums = [];
|
||||
|
|
@ -356,17 +369,26 @@ export default {
|
|||
}
|
||||
.remark-row {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
padding: 10px;
|
||||
min-height: 60px;
|
||||
color: #8B4513;
|
||||
border-top: 1px solid #8B4513;
|
||||
}
|
||||
.remark-label {
|
||||
width: 120px;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
border-right: 1px solid #8B4513;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.remark-content {
|
||||
flex: 1;
|
||||
padding: 5px 10px;
|
||||
font-size: 13px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.invoice-type-select {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ public class OmsInvoiceBill extends BaseEntity
|
|||
private String sellerCreditCode;
|
||||
private String sellerBank;
|
||||
private String sellerBankAccount;
|
||||
/** 信息备注 */
|
||||
private String informationNote;
|
||||
|
||||
|
||||
private String projectCode;
|
||||
|
|
@ -191,4 +193,4 @@ public class OmsInvoiceBill extends BaseEntity
|
|||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ public class OmsReceivableInvoiceDetailItem {
|
|||
* 产品编码
|
||||
*/
|
||||
private String productCode;
|
||||
/**
|
||||
* 产品类型
|
||||
*/
|
||||
private String productType;
|
||||
/**
|
||||
* 产品名称
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public class InvoiceProductDto extends BaseEntity {
|
|||
private Long projectId;
|
||||
private String productName;
|
||||
private String productCode;
|
||||
private String productType;
|
||||
private String orderCode;
|
||||
private String productModel;
|
||||
private String productDesc;
|
||||
|
|
|
|||
|
|
@ -461,6 +461,7 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo
|
|||
if (productInfo != null){
|
||||
invoiceProductDto.setProductModel(productInfo.getModel());
|
||||
invoiceProductDto.setProductName(productInfo.getProductName());
|
||||
invoiceProductDto.setProductType(productInfo.getType());
|
||||
invoiceProductDto.setProductDesc(productInfo.getProductDesc());
|
||||
invoiceProductDto.setPrice(productInfo.getPrice());
|
||||
BigDecimal allPriceWithoutTax = invoiceProductDto.getAllPrice().divide(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
<result property="projectName" column="project_name"/>
|
||||
<result property="orderCode" column="order_code"/>
|
||||
<result property="productCode" column="product_code"/>
|
||||
<result property="productType" column="product_type"/>
|
||||
<result property="productName" column="product_name"/>
|
||||
<result property="productModel" column="product_model"/>
|
||||
<result property="quantity" column="quantity"/>
|
||||
|
|
@ -19,7 +20,7 @@
|
|||
|
||||
<!-- 基本字段 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, invoice_bill_code, project_name, order_code, product_code, product_name, product_model, quantity, price, all_price, tax_amount, tax_rate,unit
|
||||
id, invoice_bill_code, project_name, order_code, product_code, product_type, product_name, product_model, quantity, price, all_price, tax_amount, tax_rate,unit
|
||||
</sql>
|
||||
|
||||
<!--通过实体作为筛选条件查询-->
|
||||
|
|
@ -43,6 +44,9 @@
|
|||
<if test="productCode != null and productCode != ''">
|
||||
and product_code = #{productCode}
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
and product_type = #{productType}
|
||||
</if>
|
||||
<if test="productName != null and productName != ''">
|
||||
and product_name = #{productName}
|
||||
</if>
|
||||
|
|
@ -75,6 +79,7 @@
|
|||
project_name,
|
||||
order_code,
|
||||
product_code,
|
||||
product_type,
|
||||
product_name,
|
||||
product_model,
|
||||
quantity,
|
||||
|
|
@ -129,6 +134,9 @@
|
|||
<if test="productCode != null and productCode != ''">
|
||||
product_code,
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
product_type,
|
||||
</if>
|
||||
<if test="productName != null and productName != ''">
|
||||
product_name,
|
||||
</if>
|
||||
|
|
@ -167,6 +175,9 @@
|
|||
<if test="productCode != null and productCode != ''">
|
||||
#{productCode},
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
#{productType},
|
||||
</if>
|
||||
<if test="productName != null and productName != ''">
|
||||
#{productName},
|
||||
</if>
|
||||
|
|
@ -196,7 +207,7 @@
|
|||
<insert id="insertBatch">
|
||||
INSERT INTO oms_receivable_invoice_detail_item
|
||||
(
|
||||
invoice_bill_code,project_name,order_code,product_code,product_name,product_model
|
||||
invoice_bill_code,project_name,order_code,product_code,product_type,product_name,product_model
|
||||
,quantity,price,all_price,tax_amount,tax_rate,unit)
|
||||
|
||||
|
||||
|
|
@ -206,6 +217,7 @@
|
|||
#{item.projectName},
|
||||
#{item.orderCode},
|
||||
#{item.productCode},
|
||||
#{item.productType},
|
||||
#{item.productName},
|
||||
#{item.productModel},
|
||||
#{item.quantity},
|
||||
|
|
@ -234,6 +246,9 @@
|
|||
<if test="productCode != null and productCode != ''">
|
||||
product_code = #{productCode},
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
product_type = #{productType},
|
||||
</if>
|
||||
<if test="productName != null and productName != ''">
|
||||
product_name = #{productName},
|
||||
</if>
|
||||
|
|
@ -277,6 +292,9 @@
|
|||
<if test="item.productCode != null and item.productCode != ''">
|
||||
product_code = #{item.productCode},
|
||||
</if>
|
||||
<if test="item.productType != null and item.productType != ''">
|
||||
product_type = #{item.productType},
|
||||
</if>
|
||||
<if test="item.productName != null and item.productName != ''">
|
||||
product_name = #{item.productName},
|
||||
</if>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="sellerCreditCode" column="seller_credit_code" />
|
||||
<result property="sellerBank" column="seller_bank" />
|
||||
<result property="sellerBankAccount" column="seller_bank_account" />
|
||||
<result property="informationNote" column="information_note" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectOmsInvoiceBillVo">
|
||||
|
|
@ -48,7 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
t1.remark, t1.del_flag, t1.actual_invoice_time, t1.invoice_status,
|
||||
t1.approve_status, t1.approve_time, t1.refund_status
|
||||
, t1.original_bill_id, t1.invoice_apply_user, t1.buyer_name, t1.buyer_credit_code, t1.buyer_bank, t1.buyer_bank_account,
|
||||
t1.seller_name, t1.seller_credit_code, t1.seller_bank, t1.seller_bank_account
|
||||
t1.seller_name, t1.seller_credit_code, t1.seller_bank, t1.seller_bank_account, t1.information_note
|
||||
from oms_invoice_bill t1
|
||||
</sql>
|
||||
|
||||
|
|
@ -175,6 +176,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="sellerBankAccount != null and sellerBankAccount != ''">
|
||||
and seller_bank_account = #{sellerBankAccount}
|
||||
</if>
|
||||
<if test="informationNote != null and informationNote != ''">
|
||||
and information_note = #{informationNote}
|
||||
</if>
|
||||
<if test="(params.beginApproveTime != null and params.beginApproveTime != '') or (params.endApproveTime != null and params.endApproveTime!='')">
|
||||
<choose>
|
||||
<when test="(params.beginApproveTime != null and params.beginApproveTime != '') and (params.endApproveTime != null and params.endApproveTime!='')">
|
||||
|
|
@ -314,6 +318,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="invoiceApplyUser != null and invoiceApplyUser != ''">
|
||||
invoice_apply_user,
|
||||
</if>
|
||||
<if test="informationNote != null and informationNote != ''">
|
||||
information_note,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="invoiceBillCode != null and invoiceBillCode != ''">
|
||||
|
|
@ -416,6 +423,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="invoiceApplyUser != null and invoiceApplyUser != ''">
|
||||
#{invoiceApplyUser},
|
||||
</if>
|
||||
<if test="informationNote != null and informationNote != ''">
|
||||
#{informationNote},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
|
|
@ -518,6 +528,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="invoiceApplyUser != null and invoiceApplyUser != ''">
|
||||
invoice_apply_user = #{invoiceApplyUser},
|
||||
</if>
|
||||
<if test="informationNote != null and informationNote != ''">
|
||||
information_note = #{informationNote},
|
||||
</if>
|
||||
|
||||
update_time = now()
|
||||
</trim>
|
||||
|
|
@ -562,6 +575,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
approve_status=#{approveStatus},
|
||||
invoice_type=#{invoiceType},
|
||||
remark=#{remark},
|
||||
information_note=#{informationNote},
|
||||
update_time=now()
|
||||
where invoice_bill_code = #{invoiceBillCode}
|
||||
|
||||
|
|
@ -649,4 +663,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
from oms_invoice_bill
|
||||
where invoice_bill_code LIKE CONCAT(#{codePrefix}, '%')
|
||||
</select>
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue