feat(finance): 重构收票单新增功能并完善相关逻辑
- 新增收票计划选择器组件及交互逻辑 - 优化收票单表单结构,支持从应付单合并生成收票单 - 增加收票计划金额和比例计算功能 - 完善收票单提交校验逻辑,确保数据完整性 - 更新收票单详情展示字段,修正显示错误 - 调整收票单列表操作按钮权限控制 - 扩展后端服务接口,支持根据收票单编号查询明细 - 优化收票单审批状态管理及相关业务逻辑处理dev_1.0.0
parent
49cd27c221
commit
dc1f5f7302
|
|
@ -1,94 +1,202 @@
|
|||
<template>
|
||||
<el-dialog title="新增收票单" :visible.sync="internalVisible" width="500px" @close="handleClose">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="收票单类型" prop="receiptBillType">
|
||||
<el-select v-model="form.receiptBillType" disabled placeholder="请选择收票单类型">
|
||||
<el-dialog title="新增收票单" :visible.sync="internalVisible" width="80%" @close="handleClose" append-to-body>
|
||||
<div class="dialog-body">
|
||||
<el-form ref="form" :model="queryParams" :inline="true" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="收票单类型" prop="ticketBillType">
|
||||
<!-- Mapping receiptBillType to ticketBillType for consistency with the merge logic -->
|
||||
<el-select disabled v-model="form.receiptBillType" placeholder="请选择收票单类型" clearable>
|
||||
<!-- Using dicts.receipt_bill_type if available, or dict.type.payment_bill_type if that was the intent.
|
||||
The original code used dicts.receipt_bill_type. I'll stick to that but ensure it's passed or available.
|
||||
The user instructions imply 'MergeReceiptDialog' logic which used payment_bill_type.
|
||||
I will use the existing props 'dicts' -->
|
||||
<el-option
|
||||
v-for="dict in dicts.receipt_bill_type"
|
||||
v-for="dict in dict.type.payment_bill_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
></el-option>
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="制造商名称" prop="vendorCode">
|
||||
<el-select v-model="form.vendorCode" placeholder="请选择制造商" style="width:100%" >
|
||||
<el-option v-for="item in vendorOptions" :key="item.vendorCode" :label="item.vendorName" :value="item.vendorCode"></el-option>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="制造商名称">
|
||||
<el-select
|
||||
v-model="queryParams.vendorCode"
|
||||
placeholder="请选择制造商"
|
||||
filterable
|
||||
clearable
|
||||
@change="handleVendorChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in vendorOptions"
|
||||
:key="item.vendorCode"
|
||||
:label="item.vendorName"
|
||||
:value="item.vendorCode"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计收票时间" prop="receiptTime">
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="厂家开票时间" prop="vendorTicketTime">
|
||||
<el-date-picker
|
||||
v-model="form.receiptTime"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
v-model="form.vendorTicketTime"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="选择日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="含税总价" prop="totalPriceWithTax">
|
||||
<el-input-number v-model="form.totalPriceWithTax" @change="handlePriceChange" :precision="2"
|
||||
:step="1"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="税率" prop="taxRate">
|
||||
<el-input-number v-model="form.taxRate" @change="handlePriceChange" :precision="2" :step="0.01"
|
||||
:max="1"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="未税总价" prop="totalPriceWithoutTax">
|
||||
<el-input v-model="form.totalPriceWithoutTax" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="税额" prop="taxAmount">
|
||||
<el-input v-model="form.taxAmount" :disabled="true"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-divider content-position="left">采购应付单表</el-divider>
|
||||
<el-table
|
||||
:data="payableOrdersWithPlans"
|
||||
border
|
||||
max-height="300px"
|
||||
style="margin-bottom: 20px;"
|
||||
row-key="id"
|
||||
@selection-change="handleSelectionChange"
|
||||
ref="table"
|
||||
>
|
||||
<el-table-column type="selection" :reserve-selection="true" width="55" align="center" />
|
||||
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
|
||||
<el-table-column label="预计收票时间" align="center" prop="planTicketDate" width="180"/>
|
||||
<el-table-column label="收票计划" align="center" width="100" prop="planTicketAmount">
|
||||
</el-table-column>
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
|
||||
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
|
||||
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
|
||||
<el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
|
||||
<el-table-column label="未收票金额" align="center" prop="unInvoicedAmount" width="120"/>
|
||||
<el-table-column label="本次收票金额" align="center" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ calculateOrderCurrentTicketAmount(scope.row.id).toFixed(2) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="本次收票比例" align="center" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ calculateOrderCurrentTicketRate(scope.row.id) }}%
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已收票金额" align="center" prop="invoicedAmount" width="120"/>
|
||||
<el-table-column label="操作" align="center" 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="handleOpenTicketPlanSelector(scope.row, scope.$index)"
|
||||
>选择
|
||||
</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"
|
||||
/>
|
||||
|
||||
<div class="total-info">
|
||||
<span style="margin-left: 20px;">计划收票总金额: <el-tag type="success">{{ totalPlannedAmount.toFixed(2) }}</el-tag></span>
|
||||
<span>计划收票比例: <el-tag type="info">{{ totalPayableAmountWithTax ? this.$calc.mul(this.$calc.div(totalPlannedAmount,totalPayableAmountWithTax,4),100) : 0 }}%</el-tag></span>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="planTitle" :visible.sync="isTicketPlanSelectorOpen" width="70%"
|
||||
@close="isTicketPlanSelectorOpen=false" append-to-body>
|
||||
<receiving-ticket-plan
|
||||
ref="planSelector"
|
||||
:payable-data="choosePayable"
|
||||
:selected-plans="choosePayable.ticketPlans"
|
||||
@confirm="handleTicketPlanConfirm"
|
||||
/>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="isTicketPlanSelectorOpen=false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleChooseConfirm">保 存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listAllVendor } from "@/api/base/vendor";
|
||||
import { listPayable } from "@/api/finance/payable";
|
||||
// Importing from the payable component directory as it likely shares logic
|
||||
import ReceivingTicketPlan from "@/views/finance/payable/components/ReceivingTicketPlan.vue";
|
||||
|
||||
export default {
|
||||
name: "AddForm",
|
||||
components: { ReceivingTicketPlan },
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dicts: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
dicts:['payment_bill_type','invoice_status'],
|
||||
data() {
|
||||
return {
|
||||
internalVisible: this.visible,
|
||||
vendorOptions: [],
|
||||
form: {
|
||||
receiptBillType:'STANDARD_INVOICE', // Default type, assuming STANDARD_INVOICE exists or user changes it
|
||||
vendorName: null,
|
||||
receiptTime: null,
|
||||
totalPriceWithTax: 0,
|
||||
taxRate: 0.13, // Default tax rate
|
||||
totalPriceWithoutTax: 0,
|
||||
taxAmount: 0
|
||||
// Search params
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
ticketBillType: 'FROM_PAYABLE', // Used for filtering if needed
|
||||
vendorId: null,
|
||||
invoiceStatus: null,
|
||||
},
|
||||
rules: {
|
||||
receiptBillType: [{required: true, message: "收票单类型不能为空", trigger: "change"}],
|
||||
vendorName: [{required: true, message: "制造商名称不能为空", trigger: "blur"}],
|
||||
receiptTime: [{required: true, message: "预计收票时间不能为空", trigger: "change"}],
|
||||
totalPriceWithTax: [{required: true, message: "含税总价不能为空", trigger: "blur"}]
|
||||
}
|
||||
// Form data for submission
|
||||
form: {
|
||||
receiptBillType: 'FROM_PAYABLE',
|
||||
vendorTicketTime: null,
|
||||
},
|
||||
payableOrdersWithPlans: [], // Current page data
|
||||
selectedRows: [], // Cross-page selection
|
||||
total: 0,
|
||||
|
||||
// Plan Selector State
|
||||
planTitle: '',
|
||||
isTicketPlanSelectorOpen: false,
|
||||
choosePayable: {},
|
||||
currentPayableOrderIndexForPlan: -1,
|
||||
loadingTicketPlans: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// Calculate totals based on SELECTED rows
|
||||
totalPayableAmountWithTax() {
|
||||
return this.selectedRows.reduce((sum, order) => sum + (order.totalPriceWithTax || 0), 0);
|
||||
},
|
||||
totalPlannedAmount() {
|
||||
return this.selectedRows.reduce((orderSum, order) => {
|
||||
const orderPlansTotal = (order.ticketPlans || []).reduce((planSum, plan) => planSum + (plan.planAmount || 0), 0);
|
||||
return orderSum + orderPlansTotal;
|
||||
}, 0);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
visible(newVal) {
|
||||
this.internalVisible = newVal;
|
||||
if (newVal) {
|
||||
this.resetForm();
|
||||
this.getVendorList();
|
||||
|
||||
}
|
||||
},
|
||||
internalVisible(newVal) {
|
||||
|
|
@ -96,47 +204,201 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
/** 获取厂商列表 */
|
||||
getVendorList() {
|
||||
return listAllVendor().then(res => {
|
||||
this.vendorOptions = res.data;
|
||||
listAllVendor().then(res => {
|
||||
this.vendorOptions = res.data || [];
|
||||
})
|
||||
},
|
||||
handlePriceChange() {
|
||||
const taxed = this.form.totalPriceWithTax || 0;
|
||||
const rate = this.form.taxRate || 0;
|
||||
|
||||
const unTaxed = this.$calc.div(taxed, this.$calc.add(1, rate));
|
||||
const taxAmount = this.$calc.sub(taxed, unTaxed);
|
||||
|
||||
this.form.totalPriceWithoutTax = unTaxed;
|
||||
this.form.taxAmount = taxAmount;
|
||||
handleVendorChange() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.selectedRows = [];
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clearSelection();
|
||||
}
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
if (!this.queryParams.vendorCode) {
|
||||
this.payableOrdersWithPlans = [];
|
||||
this.total = 0;
|
||||
return;
|
||||
}
|
||||
this.loadingTicketPlans = true;
|
||||
listPayable(this.queryParams).then(response => {
|
||||
this.payableOrdersWithPlans = response.rows.map(order => {
|
||||
// Initialize ticket plans
|
||||
const ticketPlans = order.ticketPlans ? [...order.ticketPlans] : [];
|
||||
if (ticketPlans.length === 0 && order.lastTicketPlanId) {
|
||||
ticketPlans.push({
|
||||
id: order.lastTicketPlanId,
|
||||
planAmount: order.planTicketAmount,
|
||||
planTicketDate: order.planTicketDate,
|
||||
planRate: order.totalPriceWithTax ? this.$calc.mul(this.$calc.div(order.planTicketAmount, order.totalPriceWithTax, 4), 100) : 0
|
||||
});
|
||||
}
|
||||
return {
|
||||
...order,
|
||||
ticketPlans: ticketPlans,
|
||||
totalPriceWithTax: order.totalPriceWithTax || 0,
|
||||
unInvoicedAmount: order.unInvoicedAmount || 0,
|
||||
invoicedAmount: order.invoicedAmount || 0,
|
||||
};
|
||||
});
|
||||
this.total = response.total;
|
||||
this.loadingTicketPlans = false;
|
||||
});
|
||||
},
|
||||
handleSelectionChange(selection) {
|
||||
this.selectedRows = selection;
|
||||
},
|
||||
handleClose() {
|
||||
this.internalVisible = false;
|
||||
this.resetForm();
|
||||
},
|
||||
handleChooseConfirm() {
|
||||
if (!this.$refs.planSelector) {
|
||||
this.$modal.msgError('无法获取计划选择器组件');
|
||||
return;
|
||||
}
|
||||
const selectedPlans = this.$refs.planSelector.selectedPlan || [];
|
||||
|
||||
const orderIndex = this.payableOrdersWithPlans.findIndex(o => o.id === this.choosePayable.id);
|
||||
if (orderIndex === -1) {
|
||||
this.$modal.msgError('找不到要更新的应付单');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentOrder = this.payableOrdersWithPlans[orderIndex];
|
||||
// Update view
|
||||
this.$set(currentOrder, 'ticketPlans', [...selectedPlans]);
|
||||
|
||||
// Update selectedRows
|
||||
const selectedIndex = this.selectedRows.findIndex(o => o.id === this.choosePayable.id);
|
||||
if (selectedIndex !== -1) {
|
||||
this.$set(this.selectedRows[selectedIndex], 'ticketPlans', [...selectedPlans]);
|
||||
}
|
||||
|
||||
this.isTicketPlanSelectorOpen = false;
|
||||
this.$modal.msgSuccess(`已更新收票计划选择,共 ${selectedPlans.length} 条`);
|
||||
},
|
||||
handleOpenTicketPlanSelector(row, index) {
|
||||
this.planTitle = `选择收票计划 - ${row.payableBillCode}`;
|
||||
this.choosePayable = row;
|
||||
this.currentPayableOrderIndexForPlan = index;
|
||||
this.isTicketPlanSelectorOpen = true;
|
||||
},
|
||||
handleTicketPlanConfirm(updatedPlans) {
|
||||
// Callback from ReceivingTicketPlan if it emits 'confirm' directly,
|
||||
// but here we use handleChooseConfirm triggered by the dialog button.
|
||||
// Current logic relies on ref access in handleChooseConfirm.
|
||||
},
|
||||
calculateOrderCurrentTicketAmount(orderId) {
|
||||
const order = this.payableOrdersWithPlans.find(o => o.id === orderId);
|
||||
if (order && order.ticketPlans) {
|
||||
return order.ticketPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
calculateOrderCurrentTicketRate(orderId) {
|
||||
const order = this.payableOrdersWithPlans.find(o => o.id === orderId);
|
||||
if (order && order.ticketPlans && order.unInvoicedAmount >= 0) {
|
||||
const currentAmount = this.calculateOrderCurrentTicketAmount(orderId);
|
||||
return order.totalPriceWithTax ? this.$calc.mul(this.$calc.div(currentAmount ,order.totalPriceWithTax,4 ),100) : 0;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
this.$emit("submit", this.form);
|
||||
if (!this.queryParams.vendorCode) {
|
||||
this.$modal.msgError('请选择制造商');
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!this.form.vendorTicketTime) {
|
||||
this.$modal.msgError('请选择厂家开票时间');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectedRows.length === 0) {
|
||||
this.$modal.msgError('请至少勾选一条应付单');
|
||||
return;
|
||||
}
|
||||
|
||||
const ordersToSubmit = this.selectedRows;
|
||||
|
||||
// Validate plans
|
||||
for (const order of ordersToSubmit) {
|
||||
if (!order.ticketPlans || order.ticketPlans.length === 0) {
|
||||
this.$modal.msgError(`应付单 ${order.payableBillCode} 至少需要一条收票计划`);
|
||||
return;
|
||||
}
|
||||
for (const plan of order.ticketPlans) {
|
||||
if (!plan.planTicketDate) {
|
||||
this.$modal.msgError(`应付单 ${order.payableBillCode} 的收票计划中预计收票时间不能为空。`);
|
||||
return;
|
||||
}
|
||||
if (plan.planAmount === null || plan.planAmount === undefined || plan.planAmount <= 0) {
|
||||
this.$modal.msgError(`应付单 ${order.payableBillCode} 的收票计划中预计收票金额必须大于0。`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct payload
|
||||
const data = {
|
||||
receiptBillType: this.form.receiptBillType,
|
||||
vendorTicketTime: this.form.vendorTicketTime,
|
||||
vendorId: this.queryParams.vendorId,
|
||||
payableOrders: ordersToSubmit.map(order => ({
|
||||
id: order.id,
|
||||
payableBillCode: order.payableBillCode,
|
||||
ticketPlans: order.ticketPlans.map(plan => ({
|
||||
planTicketDate: plan.planTicketDate,
|
||||
planAmount: plan.planAmount,
|
||||
planRate: plan.planRate,
|
||||
remark: plan.remark,
|
||||
id: plan.id,
|
||||
})),
|
||||
})),
|
||||
totalMergeTicketAmount: this.totalPlannedAmount,
|
||||
};
|
||||
|
||||
this.$emit("submit", data);
|
||||
// internalVisible will be handled by parent or by success callback usually,
|
||||
// but here we just emit submit. The parent likely handles the API call.
|
||||
// If we want to close immediately:
|
||||
// this.internalVisible = false;
|
||||
},
|
||||
resetForm() {
|
||||
if (this.$refs.form) {
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
this.form = {
|
||||
receiptBillType: 'STANDARD_INVOICE',
|
||||
vendorName: null,
|
||||
receiptTime: null,
|
||||
totalPriceWithTax: 0,
|
||||
taxRate: 0.13,
|
||||
totalPriceWithoutTax: 0,
|
||||
taxAmount: 0
|
||||
receiptBillType: 'FROM_PAYABLE',
|
||||
vendorTicketTime: null,
|
||||
};
|
||||
this.handlePriceChange();
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
ticketBillType: 'FROM_PAYABLE',
|
||||
vendorId: null,
|
||||
invoiceStatus: null,
|
||||
};
|
||||
this.payableOrdersWithPlans = [];
|
||||
this.selectedRows = [];
|
||||
this.total = 0;
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog-body {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.total-info {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@
|
|||
<div class="detail-item">税额: {{ detail.taxAmount }}</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="detail-item">发票含税总价: {{ detail.actualReceiptTime || '-'}}</div>
|
||||
<div class="detail-item">发票含税总价: {{ detail.ticketPriceWithTax || '-'}}</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="detail-item">发票未税总价: {{ detail.actualReceiptTime || '-'}}</div>
|
||||
<div class="detail-item">发票未税总价: {{ detail.ticketPriceWithoutTax || '-'}}</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="detail-item">发票税额: {{ detail.taxAmount }}</div>
|
||||
<div class="detail-item">发票税额: {{ detail.ticketAmount }}</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="detail-item">收票状态:
|
||||
|
|
|
|||
|
|
@ -176,11 +176,12 @@
|
|||
type="text"
|
||||
icon="el-icon-document"
|
||||
@click="handleReceipt(scope.row)"
|
||||
>收票附件</el-button>
|
||||
>发票</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-document"
|
||||
v-show="scope.row.approveStatus==='0'"
|
||||
@click="handleReturn(scope.row)"
|
||||
>退回</el-button>
|
||||
<el-button
|
||||
|
|
@ -262,7 +263,7 @@ export default {
|
|||
addOpen: false,
|
||||
// 收票附件弹窗
|
||||
receiptOpen: false,
|
||||
currentRow: null
|
||||
currentRow: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
|
|||
|
|
@ -70,4 +70,6 @@ public interface IOmsPayableTicketDetailService
|
|||
List<OmsPayableTicketDetail> listByPayableBillIdList(List<Long> collect);
|
||||
|
||||
List<OmsPayableTicketDetail> selectByTicketPlanIds(List<Long> ticketPlanIds);
|
||||
|
||||
List<OmsPayableTicketDetail> listDetailByTicketCode(String ticketBillCode);
|
||||
}
|
||||
|
|
@ -157,4 +157,11 @@ public class OmsPayableTicketDetailServiceImpl implements IOmsPayableTicketDetai
|
|||
public List<OmsPayableTicketDetail> selectByTicketPlanIds(List<Long> ticketPlanIds) {
|
||||
return omsPayableTicketDetailMapper.selectByTicketPlanIds(ticketPlanIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OmsPayableTicketDetail> listDetailByTicketCode(String ticketBillCode) {
|
||||
OmsPayableTicketDetail omsPayableTicketDetail = new OmsPayableTicketDetail();
|
||||
omsPayableTicketDetail.setTicketBillCode(ticketBillCode);
|
||||
return omsPayableTicketDetailMapper.selectOmsPayableTicketDetailList(omsPayableTicketDetail);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,23 +2,25 @@ package com.ruoyi.sip.service.impl;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.enums.ApproveStatusEnum;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.ShiroUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.sip.domain.OmsFinAttachment;
|
||||
import com.ruoyi.sip.domain.OmsPaymentBill;
|
||||
import com.ruoyi.sip.domain.*;
|
||||
import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
|
||||
import com.ruoyi.sip.service.IOmsFinAttachmentService;
|
||||
import com.ruoyi.sip.service.IOmsPayableBillService;
|
||||
import com.ruoyi.sip.service.IOmsPayableTicketDetailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.sip.mapper.OmsTicketBillMapper;
|
||||
import com.ruoyi.sip.domain.OmsTicketBill;
|
||||
import com.ruoyi.sip.service.IOmsTicketBillService;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
|
|
@ -41,6 +43,8 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
private IOmsPayableTicketDetailService payableTicketDetailService;
|
||||
@Autowired
|
||||
private IOmsFinAttachmentService omsFinAttachmentService;
|
||||
@Autowired
|
||||
private IOmsPayableBillService payableBillService;
|
||||
|
||||
/**
|
||||
* 查询采购收票单
|
||||
|
|
@ -78,6 +82,9 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
@Override
|
||||
public int insertOmsTicketBill(OmsTicketBill omsTicketBill)
|
||||
{
|
||||
if (StringUtils.isEmpty(omsTicketBill.getApproveStatus())){
|
||||
omsTicketBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
|
||||
}
|
||||
omsTicketBill.setTicketBillCode(generateTicketBillCode());
|
||||
omsTicketBill.setCreateTime(DateUtils.getNowDate());
|
||||
return omsTicketBillMapper.insertOmsTicketBill(omsTicketBill);
|
||||
|
|
@ -169,12 +176,13 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
attachment.setCreateBy(loginUser.getUserId().toString());
|
||||
omsFinAttachmentService.insertOmsFinAttachment(attachment);
|
||||
omsTicketBill.setActualTicketTime(DateUtils.getNowDate());
|
||||
omsTicketBill.setTicketStatus(OmsTicketBill.TicketStatusEnum.TICKET.getCode());
|
||||
// omsTicketBill.setTicketStatus(OmsTicketBill.TicketStatusEnum.TICKET.getCode());
|
||||
omsTicketBill.setApproveStatus(ApproveStatusEnum.WAIT_APPROVE.getCode());
|
||||
omsTicketBill.setTicketPriceWithTax(bill.getTicketPriceWithTax());
|
||||
omsTicketBill.setTicketPriceWithoutTax(bill.getTicketPriceWithoutTax());
|
||||
omsTicketBill.setTicketType(bill.getTicketType());
|
||||
updateOmsTicketBill(omsTicketBill);
|
||||
|
||||
//todo 开启审批流程
|
||||
return AjaxResult.success(attachment);
|
||||
}
|
||||
|
||||
|
|
@ -207,6 +215,7 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
refundBill.setTicketType(originalBill.getTicketType());
|
||||
// 设置新属性
|
||||
refundBill.setTicketBillType(OmsTicketBill.TicketBillTypeEnum.RED_RUSH.getCode());
|
||||
refundBill.setTicketStatus(OmsTicketBill.TicketStatusEnum.TICKET.getCode());
|
||||
refundBill.setRefundStatus(OmsTicketBill.RefundStatusEnum.REFUNDED.getCode());
|
||||
refundBill.setApproveStatus(ApproveStatusEnum.WAIT_APPROVE.getCode());
|
||||
refundBill.setOriginalBillId(originalBill.getId());
|
||||
|
|
@ -244,7 +253,7 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
if (!OmsTicketBill.TicketBillTypeEnum.FROM_PAYABLE.getCode().equals(ticketBill.getTicketBillType())) {
|
||||
return AjaxResult.error("只有由应付单合并生成的收票单才能执行退回操作");
|
||||
}
|
||||
|
||||
List<OmsPayableTicketDetail> omsPayableTicketDetails = payableTicketDetailService.listDetailByTicketCode(ticketBill.getTicketBillCode());
|
||||
// 3. 清楚关联
|
||||
payableTicketDetailService.clearRelationPayable(ticketBill.getTicketBillCode());
|
||||
|
||||
|
|
@ -254,7 +263,9 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
if (result <= 0) {
|
||||
throw new RuntimeException("删除付款单失败");
|
||||
}
|
||||
|
||||
if (CollUtil.isNotEmpty(omsPayableTicketDetails)) {
|
||||
payableBillService.updateTicketAmount(omsPayableTicketDetails.stream().map(OmsPayableTicketDetail::getPayableBillId).distinct().collect(Collectors.toList()));
|
||||
}
|
||||
return AjaxResult.success("付款单退回成功!");
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue