feat(finance): 添加收款单手工核销功能

- 实现收款单手工匹配核销界面,支持应收单与收款单关联
- 新增应收单和收款单过滤查询功能,支持按进货商和单据编号筛选
- 添加核销金额计算逻辑,包含含税和未税金额转换
- 实现收款计划选择功能,支持批量核销操作
- 添加核销金额校验机制,确保应收与收款金额平衡
- 新增收款单核销状态管理和金额更新功能
- 实现核销详情批量处理和数据同步机制
dev_1.0.1
chenhao 2025-12-24 14:48:30 +08:00
parent d3bbf2da62
commit fb3f3c721e
33 changed files with 2188 additions and 143 deletions

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 查询销售核销记录列表
export function listReceivableWriteOff(query) {
return request({
url: '/finance/receivable/writeoff/list',
method: 'get',
params: query
})
}
// 查询销售核销详情
export function getReceivableWriteOff(id) {
return request({
url: '/finance/receivable/writeoff/' + id,
method: 'get'
})
}
// 删除销售核销记录
export function delReceivableWriteOff(ids) {
return request({
url: '/finance/receivable/writeoff/' + ids,
method: 'delete'
})
}

View File

@ -94,3 +94,24 @@ export function submitRefund(data) {
needLoading: true needLoading: true
}) })
} }
// 查询收款单列表 (核销专用)
export function listReceiptForWriteOff(query) {
return request({
url: '/finance/receipt/write-off/list',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: tansParams(query)
})
}
// 手工匹配核销
export function manualReceiptWriteOff(data) {
return request({
url: '/finance/receivable/writeoff',
method: 'post',
data: data
})
}

View File

@ -424,11 +424,6 @@ export default {
this.$emit("submit", submitData); this.$emit("submit", submitData);
} else { } else {
// Pre-receipt logic
if (this.selectedRows.length !== 1) {
this.$modal.msgWarning("请选择一笔订单");
return;
}
if ((this.form.totalPriceWithTax || 0) <= 0) { if ((this.form.totalPriceWithTax || 0) <= 0) {
this.$message.warning("预收金额需要大于0"); this.$message.warning("预收金额需要大于0");
return; return;

View File

@ -0,0 +1,91 @@
<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="partnerName" label="进货商名称" align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="receiptBillCode" label="销售-收款单编号" align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="receiptCreateTime" label="收款单生成时间" align="center" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.receiptBill ? scope.row.receiptBill.createTime : '') }}</span>
</template>
</el-table-column>
<el-table-column prop="receiptBillType" label="收款单类型" align="center">
<template slot-scope="scope">
<dict-tag :options="dict.type.receipt_bill_type" :value="scope.row.receiptBill ? scope.row.receiptBill.receiptBillType : ''"/>
</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="receiptAmount" label="本次核销含税总价(元)" align="center"></el-table-column>
<el-table-column prop="partnerName" label="进货商名称" align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="receivableBillCode" 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', 'receipt_bill_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>

View File

@ -0,0 +1,558 @@
<template>
<div class="app-container">
<!-- 顶部按钮工具栏 -->
<div style="margin-bottom: 20px;">
<el-button type="primary" icon="el-icon-search" size="small" @click="handleOpenReceivableFilter">
</el-button>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleOpenReceiptFilter">
</el-button>
<el-button type="success" icon="el-icon-check" size="small" @click="handleManualWriteOff"></el-button>
</div>
<!-- 应收单过滤弹窗 -->
<el-dialog title="应收单查询条件" :visible.sync="receivableFilterVisible" width="500px" append-to-body>
<el-form :model="queryParams" ref="receivableQueryForm" size="small" label-width="120px">
<el-form-item label="进货商名称" prop="partnerName">
<el-input v-model="queryParams.partnerName" placeholder="请选择进货商" readonly @click.native="handleOpenPartnerSelect">
<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-input>
</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="应收单生成时间">
<el-date-picker
v-model="receivableDateRange"
style="width: 100%"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button icon="el-icon-refresh" size="small" @click="resetReceivableQuery"> </el-button>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery"> </el-button>
</div>
</el-dialog>
<!-- 收款单过滤弹窗 -->
<el-dialog title="收款单查询条件" :visible.sync="receiptFilterVisible" width="500px" append-to-body>
<el-form :model="queryParams" ref="receiptQueryForm" size="small" label-width="120px">
<el-form-item label="进货商名称" prop="partnerName">
<el-input v-model="queryParams.partnerName" placeholder="请选择进货商" readonly @click.native="handleOpenPartnerSelect">
<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-input>
</el-form-item>
<el-form-item label="销售收款单编号" prop="receiptCode">
<el-input v-model="queryParams.receiptCode" placeholder="请输入销售收款单编号" clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="收款单生成时间">
<el-date-picker
v-model="receiptDateRange"
style="width: 100%"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button icon="el-icon-refresh" size="small" @click="resetReceiptQuery"> </el-button>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery"> </el-button>
</div>
</el-dialog>
<div v-if="showTables">
<!-- 销售应收单表格 -->
<h3>销售-应收单</h3>
<div class="table-summary" style="margin-bottom: 10px;">
<span style="font-weight: bold; margin-right: 20px;">应收单本次核销总额: <span
style="color: #409EFF">{{ totalReceivableWriteOffAmount.toFixed(2) }}</span></span>
</div>
<el-table
v-loading="loadingReceivable"
:data="receivableList"
border
@selection-change="handleReceivableSelectionChange"
ref="receivableTable"
row-key="id"
>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="本次核销含税总价(元)" align="center" width="150">
<template slot-scope="scope">
<el-input
v-model="scope.row.currentWriteOffAmount"
placeholder="点击选择计划"
readonly
@click.native="handleOpenPlanSelector(scope.row)"
style="cursor: pointer;"
>
<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-input>
</template>
</el-table-column>
<el-table-column label="未核销含税总价(元)" align="center" prop="unreceivedAmount" width="150"/>
<el-table-column label="未核销未税总价(元)" align="center" prop="unreceivedAmount" width="150">
<template slot-scope="scope">
{{ calculateExcludingTax(scope.row.unreceivedAmount, scope.row.taxRate) }}
</template>
</el-table-column>
<el-table-column label="未核销税额(元)" align="center" width="150">
<template slot-scope="scope">
{{ calculateTax(scope.row.unreceivedAmount, scope.row.taxRate) }}
</template>
</el-table-column>
<el-table-column label="核销中含税总价(元)" align="center" prop="receivedAmount" width="150">
<template slot-scope="scope">
{{
$calc.sub($calc.sub(scope.row.totalPriceWithTax, scope.row.receivedAmount), scope.row.unreceivedAmount)
}}
</template>
</el-table-column>
<el-table-column label="已核销含税总价(元)" align="center" prop="receivedAmount" width="150"/>
<el-table-column label="已核销未税总价(元)" align="center" width="150">
<template slot-scope="scope">
{{ calculateExcludingTax(scope.row.receivedAmount, scope.row.taxRate) }}
</template>
</el-table-column>
<el-table-column label="已核销税额(元)" align="center" width="120">
<template slot-scope="scope">
{{ calculateTax(scope.row.receivedAmount, scope.row.taxRate) }}
</template>
</el-table-column>
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax" width="120"/>
<el-table-column label="进货商名称" fixed="right" align="center" prop="partnerName" width="150"
show-overflow-tooltip/>
<el-table-column label="销售-应收单编号" fixed="right" align="center" prop="receivableBillCode" width="150"
show-overflow-tooltip/>
<el-table-column label="应收单生成时间" fixed="right" align="center" prop="createTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="receivableTotal>0"
:total="receivableTotal"
:pageSizes="[5,10,20,50]"
:page.sync="receivableQueryParams.pageNum"
:limit.sync="receivableQueryParams.pageSize"
@pagination="getReceivableList"
/>
<!-- 销售收款单表格 -->
<h3 style="margin-top: 30px;">销售-收款单</h3>
<div class="table-summary" style="margin-bottom: 10px;">
<span style="font-weight: bold; margin-right: 20px;">本次核销含税总价(): <span
:style="{color: isWriteOffAmountValid ? '#67C23A' : '#F56C6C'}">{{
totalReceiptWriteOffAmount.toFixed(2)
}}</span></span>
<span v-if="!isWriteOffAmountValid" style="color: #F56C6C; font-size: 12px;"><i class="el-icon-warning"></i> </span>
</div>
<el-table v-loading="loadingReceipt" :data="receiptList" border highlight-current-row
@current-change="handleReceiptSelectionChange" row-key="id">
<el-table-column width="55" align="center">
<template slot-scope="scope">
<el-radio v-model="selectedReceiptId" :label="scope.row.receiptBillCode"><i></i></el-radio>
</template>
</el-table-column>
<el-table-column label="本次核销含税总价(元)" align="center" width="150">
<template slot-scope="scope">
<el-input-number
v-model="scope.row.currentWriteOffAmount"
:precision="2"
:step="100"
:min="0"
:max="scope.row.unWrittenAmount || scope.row.receiptAmount"
size="small"
style="width: 100%"
:disabled="selectedReceiptId !== scope.row.receiptBillCode"
/>
</template>
</el-table-column>
<el-table-column label="未核销含税总价(元)" align="center" width="150">
<template slot-scope="scope">
{{ scope.row.remainingAmount || '0.00' }} <!-- Assuming receiptAmount is total initially -->
</template>
</el-table-column>
<el-table-column label="已核销含税总价(元)" align="center" prop="writeOffAmount" width="150"/>
<el-table-column label="已核销未税总价(元)" align="center" width="150" prop="writeOffAmountWithoutTax"/>
<el-table-column label="已核销税额(元)" align="center" width="150" prop="writeOffTaxAmount"/>
<el-table-column label="含税总价(元)" align="center" prop="totalPriceWithTax"/>
<el-table-column label="进货商名称" align="center" prop="partnerName" width="150"
show-overflow-tooltip/>
<el-table-column label="销售-收款单编号" align="center" prop="receiptBillCode" width="150"
show-overflow-tooltip/>
<el-table-column label="收款单生成时间" align="center" prop="createTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" width="80"></el-table-column>
</el-table>
<pagination
v-show="receiptTotal>0"
:total="receiptTotal"
:page.sync="receiptQueryParams.pageNum"
:limit.sync="receiptQueryParams.pageSize"
@pagination="getReceiptList"
:pageSizes="[5,10,20,50]"
/>
</div>
<!-- 弹窗选择应收计划 -->
<el-dialog :title="planDialogTitle" :visible.sync="planDialogVisible" width="70%" append-to-body>
<receipt-plan-selector
v-if="planDialogVisible"
ref="planSelector"
:receivable-data="currentReceivableRow"
:selected-plans="currentReceivableRow ? currentReceivableRow.selectedPlans : []"
:is-init-edit="false"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="planDialogVisible = false"> </el-button>
<el-button type="primary" @click="handlePlanSelectionConfirm"> </el-button>
</div>
</el-dialog>
<!-- 弹窗选择进货商 -->
<select-partner
v-if="partnerSelectVisible"
:visible.sync="partnerSelectVisible"
@partner-selected="handlePartnerSelected"
/>
</div>
</template>
<script>
import {listReceivable} from "@/api/finance/receivable";
import {listReceiptForWriteOff, manualReceiptWriteOff} from "@/api/finance/receive";
import ReceiptPlanSelector from "../../receivable/components/ReceiptPlan.vue";
import SelectPartner from "@/views/system/partner/selectPartner.vue";
export default {
name: "ManualReceiptWriteOff",
components: {ReceiptPlanSelector, SelectPartner},
dicts: ['payment_status', 'payment_bill_type'], // Might need receipt_bill_type if available
data() {
return {
//
receivableFilterVisible: false,
receiptFilterVisible: false,
partnerSelectVisible: false,
//
loadingReceivable: false,
loadingReceipt: false,
//
showTables: false,
//
queryParams: {
partnerName: undefined,
partnerCode: undefined,
receivableBillCode: undefined,
receiptCode: undefined,
},
receivableDateRange: [],
receiptDateRange: [],
//
receivableList: [],
receivableTotal: 0,
receivableQueryParams: {
pageNum: 1,
pageSize: 5,
partnerName: undefined,
partnerCode: undefined,
receivableBillCode: undefined,
unreceivedReceivableAmount: -1,
params: {}
},
selectedReceivables: [], //
//
receiptList: [],
receiptTotal: 0,
receiptQueryParams: {
pageNum: 1,
pageSize: 5,
partnerName: undefined,
partnerCode: undefined,
receiptCode: undefined,
receiptBillType: 'PRE_RECEIPT', // (Assume PRE_RECEIPT or similar exists)
receiptStatus: '2',
params: {}
},
selectedReceiptId: null, // ID (使 BillCode)
selectedReceiptRow: null, //
//
planDialogVisible: false,
currentReceivableRow: null,
planDialogTitle: "选择应收计划"
};
},
watch: {
totalReceivableWriteOffAmount(newVal) {
this.updateReceiptWriteOffAmount();
}
},
computed: {
totalReceivableWriteOffAmount() {
return this.selectedReceivables.reduce((sum, row) => sum + (row.currentWriteOffAmount || 0), 0);
},
totalReceiptWriteOffAmount() {
if (!this.selectedReceiptRow) return 0;
return this.selectedReceiptRow.currentWriteOffAmount || 0;
},
isWriteOffAmountValid() {
// use a small epsilon for float comparison if needed, but direct comparison is usually okay for UI validation
return this.totalReceiptWriteOffAmount <= this.totalReceivableWriteOffAmount + 0.01;
}
},
created() {
this.receivableFilterVisible = true; //
},
methods: {
handleOpenReceivableFilter() {
this.receivableFilterVisible = true;
},
handleOpenReceiptFilter() {
this.receiptFilterVisible = true;
},
handleOpenPartnerSelect() {
this.partnerSelectVisible = true;
},
handlePartnerSelected(row) {
this.queryParams.partnerName = row.partnerName;
this.queryParams.partnerCode = row.partnerCode;
},
/** 搜索按钮操作 */
handleQuery() {
if (!this.queryParams.partnerName) {
this.$modal.msgError("请选择进货商名称");
return;
}
this.receivableFilterVisible = false;
this.receiptFilterVisible = false;
this.showTables = true;
this.receivableQueryParams.pageNum = 1;
this.receiptQueryParams.pageNum = 1;
this.syncParams();
this.getReceivableList();
this.getReceiptList();
},
/** 重置按钮操作 */
resetReceivableQuery() {
this.receivableDateRange = [];
this.queryParams.partnerName = undefined;
this.queryParams.partnerCode = undefined;
this.queryParams.receivableBillCode = undefined;
},
resetReceiptQuery() {
this.receiptDateRange = [];
this.queryParams.partnerName = undefined;
this.queryParams.partnerCode = undefined;
this.queryParams.receiptCode = undefined;
},
syncParams() {
this.receivableQueryParams.partnerName = this.queryParams.partnerName;
this.receivableQueryParams.partnerCode = this.queryParams.partnerCode;
this.receivableQueryParams.receivableBillCode = this.queryParams.receivableBillCode;
this.receivableQueryParams.params = {};
if (null != this.receivableDateRange && '' != this.receivableDateRange) {
this.receivableQueryParams.params["beginTime"] = this.receivableDateRange[0];
this.receivableQueryParams.params["endTime"] = this.receivableDateRange[1];
}
this.receiptQueryParams.partnerName = this.queryParams.partnerName;
this.receiptQueryParams.partnerCode = this.queryParams.partnerCode;
this.receiptQueryParams.receiptCode = this.queryParams.receiptCode;
// this.receiptQueryParams.receiptBillType = 'PRE_RECEIPT'; // Ensure params
this.receiptQueryParams.params = {};
if (null != this.receiptDateRange && '' != this.receiptDateRange) {
this.receiptQueryParams.params["beginTime"] = this.receiptDateRange[0];
this.receiptQueryParams.params["endTime"] = this.receiptDateRange[1];
}
},
getReceivableList() {
this.loadingReceivable = true;
listReceivable(this.receivableQueryParams).then(response => {
this.receivableList = response.rows.map(item => ({
...item,
currentWriteOffAmount: item.planAmount || 0, // Default to planAmount
selectedPlans: (item.lastReceiptPlanId && item.planAmount) ? [{
id: item.lastReceiptPlanId,
planAmount: item.planAmount,
planRate: 0 // Default or derived if available
}] : []
}));
this.receivableTotal = response.total;
this.loadingReceivable = false;
//
this.$refs.receivableTable.clearSelection();
this.selectedReceivables = [];
});
},
getReceiptList() {
this.loadingReceipt = true;
listReceiptForWriteOff(this.receiptQueryParams).then(response => {
this.receiptList = response.rows.map(item => ({
...item,
currentWriteOffAmount: 0, // Initialize
// Mocking fields not yet in standard listReceipt (or assuming defaults)
unWrittenAmount: item.receiptAmount - (item.writtenAmount || 0),
writtenAmount: item.writtenAmount || 0
}));
this.receiptTotal = response.total;
this.loadingReceipt = false;
//
this.selectedReceiptId = null;
this.selectedReceiptRow = null;
});
},
handleReceivableSelectionChange(selection) {
this.selectedReceivables = selection;
},
handleReceiptSelectionChange(currentRow) {
if (currentRow) {
this.selectedReceiptId = currentRow.receiptBillCode;
this.selectedReceiptRow = currentRow;
//
this.updateReceiptWriteOffAmount();
} else {
this.selectedReceiptId = null;
this.selectedReceiptRow = null;
}
},
// Logic for Plan Selection
handleOpenPlanSelector(row) {
this.currentReceivableRow = row;
this.planDialogTitle = `选择应收计划 - ${row.receivableBillCode}`;
this.planDialogVisible = true;
},
handlePlanSelectionConfirm() {
if (this.$refs.planSelector && this.$refs.planSelector.selectedPlan) {
const selected = this.$refs.planSelector.selectedPlan;
this.currentReceivableRow.selectedPlans = selected;
// Calculate sum
const sum = selected.reduce((acc, plan) => acc + (plan.planAmount || 0), 0);
this.currentReceivableRow.currentWriteOffAmount = sum;
this.$modal.msgSuccess(`已选择 ${selected.length} 个计划,总金额 ${sum.toFixed(2)}`);
// 1.
}
this.planDialogVisible = false;
},
// Tax Calculations
calculateTax(amount, taxRate) {
let calculateExcludingTax = this.calculateExcludingTax(amount, taxRate);
return this.$calc.sub(amount, calculateExcludingTax)
},
calculateExcludingTax(amount, taxRate) {
if (!amount) return '0.00';
// Amount / (1 + Rate/100)
const rate = taxRate ?? 0.13;
return this.$calc.div(amount, this.$calc.add(1, rate))
},
//
updateReceiptWriteOffAmount() {
if (this.selectedReceiptRow) {
const receivableSum = this.totalReceivableWriteOffAmount;
const maxAmount = this.selectedReceiptRow.unWrittenAmount || this.selectedReceiptRow.remainingAmount || 0;
if (receivableSum > maxAmount) {
//
this.selectedReceiptRow.currentWriteOffAmount = maxAmount;
this.$modal.msgWarning(`应收单核销总额(${receivableSum.toFixed(2)})超过收款单剩余额度(${maxAmount}),已自动调整为最大可核销额度。`);
} else {
this.selectedReceiptRow.currentWriteOffAmount = receivableSum;
}
}
},
//
handleManualWriteOff() {
if (!this.selectedReceiptRow) {
this.$modal.msgError("请选择一个收款单");
return;
}
if (this.selectedReceivables.length === 0) {
this.$modal.msgError("请至少选择一个应收单");
return;
}
//
if (Math.abs(this.totalReceiptWriteOffAmount - this.totalReceivableWriteOffAmount) > 0.01) {
this.$modal.msgError(`收款单核销金额(${this.totalReceiptWriteOffAmount.toFixed(2)})必须等于应收单核销总额(${this.totalReceivableWriteOffAmount.toFixed(2)})`);
return;
}
const detailList = [];
this.selectedReceivables.forEach(receivable => {
if (receivable.selectedPlans && receivable.selectedPlans.length > 0) {
receivable.selectedPlans.forEach(plan => {
const amount = plan.planAmount;
detailList.push({
receiptPlanId: plan.id, // Assuming ReceiptPlan ID
receivableBillId: receivable.id,
receiptBillCode: this.selectedReceiptRow.receiptBillCode,
receiptAmount: amount, // Assuming receiptAmount is the field
receiptRate: plan.planRate,
receiptAmountWithoutTax: this.calculateExcludingTax(amount, receivable.taxRate),
receiptAmountTax: this.calculateTax(amount, receivable.taxRate)
});
});
}
});
if (detailList.length === 0) {
this.$modal.msgError("请为选中的应收单选择计划(点击放大镜图标)");
return;
}
let partnerCode = this.selectedReceiptRow.partnerCode || this.queryParams.partnerCode;
let partnerName = this.selectedReceiptRow.partnerName || this.queryParams.partnerName;
const data = {
receiptBillId: this.selectedReceiptRow.receiptBillId || this.selectedReceiptRow.id,
partnerCode: partnerCode,
partnerName: partnerName,
detailList: detailList
};
manualReceiptWriteOff(data).then(response => {
this.$modal.msgSuccess("核销成功");
this.handleQuery();
});
}
}
};
</script>
<style scoped>
.table-summary {
background-color: #f8f8f9;
padding: 10px;
border-radius: 4px;
border: 1px solid #ebeef5;
}
</style>

View File

@ -0,0 +1,226 @@
<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="receivableBillCode">
<el-input
v-model="queryParams.receivableBillCode"
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="partnerName">
<el-input
v-model="queryParams.partnerName"
placeholder="请输入进货商"
clearable
/>
</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 HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</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="receiptBillCode" />
<el-table-column label="进货商名称" align="center" prop="partnerName" />
<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>
</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 { listReceivableWriteOff, getReceivableWriteOff, delReceivableWriteOff } from "@/api/finance/receivableWriteoff";
import { listPartner } from "@/api/system/partner";
import WriteOffDetailDrawer from "./WriteOffDetailDrawer";
export default {
name: "WriteOffRecord",
components: {
WriteOffDetailDrawer
},
dicts: ['finance_write_off_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
writeOffList: [],
//
partnerOptions: [],
//
title: "",
//
open: false,
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
writeOffCode: null,
receivableBillCode: null,
receiptBillCode: null,
partnerName: null,
writeOffType: null,
},
//
form: {}
};
},
created() {
this.getList();
this.getPartnerList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listReceivableWriteOff(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.writeOffList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 查询进货商列表 */
getPartnerList() {
listPartner().then(response => {
this.partnerOptions = response.rows;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/** 查看详情 */
handleDetail(row) {
this.loading = true;
getReceivableWriteOff(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 delReceivableWriteOff(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("反核销成功");
}).catch(() => {});
}
}
};
</script>

View File

@ -70,6 +70,9 @@ export default {
} }
}, },
}, },
created() {
this.getList();
},
methods: { methods: {
/** 查询进货商列表 */ /** 查询进货商列表 */
getList() { getList() {

View File

@ -42,7 +42,14 @@ public class OmsReceiptBillController extends BaseController {
List<OmsReceiptBill> list = omsReceiptBillService.queryAll(omsReceiptBill); List<OmsReceiptBill> list = omsReceiptBillService.queryAll(omsReceiptBill);
return getDataTable(list); return getDataTable(list);
} }
@PostMapping("/write-off/list")
@ResponseBody
public TableDataInfo listWriteOff(OmsReceiptBill omsReceiptBill)
{
startPage();
List<OmsReceiptBill> list = omsReceiptBillService.listWriteOff(omsReceiptBill);
return getDataTable(list);
}
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) { public AjaxResult getInfo(@PathVariable("id") Long id) {

View File

@ -0,0 +1,113 @@
package com.ruoyi.sip.controller;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.sip.domain.OmsReceivableWriteOff;
import com.ruoyi.sip.dto.WriteOffDetailResultDto;
import com.ruoyi.sip.dto.WriteOffReceiptRequestDto;
import com.ruoyi.sip.dto.WriteOffRequestDto;
import com.ruoyi.sip.service.IOmsReceivableWriteOffService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Controller
*
* @author zghz
* @date 2025-12-23
*/
@RestController
@RequestMapping("/finance/receivable/writeoff")
public class OmsReceivableWriteOffController extends BaseController
{
@Autowired
private IOmsReceivableWriteOffService omsReceivableWriteOffService;
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:list")
@GetMapping("/list")
public TableDataInfo list(OmsReceivableWriteOff writeOffQueryDto)
{
startPage();
List<OmsReceivableWriteOff> list = omsReceivableWriteOffService.selectOmsReceivableWriteOffList(writeOffQueryDto);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:export")
@Log(title = "销售应收核销单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, OmsReceivableWriteOff writeOffQueryDto)
{
List<OmsReceivableWriteOff> list = omsReceivableWriteOffService.selectOmsReceivableWriteOffList(writeOffQueryDto);
ExcelUtil<OmsReceivableWriteOff> util = new ExcelUtil<OmsReceivableWriteOff>(OmsReceivableWriteOff.class);
util.exportExcel(response, list, "销售应收核销单数据");
}
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return AjaxResult.success(omsReceivableWriteOffService.selectOmsReceivableWriteOffById(id));
}
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:add")
@Log(title = "销售应收核销单", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody WriteOffReceiptRequestDto writeOffRequestDto)
{
Long writeOffId = omsReceivableWriteOffService.userWriteOff(writeOffRequestDto);
return AjaxResult.success();
}
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:edit")
@Log(title = "销售应收核销单", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody OmsReceivableWriteOff omsReceivableWriteOff)
{
return toAjax(omsReceivableWriteOffService.updateOmsReceivableWriteOff(omsReceivableWriteOff));
}
/**
*
*/
@RequiresPermissions("sip:receivable:writeoff:remove")
@Log(title = "销售应收核销单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(omsReceivableWriteOffService.deleteOmsReceivableWriteOffByIds(ids));
}
/**
* ID
*/
@RequiresPermissions("sip:receivable:writeoff:query")
@GetMapping("/details/{writeOffId}")
public AjaxResult getWriteOffDetails(@PathVariable("writeOffId") Long writeOffId)
{
List<WriteOffDetailResultDto> details = omsReceivableWriteOffService.selectWriteOffDetailsByWriteOffId(writeOffId);
return AjaxResult.success(details);
}
}

View File

@ -29,6 +29,7 @@ public class OmsReceiptBill {
*/ */
private String receiptBillCode; private String receiptBillCode;
private List<String> receiptBillCodeList;
/** /**
* (FROM_RECEIVABLE, PRE_RECEIPT) * (FROM_RECEIVABLE, PRE_RECEIPT)
*/ */
@ -163,6 +164,12 @@ public class OmsReceiptBill {
private Long originalBillId; private Long originalBillId;
private OmsFinAttachment attachment; private OmsFinAttachment attachment;
private List<ReceiptDetailDTO> detailDTOList; private List<ReceiptDetailDTO> detailDTOList;
private BigDecimal writeOffAmount;
private BigDecimal writeOffAmountWithoutTax;
private BigDecimal writeOffTaxAmount;
@Getter @Getter
public enum ReceiptBillTypeEnum { public enum ReceiptBillTypeEnum {

View File

@ -30,6 +30,7 @@ public class OmsReceivableReceiptDetail extends BaseEntity
/** 收款计划ID */ /** 收款计划ID */
@Excel(name = "收款计划ID") @Excel(name = "收款计划ID")
private Long receiptPlanId; private Long receiptPlanId;
private List<Long> receiptPlanIdList;
/** 应收单ID */ /** 应收单ID */
@Excel(name = "应收单ID") @Excel(name = "应收单ID")
@ -65,8 +66,10 @@ 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 receiptAmountWithoutTax;
private BigDecimal paymentAmountTax; private BigDecimal receiptAmountTax;
private Long writeOffId;
private List<Long> writeOffIdList;
@Getter @Getter
public enum ReceivableDetailTypeEnum { public enum ReceivableDetailTypeEnum {

View File

@ -0,0 +1,102 @@
package com.ruoyi.sip.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* oms_receivable_write_off
*
* @author zghz
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OmsReceivableWriteOff extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 核销单编号 */
@Excel(name = "核销单编号")
private String writeOffCode;
/** 核销类型 AUTO:系统自动核销 USER:用户手动核销 */
@Excel(name = "核销类型")
private String writeOffType;
/** 收款单编号 */
@Excel(name = "收款单编号")
private String receiptBillCode;
private List<String> receiptBillCodeList;
private String receivableBillCode;
/** 客户编码 */
@Excel(name = "客户编码")
private String partnerCode;
private String partnerName;
/** 本次核销总金额 */
@Excel(name = "本次核销总金额")
private BigDecimal writeOffAmount ;
/** 本次核销未税总金额 */
@Excel(name = "本次核销未税总金额")
private BigDecimal writeOffAmountWithoutTax;
/** 本次核销税额 */
@Excel(name = "本次核销税额")
private BigDecimal writeOffTaxAmount;
/** 核销时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "核销时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date writeOffTime;
/** 备注 */
@Excel(name = "备注")
private String remark;
/** 创建人 */
private String createBy;
private String createByName;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新人 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
private List<ReceiptDetailDTO> detailList;
private OmsReceiptBill receiptBill;
@Getter
public enum WriteOffTypeEnum {
AUTO("AUTO", "自动核销"),
USER("USER", "手动核销"),
;
private final String code;
private final String desc;
WriteOffTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
}
}

View File

@ -0,0 +1,75 @@
package com.ruoyi.sip.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* oms_receivable_write_off_detail
*
* @author zghz
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OmsReceivableWriteOffDetail extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 核销单ID */
private Long writeOffId;
/** 应收单ID */
private Long receivableBillId;
/** 应收单编号 */
@Excel(name = "应收单编号")
private String receivableBillCode;
/** 应收单收款计划ID */
private Long receiptPlanId;
/** 收款单ID */
private Long receiptBillId;
/** 收款单编号 */
@Excel(name = "收款单编号")
private String receiptBillCode;
/** 核销金额 */
@Excel(name = "核销金额")
private BigDecimal writeOffAmount = BigDecimal.ZERO;
/** 本次核销未税总金额 */
@Excel(name = "本次核销未税总金额")
private BigDecimal writeOffAmountWithoutTax = BigDecimal.ZERO;
/** 本次核销税额 */
@Excel(name = "本次核销税额")
private BigDecimal writeOffTaxAmount = BigDecimal.ZERO;
/** 备注 */
@Excel(name = "备注")
private String remark;
/** 创建人 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新人 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.sip.dto;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/** /**
* DTO * DTO
@ -10,6 +11,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
* @author zghz * @author zghz
* @date 2025-12-16 * @date 2025-12-16
*/ */
@Data
public class WriteOffDetailResultDto public class WriteOffDetailResultDto
{ {
/** 主键ID */ /** 主键ID */
@ -52,108 +54,5 @@ public class WriteOffDetailResultDto
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getWriteOffId() {
return writeOffId;
}
public void setWriteOffId(Long writeOffId) {
this.writeOffId = writeOffId;
}
public String getWriteOffCode() {
return writeOffCode;
}
public void setWriteOffCode(String writeOffCode) {
this.writeOffCode = writeOffCode;
}
public Long getPayableBillId() {
return payableBillId;
}
public void setPayableBillId(Long payableBillId) {
this.payableBillId = payableBillId;
}
public String getPayableBillCode() {
return payableBillCode;
}
public void setPayableBillCode(String payableBillCode) {
this.payableBillCode = payableBillCode;
}
public Long getPaymentPlanId() {
return paymentPlanId;
}
public void setPaymentPlanId(Long paymentPlanId) {
this.paymentPlanId = paymentPlanId;
}
public Long getPaymentBillId() {
return paymentBillId;
}
public void setPaymentBillId(Long paymentBillId) {
this.paymentBillId = paymentBillId;
}
public String getPaymentBillCode() {
return paymentBillCode;
}
public void setPaymentBillCode(String paymentBillCode) {
this.paymentBillCode = paymentBillCode;
}
public BigDecimal getWriteOffAmount() {
return writeOffAmount;
}
public void setWriteOffAmount(BigDecimal writeOffAmount) {
this.writeOffAmount = writeOffAmount;
}
public BigDecimal getWriteOffAmountWithoutTax() {
return writeOffAmountWithoutTax;
}
public void setWriteOffAmountWithoutTax(BigDecimal writeOffAmountWithoutTax) {
this.writeOffAmountWithoutTax = writeOffAmountWithoutTax;
}
public BigDecimal getWriteOffTaxAmount() {
return writeOffTaxAmount;
}
public void setWriteOffTaxAmount(BigDecimal writeOffTaxAmount) {
this.writeOffTaxAmount = writeOffTaxAmount;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
} }

View File

@ -0,0 +1,44 @@
package com.ruoyi.sip.dto;
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* DTO
*
* @author zghz
* @date 2025-12-16
*/
@Data
public class WriteOffReceiptRequestDto
{
/**
* ID
*/
@NotNull(message = "收款单ID不能为空")
private Long receiptBillId;
/**
*
*/
private List<OmsReceivableReceiptDetail> detailList;
/**
*
*/
@NotBlank(message = "进货商代码不能为空")
private String partnerCode;
@NotBlank(message = "进货商名称不能为空")
private String partnerName;
/**
*
*/
private String remark;
}

View File

@ -17,7 +17,7 @@ public interface OmsPayablePaymentDetailMapper {
List<OmsPayablePaymentDetail> selectByPaymentPlanIds(@Param("paymentPlanIds") List<Long> paymentPlanIds); List<OmsPayablePaymentDetail> selectByPaymentPlanIds(@Param("paymentPlanIds") List<Long> paymentPlanIds);
int deleteByWriteOffIds(@Param("ids") Long[] ids); int clearWriteOffByWriteOffId(@Param("ids") Long[] ids);
List<PaymentBillPayableDetailDTO> listPayableByWriteOffId(List<Long> writeOffIds); List<PaymentBillPayableDetailDTO> listPayableByWriteOffId(List<Long> writeOffIds);

View File

@ -51,4 +51,8 @@ public interface OmsReceiptBillMapper {
List<OmsReceiptBill> listRemainingAmountByPartnerCodeList(List<String> collect); List<OmsReceiptBill> listRemainingAmountByPartnerCodeList(List<String> collect);
void clearRelationReceivable(String receiptBillCode); void clearRelationReceivable(String receiptBillCode);
OmsReceiptBill queryByCode(String code);
void updateReturnWriteOffBatch(List<OmsReceiptBill> updateBills);
} }

View File

@ -67,4 +67,10 @@ public interface OmsReceivableReceiptDetailMapper
List<ReceiptDetailDTO> listReceivableByReceiptBillCode(List<String> receiptBillCode); List<ReceiptDetailDTO> listReceivableByReceiptBillCode(List<String> receiptBillCode);
void insertBatch(List<OmsReceivableReceiptDetail> addList); void insertBatch(List<OmsReceivableReceiptDetail> addList);
List<ReceiptDetailDTO> listReceivableByWriteOffId(List<Long> writeOffIds);
void updateWriteOffIdBatch(List<OmsReceivableReceiptDetail> updateList);
void clearWriteOffByWriteOffId(List<Long> ids);
} }

View File

@ -0,0 +1,66 @@
package com.ruoyi.sip.mapper;
import java.util.List;
import com.ruoyi.sip.domain.OmsReceivableWriteOff;
/**
* Mapper
*
* @author zghz
* @date 2025-12-23
*/
public interface OmsReceivableWriteOffMapper
{
/**
*
*
* @param id ID
* @return
*/
public OmsReceivableWriteOff selectOmsReceivableWriteOffById(Long id);
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
public List<OmsReceivableWriteOff> selectOmsReceivableWriteOffList(OmsReceivableWriteOff omsReceivableWriteOff);
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
public int insertOmsReceivableWriteOff(OmsReceivableWriteOff omsReceivableWriteOff);
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
public int updateOmsReceivableWriteOff(OmsReceivableWriteOff omsReceivableWriteOff);
/**
*
*
* @param id ID
* @return
*/
public int deleteOmsReceivableWriteOffById(Long id);
/**
*
*
* @param ids ID
* @return
*/
public int deleteOmsReceivableWriteOffByIds(Long[] ids);
int selectMaxCodeByPrefix(String codePrefix);
List<OmsReceivableWriteOff> listByIds(Long[] ids);
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.sip.service; package com.ruoyi.sip.service;
import com.ruoyi.sip.domain.OmsPayablePaymentDetail; import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
import com.ruoyi.sip.domain.OmsPayableWriteOffDetail;
import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO; import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
import java.util.List; import java.util.List;
@ -24,7 +23,7 @@ public interface IOmsPayablePaymentDetailService {
void insertBatch(List<OmsPayablePaymentDetail> detailList); void insertBatch(List<OmsPayablePaymentDetail> detailList);
int deleteByWriteOffIds(Long[] ids); int clearWriteOffByWriteOffId(Long[] ids);
void updateBatch(List<OmsPayablePaymentDetail> updateList); void updateBatch(List<OmsPayablePaymentDetail> updateList);

View File

@ -2,7 +2,9 @@ package com.ruoyi.sip.service;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.sip.domain.OmsFinAttachment; import com.ruoyi.sip.domain.OmsFinAttachment;
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 org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
@ -25,6 +27,7 @@ public interface IOmsReceiptBillService {
* ID * ID
*/ */
OmsReceiptBill queryById(Long id); OmsReceiptBill queryById(Long id);
OmsReceiptBill queryByCode(String code);
/** /**
* *
@ -55,6 +58,10 @@ public interface IOmsReceiptBillService {
AjaxResult applyRefund(OmsReceiptBill omsReceiptBill); AjaxResult applyRefund(OmsReceiptBill omsReceiptBill);
AjaxResult uploadReceipt(OmsFinAttachment attachment, MultipartFile file) throws IOException; AjaxResult uploadReceipt(OmsFinAttachment attachment, MultipartFile file) throws IOException;
void returnWriteOff(List<String> collect, List<OmsReceivableReceiptDetail> omsReceivableReceiptDetails);
List<OmsReceiptBill> listWriteOff(OmsReceiptBill omsReceiptBill);
} }

View File

@ -2,7 +2,6 @@ package com.ruoyi.sip.service;
import java.util.List; import java.util.List;
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; import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
@ -73,4 +72,14 @@ public interface IOmsReceivableReceiptDetailService
List<OmsReceivableReceiptDetail> listByReceiptBillCode(String receiptBillCode); List<OmsReceivableReceiptDetail> listByReceiptBillCode(String receiptBillCode);
void applyRefund(String originalReceiptBillCode, String targetReceiptBillCode); void applyRefund(String originalReceiptBillCode, String targetReceiptBillCode);
List<ReceiptDetailDTO> listReceivableByWriteOffId(List<Long> longs);
void updateWriteOffIdBatch(List<OmsReceivableReceiptDetail> updateList);
List<OmsReceivableReceiptDetail> listByWriteOffIds(Long[] ids);
void clearWriteOffByWriteOffId(List<Long> ids);
List<OmsReceivableReceiptDetail> listByPlanIdList(List<Long> planIdList);
} }

View File

@ -0,0 +1,77 @@
package com.ruoyi.sip.service;
import com.ruoyi.sip.domain.OmsReceivableWriteOff;
import com.ruoyi.sip.dto.WriteOffDetailResultDto;
import com.ruoyi.sip.dto.WriteOffReceiptRequestDto;
import com.ruoyi.sip.dto.WriteOffRequestDto;
import java.util.List;
/**
* Service
*
* @author zghz
* @date 2025-12-23
*/
public interface IOmsReceivableWriteOffService
{
/**
*
*
* @param id ID
* @return
*/
public OmsReceivableWriteOff selectOmsReceivableWriteOffById(Long id);
/**
*
*
* @param writeOffQueryDto
* @return
*/
public List<OmsReceivableWriteOff> selectOmsReceivableWriteOffList(OmsReceivableWriteOff writeOffQueryDto);
/**
*
*
* @param writeOffRequestDto
* @return
*/
public Long userWriteOff(WriteOffReceiptRequestDto writeOffRequestDto);
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
public int updateOmsReceivableWriteOff(OmsReceivableWriteOff omsReceivableWriteOff);
/**
*
*
* @param ids ID
* @return
*/
public int deleteOmsReceivableWriteOffByIds(Long[] ids);
/**
*
*
* @param id ID
* @return
*/
public int deleteOmsReceivableWriteOffById(Long id);
/**
* ID
*
* @param writeOffId ID
* @return
*/
public List<WriteOffDetailResultDto> selectWriteOffDetailsByWriteOffId(Long writeOffId);
List<OmsReceivableWriteOff> listByReceiptBillCodeList(List<String> collect);
void autoWriteOff(WriteOffReceiptRequestDto writeOffRequestDto);
}

View File

@ -142,11 +142,11 @@ public class OmsPayablePaymentDetailServiceImpl implements IOmsPayablePaymentDet
} }
@Override @Override
public int deleteByWriteOffIds(Long[] ids) { public int clearWriteOffByWriteOffId(Long[] ids) {
if (ids == null || ids.length == 0) { if (ids == null || ids.length == 0) {
return 0; return 0;
} }
return omsPayablePaymentDetailMapper.deleteByWriteOffIds(ids); return omsPayablePaymentDetailMapper.clearWriteOffByWriteOffId(ids);
} }
@Override @Override

View File

@ -14,7 +14,6 @@ import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
import com.ruoyi.sip.dto.WriteOffDetailResultDto; import com.ruoyi.sip.dto.WriteOffDetailResultDto;
import com.ruoyi.sip.dto.WriteOffRequestDto; import com.ruoyi.sip.dto.WriteOffRequestDto;
import com.ruoyi.sip.mapper.OmsPayableWriteOffMapper; import com.ruoyi.sip.mapper.OmsPayableWriteOffMapper;
import com.ruoyi.sip.mapper.OmsPaymentBillMapper;
import com.ruoyi.sip.service.IOmsPayableBillService; import com.ruoyi.sip.service.IOmsPayableBillService;
import com.ruoyi.sip.service.IOmsPayablePaymentDetailService; import com.ruoyi.sip.service.IOmsPayablePaymentDetailService;
import com.ruoyi.sip.service.IOmsPayableWriteOffService; import com.ruoyi.sip.service.IOmsPayableWriteOffService;
@ -138,6 +137,8 @@ public class OmsPayableWriteOffServiceImpl implements IOmsPayableWriteOffService
// 保存核销主记录 // 保存核销主记录
omsPayableWriteOffMapper.insertOmsPayableWriteOff(writeOff); omsPayableWriteOffMapper.insertOmsPayableWriteOff(writeOff);
// 保存核销明细 // 保存核销明细
//todo 检验只有一条数据
for (OmsPayablePaymentDetail omsPayablePaymentDetail : writeOffRequestDto.getDetailList()) { for (OmsPayablePaymentDetail omsPayablePaymentDetail : writeOffRequestDto.getDetailList()) {
omsPayablePaymentDetail.setPayableDetailType(OmsPayablePaymentDetail.PayableDetailTypeEnum.PREPAY_WRITE_OFF.getCode()); omsPayablePaymentDetail.setPayableDetailType(OmsPayablePaymentDetail.PayableDetailTypeEnum.PREPAY_WRITE_OFF.getCode());
omsPayablePaymentDetail.setPaymentTime(DateUtils.getNowDate()); omsPayablePaymentDetail.setPaymentTime(DateUtils.getNowDate());
@ -200,7 +201,7 @@ public class OmsPayableWriteOffServiceImpl implements IOmsPayableWriteOffService
// 批量删除对应的支付详情记录 // 批量删除对应的支付详情记录
if (ids != null && ids.length > 0) { if (ids != null && ids.length > 0) {
// 使用专门的方法删除 // 使用专门的方法删除
omsPayablePaymentDetailService.deleteByWriteOffIds(ids); omsPayablePaymentDetailService.clearWriteOffByWriteOffId(ids);
} }
// 获取涉及的应付单ID用于后续更新应付单的支付金额 // 获取涉及的应付单ID用于后续更新应付单的支付金额

View File

@ -15,20 +15,15 @@ import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
import com.ruoyi.sip.dto.WriteOffRequestDto; import com.ruoyi.sip.dto.WriteOffRequestDto;
import com.ruoyi.sip.mapper.OmsReceiptBillMapper; import com.ruoyi.sip.mapper.OmsReceiptBillMapper;
import com.ruoyi.sip.service.IOmsFinAttachmentService; import com.ruoyi.sip.service.*;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.math.BigDecimal;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -49,6 +44,9 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
@Autowired @Autowired
private IOmsFinAttachmentService attachmentService; private IOmsFinAttachmentService attachmentService;
@Autowired
private IOmsReceivableWriteOffService omsReceivableWriteOffService;
/** /**
* *
* *
@ -75,6 +73,11 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
return receiptBill; return receiptBill;
} }
@Override
public OmsReceiptBill queryByCode(String code) {
return omsReceiptBillMapper.queryByCode(code);
}
@Override @Override
public int insert(OmsReceiptBill omsReceiptBill) { public int insert(OmsReceiptBill omsReceiptBill) {
@ -296,6 +299,133 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService {
} }
return AjaxResult.success(attachment); return AjaxResult.success(attachment);
} }
@Override
public void returnWriteOff(List<String> collect, List<OmsReceivableReceiptDetail> omsReceivableReceiptDetails) {
OmsReceiptBill receiptBill = new OmsReceiptBill();
receiptBill.setReceiptBillCodeList(collect);
List<OmsReceiptBill> billList = queryAll(receiptBill);
Map<String, List<OmsReceiptBill>> listMap = billList.stream()
.collect(Collectors.groupingBy(OmsReceiptBill::getReceiptBillType));
// 处理预收
List<OmsReceiptBill> preBillList = listMap.remove(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode());
// 预收处理逻辑
// 1:通过omsPayablePaymentDetailService查询对应的详情然后根据paymentBillCode分组
// 将含税金额总和计算出来,加在预付单的剩余额度上
// 按付款单code分组核销详情
Map<String, List<OmsReceivableReceiptDetail>> groupedDetails =
omsReceivableReceiptDetails.stream()
.filter(detail -> detail.getReceiptBillCode() != null)
.collect(Collectors.groupingBy(OmsReceivableReceiptDetail::getReceiptBillCode));
if (CollUtil.isNotEmpty(preBillList)) {
// 计算每个付款单的核销金额合计
Map<String, BigDecimal> paymentBillWriteOffAmountMap = groupedDetails.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().stream()
.map(OmsReceivableReceiptDetail::getReceiptAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add)
));
// 更新预付单的剩余额度 - 批量操作
StringJoiner detailIds = new StringJoiner(",");
List<OmsReceiptBill> updateBills = preBillList.stream()
.map(prePaymentBill -> {
BigDecimal increaseAmount = paymentBillWriteOffAmountMap.getOrDefault(
prePaymentBill.getReceiptBillCode(), BigDecimal.ZERO);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = groupedDetails.get(prePaymentBill.getReceiptBillCode());
if (CollUtil.isNotEmpty(omsReceivableReceiptDetailList)) {
for (OmsReceivableReceiptDetail detail : omsReceivableReceiptDetailList) {
detailIds.add(detail.getId().toString());
}
}
if (increaseAmount.compareTo(BigDecimal.ZERO) > 0) {
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(prePaymentBill.getId());
// 在原剩余额度基础上加回本次核销金额
BigDecimal newResidueAmount = prePaymentBill.getRemainingAmount()
.add(increaseAmount);
updateBill.setRemainingAmount(newResidueAmount);
return updateBill;
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(updateBills)) {
for (OmsReceiptBill bill : updateBills) {
update(bill);
}
}
//预收单的detail直接删除
if (detailIds.length() > 0) {
omsReceivableReceiptDetailService.deleteOmsReceivableReceiptDetailByIds(detailIds.toString());
}
}
//处理其余数据
if (CollUtil.isNotEmpty(listMap.values())) {
List<OmsReceiptBill> updateBills = new ArrayList<>();
List<Long> writeOffIdList = new ArrayList<>();
for (List<OmsReceiptBill> omsReceiptBillList : listMap.values()) {
for (OmsReceiptBill tempBill : omsReceiptBillList) {
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(tempBill.getId());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode());
updateBill.setActualReceiptTime(null);
updateBills.add(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = groupedDetails.get(tempBill.getReceiptBillCode());
if (CollUtil.isNotEmpty(omsReceivableReceiptDetailList)) {
for (OmsReceivableReceiptDetail omsReceivableReceiptDetail : omsReceivableReceiptDetailList) {
if (omsReceivableReceiptDetail.getWriteOffId() != null) {
writeOffIdList.add(omsReceivableReceiptDetail.getWriteOffId());
}
}
}
}
}
if (CollUtil.isNotEmpty(updateBills)) {
omsReceiptBillMapper.updateReturnWriteOffBatch(updateBills);
attachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsReceiptBill::getId).collect(Collectors.toList()), OmsFinAttachment.RelatedBillTypeEnum.PAYMENT.getCode());
}
omsReceivableReceiptDetailService.clearWriteOffByWriteOffId(writeOffIdList);
}
}
@Override
public List<OmsReceiptBill> listWriteOff(OmsReceiptBill omsReceiptBill) {
omsReceiptBill.setRemainingAmount(new BigDecimal("-1"));
List<OmsReceiptBill> omsReceiptBills = omsReceiptBillMapper.queryAll(omsReceiptBill);
if (CollUtil.isEmpty(omsReceiptBills)) {
return omsReceiptBills;
}
//实时计算已核销金额 查询核销数据
List<OmsReceivableWriteOff> omsReceivableWriteOffs = omsReceivableWriteOffService.listByReceiptBillCodeList(omsReceiptBills.stream().map(OmsReceiptBill::getReceiptBillCode).collect(Collectors.toList()));
Map<String, List<OmsReceivableWriteOff>> writeOffListMap = omsReceivableWriteOffs.stream().collect(Collectors.groupingBy(OmsReceivableWriteOff::getReceiptBillCode));
for (OmsReceiptBill receiptBill : omsReceiptBills) {
List<OmsReceivableWriteOff> writeOffList = writeOffListMap.get(receiptBill.getReceiptBillCode());
BigDecimal writeOffAmount = BigDecimal.ZERO;
BigDecimal writeOffAmountWithoutTax = BigDecimal.ZERO;
BigDecimal writeOffTaxAmount = BigDecimal.ZERO;
if (CollUtil.isNotEmpty(writeOffList)) {
for (OmsReceivableWriteOff omsReceivableWriteOff : writeOffList) {
writeOffAmount = writeOffAmount.add(omsReceivableWriteOff.getWriteOffAmount());
writeOffAmountWithoutTax = writeOffAmountWithoutTax.add(omsReceivableWriteOff.getWriteOffAmountWithoutTax());
writeOffTaxAmount = writeOffTaxAmount.add(omsReceivableWriteOff.getWriteOffTaxAmount());
}
}
receiptBill.setWriteOffAmount(writeOffAmount);
receiptBill.setWriteOffAmountWithoutTax(writeOffAmountWithoutTax);
receiptBill.setWriteOffTaxAmount(writeOffTaxAmount);
}
return omsReceiptBills;
}
} }

View File

@ -230,8 +230,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.setReceiptAmountWithoutTax(plan.getPlanAmount().divide(BigDecimal.ONE.add(taxRate), 2, java.math.RoundingMode.HALF_UP));
detail.setPaymentAmountTax(detail.getReceiptAmount().subtract(detail.getPaymentAmountWithoutTax())); detail.setReceiptAmountTax(detail.getReceiptAmount().subtract(detail.getReceiptAmountWithoutTax()));
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());

View File

@ -183,4 +183,45 @@ public class OmsReceivableReceiptDetailServiceImpl implements IOmsReceivableRece
omsReceivableReceiptDetailMapper.insertBatch(addList); omsReceivableReceiptDetailMapper.insertBatch(addList);
} }
} }
@Override
public List<ReceiptDetailDTO> listReceivableByWriteOffId(List<Long> writeOffIds) {
if (CollUtil.isEmpty(writeOffIds)){
return Collections.emptyList();
}
List<ReceiptDetailDTO> detailDTOList=omsReceivableReceiptDetailMapper.listReceivableByWriteOffId(writeOffIds);
return detailDTOList;
}
@Override
public void updateWriteOffIdBatch(List<OmsReceivableReceiptDetail> updateList) {
omsReceivableReceiptDetailMapper.updateWriteOffIdBatch(updateList);
}
@Override
public List<OmsReceivableReceiptDetail> listByWriteOffIds(Long[] ids) {
if (ids == null || ids.length == 0) {
return new ArrayList<>();
}
OmsReceivableReceiptDetail query = new OmsReceivableReceiptDetail();
query.setWriteOffIdList(java.util.Arrays.asList(ids));
return omsReceivableReceiptDetailMapper.list(query);
}
@Override
public void clearWriteOffByWriteOffId(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return ;
}
omsReceivableReceiptDetailMapper.clearWriteOffByWriteOffId(ids);
}
@Override
public List<OmsReceivableReceiptDetail> listByPlanIdList(List<Long> planIdList) {
OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail();
omsReceivableReceiptDetail.setReceiptPlanIdList(planIdList);
return omsReceivableReceiptDetailMapper.list(omsReceivableReceiptDetail);
}
} }

View File

@ -0,0 +1,314 @@
package com.ruoyi.sip.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.sip.domain.OmsPayablePaymentDetail;
import com.ruoyi.sip.domain.OmsReceiptBill;
import com.ruoyi.sip.domain.OmsReceivableReceiptDetail;
import com.ruoyi.sip.domain.OmsReceivableWriteOff;
import com.ruoyi.sip.domain.dto.ReceiptDetailDTO;
import com.ruoyi.sip.dto.WriteOffDetailResultDto;
import com.ruoyi.sip.dto.WriteOffReceiptRequestDto;
import com.ruoyi.sip.mapper.OmsReceivableWriteOffMapper;
import com.ruoyi.sip.service.IOmsReceiptBillService;
import com.ruoyi.sip.service.IOmsReceivableBillService;
import com.ruoyi.sip.service.IOmsReceivableReceiptDetailService;
import com.ruoyi.sip.service.IOmsReceivableWriteOffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* Service
*
* @author zghz
* @date 2025-12-23
*/
@Service
public class OmsReceivableWriteOffServiceImpl implements IOmsReceivableWriteOffService
{
@Autowired
private OmsReceivableWriteOffMapper omsReceivableWriteOffMapper;
@Autowired
private IOmsReceiptBillService omsReceiptBillService;
@Autowired
private IOmsReceivableReceiptDetailService omsReceivableReceiptDetailService;
@Autowired
private IOmsReceivableBillService receivableBillService;
/**
*
*
* @param id ID
* @return
*/
@Override
public OmsReceivableWriteOff selectOmsReceivableWriteOffById(Long id)
{
OmsReceivableWriteOff omsReceivableWriteOff = omsReceivableWriteOffMapper.selectOmsReceivableWriteOffById(id);
OmsReceiptBill omsReceiptBill = omsReceiptBillService.queryByCode(omsReceivableWriteOff.getReceiptBillCode());
omsReceivableWriteOff.setReceiptBill(omsReceiptBill);
// 这里需要获取核销详情列表但目前没有对应的detail service
List<ReceiptDetailDTO> detailDTOList = omsReceivableReceiptDetailService.listReceivableByWriteOffId(Collections.singletonList(id));
omsReceivableWriteOff.setDetailList(detailDTOList);
return omsReceivableWriteOff;
}
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
@Override
public List<OmsReceivableWriteOff> selectOmsReceivableWriteOffList(OmsReceivableWriteOff omsReceivableWriteOff)
{
return omsReceivableWriteOffMapper.selectOmsReceivableWriteOffList(omsReceivableWriteOff);
}
/**
*
*
* @param writeOffRequestDto
* @return
*/
@Override
@Transactional
public Long userWriteOff(WriteOffReceiptRequestDto writeOffRequestDto)
{
if (CollUtil.isEmpty(writeOffRequestDto.getDetailList())){
throw new ServiceException("请选择核销明细");
}
// 获取收款单信息
OmsReceiptBill receiptBill = omsReceiptBillService.queryById(writeOffRequestDto.getReceiptBillId());
if (receiptBill == null) {
throw new ServiceException("收款单不存在");
}
// 创建核销主记录
OmsReceivableWriteOff writeOff = new OmsReceivableWriteOff();
writeOff.setWriteOffCode(generateWriteOffCode());
// 默认为用户手动核销
writeOff.setWriteOffType(OmsReceivableWriteOff.WriteOffTypeEnum.USER.getCode());
writeOff.setReceiptBillCode(receiptBill.getReceiptBillCode());
writeOff.setPartnerCode(writeOffRequestDto.getPartnerCode());
writeOff.setPartnerName(writeOffRequestDto.getPartnerName());
writeOff.setWriteOffTime(new Date());
writeOff.setRemark(writeOffRequestDto.getRemark());
// 计算总金额和相关税额
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal totalAmountWithoutTax = BigDecimal.ZERO;
BigDecimal totalTaxAmount = BigDecimal.ZERO;
// 将传入的detailList转换为OmsReceivableReceiptDetail类型进行处理
for (OmsReceivableReceiptDetail item : writeOffRequestDto.getDetailList()) {
totalAmount = totalAmount.add(item.getReceiptAmount());
totalAmountWithoutTax = totalAmountWithoutTax.add(item.getReceiptAmountWithoutTax());
totalTaxAmount = totalTaxAmount.add(item.getReceiptAmountTax());
}
writeOff.setWriteOffAmount(totalAmount);
writeOff.setWriteOffAmountWithoutTax(totalAmountWithoutTax);
writeOff.setWriteOffTaxAmount(totalTaxAmount);
// 设置创建时间
writeOff.setCreateTime(new Date());
writeOff.setCreateBy(ShiroUtils.getUserId().toString());
writeOff.setUpdateTime(new Date());
// 保存核销主记录
omsReceivableWriteOffMapper.insertOmsReceivableWriteOff(writeOff);
//预付额度减少
OmsReceiptBill updateBill = new OmsReceiptBill();
BigDecimal decimal = receiptBill.getRemainingAmount().subtract(totalAmount);
if (decimal.compareTo(BigDecimal.ZERO) < 0) {
throw new RuntimeException("核销金额不能大于预付剩余额度");
}
updateBill.setRemainingAmount(decimal);
updateBill.setId(receiptBill.getId());
omsReceiptBillService.update(updateBill);
List<Long> collect = writeOffRequestDto.getDetailList().stream().map(OmsReceivableReceiptDetail::getReceiptPlanId).distinct().collect(Collectors.toList());
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByPlanIdList(collect);
if (CollUtil.isNotEmpty(omsReceivableReceiptDetailList)){
throw new ServiceException("应收单的付款计划已被处理,请刷新后重试");
}
// 保存核销明细
for (OmsReceivableReceiptDetail detail : writeOffRequestDto.getDetailList()) {
detail.setReceivableDetailType(OmsReceivableReceiptDetail.ReceivableDetailTypeEnum.PRE_RECEIVE_WRITE_OFF.getCode());
detail.setReceiptTime(DateUtils.getNowDate());
detail.setCreateBy(ShiroUtils.getUserId().toString());
detail.setWriteOffId(writeOff.getId());
omsReceivableReceiptDetailService.insertOmsReceivableReceiptDetail(detail);
}
receivableBillService.updateReceiptAmount(writeOffRequestDto.getDetailList().stream().map(OmsReceivableReceiptDetail::getReceivableBillId).distinct().collect(Collectors.toList()));
return writeOff.getId();
}
private String generateWriteOffCode() {
String prefix = "SKHX";
// 查询当天已有的最大序列号
String codePrefix = prefix + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN);
int maxSequence = omsReceivableWriteOffMapper.selectMaxCodeByPrefix(codePrefix);
// 生成新的序列号
int newSequence = maxSequence + 1;
// 序列号补零到4位
String sequenceStr = String.format("%04d", newSequence);
return codePrefix + sequenceStr;
}
/**
*
*
* @param omsReceivableWriteOff
* @return
*/
@Override
public int updateOmsReceivableWriteOff(OmsReceivableWriteOff omsReceivableWriteOff)
{
return omsReceivableWriteOffMapper.updateOmsReceivableWriteOff(omsReceivableWriteOff);
}
/**
*
*
* @param ids ID
* @return
*/
@Override
@Transactional
public int deleteOmsReceivableWriteOffByIds(Long[] ids)
{
// 反核销逻辑
List<OmsReceivableWriteOff> omsReceivableWriteOffs = omsReceivableWriteOffMapper.listByIds(ids);
if (CollUtil.isEmpty(omsReceivableWriteOffs)) {
return 0;
}
// 通过writeOffId获取对应的收款详情记录
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetails =
omsReceivableReceiptDetailService.listByWriteOffIds(ids);
// 处理收款单
omsReceiptBillService.returnWriteOff(omsReceivableWriteOffs.stream()
.map(OmsReceivableWriteOff::getReceiptBillCode).collect(Collectors.toList()),omsReceivableReceiptDetails);
// 获取涉及的应收单ID用于后续更新应收单的收款金额
List<Long> receivableBillIds = omsReceivableReceiptDetails.stream()
.map(OmsReceivableReceiptDetail::getReceivableBillId)
.distinct()
.collect(Collectors.toList());
// 根据对应的应收单id更新对应的数据
if (CollUtil.isNotEmpty(receivableBillIds)) {
receivableBillService.updateReceiptAmount(receivableBillIds);
}
// 最后删除主记录
return omsReceivableWriteOffMapper.deleteOmsReceivableWriteOffByIds(ids);
}
/**
*
*
* @param id ID
* @return
*/
@Override
@Transactional
public int deleteOmsReceivableWriteOffById(Long id)
{
// 再删除主记录
return deleteOmsReceivableWriteOffByIds(new Long[]{id});
}
/**
* ID
*
* @param writeOffId ID
* @return
*/
@Override
public List<WriteOffDetailResultDto> selectWriteOffDetailsByWriteOffId(Long writeOffId)
{
// List<OmsReceivableWriteOffDetail> details = omsReceivableWriteOffDetailMapper.selectOmsReceivableWriteOffDetailByWriteOffId(writeOffId);
// return details.stream().map(this::convertToWriteOffDetailResultDto).collect(Collectors.toList());
return null;
}
@Override
public List<OmsReceivableWriteOff> listByReceiptBillCodeList(List<String> collect) {
OmsReceivableWriteOff omsReceivableWriteOff = new OmsReceivableWriteOff();
omsReceivableWriteOff.setReceiptBillCodeList(collect);
return omsReceivableWriteOffMapper.selectOmsReceivableWriteOffList(omsReceivableWriteOff);
}
@Override
public void autoWriteOff(WriteOffReceiptRequestDto writeOffRequestDto) {
if (CollUtil.isEmpty(writeOffRequestDto.getDetailList())){
throw new ServiceException("请选择核销明细");
}
// 获取收款单信息
OmsReceiptBill receiptBill = omsReceiptBillService.queryById(writeOffRequestDto.getReceiptBillId());
if (receiptBill == null) {
throw new ServiceException("收款单不存在");
}
// 创建核销主记录
OmsReceivableWriteOff writeOff = new OmsReceivableWriteOff();
writeOff.setWriteOffCode(generateWriteOffCode());
// 默认为用户手动核销
writeOff.setWriteOffType(OmsReceivableWriteOff.WriteOffTypeEnum.AUTO.getCode());
writeOff.setReceiptBillCode(receiptBill.getReceiptBillCode());
writeOff.setPartnerCode(writeOffRequestDto.getPartnerCode());
writeOff.setPartnerName(writeOffRequestDto.getPartnerName());
writeOff.setWriteOffTime(new Date());
writeOff.setRemark(writeOffRequestDto.getRemark());
// 计算总金额和相关税额
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal totalAmountWithoutTax = BigDecimal.ZERO;
BigDecimal totalTaxAmount = BigDecimal.ZERO;
// 将传入的detailList转换为OmsReceivableReceiptDetail类型进行处理
for (OmsReceivableReceiptDetail item : writeOffRequestDto.getDetailList()) {
totalAmount = totalAmount.add(item.getReceiptAmount());
totalAmountWithoutTax = totalAmountWithoutTax.add(item.getReceiptAmountWithoutTax());
totalTaxAmount = totalTaxAmount.add(item.getReceiptAmountTax());
}
writeOff.setWriteOffAmount(totalAmount);
writeOff.setWriteOffAmountWithoutTax(totalAmountWithoutTax);
writeOff.setWriteOffTaxAmount(totalTaxAmount);
// 设置创建时间
writeOff.setCreateTime(new Date());
writeOff.setCreateBy(ShiroUtils.getUserId().toString());
writeOff.setUpdateTime(new Date());
// 保存核销主记录
omsReceivableWriteOffMapper.insertOmsReceivableWriteOff(writeOff);
List<OmsReceivableReceiptDetail> updateList = writeOffRequestDto.getDetailList().stream().map(item -> {
OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail();
omsReceivableReceiptDetail.setId(item.getId());
omsReceivableReceiptDetail.setWriteOffId(writeOff.getId());
return omsReceivableReceiptDetail;
}).collect(Collectors.toList());
omsReceivableReceiptDetailService.updateWriteOffIdBatch(updateList);
receivableBillService.updateReceiptAmount(writeOffRequestDto.getDetailList().stream().map(OmsReceivableReceiptDetail::getReceivableBillId).distinct().collect(Collectors.toList()));
}
}

View File

@ -57,6 +57,23 @@
<if test="receiptBillCode != null and receiptBillCode != ''"> <if test="receiptBillCode != null and receiptBillCode != ''">
and t1.receipt_bill_code = #{receiptBillCode} and t1.receipt_bill_code = #{receiptBillCode}
</if> </if>
<if test="receiptBillCodeList != null and receiptBillCodeList != ''">
and t1.receipt_bill_code in
<foreach collection="receiptBillCodeList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</if>
<if test="remainingAmount != null and remainingAmount != ''">
<choose>
<when test="remainingAmount == -1">
and t1.remaining_amount != 0
</when>
<when test="remainingAmount !== -1">
and t1.remaining_amount = #{remainingAmount}
</when>
</choose>
</if>
<if test="receiptBillType != null and receiptBillType != ''"> <if test="receiptBillType != null and receiptBillType != ''">
and t1.receipt_bill_type = #{receiptBillType} and t1.receipt_bill_type = #{receiptBillType}
</if> </if>
@ -191,6 +208,12 @@
GROUP BY GROUP BY
partner_code partner_code
</select> </select>
<select id="queryByCode" resultType="com.ruoyi.sip.domain.OmsReceiptBill">
<include refid="selectReceiptBillVo"/>
<where>
receipt_bill_code = #{receiptBillCode}
</where>
</select>
<!--新增所有列--> <!--新增所有列-->
@ -461,6 +484,15 @@
</trim> </trim>
WHERE id = #{id} WHERE id = #{id}
</update> </update>
<update id="updateReturnWriteOffBatch">
<foreach collection="list" item="item" separator=";">
update oms_receipt_bill
set actual_receipt_time=null,
receipt_status=#{item.receiptStatus},
update_time=now()
where id = #{item.id}
</foreach>
</update>
<!--通过主键删除--> <!--通过主键删除-->
<delete id="deleteById"> <delete id="deleteById">

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sip.mapper.OmsReceivableWriteOffMapper">
<resultMap type="com.ruoyi.sip.domain.OmsReceivableWriteOff" id="OmsReceivableWriteOffResult">
<result property="id" column="id" />
<result property="writeOffCode" column="write_off_code" />
<result property="writeOffType" column="write_off_type" />
<result property="receiptBillCode" column="receipt_bill_code" />
<result property="partnerCode" column="partner_code" />
<result property="writeOffAmount" column="write_off_amount" />
<result property="writeOffAmountWithoutTax" column="write_off_amount_without_tax" />
<result property="writeOffTaxAmount" column="write_off_tax_amount" />
<result property="writeOffTime" column="write_off_time" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectOmsReceivableWriteOffVo">
select t1.id, t1.write_off_code, t1.write_off_type, t1.receipt_bill_code, t1.partner_code,
t1.write_off_amount, t1.write_off_amount_without_tax, t1.write_off_tax_amount, t1.write_off_time,
t1.remark, t1.create_by, t1.create_time, t1.update_by, t1.update_time,
t1.partner_name,t3.user_name as create_by_name
from oms_receivable_write_off t1
left join sys_user t3 on t1.create_by=t3.user_id
</sql>
<select id="selectOmsReceivableWriteOffById" parameterType="Long" resultMap="OmsReceivableWriteOffResult">
<include refid="selectOmsReceivableWriteOffVo"/>
where t1.id = #{id}
</select>
<select id="selectOmsReceivableWriteOffList" parameterType="com.ruoyi.sip.domain.OmsReceivableWriteOff" resultMap="OmsReceivableWriteOffResult">
<include refid="selectOmsReceivableWriteOffVo"/>
<where>
<if test="writeOffCode != null and writeOffCode != ''"> and t1.write_off_code = #{writeOffCode}</if>
<if test="writeOffType != null and writeOffType != ''"> and t1.write_off_type = #{writeOffType}</if>
<if test="receiptBillCode != null and receiptBillCode != ''"> and t1.receipt_bill_code = #{receiptBillCode}</if>
<if test="receivableBillCode != null and receivableBillCode != ''"> and t1.id in (
select write_off_id from oms_receivable_receipt_detail t1
inner join oms_receivable_bill t2 on t1.receivable_bill_id=t2.id
where t2.receivable_bill_code=#{receivableBillCode}
) </if>
<if test="receiptBillCodeList != null and receiptBillCodeList.size>0"> and t1.receipt_bill_code in
<foreach index="index" collection="receiptBillCodeList" item="receiptBillCode" separator="," open="(" close=")">
#{receiptBillCode}
</foreach>
</if>
<if test="partnerCode != null and partnerCode != ''"> and t1.partner_code = #{partnerCode}</if>
<if test="partnerName != null and partnerName != ''"> and t1.partner_name like concat('%', #{partnerName}, '%')</if>
<if test="(params.beginTime != null and params.beginTime != '') or (params.endTime != null and params.endTime!='')">
<choose>
<when test="(params.beginTime != null and params.beginTime != '') and (params.endTime != null and params.endTime!='')">
and t1.create_time between #{params.beginTime} and #{params.endTime}
</when>
<when test="(params.beginTime != null and params.beginTime != '')">
and t1.create_time <![CDATA[ >= ]]> #{params.beginTime}
</when>
<when test="(params.endTime != null and params.endTime!='')">
and t1.create_time <![CDATA[ <= ]]> #{params.endTime}
</when>
</choose>
</if>
</where>
</select>
<select id="selectMaxCodeByPrefix" resultType="java.lang.Integer">
select ifnull(max(SUBSTR(write_off_code FROM LENGTH(#{prefix}) + 1 FOR 4)), 0)
from oms_receivable_write_off
where write_off_code like concat(#{prefix}, '%')
</select>
<select id="listByIds" resultType="com.ruoyi.sip.domain.OmsReceivableWriteOff">
<include refid="selectOmsReceivableWriteOffVo"/>
where t1.id in
<foreach item="item" index="index" collection="array" open="(" separator="," close=")" >
#{item}
</foreach>
</select>
<insert id="insertOmsReceivableWriteOff" parameterType="com.ruoyi.sip.domain.OmsReceivableWriteOff" useGeneratedKeys="true" keyProperty="id">
insert into oms_receivable_write_off
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="writeOffCode != null">write_off_code,</if>
<if test="writeOffType != null">write_off_type,</if>
<if test="receiptBillCode != null">receipt_bill_code,</if>
<if test="partnerCode != null">partner_code,</if>
<if test="partnerName != null">partner_name,</if>
<if test="writeOffAmount != null">write_off_amount,</if>
<if test="writeOffAmountWithoutTax != null">write_off_amount_without_tax,</if>
<if test="writeOffTaxAmount != null">write_off_tax_amount,</if>
<if test="writeOffTime != null">write_off_time,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="writeOffCode != null">#{writeOffCode},</if>
<if test="writeOffType != null">#{writeOffType},</if>
<if test="receiptBillCode != null">#{receiptBillCode},</if>
<if test="partnerCode != null">#{partnerCode},</if>
<if test="partnerName != null">#{partnerName},</if>
<if test="writeOffAmount != null">#{writeOffAmount},</if>
<if test="writeOffAmountWithoutTax != null">#{writeOffAmountWithoutTax},</if>
<if test="writeOffTaxAmount != null">#{writeOffTaxAmount},</if>
<if test="writeOffTime != null">#{writeOffTime},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateOmsReceivableWriteOff" parameterType="com.ruoyi.sip.domain.OmsReceivableWriteOff">
update oms_receivable_write_off
<trim prefix="SET" suffixOverrides=",">
<if test="writeOffCode != null">write_off_code = #{writeOffCode},</if>
<if test="writeOffType != null">write_off_type = #{writeOffType},</if>
<if test="receiptBillCode != null">receipt_bill_code = #{receiptBillCode},</if>
<if test="partnerCode != null">partner_code = #{partnerCode},</if>
<if test="writeOffAmount != null">write_off_amount = #{writeOffAmount},</if>
<if test="writeOffAmountWithoutTax != null">write_off_amount_without_tax = #{writeOffAmountWithoutTax},</if>
<if test="writeOffTaxAmount != null">write_off_tax_amount = #{writeOffTaxAmount},</if>
<if test="writeOffTime != null">write_off_time = #{writeOffTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteOmsReceivableWriteOffById" parameterType="Long">
delete from oms_receivable_write_off where id = #{id}
</delete>
<delete id="deleteOmsReceivableWriteOffByIds" parameterType="String">
delete from oms_receivable_write_off where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -149,11 +149,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<delete id="deleteByWriteOffIds" parameterType="java.lang.Long"> <update id="clearWriteOffByWriteOffId" parameterType="java.lang.Long">
DELETE FROM oms_payable_payment_detail WHERE write_off_id IN update oms_payable_payment_detail set write_off_id=null WHERE write_off_id IN
<foreach collection="array" item="item" open="(" separator="," close=")" index=""> <foreach collection="array" item="item" open="(" separator="," close=")" index="">
#{item} #{item}
</foreach> </foreach>
</delete> </update>
</mapper> </mapper>

View File

@ -18,12 +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="receiptAmountWithoutTax" column="receipt_amount_without_tax" />
<result property="paymentAmountTax" column="payment_amount_tax" /> <result property="receiptAmountTax" column="receipt_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, payment_amount_without_tax, payment_amount_tax 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, receipt_amount_without_tax, receipt_amount_tax
from oms_receivable_receipt_detail from oms_receivable_receipt_detail
</sql> </sql>
@ -55,6 +55,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
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> <where>
<if test="receiptPlanId != null ">and t1.receipt_plan_id = #{receiptPlanId}</if> <if test="receiptPlanId != null ">and t1.receipt_plan_id = #{receiptPlanId}</if>
<if test="receiptPlanIdList != null and receiptPlanIdList.size>0 ">and t1.receipt_plan_id in
<foreach collection="receiptPlanIdList" separator="," close=")" open="(" item="item">
#{item}
</foreach>
</if>
<if test="idList != null and idList.size>0 ">and t1.id in <if test="idList != null and idList.size>0 ">and t1.id in
<foreach collection="idList" separator="," close=")" open="(" item="item">#{item}</foreach> <foreach collection="idList" separator="," close=")" open="(" item="item">#{item}</foreach>
</if> </if>
@ -65,6 +71,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item} #{item}
</foreach> </foreach>
</if> </if>
<if test="writeOffIdList != null and writeOffIdList.size>0 ">and t1.write_off_id in
<foreach collection="writeOffIdList" separator="," close=")" open="(" item="item">
#{item}
</foreach>
</if>
</where> </where>
</select> </select>
<select id="selectByPaymentPlanIds" resultType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail"> <select id="selectByPaymentPlanIds" resultType="com.ruoyi.sip.domain.OmsReceivableReceiptDetail">
@ -95,6 +106,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join project_order_info t3 on t2.order_code = t3.order_code left join project_order_info t3 on t2.order_code = t3.order_code
left join project_info t4 on t3.project_id = t4.id left join project_info t4 on t3.project_id = t4.id
</select> </select>
<select id="listReceivableByWriteOffId" 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,t2.create_time,t2.partner_name,t2.partner_code
from (SELECT sum(receipt_amount) receipt_amount,
receivable_bill_id
FROM oms_receivable_receipt_detail
WHERE write_off_id 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
@ -111,8 +136,9 @@ 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="receiptAmountWithoutTax != null">receipt_amount_without_tax,</if>
<if test="paymentAmountTax != null">payment_amount_tax,</if> <if test="receiptAmountTax != null">receipt_amount_tax,</if>
<if test="writeOffId != null">write_off_id,</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>
@ -127,19 +153,20 @@ 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="receiptAmountWithoutTax != null">#{receiptAmountWithoutTax},</if>
<if test="paymentAmountTax != null">#{paymentAmountTax},</if> <if test="receiptAmountTax != null">#{receiptAmountTax},</if>
<if test="writeOffId != null">#{writeOffId},</if>
</trim> </trim>
</insert> </insert>
<insert id="insertBatch"> <insert id="insertBatch">
insert into oms_receivable_receipt_detail insert into oms_receivable_receipt_detail
(receipt_plan_id,receivable_bill_id,receipt_time,receipt_amount,receipt_rate,receipt_bill_code,receivable_detail_type (receipt_plan_id,receivable_bill_id,receipt_time,receipt_amount,receipt_rate,receipt_bill_code,receivable_detail_type
,remark,create_time,create_by,update_time,update_by,payment_amount_without_tax,payment_amount_tax) ,remark,create_time,create_by,update_time,update_by,receipt_amount_without_tax,receipt_amount_tax)
values values
<foreach item="item" collection="list" separator="," index=""> <foreach item="item" collection="list" separator="," index="">
(#{item.receiptPlanId},#{item.receivableBillId},#{item.receiptTime},#{item.receiptAmount},#{item.receiptRate},#{item.receiptBillCode},#{item.receivableDetailType} (#{item.receiptPlanId},#{item.receivableBillId},#{item.receiptTime},#{item.receiptAmount},#{item.receiptRate},#{item.receiptBillCode},#{item.receivableDetailType}
,#{item.remark},#{item.createTime},#{item.createBy},#{item.updateTime},#{item.updateBy},#{item.paymentAmountWithoutTax},#{item.paymentAmountTax}) ,#{item.remark},#{item.createTime},#{item.createBy},#{item.updateTime},#{item.updateBy},#{item.receiptAmountWithoutTax},#{item.receiptAmountTax})
</foreach> </foreach>
@ -158,11 +185,23 @@ 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="receiptAmountWithoutTax != null">receipt_amount_without_tax = #{receiptAmountWithoutTax},</if>
<if test="paymentAmountTax != null">payment_amount_tax = #{paymentAmountTax},</if> <if test="receiptAmountTax != null">receipt_amount_tax = #{receiptAmountTax},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>
<update id="updateWriteOffIdBatch">
<foreach collection="list" item="item" separator=";">
update oms_receivable_receipt_detail set write_off_id = #{item.writeOffId} where id = #{item.id}
</foreach>
</update>
<update id="clearWriteOffByWriteOffId">
update oms_receivable_receipt_detail set write_off_id = null where write_off_id in
<foreach item="item" collection="list" separator="," open="(" close=")">
#{item}
</foreach>
</update>
<delete id="deleteOmsReceivableReceiptDetailById" parameterType="Long"> <delete id="deleteOmsReceivableReceiptDetailById" parameterType="Long">
delete from oms_receivable_receipt_detail where id = #{id} delete from oms_receivable_receipt_detail where id = #{id}