fix(finance): 优化付款和收票单据表单及列表功能

- 移除预计付款时间字段并调整表单布局
- 将是否预付改为复选框并更新相关字段名称
- 更新表格列标题为更准确的业务术语
- 添加表格合计功能和金额格式化显示
- 优化日期选择器类型和样式
- 修复收票单时间字段验证和显示问题
- 调整合并付款和收票单验证逻辑
- 添加付款日期预警颜色标识
- 优化金额字段显示单位和格式
- 修复多个表单和列表组件的字段映射问题
- 添加表格摘要统计功能
- 优化查询表单字段标签和宽度
- 调整按钮文字和操作提示信息
dev_1.0.1
chenhao 2025-12-25 15:33:23 +08:00
parent e767c6aa50
commit b21c54a901
42 changed files with 852 additions and 431 deletions

View File

@ -5,6 +5,7 @@ export function listPayable(query) {
return request({
url: '/finance/payable/list',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
data: query
})
}
@ -39,7 +40,8 @@ export function mergeAndInitiatePayment(data) {
return request({
url: '/finance/payable/mergeAndInitiatePayment',
method: 'post',
data: data
data: data,
needLoading: true
})
}
@ -48,7 +50,8 @@ export function mergeAndInitiateReceipt(data) {
return request({
url: '/finance/payable/mergeAndInitiateReceipt',
method: 'post',
data: data
data: data,
needLoading: true
})
}

View File

@ -116,6 +116,9 @@ export function listPayableBills(query) {
return request({
url: 'finance/payable/list',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: query
})
}

View File

@ -5,11 +5,11 @@ import {tansParams} from "@/utils/ruoyi"
export function listReceipt(query) {
return request({
url: '/finance/ticket/list',
method: 'get',
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
// },
data: tansParams(query)
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: query
})
}
@ -67,3 +67,11 @@ export function addReceipt(data) {
needLoading: true
})
}
// 撤销收票单
export function revokeReceipt(id) {
return request({
url: '/finance/ticket/revoke/' + id,
method: 'put'
})
}

View File

@ -1,5 +1,5 @@
<template>
<el-drawer title="修改采购应付单" :visible.sync="internalVisible" size="70%" @close="handleClose">
<el-drawer title="采购-应付单详情" :visible.sync="internalVisible" :wrapper-closable="false" size="70%" @close="handleClose">
<div class="dialog-body">
<!-- Part 1: Details -->
<div>
@ -13,7 +13,7 @@
<div class="detail-item"><strong>项目名称:</strong> {{ formData.projectName }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>应付单编号:</strong> {{ formData.payableBillCode }}</div>
<div class="detail-item"><strong>采购-应付单编号:</strong> {{ formData.payableBillCode }}</div>
</el-col>
</el-row>
@ -25,7 +25,7 @@
<div class="detail-item"><strong>该制造商是否有预付单:</strong> {{ formData.preResidueAmount == 0 ? '否' : '是' }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>预付金额:</strong> {{ formData.preResidueAmount }}</div>
<div class="detail-item"><strong>预付金额():</strong> {{ formData.preResidueAmount }}</div>
</el-col>
</el-row>
<el-row :gutter="20">
@ -36,40 +36,40 @@
<div class="detail-item"><strong>合同编号:</strong> {{ formData.orderCode }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>入库单号:</strong> {{ formData.inventoryCode }}</div>
<div class="detail-item"><strong>/入库单号:</strong> {{ formData.inventoryCode }}</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="detail-item"><strong>含税总价:</strong> {{ formData.totalPriceWithTax }}</div>
<div class="detail-item"><strong>含税总价():</strong> {{ formData.totalPriceWithTax }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>未税总价:</strong> {{ formData.totalPriceWithoutTax }}</div>
<div class="detail-item"><strong>未税总价():</strong> {{ formData.totalPriceWithoutTax }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>税额:</strong> {{ formData.taxAmount }}</div>
<div class="detail-item"><strong>税额():</strong> {{ formData.taxAmount }}</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="detail-item"><strong>未付款金额:</strong> {{ formData.unpaidPaymentAmount }}</div>
<div class="detail-item"><strong>未付款金额():</strong> {{ formData.unpaidPaymentAmount }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>已付款金额:</strong> {{ formData.paidPaymentAmount }}</div>
<div class="detail-item"><strong>已付款金额():</strong> {{ formData.paidPaymentAmount }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>付款中金额:</strong> {{ this.$calc.sub(this.$calc.sub(formData.totalPriceWithTax,formData.paidPaymentAmount),formData.unpaidPaymentAmount) }}</div>
<div class="detail-item"><strong>付款中金额():</strong> {{ this.$calc.sub(this.$calc.sub(formData.totalPriceWithTax,formData.paidPaymentAmount),formData.unpaidPaymentAmount) }}</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="detail-item"><strong>未收票金额:</strong> {{ formData.unreceivedTicketAmount }}</div>
<div class="detail-item"><strong>未收票金额():</strong> {{ formData.unreceivedTicketAmount }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>已收票金额:</strong> {{ formData.receivedTicketAmount }}</div>
<div class="detail-item"><strong>已收票金额():</strong> {{ formData.receivedTicketAmount }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item"><strong>收票中金额:</strong> {{ this.$calc.sub(this.$calc.sub(formData.totalPriceWithTax,formData.receivedTicketAmount),formData.unreceivedTicketAmount)}}</div>
<div class="detail-item"><strong>收票中金额():</strong> {{ this.$calc.sub(this.$calc.sub(formData.totalPriceWithTax,formData.receivedTicketAmount),formData.unreceivedTicketAmount)}}</div>
</el-col>
</el-row>
<el-row :gutter="20">
@ -92,7 +92,7 @@
<div style="padding: 20px">
<el-tabs v-model="activeTab">
<el-tab-pane label="明细" name="details">
<el-divider content-position="left">采购付款单</el-divider>
<el-divider content-position="left">采购-付款单</el-divider>
<el-table :data="formData.detailList" style="width: 100%" show-summary :summary-method="getSummaries">
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="payableDetailType" label="付款通道">
@ -105,14 +105,18 @@
{{ scope.row.actualPaymentTime || '-' }}
</template>
</el-table-column>
<el-table-column prop="paymentAmount" label="本次付款金额"></el-table-column>
<el-table-column prop="paymentAmount" label="本次付款金额">
<template slot-scope="scope">
<span :style="scope.row.paymentAmount<0?{color:'red'}:{}"> {{ scope.row.paymentAmount }}</span>
</template>
</el-table-column>
<el-table-column prop="paymentRate" label="本次付款比例"></el-table-column>
<el-table-column prop="paymentStatus" label="付款状态">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
</template>
</el-table-column>
<el-table-column prop="paymentBillCode" label="采购付款单编号"></el-table-column>
<el-table-column prop="paymentBillCode" label="采购-付款单编号"></el-table-column>
<el-table-column label="回执单/退款图">
<template slot-scope="scope">
<span v-if="scope.row.finAttachment">
@ -123,7 +127,7 @@
</template>
</el-table-column>
</el-table>
<el-divider content-position="left">采购收票单</el-divider>
<el-divider content-position="left">采购-收票单</el-divider>
<el-table :data="formData.ticketDetailList" style="width: 100%" show-summary :summary-method="getSummaries">
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="payableDetailType" label="发票类型">
@ -131,20 +135,25 @@
<dict-tag :options="dict.type.ticket_detail_type" :value="scope.row.payableDetailType"/>
</template>
</el-table-column>
<el-table-column prop="vendorTicketTime" label="制造商开票时间">
<el-table-column prop="actualTicketTime" label="实际收票时间">
<template slot-scope="scope">
{{ scope.row.vendorTicketTime || '-' }}
{{ scope.row.actualTicketTime || '-' }}
</template>
</el-table-column>
<el-table-column prop="paymentAmount" label="本次收票金额"></el-table-column>
<el-table-column prop="paymentAmount" label="本次收票金额">
<template slot-scope="scope">
<span :style="scope.row.paymentAmount<0?{color:'red'}:{}"> {{ scope.row.paymentAmount }}</span>
</template>
</el-table-column>
<el-table-column prop="paymentRate" label="本次收票比例"></el-table-column>
<el-table-column prop="receiptStatus" label="收票状态">
<template slot-scope="scope">
<dict-tag :options="dict.type.receipt_status" :value="scope.row.ticketStatus"/>
</template>
</el-table-column>
<el-table-column prop="ticketBillCode" label="采购收票单编号"></el-table-column>
<el-table-column label="发票">
<el-table-column prop="ticketBillCode" label="采购-收票单编号"></el-table-column>
<el-table-column label="发票/红冲发票">
<template slot-scope="scope">
<span v-if="scope.row.finAttachment">
<el-button type="text" size="mini" icon="el-icon-view" @click="handlePreview(scope.row.finAttachment)"></el-button>
@ -266,7 +275,8 @@ export default {
return sums;
},
handleClose() {
this.internalVisible = false; // Close dialog locally
this.internalVisible = false; // Close dialog local
this.$emit('close');
},
handleSubmit() {
this.handleClose();

View File

@ -1,65 +1,79 @@
<template>
<el-dialog title="合并发起付款单" :visible.sync="dialogVisible" width="80%" :close-on-click-modal="false" @close="handleClose" append-to-body>
<el-dialog title="合并发起付款单" :visible.sync="dialogVisible" width="80%" :close-on-click-modal="false" @close="handleClose" append-to-body>
<div class="dialog-body">
<el-form ref="form" :model="form" :inline="true" label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="付款单类型" prop="paymentBillType">
<el-select disabled v-model="form.paymentBillType" placeholder="请选择付款单类型" clearable>
<el-option
v-for="dict in dict.type.payment_bill_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="8">-->
<!-- <el-form-item label="付款单类型" prop="paymentBillType">-->
<!-- <el-select disabled v-model="form.paymentBillType" placeholder="请选择付款单类型" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.payment_bill_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="8">
<el-form-item label="制造商名称">
<el-input v-model="form.vendorName" readonly/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计付款时间" prop="estimatedPaymentTime">
<el-date-picker
v-model="form.estimatedPaymentTime"
type="date"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
></el-date-picker>
</el-form-item>
</el-col>
<!-- <el-col :span="8">-->
<!-- <el-form-item label="预计付款时间" prop="estimatedPaymentTime">-->
<!-- <el-date-picker-->
<!-- v-model="form.estimatedPaymentTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd HH:mm:ss"-->
<!-- placeholder="选择日期"-->
<!-- ></el-date-picker>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
</el-row>
</el-form>
<el-divider content-position="left">采购应付单表</el-divider>
<el-table :data="payableOrdersWithPlans" border max-height="300px" style="margin-bottom: 20px;">
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="采购-应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="预计付款时间" align="center" prop="planPaymentDate" width="180"/>
<el-table-column label="付款计划" align="center" width="100" prop="planAmount">
<el-table-column label="预期付款计划" align="center" width="100" prop="planAmount">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentAmount(scope.row.id).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
<el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">
<el-table-column label="预期付款比例" align="center" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
{{ calculateOrderCurrentPaymentRate(scope.row.id) }}
</template>
</el-table-column>
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未付款金额" align="center" prop="unpaidAmount" width="120"/>
<el-table-column label="本次付款金额" align="center" width="120">
<el-table-column label="项目名称" align="center" prop="projectName" />
<el-table-column label="制造商名称" align="center" prop="vendorName" />
<!-- <el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>-->
<!-- <el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>-->
<!-- <el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- <dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未付款金额(元)" align="center" prop="unpaidPaymentAmount" width="120"/>
<!-- <el-table-column label="本次付款金额" align="center" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- {{ calculateOrderCurrentPaymentAmount(scope.row.id).toFixed(2) }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="本次付款比例" align="center" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- {{ calculateOrderCurrentPaymentRate(scope.row.id) }}%-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="已付款金额(元)" align="center" prop="paidPaymentAmount" width="120"/>
<el-table-column label="付款中金额(元)" align="center" prop="paidAmount" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentAmount(scope.row.id).toFixed(2) }}
{{ $calc.sub($calc.sub(scope.row.totalPriceWithTax, scope.row.paidPaymentAmount), scope.row.unpaidPaymentAmount) }}
</template>
</el-table-column>
<el-table-column label="本次付款比例" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentRate(scope.row.id) }}%
</template>
</el-table-column>
<el-table-column label="已付款金额" align="center" prop="paidAmount" width="120"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
<template slot-scope="scope">
<el-button
@ -239,10 +253,10 @@ export default {
this.$modal.msgError('请选择付款单类型');
return;
}
if (!this.form.estimatedPaymentTime) {
this.$modal.msgError('请选择预计付款时间');
return;
}
// if (!this.form.estimatedPaymentTime) {
// this.$modal.msgError('');
// return;
// }
// Validate each payable order's payment plans
for (const order of this.payableOrdersWithPlans) {

View File

@ -1,20 +1,20 @@
<template>
<el-dialog title="合并发起收票单" :visible.sync="dialogVisible" width="80%" @close="handleClose" append-to-body>
<el-dialog title="合并发起收票单" :close-on-click-modal="false" :visible.sync="dialogVisible" width="80%" @close="handleClose" append-to-body>
<div class="dialog-body">
<el-form ref="form" :model="form" :inline="true" label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="收票单类型" prop="ticketBillType">
<el-select disabled v-model="form.ticketBillType" placeholder="请选择收票单类型" clearable>
<el-option
v-for="dict in dict.type.payment_bill_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="8">-->
<!-- <el-form-item label="收票单类型" prop="ticketBillType">-->
<!-- <el-select disabled v-model="form.ticketBillType" placeholder="请选择收票单类型" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.payment_bill_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="8">
<el-form-item label="制造商名称">
<el-input v-model="form.vendorName" readonly/>
@ -31,10 +31,10 @@
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="8">
<el-form-item label="厂家开票时间" prop="vendorTicketTime">
<el-form-item label="制造商开票时间" prop="vendorTicketTime">
<el-date-picker
v-model="form.vendorTicketTime"
type="date"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
></el-date-picker>
@ -45,31 +45,38 @@
<el-divider content-position="left">采购应付单表</el-divider>
<el-table :data="payableOrdersWithPlans" border max-height="300px" style="margin-bottom: 20px;">
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="采购-应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="预计收票时间" align="center" prop="planTicketDate" width="180"/>
<el-table-column label="收票计划" align="center" width="100" prop="planTicketAmount">
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
<el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>
</template>
</el-table-column>
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未收票金额" align="center" prop="unInvoicedAmount" width="120"/>
<el-table-column label="本次收票金额" align="center" width="120">
<!-- <el-table-column label="收票计划" align="center" width="100" prop="planTicketAmount">-->
<!-- </el-table-column>-->
<el-table-column label="预期收票计划" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentTicketAmount(scope.row.id).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="本次收票比例" align="center" width="120">
<el-table-column label="预期收票比例" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentTicketRate(scope.row.id) }}%
{{ calculateOrderCurrentTicketRate(scope.row.id) }}
</template>
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" />
<el-table-column label="制造商名称" align="center" prop="vendorName" />
<!-- <el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>-->
<!-- <el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>-->
<!-- <el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- <dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未收票金额(元)" align="center" prop="unreceivedTicketAmount" width="120"/>
<el-table-column label="已收票金额(元)" align="center" prop="receivedTicketAmount" width="120"/>
<el-table-column label="收票中金额(元)" align="center" prop="invoicedAmount" width="120">
<template slot-scope="scope">
{{ $calc.sub($calc.sub(scope.row.totalPriceWithTax,scope.row.receivedTicketAmount),scope.row.unreceivedTicketAmount)}}
</template>
</el-table-column>
<el-table-column label="已收票金额" align="center" prop="invoicedAmount" width="120"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
<template slot-scope="scope">
<el-button

View File

@ -19,7 +19,7 @@
<el-table-column label="序号" type="index" width="50" align="center"></el-table-column>
<el-table-column label="预计付款时间" align="center" width="200">
<template slot-scope="scope">
<el-date-picker v-model="scope.row.planPaymentDate" type="date" style="width: 180px"
<el-date-picker v-model="scope.row.planPaymentDate" type="datetime" style="width: 180px"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
:disabled="!isEditing || isNumberStr(scope.row.detailId)"></el-date-picker>

View File

@ -15,7 +15,7 @@
<el-table-column label="序号" type="index" width="50" align="center"></el-table-column>
<el-table-column label="预计收票时间" align="center" width="200">
<template slot-scope="scope">
<el-date-picker v-model="scope.row.planTicketDate" type="date" style="width: 180px"
<el-date-picker v-model="scope.row.planTicketDate" type="datetime" style="width: 180px"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
:disabled="!isEditing || isNumberStr(scope.row.detailId)"></el-date-picker>

View File

@ -1,14 +1,14 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="项目编号" prop="projectCode">
<el-input
v-model="queryParams.projectCode"
placeholder="请输入项目编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px">
<!-- <el-form-item label="项目编号" prop="projectCode">-->
<!-- <el-input-->
<!-- v-model="queryParams.projectCode"-->
<!-- placeholder="请输入项目编号"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
@ -17,7 +17,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="应付单编号" prop="payableBillCode">
<el-form-item label="采购-应付单编号" prop="payableBillCode">
<el-input
v-model="queryParams.payableBillCode"
placeholder="请输入应付单编号"
@ -59,26 +59,26 @@
/>
</el-select>
</el-form-item>
<el-form-item label="付款状态" prop="paymentStatus">
<el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>
<el-option
v-for="dict in dict.type.payment_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="收票状态" prop="paymentStatus">
<el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>
<el-option
v-for="dict in dict.type.payment_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="付款状态" prop="paymentStatus">-->
<!-- <el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.payment_status"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="收票状态" prop="paymentStatus">-->
<!-- <el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.payment_status"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="生成时间">-->
<!-- <el-date-picker-->
<!-- v-model="dateRange"-->
@ -93,9 +93,9 @@
<el-form-item label="预计付款时间">
<el-date-picker
v-model="estimatedPaymentDateRange"
style="width: 240px"
style="width: 350px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@ -109,13 +109,13 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5" >
<el-button type="primary" plain icon="el-icon-plus" @click="handleMergeAndInitiatePayment" v-hasPermi="['finance:payable:mergePayment']">
合并发起付款单
<el-button type="primary" plain @click="handleMergeAndInitiatePayment" v-hasPermi="['finance:payable:mergePayment']">
合并发起付款单
</el-button>
</el-col>
<el-col :span="1.5" >
<el-button type="primary" plain icon="el-icon-plus" @click="handleMergeAndInitiateReceipt" v-hasPermi="['inventory:inner:add']">
合并发起收票单
<el-button type="primary" plain @click="handleMergeAndInitiateReceipt" v-hasPermi="['inventory:inner:add']">
合并发起收票单
</el-button>
</el-col>
@ -124,11 +124,15 @@
<el-table v-loading="loading" :data="payableList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" />
<el-table-column label="项目编号" align="center" prop="projectCode" width="120" />
<!-- <el-table-column label="项目编号" align="center" prop="projectCode" width="120" />-->
<el-table-column label="项目名称" align="center" prop="projectName" width="260" />
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150" />
<el-table-column label="采购-应付单编号" align="center" prop="payableBillCode" width="150" />
<!-- <el-table-column label="生成时间" align="center" prop="createTime" width="180"/>-->
<el-table-column label="预计付款时间" align="center" prop="planPaymentDate" width="180"/>
<el-table-column label="预计付款时间" align="center" prop="planPaymentDate" width="180">
<template slot-scope="scope">
<span :style="getPaymentDateStyle(scope.row.planPaymentDate)">{{ scope.row.planPaymentDate }}</span>
</template>
</el-table-column>
<el-table-column label="预计付款金额" align="center" prop="planAmount" width="120" />
<el-table-column label="该制造商是否有预付单" align="center" prop="hasAdvancePayment" width="150">
<template slot-scope="scope">
@ -144,7 +148,7 @@
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
</template>
</el-table-column>
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120" />
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120" />
<!-- <el-table-column label="未税总价" align="center" prop="totalPriceWithoutTax" width="120" />-->
<!-- <el-table-column label="税额" align="center" prop="taxAmount" width="120" />-->
<!-- <el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">-->
@ -171,8 +175,8 @@
<!-- >生成收票单</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="未付款金额" align="center" prop="unpaidPaymentAmount" width="120" />
<el-table-column label="未收票金额" align="center" prop="unreceivedTicketAmount" width="120" />
<el-table-column label="未付款金额(元)" align="center" prop="unpaidPaymentAmount" width="120" />
<el-table-column label="未收票金额(元)" align="center" prop="unreceivedTicketAmount" width="120" />
<!-- <el-table-column label="付款中金额" align="center" prop="payingAmount" width="120" />-->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300" fixed="right">
<template slot-scope="scope">
@ -212,7 +216,7 @@
/>
<!-- 修改弹窗 -->
<edit-form :visible.sync="open" :data="selectedRow" />
<edit-form :visible.sync="open" :data="selectedRow" @close="getList" />
<!-- 合并付款单弹窗 -->
<merge-payment-dialog :visible.sync="isMergePaymentDialogOpen" :payable-orders="selectedPayableRows" @confirm="confirmMergePayment" />
@ -326,14 +330,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 生成付款单按钮操作 */
handleGeneratePayment(row) {
console.log("handleGeneratePayment", row);
},
/** 生成收票单按钮操作 */
handleGenerateInvoice(row) {
console.log("handleGenerateInvoice", row);
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.selectedPayableRows = selection;
@ -352,9 +348,14 @@ export default {
this.$modal.msgWarning("请选择至少一条应付单进行合并操作");
return;
}
let every = this.selectedPayableRows.every(item=>item.planAmount>0);
if (!every){
this.$modal.msgWarning("温馨提示:您勾选的应付单中有已全部付款完成的应付单,请勿重复操作");
return;
}
let vendorLength = new Set(this.selectedPayableRows.map(item=>item.vendorCode)).size;
if (vendorLength > 1) {
this.$modal.msgWarning("请选择同一家供应商的应付单进行合并操作");
this.$modal.msgWarning("温馨提示:您勾选的应付单中有不同供应商,合并发起付款单需为同一供应商,请重新勾选");
return;
}
@ -374,9 +375,14 @@ export default {
this.$modal.msgWarning("请选择至少一条应付单进行合并操作");
return;
}
let every = this.selectedPayableRows.every(item=>item.planTicketAmount>0);
if (!every){
this.$modal.msgWarning("温馨提示:您勾选的应付单中有已全部收票完成的应付单,请勿重复操作");
return;
}
let vendorLength = new Set(this.selectedPayableRows.map(item=>item.vendorCode)).size;
if (vendorLength > 1) {
this.$modal.msgWarning("请选择同一家供应商的应付单进行合并操作");
this.$modal.msgWarning("温馨提示:您勾选的应付单中有不同供应商,合并发起收票单需为同一供应商,请重新勾选");
return;
}
@ -389,6 +395,16 @@ export default {
this.isMergeReceiptDialogOpen = false;
this.getList(); // Refresh the list
});
},
getPaymentDateStyle(dateStr) {
if (!dateStr) return {};
let planDate = new Date(dateStr).getTime();
let tenDaysLater = new Date().getTime() + 10 * 24 * 60 * 60 * 1000;
if (planDate <= tenDaysLater) {
return { color: '#ffba00' };
}
return {};
}
}
};

View File

@ -18,31 +18,28 @@
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>-->
<!-- <el-col :span="24">-->
<!-- <el-form-item label="预计付款时间" prop="estimatedPaymentTime">-->
<!-- <el-date-picker-->
<!-- v-model="form.estimatedPaymentTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd HH:mm:ss"-->
<!-- placeholder="选择日期"-->
<!-- ></el-date-picker>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-row>
<el-col :span="24">
<el-form-item label="预计付款时间" prop="estimatedPaymentTime">
<el-date-picker
v-model="form.estimatedPaymentTime"
type="date"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="是否预付" prop="paymentBillType">
<el-radio-group v-model="form.paymentBillType">
<el-radio label="PRE_PAYMENT"></el-radio>
<el-radio label="FROM_PAYABLE"></el-radio>
</el-radio-group>
<el-form-item label="备注" prop="paymentBillType">
<el-checkbox v-model="form.paymentBillType" true-label="PRE_PAYMENT" false-label="FROM_PAYABLE"></el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.paymentBillType === 'PRE_PAYMENT'">
<el-col :span="12">
<el-form-item label="预付金额" prop="totalPriceWithTax">
<el-form-item label="含税总价(元)" prop="totalPriceWithTax">
<el-input-number v-model="form.totalPriceWithTax" :precision="2" :step="100"
style="width: 100%"></el-input-number>
</el-form-item>
@ -52,7 +49,7 @@
<!-- Tables -->
<div v-if="form.vendorCode">
<div v-if="form.paymentBillType === 'FROM_PAYABLE'" class="table-container">
<h4>应付单</h4>
<h4>采购-应付单表</h4>
<el-table
ref="payableTable"
:data="payableList"
@ -61,33 +58,48 @@
@selection-change="handleSelectionChange"
max-height="400"
row-key="id"
show-summary
:summary-method="getPayableSummary"
>
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="采购-应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="预计付款时间" align="center" prop="planPaymentDate" width="180"/>
<el-table-column label="付款计划" align="center" width="100" prop="planAmount">
<el-table-column label="预期付款计划" align="center" width="100" prop="planAmount">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentAmount(scope.row) }}
</template>
</el-table-column>
<el-table-column label="预期付款比例" align="center" prop="projectCode" width="150">
<template slot-scope="scope">
{{ $calc.mul($calc.div(calculateOrderCurrentPaymentAmount(scope.row), scope.row.totalPriceWithTax,4),100) }}
</template>
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
<el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">
<el-table-column label="制造商名称" align="center" prop="vendorName" width="150"/>
<!-- <el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>-->
<!-- <el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- <dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未付款金额" align="center" prop="unpaidPaymentAmount" width="120"/>
<!-- <el-table-column label="本次付款金额" align="center" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- {{ calculateOrderCurrentPaymentAmount(scope.row).toFixed(2) }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="本次付款比例" align="center" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- {{ calculateOrderCurrentPaymentRate(scope.row) }}%-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="已付款金额" align="center" prop="paidPaymentAmount" width="120"/>
<el-table-column label="付款中金额" align="center" prop="paidAmount" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
{{ $calc.sub($calc.sub(scope.row.totalPriceWithTax, scope.row.paidPaymentAmount), scope.row.unpaidPaymentAmount) }}
</template>
</el-table-column>
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未付款金额" align="center" prop="unpaidAmount" width="120"/>
<el-table-column label="本次付款金额" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentAmount(scope.row).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="本次付款比例" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentPaymentRate(scope.row) }}%
</template>
</el-table-column>
<el-table-column label="已付款金额" align="center" prop="paidAmount" width="120"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100"
fixed="right">
<template slot-scope="scope">
@ -206,7 +218,7 @@ export default {
},
rules: {
vendorCode: [{required: true, message: "制造商名称不能为空", trigger: "change"}],
estimatedPaymentTime: [{required: true, message: "预计付款时间不能为空", trigger: "change"}],
// estimatedPaymentTime: [{required: true, message: "", trigger: "change"}],
paymentBillType: [{required: true, message: "请选择是否预付", trigger: "change"}],
totalPriceWithTax: [{required: false, message: "预付金额不能为空", trigger: "blur"}]
},
@ -278,7 +290,8 @@ export default {
const query = {
vendorCode: this.form.vendorCode,
pageNum: this.queryParams.pageNum,
pageSize: this.queryParams.pageSize
pageSize: this.queryParams.pageSize,
unpaidPaymentAmount:-1
};
if (this.form.paymentBillType === 'FROM_PAYABLE') {
@ -375,6 +388,33 @@ export default {
}
return 0;
},
getPayableSummary(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
if (column.label === '预期付款计划') {
const values = data.map(item => Number(this.calculateOrderCurrentPaymentAmount(item)));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
sums[index] = sums[index].toFixed(2);
} else {
sums[index] = '';
}
}
});
return sums;
},
handleClose() {
this.internalVisible = false;
@ -419,7 +459,7 @@ export default {
} else {
// Prepayment logic
console.log(this.selectedRows)
if (this.selectedRows.length > 1) {
this.$modal.msgWarning("只能选择一笔订单");
return;
@ -438,7 +478,7 @@ export default {
paymentTime: this.form.estimatedPaymentTime,
totalPriceWithTax:this.form.totalPriceWithTax
};
console.log(submitData)
this.$emit("submit", submitData);
}
}

View File

@ -1,9 +1,10 @@
<template>
<el-drawer
title="付款单详情"
title="采购-付款单详情"
:visible.sync="visible"
direction="rtl"
size="70%"
:wrapper-closable="false"
@close="handleClose"
>
<div class="dialog-body" v-if="detail">
@ -23,13 +24,13 @@
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="detail-item">含税总价: {{ detail.totalPriceWithTax }}</div>
<div class="detail-item">含税总价(): {{ detail.totalPriceWithTax }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item">未税总价: {{ detail.totalPriceWithoutTax }}</div>
<div class="detail-item">未税总价(): {{ detail.totalPriceWithoutTax }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item">税额: {{ detail.taxAmount }}</div>
<div class="detail-item">税额(): {{ detail.taxAmount }}</div>
</el-col>
</el-row>
<el-row :gutter="20">
@ -42,7 +43,7 @@
<div class="detail-item">预付单剩余额度: {{ detail.preResidueAmount || '-' }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item">财务付款时间: {{ detail.actualPaymentTime || '-'}}</div>
<div class="detail-item">实际付款时间: {{ detail.actualPaymentTime || '-'}}</div>
</el-col>
</el-row>
<el-row :gutter="20">
@ -93,7 +94,7 @@
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column property="projectCode" label="项目编号"></el-table-column>
<el-table-column property="projectName" label="项目名称"></el-table-column>
<el-table-column property="payableBillCode" label="采购应付单编号"></el-table-column>
<el-table-column property="payableBillCode" label="采购-应付单编号"></el-table-column>
<el-table-column property="totalPriceWithTax" label="含税总价"></el-table-column>
<el-table-column property="paymentAmount" label="本次付款金额"></el-table-column>
<el-table-column property="paymentRate" label="本次付款比例"></el-table-column>

View File

@ -5,7 +5,7 @@
</div>
<div v-else class="receipt-dialog-body">
<div v-if="canUpload" class="upload-btn-container">
<el-button type="primary" icon="el-icon-upload" @click="openUploadDialog">{{ titleText }}</el-button>
<el-button type="primary" icon="el-icon-upload" v-hasPermi="['finance:payment:upload']" @click="openUploadDialog">{{ titleText }}</el-button>
</div>
<el-timeline v-if="attachments.length > 0">
@ -19,7 +19,7 @@
<div class="receipt-card-content">
<div class="receipt-details">
<div class="detail-item">
<span class="item-label">方式</span>
<span class="item-label">付方式</span>
<span class="item-value">
<dict-tag :options="dicts.payment_method" :value="paymentData.paymentMethod"/>
</span>
@ -110,7 +110,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form :model="uploadForm" ref="uploadForm" label-width="120px" size="medium" >
<el-form-item label="方式">
<el-form-item label="付方式">
<el-select v-model="uploadForm.paymentMethod" disabled style="width: 100%;">
<el-option
v-for="dict in dicts.payment_method"
@ -120,7 +120,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="退款图" required>
<el-form-item :label="paymentData.paymentBillType==='FROM_PAYABLE'?'回执单': '退款图'" required>
<div style="display: flex; flex-direction: column; align-items: flex-start;">
<el-upload
ref="upload"

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="130px">
<el-form-item label="项目编号" prop="projectCode">
<el-input
v-model="queryParams.projectCode"
@ -17,7 +17,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="付款单编号" prop="paymentBillCode">
<el-form-item label="采购-付款单编号" prop="paymentBillCode">
<el-input
v-model="queryParams.paymentBillCode"
placeholder="请输入付款单编号"
@ -25,15 +25,15 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="制造商名称" prop="vendorCode">
<el-form-item label="制造商名称" prop="vendorName">
<el-input
v-model="queryParams.vendorCode"
v-model="queryParams.vendorName"
placeholder="请输入制造商名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="应付单编号" prop="payableBillCode">
<el-form-item label="采购-应付单编号" prop="payableBillCode">
<el-input
v-model="queryParams.payableBillCode"
placeholder="请输入应付单编号"
@ -41,29 +41,39 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="付款单类型" prop="paymentBillType">
<el-select v-model="queryParams.paymentBillType" placeholder="请选择付款单类型" clearable>
<el-form-item label="备注" prop="paymentBillType">
<el-select v-model="queryParams.paymentBillType" placeholder="请选择备注" clearable>
<el-option v-for="dict in dict.type.payment_bill_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="支付方式" prop="paymentMethod">
<el-select v-model="queryParams.paymentMethod" placeholder="请选择支付方式" clearable>
<el-option label="方式一" value="1" />
<el-option label="方式二" value="2" />
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="queryParams.approveStatus" placeholder="请选择审批状态" clearable>
<el-option label="待提交" value="0" />
<el-option label="审批中" value="1" />
<el-option label="已审批" value="2" />
<el-option label="已驳回" value="3" />
<el-select v-model="queryParams.paymentMethod" style="width: 100%;">
<el-option
v-for="dict in dict.type.payment_method"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="付款状态" prop="paymentStatus">
<el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>
<el-option label="待付款" value="0" />
<el-option label="已付款" value="1" />
<el-option
v-for="dict in dict.type.payment_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="queryParams.approveStatus" placeholder="请选择审批状态" clearable>
<el-option
v-for="dict in dict.type.approve_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="审批节点" prop="approveNode">
@ -74,23 +84,12 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="审批通过时间">
<el-date-picker
v-model="dateRangeApproval"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="预计付款时间">
<el-date-picker
v-model="dateRangeEstimated"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@ -100,13 +99,26 @@
<el-date-picker
v-model="dateRangeActual"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="审批通过时间">
<el-date-picker
v-model="dateRangeApproval"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
@ -127,36 +139,40 @@
</el-row>
<el-table v-loading="loading" :data="paymentList">
<el-table-column label="付款单编号" align="center" prop="paymentBillCode" />
<el-table-column label="采购-付款单编号" width="200" align="center" prop="paymentBillCode"/>
<el-table-column label="预计付款时间" align="center" prop="paymentTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.paymentTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="制造商名称" align="center" prop="vendorName" />
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" />
<el-table-column label="付款单类型" align="center" prop="paymentBillType" >
<el-table-column label="制造商名称" width="200" align="center" prop="vendorName"/>
<el-table-column label="含税总价(元)" align="center" width="200" prop="totalPriceWithTax">
<template slot-scope="scope">
<span :style="scope.row.totalPriceWithTax<0?{color:'red'}:{}">{{ scope.row.totalPriceWithTax }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" width="100" prop="paymentBillType">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_bill_type" :value="scope.row.paymentBillType"/>
</template>
</el-table-column>
<el-table-column label="预付单剩余额度" align="center" prop="preResidueAmount" />
<el-table-column label="预付单剩余额度" align="center" width="200" prop="preResidueAmount"/>
<el-table-column label="实际付款时间" align="center" prop="actualPaymentTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.actualPaymentTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="支付方式" align="center" prop="paymentMethod" >
<el-table-column label="支付方式" align="center" width="100" prop="paymentMethod">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_method" :value="scope.row.paymentMethod"/>
</template>
</el-table-column>
<el-table-column label="付款状态" align="center" prop="paymentStatus" >
<el-table-column label="付款状态" align="center" width="100" prop="paymentStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
</template>
</el-table-column>
<el-table-column label="审批状态" align="center" prop="approveStatus" >
<el-table-column label="审批状态" align="center" width="100" prop="approveStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.approve_status" :value="scope.row.approveStatus"/>
</template>
@ -166,8 +182,8 @@
<span>{{ parseTime(scope.row.approveTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="审批节点" align="center" prop="approveNode" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="审批节点" fixed="right" width="150" align="center" prop="approveNode"/>
<el-table-column label="操作" fixed="right" width="400" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
@ -186,21 +202,21 @@
size="mini"
type="text"
icon="el-icon-position"
v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3')"
v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && (scope.row.paymentBillType==='FROM_PAYABLE'||scope.row.paymentBillType==='PRE_PAYMENT')"
@click="applyPayment(scope.row)"
>发起付款</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-position"
v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && scope.row.paymentBillType==='REFUND' "
@click="applyRefundApprove(scope.row)"
>发起退款</el-button>
>申请付款</el-button>
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-position"-->
<!-- v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && scope.row.paymentBillType==='REFUND' "-->
<!-- @click="applyRefundApprove(scope.row)"-->
<!-- >发起退款</el-button>-->
<el-button
size="mini"
type="text"
icon="el-icon-refresh-left"
v-show="scope.row.paymentBillType==='FROM_PAYABLE' && scope.row.paymentStatus==='1' && (scope.row.approveStatus==='0' || scope.row.approveStatus==='3')"
v-show="scope.row.paymentBillType==='FROM_PAYABLE' && scope.row.paymentStatus==='1' && scope.row.approveStatus==='0' "
@click="handleReturn(scope.row)"
>退回</el-button>
<el-button
@ -209,12 +225,12 @@
icon="el-icon-refresh-right"
v-if="scope.row.paymentStatus === '2' && scope.row.refundStatus !== 'REFUND_APPLIED' && scope.row.paymentBillType !== 'REFUND'"
@click="handleApplyRefund(scope.row)"
>退款</el-button>
>申请退款</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-refresh-right"
v-if="scope.row.paymentStatus === '1' && scope.row.approveStatus==='2'"
v-if="(scope.row.approveStatus === '2' || scope.row.approveStatus==='3') && (scope.row.paymentStatus==='1'||scope.row.paymentStatus==='3')"
@click="handleRevoke(scope.row)"
>撤销</el-button>
</template>
@ -238,8 +254,8 @@
<!-- 付款申请弹窗 -->
<el-dialog title="发起付款" :visible.sync="applyPaymentOpen" width="600px" append-to-body>
<el-form ref="applyPaymentForm" :model="applyPaymentForm" label-width="120px">
<el-form-item label="方式" prop="paymentMethod">
<el-select v-model="applyPaymentForm.paymentMethod" placeholder="请选择方式">
<el-form-item label="付方式" prop="paymentMethod">
<el-select v-model="applyPaymentForm.paymentMethod" placeholder="请选择付方式">
<el-option
v-for="dict in dict.type.payment_method"
:key="dict.value"
@ -426,7 +442,7 @@ export default {
},
/** 退回按钮操作 */
handleReturn(row) {
this.$modal.confirm('是否确认退回付款单编号为"' + row.paymentBillCode + '"的数据项?').then(function() {
this.$modal.confirm('是否将该笔采购-付款单退回至采购-应付单').then(function() {
return returnPayment(row.id);
}).then(() => {
this.getList();
@ -434,7 +450,7 @@ export default {
}).catch(() => {});
},
applyRefundApprove(row) {
this.$modal.confirm('是否对付款单编号为"' + row.paymentBillCode + '"的数据项发起退款').then(function() {
this.$modal.confirm('收款单退款申请,确认提交至财务审批吗').then(function() {
return applyRefundApprove(row.id);
}).then(() => {
this.getList();
@ -443,7 +459,7 @@ export default {
},
/** 申请退款按钮操作 */
handleApplyRefund(row) {
this.$modal.confirm('是否确认对付款单编号为"' + row.paymentBillCode + '"的款项申请退款').then(() => {
this.$modal.confirm('收款单退款申请,确认提交至财务审批吗').then(() => {
return applyRefund(row.id);
}).then(() => {
this.getList();
@ -451,7 +467,8 @@ export default {
}).catch(() => {});
},
handleRevoke(row) {
this.$modal.confirm('是否撤销对付款单编号为"' + row.paymentBillCode + '"的款项?').then(() => {
let msg=row.paymentBillType==='REFUND'?'是否将该笔采购-退款单撤销,将退款单撤销至付款单':'是否将该笔采购-付款单撤销,撤销至付款单未审批状态';
this.$modal.confirm(msg).then(() => {
return handleRevoke(row.id);
}).then(() => {
this.getList();

View File

@ -3,23 +3,23 @@
<div class="dialog-body">
<el-form ref="form" :model="queryParams" :inline="true" label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="收票单类型" prop="ticketBillType">
<!-- Mapping receiptBillType to ticketBillType for consistency with the merge logic -->
<el-select disabled v-model="form.receiptBillType" placeholder="请选择收票单类型" clearable>
<!-- Using dicts.receipt_bill_type if available, or dict.type.payment_bill_type if that was the intent.
The original code used dicts.receipt_bill_type. I'll stick to that but ensure it's passed or available.
The user instructions imply 'MergeReceiptDialog' logic which used payment_bill_type.
I will use the existing props 'dicts' -->
<el-option
v-for="dict in dict.type.payment_bill_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="8">-->
<!-- <el-form-item label="收票单类型" prop="ticketBillType">-->
<!-- &lt;!&ndash; Mapping receiptBillType to ticketBillType for consistency with the merge logic &ndash;&gt;-->
<!-- <el-select disabled v-model="form.receiptBillType" placeholder="请选择收票单类型" clearable>-->
<!-- &lt;!&ndash; Using dicts.receipt_bill_type if available, or dict.type.payment_bill_type if that was the intent.-->
<!-- The original code used dicts.receipt_bill_type. I'll stick to that but ensure it's passed or available.-->
<!-- The user instructions imply 'MergeReceiptDialog' logic which used payment_bill_type.-->
<!-- I will use the existing props 'dicts' &ndash;&gt;-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.payment_bill_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="8">
<el-form-item label="制造商名称">
<el-select
@ -39,10 +39,10 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="厂家开票时间" prop="vendorTicketTime">
<el-form-item label="制造商开票时间" prop="vendorTicketTime">
<el-date-picker
v-model="form.vendorTicketTime"
type="date"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
></el-date-picker>
@ -62,31 +62,38 @@
ref="table"
>
<el-table-column type="selection" :reserve-selection="true" width="55" align="center" />
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="采购-应付单编号" align="center" prop="payableBillCode" width="150"/>
<el-table-column label="预计收票时间" align="center" prop="planTicketDate" width="180"/>
<el-table-column label="收票计划" align="center" width="100" prop="planTicketAmount">
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
<el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>
</template>
</el-table-column>
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未收票金额" align="center" prop="unInvoicedAmount" width="120"/>
<el-table-column label="本次收票金额" align="center" width="120">
<!-- <el-table-column label="收票计划" align="center" width="100" prop="planTicketAmount">-->
<!-- </el-table-column>-->
<el-table-column label="预期收票计划" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentTicketAmount(scope.row.id).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="本次收票比例" align="center" width="120">
<el-table-column label="预期收票比例" align="center" width="120">
<template slot-scope="scope">
{{ calculateOrderCurrentTicketRate(scope.row.id) }}%
</template>
</el-table-column>
<el-table-column label="已收票金额" align="center" prop="invoicedAmount" width="120"/>
<el-table-column label="项目名称" align="center" prop="projectName" />
<el-table-column label="制造商名称" align="center" prop="vendorName" />
<!-- <el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>-->
<!-- <el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>-->
<!-- <el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">-->
<!-- <template slot-scope="scope">-->
<!-- <dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="未收票金额(元)" align="center" prop="unInvoicedAmount" width="120"/>
<el-table-column label="已收票金额(元)" align="center" prop="invoicedAmount" width="120"/>
<el-table-column label="收票中金额(元)" align="center" prop="invoicedAmount" width="120">
<template slot-scope="scope">
{{ $calc.sub($calc.sub(scope.row.totalPriceWithTax,scope.row.receivedTicketAmount),scope.row.unreceivedTicketAmount)}}
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
<template slot-scope="scope">
<el-button
@ -161,6 +168,7 @@ export default {
ticketBillType: 'FROM_PAYABLE', // Used for filtering if needed
vendorId: null,
invoiceStatus: null,
unreceivedTicketAmount:-1
},
// Form data for submission
form: {
@ -232,6 +240,7 @@ export default {
ticketPlans.push({
id: order.lastTicketPlanId,
planAmount: order.planTicketAmount,
taxRate: order.taxRate,
planTicketDate: order.planTicketDate,
planRate: order.totalPriceWithTax ? this.$calc.mul(this.$calc.div(order.planTicketAmount, order.totalPriceWithTax, 4), 100) : 0
});
@ -313,7 +322,7 @@ export default {
return;
}
if (!this.form.vendorTicketTime) {
this.$modal.msgError('请选择厂家开票时间');
this.$modal.msgError('请选择制造商开票时间');
return;
}
@ -331,14 +340,14 @@ export default {
return;
}
for (const plan of order.ticketPlans) {
if (!plan.planTicketDate) {
this.$modal.msgError(`应付单 ${order.payableBillCode} 的收票计划中预计收票时间不能为空。`);
return;
}
if (plan.planAmount === null || plan.planAmount === undefined || plan.planAmount <= 0) {
this.$modal.msgError(`应付单 ${order.payableBillCode} 的收票计划中预计收票金额必须大于0。`);
return;
}
if (!plan.planTicketDate) {
this.$modal.msgError(`应付单 ${order.payableBillCode} 的收票计划中预计收票时间不能为空。`);
return;
}
}
}
@ -354,6 +363,7 @@ export default {
planTicketDate: plan.planTicketDate,
planAmount: plan.planAmount,
planRate: plan.planRate,
taxRate: order.taxRate,
remark: plan.remark,
id: plan.id,
})),
@ -378,6 +388,7 @@ export default {
ticketBillType: 'FROM_PAYABLE',
vendorId: null,
invoiceStatus: null,
unreceivedTicketAmount:-1
};
this.payableOrdersWithPlans = [];
this.selectedRows = [];

View File

@ -143,19 +143,19 @@
<span>{{ receiptData.totalPriceWithTax }}</span>
</el-form-item>
<el-form-item label="发票含税总价" prop="ticketPriceWithTax" required>
<el-input v-model="uploadForm.ticketPriceWithTax" placeholder="请输入发票含税总价"></el-input>
<el-input v-model="uploadForm.ticketPriceWithTax" placeholder="请输入发票含税总价" @input="handlePriceWithTaxChange"></el-input>
</el-form-item>
<el-form-item label="未税总价">
<span>{{ receiptData.totalPriceWithoutTax }}</span>
</el-form-item>
<el-form-item label="发票未税总价" prop="ticketPriceWithoutTax" required>
<el-input v-model="uploadForm.ticketPriceWithoutTax" placeholder="请输入发票未税总价"></el-input>
<el-input v-model="uploadForm.ticketPriceWithoutTax" placeholder="请输入发票未税总价" @input="handlePriceWithoutTaxChange"></el-input>
</el-form-item>
<el-form-item label="税额">
<span>{{ receiptData.taxAmount }}</span>
</el-form-item>
<el-form-item label="发票税额" prop="ticketAmount" required>
<el-input v-model="uploadForm.ticketAmount" placeholder="请输入发票税额"></el-input>
<el-input v-model="uploadForm.ticketAmount" placeholder="请输入发票税额" @input="handleAmountChange"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input
@ -210,6 +210,10 @@ export default {
dicts: {
type: Object,
default: () => ({})
},
autoUpload: {
type: Boolean,
default: false,
}
},
dicts:['finance_invoice_type'],
@ -220,24 +224,51 @@ export default {
// Upload Dialog Data
uploadDialogVisible: false,
uploadForm: {
totalPriceWithTax: '',
ticketPriceWithTax: '',
totalPriceWithoutTax: '',
ticketPriceWithoutTax: '',
taxAmount: '',
ticketAmount: '',
ticketType: '',
remark: '',
file: null
},
rules: {
ticketPriceWithTax: [
{ required: true, message: "请输入发票含税总价", trigger: "blur" }
{ required: true, message: "请输入发票含税总价", trigger: "blur" },
{ validator: (rule, value, callback) => {
if (Number(value) !== Number(this.receiptData.totalPriceWithTax)) {
callback(new Error('发票含税总价必须等于含税总价'));
} else {
callback();
}
}, trigger: 'blur' }
],
ticketPriceWithoutTax: [
{ required: true, message: "请输入发票未税总价", trigger: "blur" }
{ required: true, message: "请输入发票未税总价", trigger: "blur" },
{ validator: (rule, value, callback) => {
const total = Number(this.receiptData.totalPriceWithTax);
const val = Number(value);
if (total > 0 && val < 0) {
callback(new Error('发票未税总价不能小于0'));
} else if (total < 0 && val > 0) {
callback(new Error('发票未税总价不能大于0'));
} else {
callback();
}
}, trigger: 'blur' }
],
ticketAmount: [
{ required: true, message: "请输入发票税额", trigger: "blur" }
{ required: true, message: "请输入发票税额", trigger: "blur" },
{ validator: (rule, value, callback) => {
const total = Number(this.receiptData.totalPriceWithTax);
const val = Number(value);
if (total > 0 && val < 0) {
callback(new Error('发票税额不能小于0'));
} else if (total < 0 && val > 0) {
callback(new Error('发票税额不能大于0'));
} else {
callback();
}
}, trigger: 'blur' }
]
},
previewUrl: '',
@ -276,6 +307,11 @@ export default {
visible(val) {
if (val && this.receiptData) {
this.fetchAttachments();
if (this.autoUpload) {
setTimeout(() => {
this.openUploadDialog();
}, 300);
}
}
},
},
@ -341,9 +377,10 @@ export default {
// New Upload Dialog Methods
openUploadDialog() {
this.uploadForm = {
totalPriceWithTax: '',
totalPriceWithoutTax: '',
taxAmount: '',
ticketPriceWithTax: this.receiptData.totalPriceWithTax,
ticketPriceWithoutTax: this.receiptData.totalPriceWithoutTax,
ticketAmount: this.receiptData.taxAmount,
ticketType: '',
remark: '',
file: null
};
@ -354,6 +391,21 @@ export default {
this.isPreviewPdf = false;
this.uploadDialogVisible = true;
},
handlePriceWithTaxChange(val) {
const withTax = Number(val) || 0;
const withoutTax = Number(this.uploadForm.ticketPriceWithoutTax) || 0;
this.uploadForm.ticketAmount = (withTax - withoutTax).toFixed(2);
},
handlePriceWithoutTaxChange(val) {
const withTax = Number(this.uploadForm.ticketPriceWithTax) || 0;
const withoutTax = Number(val) || 0;
this.uploadForm.ticketAmount = (withTax - withoutTax).toFixed(2);
},
handleAmountChange(val) {
const withTax = Number(this.uploadForm.ticketPriceWithTax) || 0;
const amount = Number(val) || 0;
this.uploadForm.ticketPriceWithoutTax = (withTax - amount).toFixed(2);
},
closeUploadDialog() {
this.uploadDialogVisible = false;
this.uploadForm.file = null;

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px">
<el-form-item label="项目编号" prop="projectCode">
<el-input
v-model="queryParams.projectCode"
@ -17,9 +17,9 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="收票单编号" prop="receiptBillCode">
<el-form-item label="采购-收票单编号" prop="ticketBillCode">
<el-input
v-model="queryParams.receiptBillCode"
v-model="queryParams.ticketBillCode"
placeholder="请输入收票单编号"
clearable
@keyup.enter.native="handleQuery"
@ -33,7 +33,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="应付单编号" prop="payableBillCode">
<el-form-item label="采购-应付单编号" prop="payableBillCode">
<el-input
v-model="queryParams.payableBillCode"
placeholder="请输入应付单编号"
@ -46,20 +46,27 @@
<el-option v-for="dict in dict.type.receipt_bill_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="queryParams.approveStatus" placeholder="请选择审批状态" clearable>
<el-option label="待提交" value="0" />
<el-option label="审批中" value="1" />
<el-option label="已审批" value="2" />
<el-option label="已驳回" value="3" />
</el-select>
</el-form-item>
<el-form-item label="收票状态" prop="receiptStatus">
<el-select v-model="queryParams.receiptStatus" placeholder="请选择收票状态" clearable>
<el-option label="待收票" value="0" />
<el-option label="已收票" value="1" />
<el-option
v-for="dict in dict.type.receipt_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="queryParams.approveStatus" placeholder="请选择审批状态" clearable>
<el-option
v-for="dict in dict.type.approve_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="审批节点" prop="approveNode">
<el-input
v-model="queryParams.approveNode"
@ -72,30 +79,30 @@
<el-date-picker
v-model="dateRangeApproval"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="预计收票时间">
<!-- <el-form-item label="预计收票时间">-->
<!-- <el-date-picker-->
<!-- v-model="dateRangeEstimated"-->
<!-- style="width: 240px"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- type="daterange"-->
<!-- range-separator="-"-->
<!-- start-placeholder="开始日期"-->
<!-- end-placeholder="结束日期"-->
<!-- ></el-date-picker>-->
<!-- </el-form-item>-->
<el-form-item label="制造商开票时间">
<el-date-picker
v-model="dateRangeEstimated"
v-model="dateRangeVendor"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="实际收票时间">
<el-date-picker
v-model="dateRangeActual"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@ -121,7 +128,7 @@
</el-row>
<el-table v-loading="loading" :data="receiptList">
<el-table-column label="收票单编号" align="center" prop="ticketBillCode" />
<el-table-column label="采购-收票单编号" align="center" prop="ticketBillCode" />
<!-- <el-table-column label="预计收票时间" align="center" prop="ticketTime" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <span>{{ parseTime(scope.row.ticketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>-->
@ -133,9 +140,9 @@
</template>
</el-table-column>
<el-table-column label="制造商名称" align="center" prop="vendorName" />
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" />
<el-table-column label="未税总价" align="center" prop="totalPriceWithoutTax" />
<el-table-column label="税额" align="center" prop="taxAmount" />
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" />
<el-table-column label="未税总价(元)" align="center" prop="totalPriceWithoutTax" />
<el-table-column label="税额(元)" align="center" prop="taxAmount" />
<!-- <el-table-column label="收票单类型" align="center" prop="ticketBillType" >-->
<!-- <template slot-scope="scope">-->
<!-- <dict-tag :options="dict.type.ticket_bill_type" :value="scope.row.ticketBillType"/>-->
@ -175,22 +182,37 @@
size="mini"
type="text"
icon="el-icon-document"
v-show="scope.row.approveStatus!=='0'"
@click="handleReceipt(scope.row)"
>发票</el-button>
>{{scope.row.ticketBillType==='FROM_PAYABLE'?'发票' : '红冲'}}</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-document"
v-show="scope.row.approveStatus==='0'"
v-show="scope.row.approveStatus==='0' && scope.row.ticketStatus==='1'"
@click="handleReturn(scope.row)"
>退回</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-document"
v-show="scope.row.approveStatus==='0' && scope.row.ticketStatus==='1'"
@click="handleApplyInvoice(scope.row)"
>申请发票</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-refresh-left"
v-show="scope.row.approveStatus=='2'"
@click="handleRedRush(scope.row)"
v-show="scope.row.approveStatus=='2' && scope.row.ticketStatus==='2'"
@click="handleApplyRedRush(scope.row)"
>申请红冲</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-refresh-left"
v-show="scope.row.approveStatus=='3'"
@click="handleRevoke(scope.row)"
>撤销</el-button>
</template>
</el-table-column>
</el-table>
@ -208,13 +230,13 @@
<!-- 新增弹窗 -->
<add-form :visible.sync="addOpen" :dicts="dict.type" @submit="handleAddSubmit"></add-form>
<!-- 收票附件弹窗 -->
<receipt-dialog :visible.sync="receiptOpen" :receipt-data="currentRow" :dicts="dict.type"></receipt-dialog>
<receipt-dialog :visible.sync="receiptOpen" :receipt-data="currentRow" :dicts="dict.type" :auto-upload="autoUpload"></receipt-dialog>
</div>
</template>
<script>
import {listReceipt, getReceipt, redRush, addReceipt, returnReceipt} from "@/api/finance/receipt";
import {listReceipt, getReceipt, redRush, addReceipt, returnReceipt, revokeReceipt} from "@/api/finance/receipt";
import { addDateRange } from "@/utils/ruoyi";
import DetailDrawer from "./components/DetailDrawer.vue";
import AddForm from "./components/AddForm.vue";
@ -244,7 +266,7 @@ export default {
pageSize: 10,
projectCode: null,
projectName: null,
receiptBillCode: null,
ticketBillCode: null,
vendorCode: null,
payableBillCode: null,
receiptBillType: null,
@ -255,7 +277,7 @@ export default {
//
dateRangeApproval: [],
dateRangeEstimated: [],
dateRangeActual: [],
dateRangeVendor: [],
//
detailOpen: false,
detailData: null,
@ -263,7 +285,8 @@ export default {
addOpen: false,
//
receiptOpen: false,
currentRow: {}
currentRow: {},
autoUpload: false
};
},
created() {
@ -276,7 +299,7 @@ export default {
let query = { ...this.queryParams };
query = this.addDateRange(query, this.dateRangeApproval, 'ApproveTime');
query = this.addDateRange(query, this.dateRangeEstimated, 'ReceiptTime');
query = this.addDateRange(query, this.dateRangeActual, 'ActualReceiptTime');
query = this.addDateRange(query, this.dateRangeVendor, 'VendorTicketTime');
listReceipt(query).then(response => {
this.receiptList = response.rows;
@ -293,7 +316,7 @@ export default {
resetQuery() {
this.dateRangeApproval = [];
this.dateRangeEstimated = [];
this.dateRangeActual = [];
this.dateRangeVendor = [];
this.resetForm("queryForm");
this.handleQuery();
},
@ -324,23 +347,37 @@ export default {
handleReceipt(row) {
this.currentRow = row;
this.receiptOpen = true;
this.autoUpload = false;
},
handleApplyInvoice(row) {
this.currentRow = row;
this.receiptOpen = true;
this.autoUpload = true;
},
handleApplyRedRush(row) {
this.currentRow = row;
this.receiptOpen = true;
this.autoUpload = true;
},
/** 退回按钮操作 */
handleRedRush(row) {
this.$modal.confirm('是否确认收票单编号为"' + row.ticketBillCode + '"的数据项进行红冲,并提交财务审批?').then(function() {
return redRush(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("退回成功");
}).catch(() => {});
},
handleReturn(row) {
this.$modal.confirm('是否确认退回收票单编号为"' + row.ticketBillCode + '"的数据项?').then(function() {
this.$modal.confirm('是否将该笔采购-收票单退回至采购-应付单').then(function() {
return returnReceipt(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("退回成功");
}).catch(() => {});
},
handleRevoke(row) {
const msg = row.ticketBillType === 'FROM_PAYABLE'
? '是否将该笔采购-收票单撤销,撤销后重新上传发票'
: '是否将该笔采购-红冲收票单撤销,将红冲收票单撤销至收票单';
this.$modal.confirm(msg).then(function() {
return revokeReceipt(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("撤销成功");
}).catch(() => {});
}
}
};

View File

@ -53,7 +53,7 @@ public class OmsPayableBillController extends BaseController
@RequiresPermissions("finance:payable:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(@RequestBody OmsPayableBill omsPayableBill)
public TableDataInfo list(OmsPayableBill omsPayableBill)
{
startPage();
List<OmsPayableBill> list = omsPayableBillService.selectOmsPayableBillList(omsPayableBill);

View File

@ -138,7 +138,7 @@ public class OmsPaymentBillController extends BaseController
@ResponseBody
public AjaxResult addSave(@RequestBody OmsPaymentBill omsPaymentBill)
{
omsPaymentBill.setPreResidueAmount(omsPaymentBill.getTotalPriceWithTax());
omsPaymentBill.setPreResidueAmount(null);
return toAjax(omsPaymentBillService.insertOmsPaymentBill(omsPaymentBill));
}

View File

@ -44,7 +44,7 @@ private IOmsFinAttachmentService omsFinAttachmentService;
*
*/
@RequiresPermissions("sip:ticketBill:list")
@GetMapping("/list")
@PostMapping("/list")
public TableDataInfo list(OmsTicketBill omsTicketBill)
{
startPage();
@ -168,11 +168,11 @@ private IOmsFinAttachmentService omsFinAttachmentService;
/**
*
*/
@GetMapping("/applyRefund/{id}")
@PostMapping("/applyRefund")
@ResponseBody
public AjaxResult applyRefund(@PathVariable("id") Long id) {
public AjaxResult applyRefund(@RequestParam("id")OmsTicketBill ticketBill, @RequestParam("file") MultipartFile file) {
try {
return omsTicketBillService.applyRefund(id);
return omsTicketBillService.applyRefund(ticketBill,file);
} catch (Exception e) {
logger.error("申请退款失败", e);
return AjaxResult.error("操作失败:" + e.getMessage());
@ -196,7 +196,26 @@ private IOmsFinAttachmentService omsFinAttachmentService;
// 调用服务层方法处理退回逻辑
return omsTicketBillService.returnTicket(id);
} catch (Exception e) {
logger.error("退回付款单失败", e);
logger.error("退回收票单失败", e);
return AjaxResult.error("操作失败:" + e.getMessage());
}
}
@RequiresPermissions("finance:payment:return")
@Log(title = "撤销", businessType = BusinessType.UPDATE)
@PutMapping("/revoke/{id}")
@ResponseBody
public AjaxResult revokeTicket(@PathVariable("id") Long id)
{
try {
// 验证付款单ID
if (id == null) {
return AjaxResult.error("收票ID不能为空");
}
// 调用服务层方法处理退回逻辑
return omsTicketBillService.revokeTicket(id);
} catch (Exception e) {
logger.error("撤销收票单失败", e);
return AjaxResult.error("操作失败:" + e.getMessage());
}
}

View File

@ -170,6 +170,7 @@ public class OmsPaymentBill extends BaseEntity
WAIT_PAYMENT("1", "未付款"),
/** 预付单 */
PAYMENT("2", "已付款"),
WAIT_REFUNDED("3", "未退款"),

View File

@ -115,6 +115,8 @@ public class OmsTicketBill extends BaseEntity
private String processKey;
private String todoId;
private String taskId;
private String projectName;
private String projectCode;
public BigDecimal getTaxAmount() {
if (null != totalPriceWithTax && null != totalPriceWithoutTax){
@ -157,6 +159,7 @@ public class OmsTicketBill extends BaseEntity
WAIT_TICKET("1", "未收票"),
/** 预付单 */
TICKET("2", "已收票"),
WAIT_RED_RUSH("3", "未红冲"),

View File

@ -17,9 +17,12 @@ public interface OmsPayablePaymentDetailMapper {
List<OmsPayablePaymentDetail> selectByPaymentPlanIds(@Param("paymentPlanIds") List<Long> paymentPlanIds);
int clearWriteOffByWriteOffId(@Param("ids") Long[] ids);
int clearWriteOffByWriteOffId(Long[] ids);
List<PaymentBillPayableDetailDTO> listPayableByWriteOffId(List<Long> writeOffIds);
void updateBatch(List<OmsPayablePaymentDetail> updateList);
void deleteByPaymentCode(String payableBillCode);
}

View File

@ -77,4 +77,5 @@ public interface OmsPayableTicketDetailMapper
void updateBatch(List<OmsPayableTicketDetail> updateList);
void deleteByTicketBillCode(String ticketBillCode);
}

View File

@ -70,4 +70,6 @@ public interface OmsTicketBillMapper
void updateReturnWriteOffBatch(List<OmsTicketBill> updateBills);
void revokeTicket(OmsTicketBill updateBill);
}

View File

@ -77,7 +77,7 @@ public interface IOmsFinAttachmentService
List<OmsFinAttachment> list(List<Long> ids, String type);
void deleteOmsFinAttachmentByPayment(List<Long> relatedIdList,String type);
void deleteOmsFinAttachment(List<Long> relatedIdList, String type);
void deleteOmsFinAttachmentByRelationId(Long id);

View File

@ -27,6 +27,9 @@ public interface IOmsPayablePaymentDetailService {
void updateBatch(List<OmsPayablePaymentDetail> updateList);
void deleteByPaymentCode(String payableBillCode);
// List<OmsPayableWriteOffDetail> listWriteOffByPaymentCode(List<String> );
}

View File

@ -82,4 +82,6 @@ public interface IOmsPayableTicketDetailService
void insertBatch(List<OmsPayableTicketDetail> detailList);
void updateBatch(List<OmsPayableTicketDetail> updateList);
void deleteByTicketBillCode(String ticketBillCode);
}

View File

@ -65,7 +65,7 @@ public interface IOmsTicketBillService
AjaxResult uploadReceipt(OmsTicketBill attachment, MultipartFile file) throws Exception;
AjaxResult applyRefund(Long id);
AjaxResult applyRefund(OmsTicketBill ticketBill, MultipartFile file);
AjaxResult returnTicket(Long id);
@ -76,4 +76,7 @@ public interface IOmsTicketBillService
OmsTicketBill selectOmsTicketBillByCode(String ticketBillCode);
void returnTicketWriteOff(List<String> collect, List<OmsPayableTicketDetail> omsPayableTicketDetails);
AjaxResult revokeTicket(Long id);
}

View File

@ -55,7 +55,7 @@ public class OmsFinAttachmentServiceImpl implements IOmsFinAttachmentService
}
@Override
public void deleteOmsFinAttachmentByPayment(List<Long> relatedIdList,String type) {
public void deleteOmsFinAttachment(List<Long> relatedIdList, String type) {
omsFinAttachmentMapper.deleteOmsFinAttachmentByPayment(relatedIdList,type);
}

View File

@ -510,7 +510,7 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo
}
if (CollUtil.isNotEmpty(updateBills)) {
omsInvoiceBillMapper.updateReturnWriteOffBatch(updateBills);
omsFinAttachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsInvoiceBill::getId).collect(Collectors.toList()),
omsFinAttachmentService.deleteOmsFinAttachment(updateBills.stream().map(OmsInvoiceBill::getId).collect(Collectors.toList()),
OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE.getCode());
}
//清理detail数据

View File

@ -212,8 +212,10 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
return 0;
}
// Fetch bills once
Date minPaymentDate = DateUtils.getNowDate();
for (PayableOrderDto order : dto.getPayableOrders()) {
for (OmsPayablePaymentPlan plan : order.getPaymentPlans()) {
minPaymentDate = minPaymentDate.after(plan.getPlanPaymentDate()) ? plan.getPlanPaymentDate() : minPaymentDate;
// 计算每个 plan 的未税金额 = planAmount / (1 + 税率),保留两位小数
BigDecimal taxRate = order.getTaxRate();
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
@ -232,7 +234,7 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
OmsPayableBill firstPayableBill = omsPayableBillMapper.selectOmsPayableBillById(dto.getPayableOrders().get(0).getId());
paymentBill.setPaymentBillType(dto.getPaymentBillType());
paymentBill.setVendorCode(firstPayableBill.getVendorCode());
paymentBill.setPaymentTime(dto.getEstimatedPaymentTime());
paymentBill.setPaymentTime(dto.getEstimatedPaymentTime()==null?minPaymentDate:dto.getEstimatedPaymentTime());
paymentBill.setTotalPriceWithTax(dto.getTotalMergePaymentAmount());
// Set Calculated Tax Info
@ -266,6 +268,11 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
// 遍历所有计划并检查是否有已付款的记录
for (PayableOrderDto payableOrderDto : dto.getPayableOrders()) {
BigDecimal taxRate = payableOrderDto.getTaxRate();
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
// 如果税率为空或小于0则默认为0
taxRate = new BigDecimal(defaultTax);
}
for (OmsPayablePaymentPlan paymentPlanDto : payableOrderDto.getPaymentPlans()) {
// 检查是否存在已付款的记录
OmsPayablePaymentDetail existingDetail = existingDetailsMap.get(paymentPlanDto.getId());
@ -281,7 +288,7 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
detail.setPaymentPlanId(paymentPlanDto.getId());
detail.setPaymentBillCode(paymentBill.getPaymentBillCode());
detail.setPaymentAmount(paymentPlanDto.getPlanAmount());
detail.setPaymentAmountWithoutTax(paymentPlanDto.getPlanAmount().divide(BigDecimal.ONE.add(paymentPlanDto.getPlanRate()), 2, java.math.RoundingMode.HALF_UP));
detail.setPaymentAmountWithoutTax(paymentPlanDto.getPlanAmount().divide(BigDecimal.ONE.add(taxRate), 2, java.math.RoundingMode.HALF_UP));
detail.setPaymentAmountTax(detail.getPaymentAmount().subtract(detail.getPaymentAmountWithoutTax()));
detail.setPaymentRate(paymentPlanDto.getPlanRate());
detail.setPaymentTime(paymentPlanDto.getPlanPaymentDate());
@ -311,11 +318,12 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
}
Date minTicketDate = DateUtils.getNowDate();
// Fetch bills once
for (PayableOrderReceiptDto order : dto.getPayableOrders()) {
for (OmsPayableTicketPlan plan : order.getTicketPlans()) {
minTicketDate = minTicketDate.after(plan.getPlanTicketDate()) ? plan.getPlanTicketDate() : minTicketDate;
// 计算每个 plan 的未税金额 = planAmount / (1 + 税率),保留两位小数
BigDecimal taxRate = order.getTaxRate();
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
@ -332,11 +340,12 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
// 2. 创建收票单
OmsTicketBill ticketBill = new OmsTicketBill();
OmsPayableBill firstPayableBill = omsPayableBillMapper.selectOmsPayableBillById(dto.getPayableOrders().get(0).getId());
ticketBill.setTicketBillType(dto.getTicketBillType());
ticketBill.setVendorTicketTime(dto.getVendorTicketTime());
ticketBill.setVendorCode(firstPayableBill.getVendorCode());
ticketBill.setVendorName(firstPayableBill.getVendorName());
ticketBill.setTicketTime(dto.getTicketTime());
ticketBill.setTicketTime(dto.getTicketTime()==null?minTicketDate:dto.getTicketTime());
ticketBill.setTotalPriceWithTax(dto.getTotalMergeTicketAmount());
// Set Calculated Tax Info
@ -462,6 +471,10 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
.subtract(paidAmount)
.subtract(waitPayAmount)
);
}else{
payableBill.setPaidPaymentAmount(BigDecimal.ZERO);
payableBill.setUnpaidPaymentAmount(payableBill.getTotalPriceWithTax() );
}
// 5. 获取首个未支付计划
@ -522,13 +535,17 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
amountMap.getOrDefault(
OmsTicketBill.TicketStatusEnum.WAIT_TICKET.getCode(), BigDecimal.ZERO);
payableBill.setPaidPaymentAmount(paidAmount);
payableBill.setReceivedTicketAmount(paidAmount);
payableBill.setUnpaidPaymentAmount(
payableBill.setUnreceivedTicketAmount(
payableBill.getTotalPriceWithTax()
.subtract(paidAmount)
.subtract(waitPayAmount)
);
}else{
payableBill.setUnreceivedTicketAmount( payableBill.getTotalPriceWithTax());
payableBill.setReceivedTicketAmount(BigDecimal.ZERO);
}
OmsPayableTicketPlan omsPayableTicketPlan = omsPayableTicketPlanMapper.firstUnPayPlan(payableBill.getId());
payableBill.setLastTicketPlanId(omsPayableTicketPlan == null ? -1 : omsPayableTicketPlan.getId());

View File

@ -153,4 +153,9 @@ public class OmsPayablePaymentDetailServiceImpl implements IOmsPayablePaymentDet
public void updateBatch(List<OmsPayablePaymentDetail> updateList) {
omsPayablePaymentDetailMapper.updateBatch(updateList);
}
@Override
public void deleteByPaymentCode(String payableBillCode) {
omsPayablePaymentDetailMapper.deleteByPaymentCode(payableBillCode);
}
}

View File

@ -123,7 +123,7 @@ public class OmsPayablePaymentPlanServiceImpl implements IOmsPayablePaymentPlanS
}
}
if (!found) {
throw new ServiceException("因付款计划表与开票计划表中已付款/开票数据已不一致,所以无法关联开票计划");
throw new ServiceException("温馨提示:该操作无法完成,因为付款计划与开票计划中的累计金额信息已存在差异,系统无法在数据不一致的情况下建立关联。");
}
}

View File

@ -215,4 +215,9 @@ public class OmsPayableTicketDetailServiceImpl implements IOmsPayableTicketDetai
public void updateBatch(List<OmsPayableTicketDetail> updateList) {
omsPayableTicketDetailMapper.updateBatch(updateList);
}
@Override
public void deleteByTicketBillCode(String ticketBillCode) {
omsPayableTicketDetailMapper.deleteByTicketBillCode(ticketBillCode);
}
}

View File

@ -107,6 +107,9 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
omsPaymentBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
omsPaymentBill.setPaymentBillCode(generatePaymentBillCode());
omsPaymentBill.setCreateTime(DateUtils.getNowDate());
if (omsPaymentBill.getPaymentTime() == null) {
omsPaymentBill.setPaymentTime(DateUtils.getNowDate());
}
return omsPaymentBillMapper.insertOmsPaymentBill(omsPaymentBill);
}
@ -462,8 +465,24 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
@Override
public AjaxResult revoke(OmsPaymentBill paymentBill) {
paymentBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
omsPaymentBillMapper.revoke(paymentBill);
OmsPaymentBill existBill = selectOmsPaymentBillById(paymentBill.getId());
if (existBill == null){
return AjaxResult.error("付款单不存在,请刷新后重试");
}
if (OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode().equals(existBill.getPaymentBillType())){
// 撤销退款单
deleteOmsPaymentBillById(existBill.getId());
detailService.deleteByPaymentCode(existBill.getPayableBillCode());
OmsPaymentBill omsPaymentBill = new OmsPaymentBill();
omsPaymentBill.setId(existBill.getOriginalBillId());
omsPaymentBill.setRefundStatus(OmsPaymentBill.RefundStatusEnum.WAIT_REFUNDED.getCode());
updateOmsPaymentBill(omsPaymentBill);
}else{
// 撤销付款单
paymentBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
omsPaymentBillMapper.revoke(paymentBill);
}
return AjaxResult.success("撤销成功");
}
@ -587,7 +606,7 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
}
if (CollUtil.isNotEmpty(updateBills)) {
omsPaymentBillMapper.updateReturnWriteOffBatch(updateBills);
omsFinAttachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsPaymentBill::getId).collect(Collectors.toList()), OmsFinAttachment.RelatedBillTypeEnum.PAYMENT.getCode());
omsFinAttachmentService.deleteOmsFinAttachment(updateBills.stream().map(OmsPaymentBill::getId).collect(Collectors.toList()), OmsFinAttachment.RelatedBillTypeEnum.PAYMENT.getCode());
}
}

View File

@ -3,7 +3,6 @@ package com.ruoyi.sip.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
@ -13,7 +12,6 @@ import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
import com.ruoyi.sip.dto.WriteOffRequestDto;
import com.ruoyi.sip.mapper.OmsReceiptBillMapper;
import com.ruoyi.sip.service.*;
import org.springframework.beans.factory.annotation.Autowired;
@ -391,7 +389,7 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
}
if (CollUtil.isNotEmpty(updateBills)) {
omsReceiptBillMapper.updateReturnWriteOffBatch(updateBills);
attachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsReceiptBill::getId).collect(Collectors.toList()), OmsFinAttachment.RelatedBillTypeEnum.PAYMENT.getCode());
attachmentService.deleteOmsFinAttachment(updateBills.stream().map(OmsReceiptBill::getId).collect(Collectors.toList()), OmsFinAttachment.RelatedBillTypeEnum.PAYMENT.getCode());
}
omsReceivableReceiptDetailService.clearWriteOffByWriteOffId(writeOffIdList);
}

View File

@ -1,6 +1,5 @@
package com.ruoyi.sip.service.impl;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@ -211,9 +210,9 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService, TodoComm
}
@Override
public AjaxResult applyRefund(Long originalId) {
public AjaxResult applyRefund(OmsTicketBill ticketBill, MultipartFile file) {
// 1. 验证原始付款单
OmsTicketBill originalBill = selectOmsTicketBillById(originalId);
OmsTicketBill originalBill = selectOmsTicketBillById(ticketBill.getOriginalBillId());
if (originalBill == null) {
return AjaxResult.error("原始付款单不存在");
}
@ -241,7 +240,10 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService, TodoComm
refundBill.setTicketBillType(OmsTicketBill.TicketBillTypeEnum.RED_RUSH.getCode());
refundBill.setTicketStatus(OmsTicketBill.TicketStatusEnum.TICKET.getCode());
refundBill.setRefundStatus(OmsTicketBill.RefundStatusEnum.REFUNDED.getCode());
refundBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
refundBill.setApproveStatus(ApproveStatusEnum.WAIT_APPROVE.getCode());
refundBill.setTicketPriceWithoutTax(ticketBill.getTicketPriceWithoutTax());
refundBill.setTicketPriceWithTax(ticketBill.getTicketPriceWithTax());
refundBill.setTicketAmount(ticketBill.getTaxAmount());
refundBill.setOriginalBillId(originalBill.getId());
refundBill.setActualTicketTime(null);
refundBill.setApproveTime(null);
@ -256,6 +258,13 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService, TodoComm
//4 创建付款明细
payableTicketDetailService.applyRefund(originalBill.getTicketBillCode(),refundBill.getTicketBillCode());
//上传文件 再开启流程
try {
omsFinAttachmentService.uploadAttachment(file, refundBill.getId(), OmsFinAttachment.RelatedBillTypeEnum.INVOICE);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return AjaxResult.success("退款申请已提交,新的退款单号为:" + refundBill.getTicketBillCode());
}
@ -381,13 +390,41 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService, TodoComm
}
if (CollUtil.isNotEmpty(updateBills)) {
omsTicketBillMapper.updateReturnWriteOffBatch(updateBills);
omsFinAttachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsTicketBill::getId).collect(Collectors.toList()),
omsFinAttachmentService.deleteOmsFinAttachment(updateBills.stream().map(OmsTicketBill::getId).collect(Collectors.toList()),
OmsFinAttachment.RelatedBillTypeEnum.INVOICE.getCode());
}
}
}
@Override
public AjaxResult revokeTicket(Long id) {
OmsTicketBill existBill = selectOmsTicketBillById(id);
if (!existBill.getApproveStatus().equals(ApproveStatusEnum.APPROVE_REJECT.getCode())) {
return AjaxResult.error("退回收票单操作失败:该收票单不处于审批驳回状态");
}
if (existBill.getTicketBillType().equals(OmsTicketBill.TicketBillTypeEnum.FROM_PAYABLE.getCode())) {
//1:修改状态
OmsTicketBill updateBill = new OmsTicketBill();
updateBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
updateBill.setId(existBill.getId());
omsTicketBillMapper.revokeTicket(updateBill);
//2:删除对应的文件
omsFinAttachmentService.deleteOmsFinAttachment(Collections.singletonList(existBill.getId()), OmsFinAttachment.RelatedBillTypeEnum.INVOICE.getCode());
} else {
//红冲撤销
deleteOmsTicketBillById(id);
payableTicketDetailService.deleteByTicketBillCode(existBill.getTicketBillCode());
OmsTicketBill ticketBill = new OmsTicketBill();
ticketBill.setId(existBill.getOriginalBillId());
ticketBill.setRefundStatus(OmsTicketBill.RefundStatusEnum.WAIT_REFUNDED.getCode());
updateOmsTicketBill(ticketBill);
}
return null;
}
@Override
public Object todoDetail(String businessKey, String processKey, String todoId) {

View File

@ -119,7 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="unpaidPaymentAmount != null ">
<choose>
<when test="unpaidPaymentAmount==-1">
and t1.unpaid_payment_amount != 0
and t1.unpaid_payment_amount > 0
</when>
<otherwise>
@ -131,7 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="unreceivedTicketAmount != null ">
<choose>
<when test="unreceivedTicketAmount==-1">
and t1.unreceived_ticket_amount != 0
and t1.unreceived_ticket_amount > 0
</when>
<otherwise>
@ -158,19 +158,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</choose>
</if>
<if test="planPaymentDateStart != null or planPaymentDateEnd != null">
<if test="estimatedPaymentTimeStart != null or estimatedPaymentTimeEnd != null">
<choose>
<when test="planPaymentDateStart != null and planPaymentDateEnd != null">
and ppp.plan_payment_date between date_format(#{planPaymentDateStart}, '%Y-%m-%d 00:00:00') and
date_format(#{planPaymentDateEnd}, '%Y-%m-%d 23:59:59')
<when test="estimatedPaymentTimeStart != null and estimatedPaymentTimeEnd != null">
and ppp.plan_payment_date between #{estimatedPaymentTimeStart} and #{estimatedPaymentTimeEnd}
</when>
<when test="planPaymentDateStart != null">
and ppp.plan_payment_date <![CDATA[ >= ]]> date_format(#{planPaymentDateStart}, '%Y-%m-%d
00:00:00')
<when test="estimatedPaymentTimeStart != null">
and ppp.plan_payment_date <![CDATA[ >= ]]> #{estimatedPaymentTimeStart}
</when>
<when test="planPaymentDateEnd != null">
and ppp.plan_payment_date <![CDATA[ <= ]]> date_format(#{planPaymentDateEnd}, '%Y-%m-%d
23:59:59')
<when test="estimatedPaymentTimeEnd != null">
and ppp.plan_payment_date <![CDATA[ <= ]]> #{estimatedPaymentTimeEnd}
</when>
</choose>
</if>

View File

@ -75,6 +75,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{item.id}
</foreach>
</update>
<delete id="deleteByPaymentCode">
delete from oms_payable_payment_detail where payment_bill_code = #{paymentBillCode}
</delete>
<select id="list" resultType="com.ruoyi.sip.domain.OmsPayablePaymentDetail">
SELECT
@ -122,8 +125,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select t1.payment_amount, t2.payable_bill_code, t4.project_name, t4.project_code, t2.total_price_with_tax
from (SELECT sum(payment_amount) payment_amount,
payable_bill_id
FROM oms_payable_payment_detail
WHERE write_off_id is null and payment_bill_code in
FROM oms_payable_payment_detail t1
left join oms_payable_write_off t2 on t1.write_off_id=t2.id
WHERE (t1.write_off_id is null or t1.payment_bill_code=t2.payment_bill_code) and t1.payment_bill_code in
<foreach item="item" collection="list" separator="," open="(" close=")" index="">
#{item}
</foreach>

View File

@ -125,8 +125,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paymentTime != null ">and date_format(pb.payment_time,'%Y-%m-%d') =
date_format(#{paymentTime},'%Y-%m-%d')
</if>
<if test="vendorCode != null and vendorCode != ''">and pb.vendor_code like concat('%', #{vendorCode},
'%')
<if test="vendorCode != null and vendorCode != ''">and pb.vendor_code = #{vendorCode}
</if>
<if test="vendorName != null and vendorName != ''">
and ovi.vendor_name like concat('%', #{vendorName}, '%')
</if>
<if test="orderCode != null and orderCode != ''">and pb.order_code like concat('%', #{orderCode}, '%')</if>
<if test="totalPriceWithTax != null ">and pb.total_price_with_tax = #{totalPriceWithTax}</if>
@ -144,12 +146,63 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="approveTime != null ">and date_format(pb.approve_time,'%Y-%m-%d') =
date_format(#{approveTime},'%Y-%m-%d')
</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!='')">
and pb.approve_time between #{params.beginApproveTime} and #{params.endApproveTime}
</when>
<when test="(params.beginApproveTime != null and params.beginApproveTime != '')">
and pb.approve_time <![CDATA[ >= ]]> #{params.beginApproveTime}
</when>
<when test="(params.endApproveTime != null and params.endApproveTime!='')">
and pb.approve_time <![CDATA[ <= ]]> #{params.endApproveTime}
</when>
</choose>
</if>
<if test="(params.beginPaymentTime != null and params.beginPaymentTime != '') or (params.endPaymentTime != null and params.endPaymentTime!='')">
<choose>
<when test="(params.beginPaymentTime != null and params.beginPaymentTime != '') and (params.endPaymentTime != null and params.endPaymentTime!='')">
and pb.payment_time between #{params.beginPaymentTime} and #{params.endPaymentTime}
</when>
<when test="(params.beginPaymentTime != null and params.beginPaymentTime != '')">
and pb.payment_time <![CDATA[ >= ]]> #{params.beginPaymentTime}
</when>
<when test="(params.endPaymentTime != null and params.endPaymentTime!='')">
and pb.payment_time <![CDATA[ <= ]]> #{params.endPaymentTime}
</when>
</choose>
</if>
<if test="(params.beginActualPaymentTime != null and params.beginActualPaymentTime != '') or (params.endActualPaymentTime != null and params.endActualPaymentTime!='')">
<choose>
<when test="(params.beginActualPaymentTime != null and params.beginActualPaymentTime != '') and (params.endActualPaymentTime != null and params.endActualPaymentTime!='')">
and pb.actual_payment_time between #{params.beginActualPaymentTime } and #{params.endActualPaymentTime}
</when>
<when test="(params.beginActualPaymentTime != null and params.beginActualPaymentTime != '')">
and pb.actual_payment_time <![CDATA[ >= ]]> #{params.beginActualPaymentTime }
</when>
<when test="(params.endActualPaymentTime != null and params.endActualPaymentTime!='')">
and pb.actual_payment_time <![CDATA[ <= ]]> #{params.endActualPaymentTime}
</when>
</choose>
</if>
<if test="actualPaymentTime != null ">and date_format(pb.actual_payment_time,'%Y-%m-%d') =
date_format(#{actualPaymentTime},'%Y-%m-%d')
</if>
<if test="paymentMethod != null and paymentMethod != ''">and pb.payment_method = #{paymentMethod}</if>
<if test="payableBillCode != null and payableBillCode != ''">and apb.payable_bill_code like concat('%',
#{payableBillCode}, '%')
<if test="approveNode != null and approveNode != ''">and pb.payment_bill_code in
(
select business_key from bu_todo where approve_user_name like concat('%', #{approveNode}, '%') and process_key in (
'finance_payment','finance_refund')
)
</if>
<if test="payableBillCode != null and payableBillCode != ''">and pb.payment_bill_code in (
select payment_bill_code from oms_payable_payment_detail t1 left join oms_payable_bill t2 on
t1.payable_bill_id=t2.id
where t2.payable_bill_code=#{payableBillCode}
)
</if>
<if test="preResidueAmount != null and preResidueAmount != ''">
<choose>

View File

@ -337,5 +337,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</delete>
<delete id="deleteByTicketBillCode">
delete from oms_payable_ticket_detail where ticket_bill_code = #{code}
</delete>
</mapper>

View File

@ -43,6 +43,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="ticketBillCode != null and ticketBillCode != ''">
and ticket_bill_code = #{ticketBillCode}
</if>
<if test="projectCode != null and projectCode != ''">
and t1.ticket_bill_code in (
select t1.ticket_bill_code from oms_payable_ticket_detail t1
inner join oms_payable_bill t2 on t1.payable_bill_id=t2.id
inner join project_order_info t3 on t2.order_code=t3.order_code
inner join project_info t4 on t3.project_id=t4.id
where t4.project_code = #{projectCode}
)
</if>
<if test="projectName != null and projectName != ''">
and t1.ticket_bill_code in (
select t1.ticket_bill_code from oms_payable_ticket_detail t1
inner join oms_payable_bill t2 on t1.payable_bill_id=t2.id
inner join project_order_info t3 on t2.order_code=t3.order_code
inner join project_info t4 on t3.project_id=t4.id
where t4.project_name = #{projectName}
)
</if>
<if test="ticketBillCodeList != null and ticketBillCodeList.size>0">
and ticket_bill_code in <foreach item="item" collection="ticketBillCodeList" separator="," open="(" close=")" index="">
@ -404,6 +422,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{item.id}
</foreach>
</update>
<update id="revokeTicket">
update oms_ticket_bill
set approve_status =#{approveStatus},
ticket_price_with_tax=null,
ticket_price_without_tax=null,
total_price_with_tax=null
where id = #{id}
</update>
<delete id="deleteOmsTicketBillById" parameterType="Long">
delete from oms_ticket_bill where id = #{id}