feat(finance): 新增收款单管理功能
- 新增收款单新增表单页面,支持预收和应收两种类型 - 实现收款单详情查看抽屉组件 - 添加收款单列表查询、筛选和分页功能 - 集成收款单新增、提交、退回和红冲操作 - 支持收款计划选择和金额计算逻辑 - 完善收款单据关联数据展示和处理 - 提供收款单附件管理和审批状态跟踪 - 增加代理商选择器和订单数据联动加载 - 实现收款单据类型和状态字典显示 - 添加收款单据验证规则和提交前检查dev_1.0.1
parent
1d85e92997
commit
c257cdc5cd
|
|
@ -0,0 +1,75 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import {tansParams} from "@/utils/ruoyi"
|
||||||
|
|
||||||
|
// 查询收款单列表
|
||||||
|
export function listReceive(query) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/list',
|
||||||
|
method: 'get',
|
||||||
|
data: tansParams(query)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询收款单详细
|
||||||
|
export function getReceive(id) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询收款单附件
|
||||||
|
export function getReceiveAttachments(id, params) {
|
||||||
|
return request({
|
||||||
|
url: `/finance/receipt/attachment/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传收款单附件
|
||||||
|
export function uploadReceiveAttachment(data) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/uploadReceipt',
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
needLoading: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 申请红冲
|
||||||
|
export function redRush(id) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/applyRefund/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退回收款单
|
||||||
|
export function returnReceive(id) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/returnReceivable/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增收款单 (Calls Receivable Merge Logic)
|
||||||
|
export function mergeReceivable(data) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receivable/mergeAndInitiateReceipt',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
needLoading: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function addReceipt(data) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/receipt/insert',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
needLoading: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import html2canvas from 'html2canvas';
|
||||||
|
import jsPDF from 'jspdf';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出指定DOM元素为PDF
|
||||||
|
* @param {HTMLElement} element - 要导出的DOM元素
|
||||||
|
* @param {string} fileName - 导出的文件名
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function exportElementToPDF(element, fileName) {
|
||||||
|
const disabledElements = [];
|
||||||
|
try {
|
||||||
|
// 移除所有输入框的 disabled 属性,以便在PDF中正确显示
|
||||||
|
element.querySelectorAll('input:disabled, textarea:disabled').forEach(el => {
|
||||||
|
disabledElements.push(el);
|
||||||
|
el.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用html2canvas捕获内容
|
||||||
|
const canvas = await html2canvas(element, {
|
||||||
|
scale: 2, // 提高清晰度
|
||||||
|
useCORS: true, // 允许跨域图片
|
||||||
|
logging: false, // 关闭日志
|
||||||
|
backgroundColor: '#F8F5F0' // 设置背景色
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算PDF页面尺寸
|
||||||
|
const imgWidth = 210; // A4纸宽度(mm)
|
||||||
|
const pageHeight = 297; // A4纸高度(mm)
|
||||||
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||||
|
let heightLeft = imgHeight;
|
||||||
|
|
||||||
|
// 创建PDF
|
||||||
|
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||||
|
let position = 0;
|
||||||
|
|
||||||
|
// 将canvas转换为图片
|
||||||
|
const imgData = canvas.toDataURL('image/jpeg');
|
||||||
|
|
||||||
|
// 添加第一页
|
||||||
|
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||||
|
heightLeft -= pageHeight;
|
||||||
|
|
||||||
|
// 如果内容超过一页,添加更多页
|
||||||
|
while (heightLeft > 0) {
|
||||||
|
position = heightLeft - imgHeight;
|
||||||
|
pdf.addPage();
|
||||||
|
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||||
|
heightLeft -= pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存PDF
|
||||||
|
pdf.save(fileName);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('PDF导出失败:', error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
// 恢复之前移除的 disabled 属性
|
||||||
|
disabledElements.forEach(el => {
|
||||||
|
el.disabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,482 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog title="新增收款单" :visible.sync="internalVisible" width="1200px" @close="handleClose"
|
||||||
|
:close-on-click-modal="false" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="代理商" prop="partnerName">
|
||||||
|
<el-input v-model="form.partnerName" placeholder="请选择代理商" readonly @click.native="showPartnerSelector = true">
|
||||||
|
<el-button slot="append" icon="el-icon-search" @click="showPartnerSelector = true"></el-button>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="是否预收" prop="receiveBillType">
|
||||||
|
<el-radio-group v-model="form.receiveBillType">
|
||||||
|
<el-radio label="PRE_RECEIPT">是</el-radio>
|
||||||
|
<el-radio label="FROM_RECEIVABLE">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="预计收款时间" prop="receiptTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.receiptTime"
|
||||||
|
type="date"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="选择日期"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row v-if="form.receiveBillType === 'PRE_RECEIPT'">
|
||||||
|
<el-col :span="12">
|
||||||
|
<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>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- Tables -->
|
||||||
|
<div>
|
||||||
|
<div v-if="form.receiveBillType === 'FROM_RECEIVABLE' && form.partnerCode" class="table-container">
|
||||||
|
<h4>应收单列表</h4>
|
||||||
|
<el-table
|
||||||
|
ref="receivableTable"
|
||||||
|
:data="receivableList"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
max-height="400"
|
||||||
|
row-key="id"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
|
||||||
|
<el-table-column label="应收单编号" align="center" prop="receivableBillCode" width="150"/>
|
||||||
|
<el-table-column label="预计收款时间" align="center" prop="planReceiptDate" width="180"/>
|
||||||
|
<el-table-column label="收款计划" align="center" width="100" prop="planAmount">
|
||||||
|
</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="collectionStatus" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.collection_status" :value="scope.row.collectionStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
|
||||||
|
<el-table-column label="未收款金额" align="center" prop="unreceivedAmount" width="120"/>
|
||||||
|
<el-table-column label="本次收款金额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ calculateOrderCurrentReceiptAmount(scope.row).toFixed(2) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="本次收款比例" align="center" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ calculateOrderCurrentReceiptRate(scope.row) }}%
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="已收款金额" align="center" prop="receivedAmount" width="120"/>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100"
|
||||||
|
fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleOpenReceiptPlanSelector(scope.row, scope.$index)"
|
||||||
|
>选择
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="total-info">
|
||||||
|
|
||||||
|
<span style="margin-left: 20px;">计划收款总金额: <el-tag type="success">{{
|
||||||
|
totalPlannedAmount.toFixed(2)
|
||||||
|
}}</el-tag></span>
|
||||||
|
<span>计划收款比例: <el-tag type="info">{{ totalSelectedReceivableAmount ? this.$calc.mul(this.$calc.div(totalPlannedAmount,totalSelectedReceivableAmount,4),100) : 0 }}%</el-tag></span>
|
||||||
|
</div>
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="loadTableData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="form.receiveBillType === 'PRE_RECEIPT' && form.partnerCode" class="table-container">
|
||||||
|
<h4>订单列表</h4>
|
||||||
|
<el-table
|
||||||
|
ref="orderTable"
|
||||||
|
:data="orderList"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@select="handleSelect"
|
||||||
|
@select-all="handleSelectAll"
|
||||||
|
max-height="400"
|
||||||
|
row-key="id"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
|
||||||
|
<el-table-column prop="projectCode" label="项目编号"></el-table-column>
|
||||||
|
<el-table-column prop="projectName" label="项目名称"></el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="下单时间"></el-table-column>
|
||||||
|
<el-table-column label="订单状态" prop="orderStatus">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.order_status" :value="scope.row.orderStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="loadTableData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!form.partnerCode" style="text-align: center; color: #909399; padding: 20px;">
|
||||||
|
请先选择代理商
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Receipt Plan Selector Dialog -->
|
||||||
|
<el-dialog :title="planTitle" :visible.sync="isReceiptPlanSelectorOpen" width="70%"
|
||||||
|
@close="isReceiptPlanSelectorOpen=false" append-to-body>
|
||||||
|
<receipt-plan
|
||||||
|
ref="planSelector"
|
||||||
|
:receivable-data="chooseReceivable"
|
||||||
|
:selected-plans="chooseReceivable.receiptPlans"
|
||||||
|
/>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="isReceiptPlanSelectorOpen=false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleChooseConfirm">保 存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<select-partner :visible.sync="showPartnerSelector" @partner-selected="handlePartnerSelected" />
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {listReceivable} from "@/api/finance/receivable";
|
||||||
|
import {listOrder} from "@/api/project/order";
|
||||||
|
import ReceiptPlan from "@/views/finance/receivable/components/ReceiptPlan.vue";
|
||||||
|
import SelectPartner from "@/views/system/partner/selectPartner.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AddForm",
|
||||||
|
components: {ReceiptPlan, SelectPartner},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dicts: ['order_status', 'receive_status', 'collection_status'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
internalVisible: this.visible,
|
||||||
|
receivableList: [], // List for Standard/Receivable Bills
|
||||||
|
orderList: [], // List for Pre-receipt/Sales Orders
|
||||||
|
selectedRows: [],
|
||||||
|
total: 0,
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
receiveBillType: 'FROM_RECEIVABLE',
|
||||||
|
partnerName: null,
|
||||||
|
partnerCode: null,
|
||||||
|
remark: null,
|
||||||
|
totalPriceWithTax: 0,
|
||||||
|
actualReceiveTime: null
|
||||||
|
},
|
||||||
|
showPartnerSelector: false,
|
||||||
|
rules: {
|
||||||
|
partnerName: [{required: true, message: "代理商不能为空", trigger: "change"}],
|
||||||
|
actualReceiveTime: [{required: true, message: "实际收款时间不能为空", trigger: "change"}],
|
||||||
|
receiveBillType: [{required: true, message: "请选择是否预收", trigger: "change"}],
|
||||||
|
totalPriceWithTax: [{required: false, message: "预收金额不能为空", trigger: "blur"}]
|
||||||
|
},
|
||||||
|
// Plan Selector Data
|
||||||
|
planTitle: '',
|
||||||
|
isReceiptPlanSelectorOpen: false,
|
||||||
|
chooseReceivable: {},
|
||||||
|
currentReceivableOrderIndexForPlan: -1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
totalPlannedAmount() {
|
||||||
|
if (this.form.receiveBillType === 'FROM_RECEIVABLE') {
|
||||||
|
// Calculate based on selected rows and their plans/defaults
|
||||||
|
return this.selectedRows.reduce((sum, row) => {
|
||||||
|
return sum + this.calculateOrderCurrentReceiptAmount(row);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
totalSelectedReceivableAmount() {
|
||||||
|
if (this.form.receiveBillType === 'FROM_RECEIVABLE') {
|
||||||
|
return this.selectedRows.reduce((sum, row) => {
|
||||||
|
return sum + (row.totalPriceWithTax || 0);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(newVal) {
|
||||||
|
this.internalVisible = newVal;
|
||||||
|
if (newVal) {
|
||||||
|
this.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
internalVisible(newVal) {
|
||||||
|
this.$emit("update:visible", newVal);
|
||||||
|
},
|
||||||
|
'form.receiveBillType': function (val) {
|
||||||
|
// Toggle validation for Pre-receipt Amount
|
||||||
|
if (val === 'PRE_RECEIPT') {
|
||||||
|
this.rules.totalPriceWithTax[0].required = true;
|
||||||
|
} else {
|
||||||
|
this.rules.totalPriceWithTax[0].required = false;
|
||||||
|
}
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.selectedRows = [];
|
||||||
|
this.loadTableData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handlePartnerSelected(partner) {
|
||||||
|
this.form.partnerName = partner.partnerName;
|
||||||
|
this.form.partnerCode = partner.partnerCode;
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.selectedRows = [];
|
||||||
|
this.loadTableData();
|
||||||
|
},
|
||||||
|
loadTableData() {
|
||||||
|
this.receivableList = [];
|
||||||
|
this.orderList = [];
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
pageNum: this.queryParams.pageNum,
|
||||||
|
pageSize: this.queryParams.pageSize
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.form.receiveBillType === 'FROM_RECEIVABLE' && this.form.partnerCode) {
|
||||||
|
query.partnerCode = this.form.partnerCode;
|
||||||
|
listReceivable(query).then(res => {
|
||||||
|
this.receivableList = (res.rows || []).map(item => {
|
||||||
|
const receiptPlans = item.receiptPlans ? [...item.receiptPlans] : [];
|
||||||
|
// If needed, add logic to initialize default plan similar to payment
|
||||||
|
if (receiptPlans.length === 0 && item.lastReceiptPlanId) {
|
||||||
|
receiptPlans.push({
|
||||||
|
id: item.lastReceiptPlanId,
|
||||||
|
planAmount: item.planAmount,
|
||||||
|
planReceiptDate: item.planReceiptDate,
|
||||||
|
planRate: this.$calc.mul(this.$calc.div(item.planAmount, item.totalPriceWithTax, 4), 100)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
receiptPlans: receiptPlans,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.total = res.total;
|
||||||
|
});
|
||||||
|
} else if (this.form.receiveBillType === 'PRE_RECEIPT' && this.form.partnerCode) {
|
||||||
|
// Filter Sales Orders for the agent (partner)
|
||||||
|
query.partnerCode = this.form.partnerCode;
|
||||||
|
query.orderStatus = '2'; // Example status
|
||||||
|
listOrder(query).then(res => {
|
||||||
|
this.orderList = res.rows || [];
|
||||||
|
this.total = res.total;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.receivableTable) {
|
||||||
|
this.$refs.receivableTable.clearSelection()
|
||||||
|
}
|
||||||
|
if (this.$refs.orderTable) {
|
||||||
|
this.$refs.orderTable.clearSelection()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSelect(selection, row) {
|
||||||
|
if (this.form.receiveBillType === 'PRE_RECEIPT') {
|
||||||
|
this.$refs.orderTable.clearSelection();
|
||||||
|
const isSelected = selection.some(item => item.id === row.id); // Use ID for uniqueness
|
||||||
|
if (isSelected) {
|
||||||
|
this.$refs.orderTable.toggleRowSelection(row, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectAll(selection) {
|
||||||
|
if (this.form.receiveBillType === 'PRE_RECEIPT') {
|
||||||
|
this.$refs.orderTable.clearSelection();
|
||||||
|
this.$modal.msgWarning("预收单只能选择一个订单");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.selectedRows = selection;
|
||||||
|
},
|
||||||
|
// --- Receipt Plan Logic ---
|
||||||
|
handleOpenReceiptPlanSelector(row, index) {
|
||||||
|
this.planTitle = `选择收款计划 - ${row.receivableBillCode}`;
|
||||||
|
this.chooseReceivable = row;
|
||||||
|
this.currentReceivableOrderIndexForPlan = index;
|
||||||
|
this.isReceiptPlanSelectorOpen = true;
|
||||||
|
},
|
||||||
|
handleChooseConfirm() {
|
||||||
|
if (!this.$refs.planSelector) {
|
||||||
|
this.$modal.msgError('无法获取计划选择器组件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const selectedPlans = this.$refs.planSelector.selectedPlan || [];
|
||||||
|
|
||||||
|
// Update the plans for the specific order
|
||||||
|
if (this.currentReceivableOrderIndexForPlan !== -1) {
|
||||||
|
const row = this.receivableList[this.currentReceivableOrderIndexForPlan];
|
||||||
|
this.$set(row, 'receiptPlans', [...selectedPlans]);
|
||||||
|
}
|
||||||
|
this.isReceiptPlanSelectorOpen = false;
|
||||||
|
this.$modal.msgSuccess(`已更新收款计划选择,共 ${selectedPlans.length} 条`);
|
||||||
|
},
|
||||||
|
calculateOrderCurrentReceiptAmount(order) {
|
||||||
|
if (order && order.receiptPlans && order.receiptPlans.length > 0) {
|
||||||
|
return order.receiptPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
calculateOrderCurrentReceiptRate(order) {
|
||||||
|
if (order && order.receiptPlans && order.receiptPlans.length > 0 && order.totalPriceWithTax) {
|
||||||
|
const currentAmount = this.calculateOrderCurrentReceiptAmount(order);
|
||||||
|
return this.$calc.mul((this.$calc.div(currentAmount, order.totalPriceWithTax, 4)), 100);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClose() {
|
||||||
|
this.internalVisible = false;
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.form.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.form.receiveBillType === 'FROM_RECEIVABLE') {
|
||||||
|
if (this.selectedRows.length === 0) {
|
||||||
|
this.$message.warning("请选择至少一条应收单");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process selected rows
|
||||||
|
const processedReceivableOrders = this.selectedRows.map(order => {
|
||||||
|
let finalPlans = order.receiptPlans;
|
||||||
|
// Add validation if needed: check if plans exist
|
||||||
|
if (!finalPlans || finalPlans.length === 0) {
|
||||||
|
// warning handled in previous logic, maybe add here
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: order.id,
|
||||||
|
receivableBillCode: order.receivableBillCode,
|
||||||
|
taxRate: order.taxRate,
|
||||||
|
// Map plans
|
||||||
|
receiptPlans: (finalPlans || []).map(plan => ({
|
||||||
|
id: plan.id,
|
||||||
|
planReceiptDate: plan.planReceiptDate,
|
||||||
|
planAmount: plan.planAmount,
|
||||||
|
planRate: plan.planRate,
|
||||||
|
remark: plan.remark
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// Ensure every selected order has plans?
|
||||||
|
if (processedReceivableOrders.some(o => o.receiptPlans.length === 0)) {
|
||||||
|
this.$message.warning("选中的应收单必须包含收款计划");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitData = {
|
||||||
|
receiptBillType: 'FROM_RECEIVABLE',
|
||||||
|
receiptTime: this.form.receiptTime,
|
||||||
|
receivableBills: processedReceivableOrders,
|
||||||
|
totalMergeReceiptAmount: this.totalPlannedAmount
|
||||||
|
};
|
||||||
|
this.$emit("submit", submitData);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Pre-receipt logic
|
||||||
|
if (this.selectedRows.length !== 1) {
|
||||||
|
this.$modal.msgWarning("请选择一笔订单");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((this.form.totalPriceWithTax || 0) <= 0) {
|
||||||
|
this.$message.warning("预收金额需要大于0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let order = this.selectedRows[0] ?? {};
|
||||||
|
const submitData = {
|
||||||
|
receiptBillType: 'PRE_RECEIPT',
|
||||||
|
receiptTime: this.form.receiptTime,
|
||||||
|
orderCode: order.orderCode, // Ensure orderCode is available in orderList items
|
||||||
|
partnerCode: this.form.partnerCode,
|
||||||
|
partnerName: this.form.partnerName,
|
||||||
|
projectCode: order.projectCode,
|
||||||
|
projectName: order.projectName,
|
||||||
|
totalPriceWithTax: this.form.totalPriceWithTax
|
||||||
|
};
|
||||||
|
console.log(submitData)
|
||||||
|
this.$emit("submit", submitData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
if (this.$refs.form) {
|
||||||
|
this.$refs.form.resetFields();
|
||||||
|
}
|
||||||
|
this.form = {
|
||||||
|
receiveBillType: 'FROM_RECEIVABLE',
|
||||||
|
partnerName: null,
|
||||||
|
partnerCode: null,
|
||||||
|
remark: null,
|
||||||
|
totalPriceWithTax: 0,
|
||||||
|
actualReceiveTime: null
|
||||||
|
};
|
||||||
|
this.receivableList = [];
|
||||||
|
this.orderList = [];
|
||||||
|
this.selectedRows = [];
|
||||||
|
this.queryParams = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
};
|
||||||
|
this.total = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.table-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
title="收款单详情"
|
||||||
|
:visible.sync="visible"
|
||||||
|
direction="rtl"
|
||||||
|
size="70%"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div class="dialog-body" v-if="detail">
|
||||||
|
<div class="section">
|
||||||
|
<el-divider content-position="left">销售-收款单</el-divider>
|
||||||
|
<div class="details-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">销售-收款单编号: {{ detail.receiptBillCode }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">收款时间: {{ detail.receiptTime }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">进货商名称: {{ detail.partnerName }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">含税总价(元): {{ detail.totalPriceWithTax }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">未税总价(元): {{ detail.totalPriceWithoutTax }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">税额(元): {{ detail.taxAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">收款单类型:
|
||||||
|
<dict-tag :options="dict.type.receipt_bill_type" :value="detail.receiptBillType"/></div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">对方支付方式: {{ detail.receiptMethod|| '-' }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">收款图/回执单:
|
||||||
|
<dict-tag :options="dict.type.approve_status" :value="detail.approveStatus"/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">收款金额:{{detail.totalPriceWithTax}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">备注: {{ detail.remark|| '-' }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">上传人姓名:
|
||||||
|
<dict-tag :options="dict.type.approve_status" :value="detail.approveStatus"/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">账户名称: {{ detail.receiptAccountName }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">银行账号: {{ detail.receiptBankNumber|| '-' }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">银行开户行:{{detail.receiptBankOpenAddress}}
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">银行行号: {{ detail.bankNumber }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">收款状态: <dict-tag :options="dict.type.receipt_bill_status" :value="detail.receiptStatus"/></div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">审批节点: {{ detail.approveNode|| '-' }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">审批状态:
|
||||||
|
<dict-tag :options="dict.type.approve_status" :value="detail.approveStatus"/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item">审批通过时间: {{ detail.approveTime || '-'}}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<el-divider content-position="left">销售-应收单</el-divider>
|
||||||
|
<el-table :data="detail.detailDTOList">
|
||||||
|
<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="receivableBillCode" label="应收单编号"></el-table-column>
|
||||||
|
<el-table-column property="totalPriceWithTax" label="含税总价(元)"></el-table-column>
|
||||||
|
<el-table-column property="receiptAmount" label="本次收款金额"></el-table-column>
|
||||||
|
<el-table-column property="receiptRate" label="本次收款比例(%)"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailDrawer",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
type: Object,
|
||||||
|
default: () => null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dicts:['receive_bill_type','approve_status','receive_status'],
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dialog-body {
|
||||||
|
max-height: calc(100vh - 50px);
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 20px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-container {
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
display: flex;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,486 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog :title="titleText" :visible.sync="dialogVisible" width="900px" @close="handleClose">
|
||||||
|
<div v-if="loading" class="loading-spinner">
|
||||||
|
<i class="el-icon-loading"></i>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-timeline v-if="attachments.length > 0">
|
||||||
|
<el-timeline-item
|
||||||
|
v-for="attachment in attachments"
|
||||||
|
:key="attachment.id"
|
||||||
|
:timestamp="parseTime(attachment.createTime, '{y}-{m}-{d} {h}:{i}:{s}')"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<el-card>
|
||||||
|
<div class="receipt-card-content">
|
||||||
|
<div class="receipt-details">
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="item-label">票据类型</span>
|
||||||
|
<span class="item-value"><dict-tag :options="dict.type.finance_invoice_type" :value="attachment.ticketType"/></span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="item-label">{{ titleText }}</span>
|
||||||
|
<div class="item-value">
|
||||||
|
<div class="image-wrapper">
|
||||||
|
<el-image
|
||||||
|
v-if="!isPdf(attachment.filePath)"
|
||||||
|
:src="getImageUrl(attachment.filePath)"
|
||||||
|
:preview-src-list="previewList"
|
||||||
|
style="width: 200px; height: 150px;"
|
||||||
|
fit="contain"
|
||||||
|
></el-image>
|
||||||
|
<div v-else-if="pdfUrls[attachment.filePath]" class="pdf-thumbnail-container" @click="openPdfPreview(pdfUrls[attachment.filePath])">
|
||||||
|
<iframe :src="pdfUrls[attachment.filePath]" width="100%" height="150px" frameborder="0"></iframe>
|
||||||
|
<div class="pdf-hover-overlay">
|
||||||
|
<i class="el-icon-zoom-in"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="attachment.delFlag === '2'" class="void-overlay">作废</div>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
class="download-btn"
|
||||||
|
icon="el-icon-download"
|
||||||
|
@click="downloadFile(attachment)"
|
||||||
|
>下载{{ titleText }}</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="item-label">收款总额</span>
|
||||||
|
<span class="item-value">{{ receiptData.totalAmount }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="item-label">备注</span>
|
||||||
|
<span class="item-value">{{ attachment.remark }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
</el-timeline>
|
||||||
|
<el-empty v-else :description="'暂无' + titleText"></el-empty>
|
||||||
|
</div>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- PDF Preview Dialog -->
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="pdfPreviewVisible"
|
||||||
|
width="80%"
|
||||||
|
top="5vh"
|
||||||
|
append-to-body
|
||||||
|
custom-class="pdf-preview-dialog"
|
||||||
|
>
|
||||||
|
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- Upload Dialog -->
|
||||||
|
<el-dialog
|
||||||
|
:title="'上传' + titleText"
|
||||||
|
:visible.sync="uploadDialogVisible"
|
||||||
|
width="70vw"
|
||||||
|
append-to-body
|
||||||
|
@close="closeUploadDialog"
|
||||||
|
custom-class="upload-receipt-dialog"
|
||||||
|
>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form :model="uploadForm" ref="uploadForm" :rules="rules" label-width="120px" size="medium" >
|
||||||
|
<el-form-item label="票据类型" prop="ticketType" required>
|
||||||
|
<el-select v-model="uploadForm.ticketType" placeholder="请选择票据类型">
|
||||||
|
<el-option
|
||||||
|
v-for="item in dict.type.finance_invoice_type"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收款附件" prop="file" required>
|
||||||
|
<div style="display: flex; flex-direction: column; align-items: flex-start;">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
action="#"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-change="handleFileChange"
|
||||||
|
:on-remove="handleFileRemove"
|
||||||
|
:show-file-list="false"
|
||||||
|
accept=".jpg,.jpeg,.png,.pdf"
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary" icon="el-icon-upload2">{{ uploadForm.file ? '重新上传' : '点击上传' }}</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<div class="el-upload__tip" style="line-height: 1.5; margin-top: 5px;">支持上传PNG、JPG、PDF文件格式</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收款总额">
|
||||||
|
<span>{{ receiptData.totalAmount }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="uploadForm.remark"
|
||||||
|
:rows="4"
|
||||||
|
placeholder="此处备注描述..."
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="upload-preview-container" style="height: 70vh;">
|
||||||
|
<div v-if="previewUrl" class="preview-content">
|
||||||
|
<img v-if="!isPreviewPdf" :src="previewUrl" class="preview-image" />
|
||||||
|
<iframe v-else :src="previewUrl" width="100%" height="100%" frameborder="0"></iframe>
|
||||||
|
</div>
|
||||||
|
<div v-else class="preview-placeholder">
|
||||||
|
<div class="placeholder-icon">
|
||||||
|
<i class="el-icon-picture"></i>
|
||||||
|
</div>
|
||||||
|
<div class="placeholder-text">点击图片进入预览</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitNewUpload">保存</el-button>
|
||||||
|
<el-button @click="closeUploadDialog">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getReceiveAttachments, uploadReceiveAttachment } from "@/api/finance/receive";
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ReceiveDialog",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
receiptData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => null,
|
||||||
|
},
|
||||||
|
dicts: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dicts:['finance_invoice_type'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
attachments: [],
|
||||||
|
// Upload Dialog Data
|
||||||
|
uploadDialogVisible: false,
|
||||||
|
uploadForm: {
|
||||||
|
ticketType: '',
|
||||||
|
remark: '',
|
||||||
|
file: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
ticketType: [
|
||||||
|
{ required: true, message: "请选择票据类型", trigger: "change" }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
previewUrl: '',
|
||||||
|
isPreviewPdf: false,
|
||||||
|
// PDF Preview Data
|
||||||
|
pdfUrls: {},
|
||||||
|
pdfPreviewVisible: false,
|
||||||
|
currentPdfUrl: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.visible;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit("update:visible", val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
previewList() {
|
||||||
|
return this.attachments
|
||||||
|
.filter(att => !this.isPdf(att.filePath))
|
||||||
|
.map(att => this.getImageUrl(att.filePath));
|
||||||
|
},
|
||||||
|
canUpload() {
|
||||||
|
if (!this.attachments || this.attachments.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.attachments.every(att => att.delFlag === '2');
|
||||||
|
},
|
||||||
|
titleText() {
|
||||||
|
return '收款附件';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(val) {
|
||||||
|
if (val && this.receiptData) {
|
||||||
|
this.fetchAttachments();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchAttachments() {
|
||||||
|
if (!this.receiptData.id) return;
|
||||||
|
this.loading = true;
|
||||||
|
getReceiveAttachments(this.receiptData.id, { type: 'ticket' })
|
||||||
|
.then(response => {
|
||||||
|
const data = response.data || [];
|
||||||
|
data.sort((a, b) => new Date(b.createTime) - new Date(a.createTime));
|
||||||
|
this.attachments = data;
|
||||||
|
this.loadPdfPreviews();
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.attachments = [];
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadPdfPreviews() {
|
||||||
|
this.attachments.forEach(att => {
|
||||||
|
if (this.isPdf(att.filePath) && !this.pdfUrls[att.filePath]) {
|
||||||
|
request({
|
||||||
|
url: '/common/download/resource',
|
||||||
|
method: 'get',
|
||||||
|
params: { resource: att.filePath },
|
||||||
|
responseType: 'blob'
|
||||||
|
}).then(res => {
|
||||||
|
const blob = new Blob([res.data], { type: 'application/pdf' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
this.$set(this.pdfUrls, att.filePath, url);
|
||||||
|
}).catch(console.error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openPdfPreview(url) {
|
||||||
|
if (!url) return;
|
||||||
|
this.currentPdfUrl = url;
|
||||||
|
this.pdfPreviewVisible = true;
|
||||||
|
},
|
||||||
|
getImageUrl(resource) {
|
||||||
|
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
||||||
|
},
|
||||||
|
isPdf(filePath) {
|
||||||
|
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
||||||
|
},
|
||||||
|
downloadFile(attachment) {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = this.getImageUrl(attachment.filePath);
|
||||||
|
link.download = attachment.fileName || 'receive_attachment';
|
||||||
|
link.style.display = 'none';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.attachments = [];
|
||||||
|
// Clean up object URLs
|
||||||
|
Object.values(this.pdfUrls).forEach(url => URL.revokeObjectURL(url));
|
||||||
|
this.pdfUrls = {};
|
||||||
|
},
|
||||||
|
// New Upload Dialog Methods
|
||||||
|
openUploadDialog() {
|
||||||
|
this.uploadForm = {
|
||||||
|
remark: '',
|
||||||
|
file: null
|
||||||
|
};
|
||||||
|
if (this.$refs.uploadForm) {
|
||||||
|
this.$refs.uploadForm.clearValidate();
|
||||||
|
}
|
||||||
|
this.previewUrl = '';
|
||||||
|
this.isPreviewPdf = false;
|
||||||
|
this.uploadDialogVisible = true;
|
||||||
|
},
|
||||||
|
closeUploadDialog() {
|
||||||
|
this.uploadDialogVisible = false;
|
||||||
|
this.uploadForm.file = null;
|
||||||
|
this.previewUrl = '';
|
||||||
|
},
|
||||||
|
handleFileChange(file) {
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
|
const isAcceptedType = ['image/jpeg', 'image/png', 'application/pdf'].includes(file.raw.type);
|
||||||
|
|
||||||
|
if (!isAcceptedType) {
|
||||||
|
this.$message.error('上传文件只能是 JPG/PNG/PDF 格式!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isLt2M) {
|
||||||
|
this.$message.error('上传文件大小不能超过 2MB!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uploadForm.file = file.raw;
|
||||||
|
this.isPreviewPdf = file.raw.type === 'application/pdf';
|
||||||
|
|
||||||
|
this.previewUrl = URL.createObjectURL(file.raw);
|
||||||
|
},
|
||||||
|
handleFileRemove() {
|
||||||
|
this.uploadForm.file = null;
|
||||||
|
this.previewUrl = '';
|
||||||
|
},
|
||||||
|
submitNewUpload() {
|
||||||
|
this.$refs.uploadForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (!this.uploadForm.file) {
|
||||||
|
this.$message.warning("请选择要上传的文件");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", this.uploadForm.file);
|
||||||
|
formData.append("id", this.receiptData.id);
|
||||||
|
formData.append("remark", this.uploadForm.remark);
|
||||||
|
formData.append("ticketType", this.uploadForm.ticketType);
|
||||||
|
|
||||||
|
uploadReceiveAttachment(formData)
|
||||||
|
.then(response => {
|
||||||
|
this.$message.success("上传成功");
|
||||||
|
this.closeUploadDialog();
|
||||||
|
this.fetchAttachments();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$message.error("上传失败");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.receipt-dialog-body {
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.loading-spinner {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.receipt-card-content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.receipt-details {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.detail-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.item-label {
|
||||||
|
width: 110px;
|
||||||
|
color: #606266;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 15px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.item-value {
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.image-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 200px;
|
||||||
|
min-height: 150px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid #DCDFE6;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.void-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) rotate(-30deg);
|
||||||
|
color: red;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
opacity: 0.7;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.download-btn {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.upload-btn-container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
/* New Dialog Styles */
|
||||||
|
.upload-preview-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.preview-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.preview-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
.preview-placeholder {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
.placeholder-icon {
|
||||||
|
font-size: 64px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #c0c4cc;
|
||||||
|
}
|
||||||
|
.placeholder-text {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.pdf-thumbnail-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.pdf-hover-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 24px;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.pdf-thumbnail-container:hover .pdf-hover-overlay {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,346 @@
|
||||||
|
<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-item label="项目名称" prop="projectName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.projectName"
|
||||||
|
placeholder="请输入项目名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收款单编号" prop="receiveBillCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.receiveBillCode"
|
||||||
|
placeholder="请输入收款单编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="客户名称" prop="customerName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.customerName"
|
||||||
|
placeholder="请输入客户名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="应收单编号" prop="receivableBillCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.receivableBillCode"
|
||||||
|
placeholder="请输入应收单编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收款单类型" prop="receiveBillType">
|
||||||
|
<el-select v-model="queryParams.receiveBillType" placeholder="请选择收款单类型" clearable>
|
||||||
|
<el-option v-for="dict in dict.type.receive_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="receiveStatus">
|
||||||
|
<el-select v-model="queryParams.receiveStatus" placeholder="请选择收款状态" clearable>
|
||||||
|
<el-option label="待收款" value="0" />
|
||||||
|
<el-option label="已收款" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审批节点" prop="approveNode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.approveNode"
|
||||||
|
placeholder="请输入审批节点"
|
||||||
|
clearable
|
||||||
|
@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"
|
||||||
|
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"
|
||||||
|
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>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="receiveList">
|
||||||
|
<el-table-column label="收款单编号" align="center" prop="receiptBillCode" />
|
||||||
|
<el-table-column label="预计收款时间" align="center" prop="receiptTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.receiptTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="进货商名称" align="center" prop="partnerName" />
|
||||||
|
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" />
|
||||||
|
<el-table-column label="收款单类型" align="center" prop="receiptBillType" >
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.receipt_bill_type" :value="scope.row.receiptBillType"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="预收单剩余额度" align="center" prop="remainingAmount" />
|
||||||
|
<el-table-column label="收款状态" align="center" prop="receiveStatus" >
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.receipt_bill_status" :value="scope.row.receiptStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审批状态" align="center" prop="approveStatus" >
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.approve_status" :value="scope.row.approveStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审批通过时间" align="center" prop="approveTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<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">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click="handleDetail(scope.row)"
|
||||||
|
>查看详情</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-document"
|
||||||
|
@click="handleReceipt(scope.row)"
|
||||||
|
>附件</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-document"
|
||||||
|
v-show="scope.row.receiptBillType==='FROM_RECEIVABLE' && scope.row.receiptStatus==='1' &&(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') "
|
||||||
|
@click="handleReturn(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)"
|
||||||
|
>申请红冲</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 详情抽屉 -->
|
||||||
|
<detail-drawer :visible.sync="detailOpen" :detail="detailData"></detail-drawer>
|
||||||
|
<!-- 新增弹窗 -->
|
||||||
|
<add-form :visible.sync="addOpen" :dicts="dict.type" @submit="handleAddSubmit"></add-form>
|
||||||
|
<!-- 收款附件弹窗 -->
|
||||||
|
<receive-dialog :visible.sync="receiptOpen" :receipt-data="currentRow" :dicts="dict.type"></receive-dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {listReceive, getReceive, redRush, mergeReceivable, returnReceive, addReceipt} from "@/api/finance/receive";
|
||||||
|
import { addDateRange } from "@/utils/ruoyi";
|
||||||
|
import DetailDrawer from "./components/DetailDrawer.vue";
|
||||||
|
import AddForm from "./components/AddForm.vue";
|
||||||
|
import ReceiveDialog from "./components/ReceiveDialog.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Receive",
|
||||||
|
components: {
|
||||||
|
DetailDrawer,
|
||||||
|
AddForm,
|
||||||
|
ReceiveDialog
|
||||||
|
},
|
||||||
|
dicts:['receipt_bill_type','approve_status','receipt_bill_status'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 收款单表格数据
|
||||||
|
receiveList: [],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
projectCode: null,
|
||||||
|
projectName: null,
|
||||||
|
receiveBillCode: null,
|
||||||
|
customerName: null,
|
||||||
|
receivableBillCode: null,
|
||||||
|
receiveBillType: null,
|
||||||
|
approveStatus: null,
|
||||||
|
receiveStatus: null,
|
||||||
|
approveNode: null,
|
||||||
|
},
|
||||||
|
// 日期范围
|
||||||
|
dateRangeApproval: [],
|
||||||
|
dateRangeEstimated: [],
|
||||||
|
dateRangeActual: [],
|
||||||
|
// 详情抽屉
|
||||||
|
detailOpen: false,
|
||||||
|
detailData: null,
|
||||||
|
// 新增弹窗
|
||||||
|
addOpen: false,
|
||||||
|
// 收款附件弹窗
|
||||||
|
receiptOpen: false,
|
||||||
|
currentRow: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addDateRange,
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
let query = { ...this.queryParams };
|
||||||
|
query = this.addDateRange(query, this.dateRangeApproval, 'ApproveTime');
|
||||||
|
query = this.addDateRange(query, this.dateRangeEstimated, 'PlanReceiveTime');
|
||||||
|
query = this.addDateRange(query, this.dateRangeActual, 'ActualReceiveTime');
|
||||||
|
|
||||||
|
listReceive(query).then(response => {
|
||||||
|
this.receiveList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.dateRangeApproval = [];
|
||||||
|
this.dateRangeEstimated = [];
|
||||||
|
this.dateRangeActual = [];
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.addOpen = true;
|
||||||
|
},
|
||||||
|
/** 新增提交 */
|
||||||
|
handleAddSubmit(form) {
|
||||||
|
if (form.paymentBillType==='FROM_RECEIVABLE'){
|
||||||
|
mergeReceivable(form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.addOpen = false;
|
||||||
|
this.getList();
|
||||||
|
}).catch(error => {
|
||||||
|
console.error("发起收款单失败", error);
|
||||||
|
this.$modal.msgError("新增失败");
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
addReceipt(form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.addOpen = false;
|
||||||
|
this.getList();
|
||||||
|
}).catch(error => {
|
||||||
|
console.error("新增收款单失败", error);
|
||||||
|
this.$modal.msgError("新增失败");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 详情按钮操作 */
|
||||||
|
handleDetail(row) {
|
||||||
|
getReceive(row.id).then(response => {
|
||||||
|
this.detailData = response.data;
|
||||||
|
this.detailData.approveNode = row.approveNode;
|
||||||
|
this.detailOpen = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 收款附件按钮操作 */
|
||||||
|
handleReceipt(row) {
|
||||||
|
this.currentRow = row;
|
||||||
|
this.receiptOpen = true;
|
||||||
|
},
|
||||||
|
/** 退回按钮操作 */
|
||||||
|
handleRedRush(row) {
|
||||||
|
this.$modal.confirm('是否确认收款单编号为"' + row.receiveBillCode + '"的数据项进行红冲,并提交财务审批?').then(function() {
|
||||||
|
return redRush(row.id);
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("申请成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
handleReturn(row) {
|
||||||
|
this.$modal.confirm('是否确认退回收款单编号为"' + row.receiptBillCode + '"的数据项?').then(function() {
|
||||||
|
return returnReceive(row.id);
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("退回成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
title="核销详情"
|
||||||
|
:visible.sync="visible"
|
||||||
|
direction="rtl"
|
||||||
|
size="60%"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div class="drawer-body" v-if="detail">
|
||||||
|
<div class="section">
|
||||||
|
<el-divider content-position="left">收票单信息</el-divider>
|
||||||
|
<el-table :data="[detail]" border stripe>
|
||||||
|
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="writeOffAmount" label="本次核销含税总价(元)" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="vendorName" label="制造商名称" align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="ticketBillCode" label="采购收票单编号" align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="收票单生成时间" align="center" width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.ticketBill.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column prop="receiptBillType" label="收票单类型" align="center">-->
|
||||||
|
<!-- <template slot-scope="scope">-->
|
||||||
|
<!-- <dict-tag :options="dict.type.ticket_bill_type" :value="scope.row.ticketBill.ticketBillType"/>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </el-table-column>-->
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<el-divider content-position="left">应付单明细</el-divider>
|
||||||
|
<el-table :data="detail.detailList" border stripe>
|
||||||
|
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="paymentAmount" label="本次核销金额(元)" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="vendorName" label="制造商名称" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="payableBillCode" label="采购应付单编号" align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="应付单生成时间" align="center"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "WriteOffDetailDrawer",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dicts: ['finance_write_off_type'],
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.drawer-body {
|
||||||
|
padding: 20px;
|
||||||
|
height: calc(100vh - 80px);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-container {
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f8f8f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
||||||
|
<el-form-item label="核销序号" prop="writeOffCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.writeOffCode"
|
||||||
|
placeholder="请输入核销序号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="采购应付单编号" prop="payableBillCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.payableBillCode"
|
||||||
|
placeholder="请输入采购应付单编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="采购收票单编号" prop="receiptBillCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.receiptBillCode"
|
||||||
|
placeholder="请输入采购收票单编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="制造商名称" prop="vendorName">
|
||||||
|
<el-select v-model="queryParams.vendorName" placeholder="请选择制造商名称" clearable filterable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in vendorOptions"
|
||||||
|
:key="item.vendorName"
|
||||||
|
:label="item.vendorName"
|
||||||
|
:value="item.vendorName"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核销类型" prop="writeOffType">
|
||||||
|
<el-select v-model="queryParams.writeOffType" placeholder="请选择核销类型" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.finance_write_off_type"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核销时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
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>
|
||||||
|
<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>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
>反核销</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="writeOffList" @selection-change="handleSelectionChange" row-key="id">
|
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"/>
|
||||||
|
<el-table-column label="核销序号" align="center" prop="writeOffCode" />
|
||||||
|
<el-table-column label="核销人" align="center" prop="createByName" />
|
||||||
|
<el-table-column label="核销时间" align="center" prop="createTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="采购收票单编号" align="center" prop="ticketBillCode" />
|
||||||
|
<el-table-column label="制造商名称" align="center" prop="vendorName" />
|
||||||
|
<el-table-column label="核销类型" align="center" prop="writeOffType">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.finance_write_off_type" :value="scope.row.writeOffType"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核销含税总价(元)" align="center" prop="writeOffAmount" />
|
||||||
|
<el-table-column label="核销未税总价(元)" align="center" prop="writeOffAmountWithoutTax" />
|
||||||
|
<el-table-column label="核销税额(元)" align="center" prop="writeOffTaxAmount" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click="handleDetail(scope.row)"
|
||||||
|
>查看详情</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
>反核销</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 详情抽屉 -->
|
||||||
|
<write-off-detail-drawer :visible.sync="open" :detail="form" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listTicketWriteOff, getTicketWriteoff, delTicketWriteoff } from "@/api/finance/writeoff";
|
||||||
|
import { listVendor } from "@/api/base/vendor";
|
||||||
|
import WriteOffDetailDrawer from "./WriteOffDetailDrawer";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "WriteOffTicketRecord",
|
||||||
|
components: {
|
||||||
|
WriteOffDetailDrawer
|
||||||
|
},
|
||||||
|
dicts: ['finance_write_off_type'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 表格数据
|
||||||
|
writeOffList: [],
|
||||||
|
// 制造商选项
|
||||||
|
vendorOptions: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 日期范围
|
||||||
|
dateRange: [],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
writeOffCode: null,
|
||||||
|
payableBillCode: null,
|
||||||
|
receiptBillCode: null,
|
||||||
|
vendorName: null,
|
||||||
|
writeOffType: null,
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
this.getVendorList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
listTicketWriteOff(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
|
||||||
|
this.writeOffList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 查询制造商列表 */
|
||||||
|
getVendorList() {
|
||||||
|
listVendor().then(response => {
|
||||||
|
this.vendorOptions = response.rows;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.dateRange = [];
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 查看详情 */
|
||||||
|
handleDetail(row) {
|
||||||
|
this.loading = true;
|
||||||
|
getTicketWriteoff(row.id).then(response => {
|
||||||
|
this.form = response.data;
|
||||||
|
this.open = true;
|
||||||
|
this.title = "核销详情";
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id)
|
||||||
|
this.multiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 反核销按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids;
|
||||||
|
this.$modal.confirm('是否确认反核销核销序号为"' + ids + '"的数据项?').then(function() {
|
||||||
|
return delTicketWriteoff(ids);
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("反核销成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
package com.ruoyi.sip.controller;
|
package com.ruoyi.sip.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.sip.domain.OmsReceiptBill;
|
import com.ruoyi.sip.domain.OmsReceiptBill;
|
||||||
import com.ruoyi.sip.service.IOmsReceiptBillService;
|
import com.ruoyi.sip.service.IOmsReceiptBillService;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -18,7 +21,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("omsReceiptBill")
|
@RequestMapping("/finance/receipt")
|
||||||
public class OmsReceiptBillController extends BaseController {
|
public class OmsReceiptBillController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -67,4 +70,25 @@ public class OmsReceiptBillController extends BaseController {
|
||||||
public AjaxResult batchRemove(@PathVariable("ids") Long[] ids) {
|
public AjaxResult batchRemove(@PathVariable("ids") Long[] ids) {
|
||||||
return AjaxResult.success(omsReceiptBillService.batchRemove(ids));
|
return AjaxResult.success(omsReceiptBillService.batchRemove(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresPermissions("finance:receipt:return")
|
||||||
|
@Log(title = "退回付款单", businessType = BusinessType.UPDATE)
|
||||||
|
@DeleteMapping("/returnReceivable/{id}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult returnReceivable(@PathVariable("id") Long id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 验证付款单ID
|
||||||
|
if (id == null) {
|
||||||
|
return AjaxResult.error("付款单ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用服务层方法处理退回逻辑
|
||||||
|
return omsReceiptBillService.returnPaymentBill(id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("退回付款单失败", e);
|
||||||
|
return AjaxResult.error("操作失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package com.ruoyi.sip.domain;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
|
@ -52,11 +54,17 @@ public class OmsReceiptBill {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private String orderCode;
|
private String orderCode;
|
||||||
|
/**
|
||||||
|
* 剩余金额
|
||||||
|
*/
|
||||||
|
|
||||||
|
private BigDecimal remainingAmount;
|
||||||
/**
|
/**
|
||||||
* 含税总价
|
* 含税总价
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private BigDecimal totalPriceWithTax;
|
private BigDecimal totalPriceWithTax;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 未税总价
|
* 未税总价
|
||||||
*/
|
*/
|
||||||
|
|
@ -152,6 +160,7 @@ public class OmsReceiptBill {
|
||||||
* 是否已申请退款 0:未退款 1:已申请退款
|
* 是否已申请退款 0:未退款 1:已申请退款
|
||||||
*/
|
*/
|
||||||
private String refundStatus;
|
private String refundStatus;
|
||||||
|
private List<ReceiptDetailDTO> detailDTOList;
|
||||||
@Getter
|
@Getter
|
||||||
public enum ReceiptBillTypeEnum {
|
public enum ReceiptBillTypeEnum {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public class OmsReceivableBill extends BaseEntity
|
||||||
@Excel(name = "产品类型")
|
@Excel(name = "产品类型")
|
||||||
private String productType;
|
private String productType;
|
||||||
private String productCode;
|
private String productCode;
|
||||||
|
private BigDecimal remainingAmount;
|
||||||
/** 含税总价 */
|
/** 含税总价 */
|
||||||
@Excel(name = "含税总价")
|
@Excel(name = "含税总价")
|
||||||
private BigDecimal totalPriceWithTax;
|
private BigDecimal totalPriceWithTax;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public class OmsReceivableReceiptDetail extends BaseEntity
|
||||||
/** 应收单ID */
|
/** 应收单ID */
|
||||||
@Excel(name = "应收单ID")
|
@Excel(name = "应收单ID")
|
||||||
private Long receivableBillId;
|
private Long receivableBillId;
|
||||||
|
private List<Long> receivableBillIdList;
|
||||||
|
|
||||||
/** 实际收款时间 */
|
/** 实际收款时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
|
@ -64,6 +65,8 @@ public class OmsReceivableReceiptDetail extends BaseEntity
|
||||||
private OmsFinAttachment finAttachment;
|
private OmsFinAttachment finAttachment;
|
||||||
private Date actualReceiptTime;
|
private Date actualReceiptTime;
|
||||||
private String receiptStatus;
|
private String receiptStatus;
|
||||||
|
private BigDecimal paymentAmountWithoutTax;
|
||||||
|
private BigDecimal paymentAmountTax;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum ReceivableDetailTypeEnum {
|
public enum ReceivableDetailTypeEnum {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.ruoyi.sip.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 付款单关联的应付单明细DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2024-12-08
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ReceiptDetailDTO {
|
||||||
|
|
||||||
|
/** 项目编号 */
|
||||||
|
private String projectCode;
|
||||||
|
|
||||||
|
/** 项目名称 */
|
||||||
|
private String projectName;
|
||||||
|
private String productType;
|
||||||
|
|
||||||
|
/** 采购应付单编号 */
|
||||||
|
private String receivableBillCode;
|
||||||
|
|
||||||
|
/** 应付单含税总价 */
|
||||||
|
private BigDecimal totalPriceWithTax;
|
||||||
|
|
||||||
|
/** 本次付款金额 */
|
||||||
|
private BigDecimal receiptAmount;
|
||||||
|
|
||||||
|
/** 本次付款比例 */
|
||||||
|
private BigDecimal receiptRate;
|
||||||
|
private String partnerName;
|
||||||
|
private String partnerCode;
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
|
|
@ -48,4 +48,7 @@ public interface OmsReceiptBillMapper {
|
||||||
|
|
||||||
int selectMaxCodeByPrefix(String codePrefix);
|
int selectMaxCodeByPrefix(String codePrefix);
|
||||||
|
|
||||||
|
List<OmsReceiptBill> listRemainingAmountByPartnerCodeList(List<String> collect);
|
||||||
|
|
||||||
|
void clearRelationReceivable(String receiptBillCode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.sip.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
|
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
|
||||||
|
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应收单收款明细Mapper接口
|
* 应收单收款明细Mapper接口
|
||||||
|
|
@ -62,4 +63,6 @@ public interface OmsReceivableReceiptDetailMapper
|
||||||
List<OmsReceivableReceiptDetail> list(OmsReceivableReceiptDetail omsReceivableReceiptDetail);
|
List<OmsReceivableReceiptDetail> list(OmsReceivableReceiptDetail omsReceivableReceiptDetail);
|
||||||
|
|
||||||
List<OmsReceivableReceiptDetail> selectByPaymentPlanIds(List<Long> allReceiptPlanIds);
|
List<OmsReceivableReceiptDetail> selectByPaymentPlanIds(List<Long> allReceiptPlanIds);
|
||||||
|
|
||||||
|
List<ReceiptDetailDTO> listReceivableByReceiptBillCode(List<String> receiptBillCode);
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.sip.service;
|
package com.ruoyi.sip.service;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.sip.domain.OmsReceiptBill;
|
import com.ruoyi.sip.domain.OmsReceiptBill;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -42,6 +43,9 @@ public interface IOmsReceiptBillService {
|
||||||
*/
|
*/
|
||||||
int batchRemove(Long[] ids);
|
int batchRemove(Long[] ids);
|
||||||
|
|
||||||
|
List<OmsReceiptBill> listRemainingAmountByPartnerCodeList(List<String> collect);
|
||||||
|
|
||||||
|
AjaxResult returnPaymentBill(Long id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
|
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
|
||||||
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
|
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
|
||||||
|
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应收单收款明细Service接口
|
* 应收单收款明细Service接口
|
||||||
|
|
@ -66,4 +67,8 @@ public interface IOmsReceivableReceiptDetailService
|
||||||
List<OmsReceivableReceiptDetail> selectReceiptPlanByIds(List<Long> allReceiptPlanIds);
|
List<OmsReceivableReceiptDetail> selectReceiptPlanByIds(List<Long> allReceiptPlanIds);
|
||||||
|
|
||||||
List<OmsReceivableReceiptDetail> listByReceivableBillIdList(List<Long> idList);
|
List<OmsReceivableReceiptDetail> listByReceivableBillIdList(List<Long> idList);
|
||||||
|
|
||||||
|
List<ReceiptDetailDTO> listReceivableByReceiptBillCode(String receiptBillCode);
|
||||||
|
|
||||||
|
List<OmsReceivableReceiptDetail> listByReceiptBillCode(String receiptBillCode);
|
||||||
}
|
}
|
||||||
|
|
@ -1,18 +1,28 @@
|
||||||
package com.ruoyi.sip.service.impl;
|
package com.ruoyi.sip.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.enums.ApproveStatusEnum;
|
import com.ruoyi.common.enums.ApproveStatusEnum;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
import com.ruoyi.common.utils.ShiroUtils;
|
||||||
|
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
|
||||||
import com.ruoyi.sip.domain.OmsPaymentBill;
|
import com.ruoyi.sip.domain.OmsPaymentBill;
|
||||||
import com.ruoyi.sip.domain.OmsReceiptBill;
|
import com.ruoyi.sip.domain.OmsReceiptBill;
|
||||||
|
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
|
||||||
|
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
|
||||||
import com.ruoyi.sip.mapper.OmsReceiptBillMapper;
|
import com.ruoyi.sip.mapper.OmsReceiptBillMapper;
|
||||||
import com.ruoyi.sip.service.IOmsReceiptBillService;
|
import com.ruoyi.sip.service.IOmsReceiptBillService;
|
||||||
|
import com.ruoyi.sip.service.IOmsReceivableBillService;
|
||||||
|
import com.ruoyi.sip.service.IOmsReceivableReceiptDetailService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ch
|
* @Author ch
|
||||||
|
|
@ -25,7 +35,10 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private OmsReceiptBillMapper omsReceiptBillMapper;
|
private OmsReceiptBillMapper omsReceiptBillMapper;
|
||||||
|
@Autowired
|
||||||
|
private IOmsReceivableReceiptDetailService omsReceivableReceiptDetailService;
|
||||||
|
@Autowired
|
||||||
|
private IOmsReceivableBillService receivableBillService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询列表数据
|
* 查询列表数据
|
||||||
|
|
@ -41,7 +54,10 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OmsReceiptBill queryById(Long id) {
|
public OmsReceiptBill queryById(Long id) {
|
||||||
return omsReceiptBillMapper.queryById(id);
|
OmsReceiptBill receiptBill = omsReceiptBillMapper.queryById(id);
|
||||||
|
List<ReceiptDetailDTO> receiptDetailDTOS = omsReceivableReceiptDetailService.listReceivableByReceiptBillCode(receiptBill.getReceiptBillCode());
|
||||||
|
receiptBill.setDetailDTOList(receiptDetailDTOS);
|
||||||
|
return receiptBill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -87,6 +103,47 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
|
||||||
return omsReceiptBillMapper.batchRemove(ids);
|
return omsReceiptBillMapper.batchRemove(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OmsReceiptBill> listRemainingAmountByPartnerCodeList(List<String> collect) {
|
||||||
|
return omsReceiptBillMapper.listRemainingAmountByPartnerCodeList(collect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AjaxResult returnPaymentBill(Long id) {
|
||||||
|
try {
|
||||||
|
// 1. 验证付款单是否存在
|
||||||
|
OmsReceiptBill receiptBill = omsReceiptBillMapper.queryById(id);
|
||||||
|
if (receiptBill == null) {
|
||||||
|
return AjaxResult.error("付款单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查付款单类型,只有FROM_PAYABLE类型的付款单才能退回
|
||||||
|
if (!OmsReceiptBill.ReceiptBillTypeEnum.FROM_RECEIVABLE.getCode().equals(receiptBill.getReceiptBillType())) {
|
||||||
|
return AjaxResult.error("只有由应收单合并生成的收款单才能执行退回操作");
|
||||||
|
}
|
||||||
|
List<OmsReceivableReceiptDetail> detailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
|
||||||
|
// 3. 清楚关联
|
||||||
|
omsReceiptBillMapper.clearRelationReceivable(receiptBill.getReceiptBillCode());
|
||||||
|
|
||||||
|
|
||||||
|
// 6. 删除付款单记录
|
||||||
|
int result = omsReceiptBillMapper.deleteById(id);
|
||||||
|
if (result <= 0) {
|
||||||
|
throw new RuntimeException("删除付款单失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollUtil.isNotEmpty(detailList)) {
|
||||||
|
receivableBillService.updateReceiptAmount(detailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).distinct().collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return AjaxResult.success("付款单退回成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("退回付款单操作失败:" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
package com.ruoyi.sip.service.impl;
|
package com.ruoyi.sip.service.impl;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
|
@ -11,10 +12,10 @@ import cn.hutool.core.date.DatePattern;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.common.utils.PageUtils;
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
import com.ruoyi.common.utils.ShiroUtils;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.sip.domain.*;
|
import com.ruoyi.sip.domain.*;
|
||||||
import com.ruoyi.sip.domain.dto.MergedInvoiceDataDto;
|
|
||||||
import com.ruoyi.sip.domain.dto.MergedReceviableReceiptDataDto;
|
import com.ruoyi.sip.domain.dto.MergedReceviableReceiptDataDto;
|
||||||
import com.ruoyi.sip.domain.dto.ReceivableOrderReceiptDto;
|
import com.ruoyi.sip.domain.dto.ReceivableOrderReceiptDto;
|
||||||
import com.ruoyi.sip.service.*;
|
import com.ruoyi.sip.service.*;
|
||||||
|
|
@ -75,7 +76,17 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
@Override
|
@Override
|
||||||
public List<OmsReceivableBill> selectOmsReceivableBillList(OmsReceivableBill omsReceivableBill)
|
public List<OmsReceivableBill> selectOmsReceivableBillList(OmsReceivableBill omsReceivableBill)
|
||||||
{
|
{
|
||||||
return omsReceivableBillMapper.selectOmsReceivableBillList(omsReceivableBill);
|
List<OmsReceivableBill> receivableBills = omsReceivableBillMapper.selectOmsReceivableBillList(omsReceivableBill);
|
||||||
|
if (CollUtil.isNotEmpty(receivableBills)) {
|
||||||
|
PageUtils.clearPage();
|
||||||
|
List<OmsReceiptBill> receiptBills = receiptBillService.listRemainingAmountByPartnerCodeList(receivableBills.stream().map(OmsReceivableBill::getPartnerCode).collect(Collectors.toList()));
|
||||||
|
Map<String, BigDecimal> decimalMap = receiptBills.stream().filter(item -> item.getRemainingAmount() != null)
|
||||||
|
.collect(Collectors.toMap(OmsReceiptBill::getPartnerCode, OmsReceiptBill::getRemainingAmount, BigDecimal::add));
|
||||||
|
for (OmsReceivableBill payableBill : receivableBills) {
|
||||||
|
payableBill.setReceivedAmount(decimalMap.getOrDefault(payableBill.getPartnerCode(), BigDecimal.ZERO));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return receivableBills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -142,13 +153,13 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
|
|
||||||
// Fetch bills once
|
// Fetch bills once
|
||||||
for (ReceivableOrderReceiptDto order : dto.getReceivableBills()) {
|
for (ReceivableOrderReceiptDto order : dto.getReceivableBills()) {
|
||||||
for (OmsReceivableReceiptPlan plan : order.getReceiptPlans()) {
|
|
||||||
// 计算每个 plan 的未税金额 = planAmount / (1 + 税率),保留两位小数
|
|
||||||
BigDecimal taxRate = order.getTaxRate();
|
BigDecimal taxRate = order.getTaxRate();
|
||||||
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
|
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
|
||||||
// 如果税率为空或小于0,则默认为0.13
|
// 如果税率为空或小于0,则默认为0.13
|
||||||
taxRate = new BigDecimal(defaultTax);
|
taxRate = new BigDecimal(defaultTax);
|
||||||
}
|
}
|
||||||
|
for (OmsReceivableReceiptPlan plan : order.getReceiptPlans()) {
|
||||||
|
// 计算每个 plan 的未税金额 = planAmount / (1 + 税率),保留两位小数
|
||||||
// 计算未税金额 = planAmount / (1 + 税率)
|
// 计算未税金额 = planAmount / (1 + 税率)
|
||||||
BigDecimal divisor = BigDecimal.ONE.add(taxRate);
|
BigDecimal divisor = BigDecimal.ONE.add(taxRate);
|
||||||
BigDecimal planWithoutTax = plan.getPlanAmount().divide(divisor, 2, java.math.RoundingMode.HALF_UP);
|
BigDecimal planWithoutTax = plan.getPlanAmount().divide(divisor, 2, java.math.RoundingMode.HALF_UP);
|
||||||
|
|
@ -192,6 +203,11 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
|
|
||||||
// 遍历所有计划并检查是否有已开票的记录
|
// 遍历所有计划并检查是否有已开票的记录
|
||||||
for (ReceivableOrderReceiptDto receivableOrderDto : dto.getReceivableBills()) {
|
for (ReceivableOrderReceiptDto receivableOrderDto : dto.getReceivableBills()) {
|
||||||
|
BigDecimal taxRate = receivableOrderDto.getTaxRate();
|
||||||
|
if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) {
|
||||||
|
// 如果税率为空或小于0,则默认为0.13
|
||||||
|
taxRate = new BigDecimal(defaultTax);
|
||||||
|
}
|
||||||
for (OmsReceivableReceiptPlan plan : receivableOrderDto.getReceiptPlans()) {
|
for (OmsReceivableReceiptPlan plan : receivableOrderDto.getReceiptPlans()) {
|
||||||
// 检查是否存在已开票的记录
|
// 检查是否存在已开票的记录
|
||||||
OmsReceivableReceiptDetail existingDetail = existingDetailsMap.get(plan.getId());
|
OmsReceivableReceiptDetail existingDetail = existingDetailsMap.get(plan.getId());
|
||||||
|
|
@ -210,6 +226,8 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
detail.setReceiptAmount(plan.getPlanAmount());
|
detail.setReceiptAmount(plan.getPlanAmount());
|
||||||
detail.setReceiptRate(plan.getPlanRate());
|
detail.setReceiptRate(plan.getPlanRate());
|
||||||
detail.setReceiptTime(plan.getPlanReceiptDate());
|
detail.setReceiptTime(plan.getPlanReceiptDate());
|
||||||
|
detail.setPaymentAmountWithoutTax(plan.getPlanAmount().divide(BigDecimal.ONE.add(taxRate), 2, java.math.RoundingMode.HALF_UP));
|
||||||
|
detail.setPaymentAmountTax(detail.getReceiptAmount().subtract(detail.getPaymentAmountWithoutTax()));
|
||||||
detail.setRemark(plan.getRemark());
|
detail.setRemark(plan.getRemark());
|
||||||
detail.setCreateBy(ShiroUtils.getUserId().toString());
|
detail.setCreateBy(ShiroUtils.getUserId().toString());
|
||||||
detail.setReceivableDetailType(OmsReceivableReceiptDetail.ReceivableDetailTypeEnum.NORMAL_RECEIPT.getCode());
|
detail.setReceivableDetailType(OmsReceivableReceiptDetail.ReceivableDetailTypeEnum.NORMAL_RECEIPT.getCode());
|
||||||
|
|
@ -287,23 +305,40 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
}
|
}
|
||||||
|
|
||||||
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = detailService.listByReceivableBillIdList(idList);
|
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = detailService.listByReceivableBillIdList(idList);
|
||||||
Map<Long, Map<String, BigDecimal>> planMap = omsReceivableReceiptDetailList.stream().collect(Collectors.groupingBy(OmsReceivableReceiptDetail::getReceivableBillId,
|
|
||||||
Collectors.groupingBy(
|
Map<Long, Map<Long, OmsReceivableReceiptDetail>> planMap = omsReceivableReceiptDetailList.stream().collect(Collectors.groupingBy(
|
||||||
item -> item.getReceiptStatus() == null ? OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode() : item.getReceiptStatus(),
|
OmsReceivableReceiptDetail::getReceivableBillId,
|
||||||
Collectors.reducing(
|
Collectors.toMap(
|
||||||
BigDecimal.ZERO,
|
OmsReceivableReceiptDetail::getReceiptPlanId,
|
||||||
detail -> (detail.getReceiptAmount()!=null) ? detail.getReceiptAmount() : BigDecimal.ZERO,
|
Function.identity(),
|
||||||
BigDecimal::add
|
(d1, d2) -> d1.getCreateTime().after(d2.getCreateTime()) ? d1 : d2
|
||||||
))));
|
)
|
||||||
|
));
|
||||||
|
|
||||||
for (OmsReceivableBill bill : receivableBills) {
|
for (OmsReceivableBill bill : receivableBills) {
|
||||||
Map<String, BigDecimal> amountMap = planMap.get(bill.getId());
|
Map<Long, OmsReceivableReceiptDetail> paymentDetailMap =
|
||||||
if (CollUtil.isNotEmpty(amountMap)) {
|
planMap.getOrDefault(bill.getId(), Collections.emptyMap());
|
||||||
//已付金额 = 已付款金额-退款金额
|
if (CollUtil.isNotEmpty(paymentDetailMap)) {
|
||||||
bill.setReceivedAmount(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode(), BigDecimal.ZERO)
|
Map<String, BigDecimal> amountMap =
|
||||||
.subtract(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode(), BigDecimal.ZERO)));
|
paymentDetailMap.values().stream()
|
||||||
//未付金额=总金额-已付金额-付款中金额
|
.filter(d -> d.getReceiptAmount() != null)
|
||||||
bill.setUnreceivedAmount(bill.getTotalPriceWithTax().subtract(bill.getReceivedAmount())
|
.collect(Collectors.toMap(
|
||||||
.subtract(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode(), BigDecimal.ZERO)));
|
OmsReceivableReceiptDetail::getReceiptStatus,
|
||||||
|
OmsReceivableReceiptDetail::getReceiptAmount,
|
||||||
|
BigDecimal::add
|
||||||
|
));
|
||||||
|
// 4. 金额计算(集中处理,逻辑更清晰)
|
||||||
|
BigDecimal paidAmount = amountMap
|
||||||
|
.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode(), BigDecimal.ZERO)
|
||||||
|
.add(amountMap.getOrDefault(
|
||||||
|
OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode(), BigDecimal.ZERO));
|
||||||
|
|
||||||
|
BigDecimal waitPayAmount =
|
||||||
|
amountMap.getOrDefault(
|
||||||
|
OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode(), BigDecimal.ZERO);
|
||||||
|
bill.setReceivedAmount(paidAmount);
|
||||||
|
bill.setUnreceivedAmount(bill.getTotalPriceWithTax() .subtract(paidAmount)
|
||||||
|
.subtract(waitPayAmount));
|
||||||
}
|
}
|
||||||
OmsReceivableReceiptPlan lastReceiptPlan = receiptPlanService.firstUnPayPlan(bill.getId());
|
OmsReceivableReceiptPlan lastReceiptPlan = receiptPlanService.firstUnPayPlan(bill.getId());
|
||||||
bill.setLastReceiptPlanId(lastReceiptPlan == null ? -1 : lastReceiptPlan.getId());
|
bill.setLastReceiptPlanId(lastReceiptPlan == null ? -1 : lastReceiptPlan.getId());
|
||||||
|
|
@ -364,11 +399,11 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成应收单编号 SKY+YYMMdd+当日序列号
|
* 生成应收单编号 XYS+YYMMdd+当日序列号
|
||||||
* @return 应收单编号
|
* @return 应收单编号
|
||||||
*/
|
*/
|
||||||
private String generateReceivableBillCode() {
|
private String generateReceivableBillCode() {
|
||||||
String prefix = "SKY";
|
String prefix = "XYS";
|
||||||
// 查询当天已有的最大序列号
|
// 查询当天已有的最大序列号
|
||||||
String codePrefix = prefix + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN);
|
String codePrefix = prefix + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN);
|
||||||
int maxSequence = omsReceivableBillMapper.selectMaxCodeByPrefix(codePrefix);
|
int maxSequence = omsReceivableBillMapper.selectMaxCodeByPrefix(codePrefix);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.sip.service.impl;
|
package com.ruoyi.sip.service.impl;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -9,6 +10,8 @@ import java.util.stream.Collectors;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import com.ruoyi.sip.domain.OmsFinAttachment;
|
import com.ruoyi.sip.domain.OmsFinAttachment;
|
||||||
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
|
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
|
||||||
|
import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
|
||||||
|
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
|
||||||
import com.ruoyi.sip.service.IOmsFinAttachmentService;
|
import com.ruoyi.sip.service.IOmsFinAttachmentService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -130,9 +133,27 @@ public class OmsReceivableReceiptDetailServiceImpl implements IOmsReceivableRece
|
||||||
public List<OmsReceivableReceiptDetail> listByReceivableBillIdList(List<Long> idList) {
|
public List<OmsReceivableReceiptDetail> listByReceivableBillIdList(List<Long> idList) {
|
||||||
if (CollUtil.isNotEmpty(idList)){
|
if (CollUtil.isNotEmpty(idList)){
|
||||||
OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail();
|
OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail();
|
||||||
omsReceivableReceiptDetail.setIdList(idList);
|
omsReceivableReceiptDetail.setReceivableBillIdList(idList);
|
||||||
return omsReceivableReceiptDetailMapper.selectOmsReceivableReceiptDetailList(omsReceivableReceiptDetail);
|
return omsReceivableReceiptDetailMapper.list(omsReceivableReceiptDetail);
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ReceiptDetailDTO> listReceivableByReceiptBillCode(String receiptBillCode) {
|
||||||
|
List<ReceiptDetailDTO> receiptDetailDTOS = omsReceivableReceiptDetailMapper.listReceivableByReceiptBillCode(Collections.singletonList(receiptBillCode));
|
||||||
|
for (ReceiptDetailDTO detailDTO : receiptDetailDTOS) {
|
||||||
|
detailDTO.setReceiptRate(detailDTO.getReceiptAmount()
|
||||||
|
.divide(detailDTO.getTotalPriceWithTax(),4,java.math.RoundingMode.HALF_UP)
|
||||||
|
.multiply(new BigDecimal("100")));
|
||||||
|
}
|
||||||
|
return receiptDetailDTOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OmsReceivableReceiptDetail> listByReceiptBillCode(String receiptBillCode) {
|
||||||
|
OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail();
|
||||||
|
omsReceivableReceiptDetail.setReceiptBillCode(receiptBillCode);
|
||||||
|
return omsReceivableReceiptDetailMapper.list(omsReceivableReceiptDetail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,109 +31,115 @@
|
||||||
<result property="receiptBankOpenAddress" column="receipt_bank_open_address"/>
|
<result property="receiptBankOpenAddress" column="receipt_bank_open_address"/>
|
||||||
<result property="bankNumber" column="bank_number"/>
|
<result property="bankNumber" column="bank_number"/>
|
||||||
<result property="refundStatus" column="refund_status"/>
|
<result property="refundStatus" column="refund_status"/>
|
||||||
|
<result property="remainingAmount" column="remaining_amount"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<!-- 基本字段 -->
|
<!-- 基本字段 -->
|
||||||
<sql id="Base_Column_List">
|
<sql id="selectReceiptBillVo">
|
||||||
id, receipt_bill_code, receipt_bill_type, receipt_time, actual_receipt_time, partner_code, order_code, total_price_with_tax, total_price_without_tax, tax_amount, create_by, create_time, update_by, update_time, remark, del_flag, project_code, project_name, receipt_status, approve_status, approve_node, approve_time, receipt_method, receipt_account_name, receipt_bank_number, receipt_bank_open_address, bank_number, refund_status
|
select
|
||||||
|
t1.id, t1.receipt_bill_code, t1.receipt_bill_type, t1.receipt_time, t1.actual_receipt_time, t1.partner_code,
|
||||||
|
t1.order_code, t1.total_price_with_tax, t1.total_price_without_tax, t1.tax_amount, t1.create_by, t1.create_time, t1.update_by, t1.update_time, t1.remark, t1.del_flag, t1.project_code, t1.project_name, t1.receipt_status, t1.approve_status, t1.approve_node, t1.approve_time, t1.receipt_method, t1.receipt_account_name, t1.receipt_bank_number, t1.receipt_bank_open_address, t1.bank_number, t1.refund_status,
|
||||||
|
t1.remaining_amount,t2.partner_name
|
||||||
|
from oms_receipt_bill t1
|
||||||
|
left join partner_info t2 on t1.partner_code=t2.partner_code
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<!--通过实体作为筛选条件查询-->
|
<!--通过实体作为筛选条件查询-->
|
||||||
<select id="queryAll" resultMap="OmsReceiptBillMap">
|
<select id="queryAll" resultMap="OmsReceiptBillMap">
|
||||||
select
|
|
||||||
<include refid="Base_Column_List"/>
|
<include refid="selectReceiptBillVo"/>
|
||||||
from oms_receipt_bill
|
|
||||||
<where>
|
<where>
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
and id = #{id}
|
and t1.id = #{id}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptBillCode != null and receiptBillCode != ''">
|
<if test="receiptBillCode != null and receiptBillCode != ''">
|
||||||
and receipt_bill_code = #{receiptBillCode}
|
and t1.receipt_bill_code = #{receiptBillCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptBillType != null and receiptBillType != ''">
|
<if test="receiptBillType != null and receiptBillType != ''">
|
||||||
and receipt_bill_type = #{receiptBillType}
|
and t1.receipt_bill_type = #{receiptBillType}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptTime != null">
|
<if test="receiptTime != null">
|
||||||
and receipt_time = #{receiptTime}
|
and t1.receipt_time = #{receiptTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="actualReceiptTime != null">
|
<if test="actualReceiptTime != null">
|
||||||
and actual_receipt_time = #{actualReceiptTime}
|
and t1.actual_receipt_time = #{actualReceiptTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="partnerCode != null and partnerCode != ''">
|
<if test="partnerCode != null and partnerCode != ''">
|
||||||
and partner_code = #{partnerCode}
|
and t1.partner_code = #{partnerCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="orderCode != null and orderCode != ''">
|
<if test="orderCode != null and orderCode != ''">
|
||||||
and order_code = #{orderCode}
|
and t1.order_code = #{orderCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="totalPriceWithTax != null">
|
<if test="totalPriceWithTax != null">
|
||||||
and total_price_with_tax = #{totalPriceWithTax}
|
and t1.total_price_with_tax = #{totalPriceWithTax}
|
||||||
</if>
|
</if>
|
||||||
<if test="totalPriceWithoutTax != null">
|
<if test="totalPriceWithoutTax != null">
|
||||||
and total_price_without_tax = #{totalPriceWithoutTax}
|
and t1.total_price_without_tax = #{totalPriceWithoutTax}
|
||||||
</if>
|
</if>
|
||||||
<if test="taxAmount != null">
|
<if test="taxAmount != null">
|
||||||
and tax_amount = #{taxAmount}
|
and t1.tax_amount = #{taxAmount}
|
||||||
</if>
|
</if>
|
||||||
<if test="createBy != null and createBy != ''">
|
<if test="createBy != null and createBy != ''">
|
||||||
and create_by = #{createBy}
|
and t1.create_by = #{createBy}
|
||||||
</if>
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
and create_time = #{createTime}
|
and t1.create_time = #{createTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="updateBy != null and updateBy != ''">
|
<if test="updateBy != null and updateBy != ''">
|
||||||
and update_by = #{updateBy}
|
and t1.update_by = #{updateBy}
|
||||||
</if>
|
</if>
|
||||||
<if test="updateTime != null">
|
<if test="updateTime != null">
|
||||||
and update_time = #{updateTime}
|
and t1.update_time = #{updateTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="remark != null and remark != ''">
|
<if test="remark != null and remark != ''">
|
||||||
and remark = #{remark}
|
and t1.remark = #{remark}
|
||||||
</if>
|
</if>
|
||||||
<if test="delFlag != null and delFlag != ''">
|
<if test="delFlag != null and delFlag != ''">
|
||||||
and del_flag = #{delFlag}
|
and t1.del_flag = #{delFlag}
|
||||||
</if>
|
</if>
|
||||||
<if test="projectCode != null and projectCode != ''">
|
<if test="projectCode != null and projectCode != ''">
|
||||||
and project_code = #{projectCode}
|
and t1.project_code = #{projectCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="projectName != null and projectName != ''">
|
<if test="projectName != null and projectName != ''">
|
||||||
and project_name = #{projectName}
|
and t1.project_name = #{projectName}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptStatus != null and receiptStatus != ''">
|
<if test="receiptStatus != null and receiptStatus != ''">
|
||||||
and receipt_status = #{receiptStatus}
|
and t1.receipt_status = #{receiptStatus}
|
||||||
</if>
|
</if>
|
||||||
<if test="approveStatus != null and approveStatus != ''">
|
<if test="approveStatus != null and approveStatus != ''">
|
||||||
and approve_status = #{approveStatus}
|
and t1.approve_status = #{approveStatus}
|
||||||
</if>
|
</if>
|
||||||
<if test="approveNode != null and approveNode != ''">
|
<if test="approveNode != null and approveNode != ''">
|
||||||
and approve_node = #{approveNode}
|
and t1.approve_node = #{approveNode}
|
||||||
</if>
|
</if>
|
||||||
<if test="approveTime != null">
|
<if test="approveTime != null">
|
||||||
and approve_time = #{approveTime}
|
and t1.approve_time = #{approveTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptMethod != null and receiptMethod != ''">
|
<if test="receiptMethod != null and receiptMethod != ''">
|
||||||
and receipt_method = #{receiptMethod}
|
and t1.receipt_method = #{receiptMethod}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptAccountName != null and receiptAccountName != ''">
|
<if test="receiptAccountName != null and receiptAccountName != ''">
|
||||||
and receipt_account_name = #{receiptAccountName}
|
and t1.receipt_account_name = #{receiptAccountName}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptBankNumber != null and receiptBankNumber != ''">
|
<if test="receiptBankNumber != null and receiptBankNumber != ''">
|
||||||
and receipt_bank_number = #{receiptBankNumber}
|
and t1.receipt_bank_number = #{receiptBankNumber}
|
||||||
</if>
|
</if>
|
||||||
<if test="receiptBankOpenAddress != null and receiptBankOpenAddress != ''">
|
<if test="receiptBankOpenAddress != null and receiptBankOpenAddress != ''">
|
||||||
and receipt_bank_open_address = #{receiptBankOpenAddress}
|
and t1.receipt_bank_open_address = #{receiptBankOpenAddress}
|
||||||
</if>
|
</if>
|
||||||
<if test="bankNumber != null and bankNumber != ''">
|
<if test="bankNumber != null and bankNumber != ''">
|
||||||
and bank_number = #{bankNumber}
|
and t1.bank_number = #{bankNumber}
|
||||||
</if>
|
</if>
|
||||||
<if test="refundStatus != null and refundStatus != ''">
|
<if test="refundStatus != null and refundStatus != ''">
|
||||||
and refund_status = #{refundStatus}
|
and t1.refund_status = #{refundStatus}
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<!--根据ID查详情-->
|
<!--根据ID查详情-->
|
||||||
<select id="queryById" parameterType="Integer" resultMap="OmsReceiptBillMap">
|
<select id="queryById" parameterType="Long" resultMap="OmsReceiptBillMap">
|
||||||
SELECT id,
|
SELECT id,
|
||||||
receipt_bill_code,
|
receipt_bill_code,
|
||||||
receipt_bill_type,
|
receipt_bill_type,
|
||||||
|
|
@ -161,7 +167,8 @@
|
||||||
receipt_bank_number,
|
receipt_bank_number,
|
||||||
receipt_bank_open_address,
|
receipt_bank_open_address,
|
||||||
bank_number,
|
bank_number,
|
||||||
refund_status
|
refund_status,
|
||||||
|
remaining_amount
|
||||||
FROM oms_receipt_bill
|
FROM oms_receipt_bill
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -171,6 +178,18 @@
|
||||||
FROM oms_receipt_bill
|
FROM oms_receipt_bill
|
||||||
WHERE receipt_bill_code LIKE CONCAT(#{prefix}, '%')
|
WHERE receipt_bill_code LIKE CONCAT(#{prefix}, '%')
|
||||||
</select>
|
</select>
|
||||||
|
<select id="listRemainingAmountByPartnerCodeList" resultType="com.ruoyi.sip.domain.OmsReceiptBill">
|
||||||
|
SELECT
|
||||||
|
sum( remaining_amount ) remaining_amount,partner_code
|
||||||
|
FROM
|
||||||
|
oms_receipt_bill
|
||||||
|
where receipt_status='2' and partner_code in
|
||||||
|
<foreach item="item" collection="list" separator="," open="(" close=")" index="index">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY
|
||||||
|
partner_code
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<!--新增所有列-->
|
<!--新增所有列-->
|
||||||
|
|
@ -258,6 +277,9 @@
|
||||||
<if test="refundStatus != null and refundStatus != ''">
|
<if test="refundStatus != null and refundStatus != ''">
|
||||||
refund_status,
|
refund_status,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="remainingAmount != null">
|
||||||
|
remaining_amount,
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="receiptBillCode != null and receiptBillCode != ''">
|
<if test="receiptBillCode != null and receiptBillCode != ''">
|
||||||
|
|
@ -341,6 +363,9 @@
|
||||||
<if test="refundStatus != null and refundStatus != ''">
|
<if test="refundStatus != null and refundStatus != ''">
|
||||||
#{refundStatus},
|
#{refundStatus},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="remainingAmount != null">
|
||||||
|
#{remainingAmount},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
|
@ -429,6 +454,9 @@
|
||||||
<if test="refundStatus != null and refundStatus != ''">
|
<if test="refundStatus != null and refundStatus != ''">
|
||||||
refund_status = #{refundStatus},
|
refund_status = #{refundStatus},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="remainingAmount != null">
|
||||||
|
remaining_amount = #{remainingAmount},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
@ -447,6 +475,9 @@
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
<delete id="clearRelationReceivable">
|
||||||
|
delete from oms_receivable_receipt_detail where receipt_bill_code=#{code}
|
||||||
|
</delete>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="updateTime" column="update_time" />
|
<result property="updateTime" column="update_time" />
|
||||||
<result property="updateBy" column="update_by" />
|
<result property="updateBy" column="update_by" />
|
||||||
<result property="receivableDetailType" column="receivable_detail_type" />
|
<result property="receivableDetailType" column="receivable_detail_type" />
|
||||||
|
<result property="paymentAmountWithoutTax" column="payment_amount_without_tax" />
|
||||||
|
<result property="paymentAmountTax" column="payment_amount_tax" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectOmsReceivableReceiptDetailVo">
|
<sql id="selectOmsReceivableReceiptDetailVo">
|
||||||
select id, receipt_plan_id, receivable_bill_id, receipt_time, receipt_amount, receipt_rate, receipt_bill_code, remark, create_time, create_by, update_time, receivable_detail_type
|
select id, receipt_plan_id, receivable_bill_id, receipt_time, receipt_amount, receipt_rate, receipt_bill_code, remark, create_time, create_by, update_time, receivable_detail_type, payment_amount_without_tax, payment_amount_tax
|
||||||
from oms_receivable_receipt_detail
|
from oms_receivable_receipt_detail
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
|
@ -51,6 +53,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
FROM
|
FROM
|
||||||
oms_receivable_receipt_detail t1
|
oms_receivable_receipt_detail t1
|
||||||
LEFT JOIN oms_receipt_bill t2 ON t1.receipt_bill_code = t2.receipt_bill_code
|
LEFT JOIN oms_receipt_bill t2 ON t1.receipt_bill_code = t2.receipt_bill_code
|
||||||
|
<where>
|
||||||
|
<if test="receiptPlanId != null ">and t1.receipt_plan_id = #{receiptPlanId}</if>
|
||||||
|
<if test="idList != null and idList.size>0 ">and t1.id in
|
||||||
|
<foreach collection="idList" separator="," close=")" open="(" item="item">#{item}</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="receiptBillCode != null ">and t1.receipt_bill_code = #{receiptBillCode}</if>
|
||||||
|
<if test="receivableBillId != null ">and t1.receivable_bill_id = #{receivableBillId}</if>
|
||||||
|
<if test="receivableBillIdList != null and receivableBillIdList.size>0 ">and t1.receivable_bill_id in
|
||||||
|
<foreach collection="receivableBillIdList" separator="," close=")" open="(" item="item">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
</select>
|
</select>
|
||||||
<select id="selectByPaymentPlanIds" resultType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail">
|
<select id="selectByPaymentPlanIds" resultType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail">
|
||||||
|
|
||||||
|
|
@ -66,6 +81,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</foreach>
|
</foreach>
|
||||||
ORDER BY t1.create_time DESC
|
ORDER BY t1.create_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
<select id="listReceivableByReceiptBillCode" resultType="com.ruoyi.sip.domain.dto.ReceiptDetailDTO">
|
||||||
|
select t1.receipt_amount, t2.receivable_bill_code, t4.project_name, t4.project_code, t2.total_price_with_tax
|
||||||
|
from (SELECT sum(receipt_amount) receipt_amount,
|
||||||
|
receivable_bill_id
|
||||||
|
FROM oms_receivable_receipt_detail
|
||||||
|
WHERE write_off_id is null and receipt_bill_code in
|
||||||
|
<foreach item="item" collection="list" separator="," open="(" close=")" index="">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
group by receivable_bill_id) t1
|
||||||
|
left join oms_receivable_bill t2 on t1.receivable_bill_id = t2.id
|
||||||
|
left join project_order_info t3 on t2.order_code = t3.order_code
|
||||||
|
left join project_info t4 on t3.project_id = t4.id;
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insertOmsReceivableReceiptDetail" parameterType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertOmsReceivableReceiptDetail" parameterType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into oms_receivable_receipt_detail
|
insert into oms_receivable_receipt_detail
|
||||||
|
|
@ -82,6 +111,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||||
<if test="updateTime != null">update_time,</if>
|
<if test="updateTime != null">update_time,</if>
|
||||||
<if test="updateBy != null and updateBy != ''">update_by,</if>
|
<if test="updateBy != null and updateBy != ''">update_by,</if>
|
||||||
|
<if test="paymentAmountWithoutTax != null">payment_amount_without_tax,</if>
|
||||||
|
<if test="paymentAmountTax != null">payment_amount_tax,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="receiptPlanId != null">#{receiptPlanId},</if>
|
<if test="receiptPlanId != null">#{receiptPlanId},</if>
|
||||||
|
|
@ -96,6 +127,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||||
<if test="updateTime != null">#{updateTime},</if>
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
|
<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
|
||||||
|
<if test="paymentAmountWithoutTax != null">#{paymentAmountWithoutTax},</if>
|
||||||
|
<if test="paymentAmountTax != null">#{paymentAmountTax},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
|
@ -112,6 +145,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="remark != null and remark != ''">remark = #{remark},</if>
|
<if test="remark != null and remark != ''">remark = #{remark},</if>
|
||||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||||
|
<if test="paymentAmountWithoutTax != null">payment_amount_without_tax = #{paymentAmountWithoutTax},</if>
|
||||||
|
<if test="paymentAmountTax != null">payment_amount_tax = #{paymentAmountTax},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue