| | |
| | | <div class="actions"> |
| | | <div></div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="add" icon="Plus">录入发票</el-button> --> |
| | | <el-button type="primary" @click="add" icon="Plus">录入发票</el-button> |
| | | <el-button type="success" @click="handleExport" icon="Download">导出</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="开票申请单号"> |
| | | <div style="display:flex;gap:8px;"> |
| | | <el-input v-model="applyCodeDisplay" disabled placeholder="请选择开票申请" /> |
| | | <el-button type="primary" @click="openApplyDialog" :disabled="isView">选择</el-button> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="税率" prop="taxRate"> |
| | | <el-select |
| | | v-model="form.taxRate" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="金额(不含税)" prop="amount"> |
| | | <el-input-number |
| | | v-model="form.amount" |
| | | :min="0" |
| | | :precision="2" |
| | | style="width: 100%;" |
| | | :precision="4" |
| | | :disabled="isView" |
| | | @change="calculateTax" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="税额"> |
| | | <el-input v-model="form.taxAmount" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="价税合计"> |
| | | <el-input v-model="form.totalAmount" disabled /> |
| | | </el-form-item> |
| | |
| | | </template> |
| | | </FormDialog> |
| | | |
| | | <el-dialog v-model="applyDialogVisible" |
| | | title="选择开票申请" |
| | | width="900px" |
| | | :close-on-click-modal="false"> |
| | | <div style="margin-bottom:12px;display:flex;gap:12px;"> |
| | | <el-input v-model="applySearch.applyCode" placeholder="申请单号" clearable style="width:200px;" @change="fetchApplyList" /> |
| | | <el-input v-model="applySearch.customerName" placeholder="客户名称" clearable style="width:200px;" @change="fetchApplyList" /> |
| | | <el-button type="primary" @click="fetchApplyList">搜索</el-button> |
| | | </div> |
| | | <el-table :data="applyList" border v-loading="applyLoading" height="400px"> |
| | | <el-table-column label="申请单号" prop="invoiceApplicationNo" width="150" /> |
| | | <el-table-column label="客户名称" prop="customerName" width="180" /> |
| | | <el-table-column label="开票金额" prop="invoiceAmount" width="120" /> |
| | | <el-table-column label="税率" prop="taxRate" width="80"> |
| | | <template #default="{ row }">{{ row.taxRate }}%</template> |
| | | </el-table-column> |
| | | <el-table-column label="发票类型" prop="invoiceType" width="130" /> |
| | | <el-table-column label="申请日期" prop="applyDate" width="120" /> |
| | | <el-table-column label="操作" width="80" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button type="primary" link @click="selectApply(row)">选择</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div v-if="applyPage.total > 0"> |
| | | <Pagination :total="applyPage.total" |
| | | layout="total, prev, pager, next" |
| | | :page="applyPage.current" |
| | | :limit="applyPage.size" |
| | | @pagination="applyPaginationChange" /> |
| | | </div> |
| | | <template #footer> |
| | | <el-button @click="applyDialogVisible = false">关闭</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <FileList |
| | | v-if="fileDialogVisible" |
| | | v-model:visible="fileDialogVisible" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, getCurrentInstance, defineAsyncComponent } from "vue"; |
| | | import { ref, reactive, onMounted, nextTick, getCurrentInstance, defineAsyncComponent } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import Pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { listCustomer } from "@/api/basicData/customer.js"; |
| | | import { |
| | | addAccountSalesInvoice, |
| | |
| | | cancelAccountSalesInvoice, |
| | | deleteAccountSalesInvoice, |
| | | } from "@/api/financialManagement/accountSalesInvoice.js"; |
| | | import { listPageAccountInvoiceApplication } from "@/api/financialManagement/invoiceApply.js"; |
| | | |
| | | const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue")); |
| | | |
| | |
| | | const customerList = ref([]); |
| | | const fileDialogVisible = ref(false); |
| | | const currentRecordId = ref(0); |
| | | |
| | | // 开票申请选择 |
| | | const applyDialogVisible = ref(false); |
| | | const applyLoading = ref(false); |
| | | const applyList = ref([]); |
| | | const applyCodeDisplay = ref(""); |
| | | const applySearch = reactive({ applyCode: "", customerName: "" }); |
| | | const applyPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | |
| | | const openApplyDialog = () => { |
| | | applySearch.applyCode = ""; |
| | | applySearch.customerName = ""; |
| | | applyPage.current = 1; |
| | | fetchApplyList(); |
| | | applyDialogVisible.value = true; |
| | | }; |
| | | |
| | | const fetchApplyList = () => { |
| | | applyLoading.value = true; |
| | | const params = { |
| | | current: applyPage.current, |
| | | size: applyPage.size, |
| | | status: 1, // 只查审核通过 |
| | | }; |
| | | if (applySearch.applyCode) params.applyCode = applySearch.applyCode; |
| | | if (applySearch.customerName) params.customerName = applySearch.customerName; |
| | | listPageAccountInvoiceApplication(params) |
| | | .then(res => { |
| | | applyList.value = res.data?.records || []; |
| | | applyPage.total = res.data?.total || 0; |
| | | }) |
| | | .finally(() => { |
| | | applyLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const applyPaginationChange = ({ page: p, limit }) => { |
| | | applyPage.current = p; |
| | | applyPage.size = limit; |
| | | fetchApplyList(); |
| | | }; |
| | | |
| | | const selectApply = row => { |
| | | form.accountInvoiceApplicationId = row.id; |
| | | applyCodeDisplay.value = row.invoiceApplicationNo || ""; |
| | | form.amount = Number(row.invoiceAmount) || 0; |
| | | form.taxRate = Number(row.taxRate) || 13; |
| | | form.invoiceType = row.invoiceType || "增值税专用发票"; |
| | | if (row.customerId) form.customerId = row.customerId; |
| | | calculateTax(); |
| | | nextTick(() => { |
| | | applyDialogVisible.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const openFileDialog = (row) => { |
| | | if (!row.accountInvoiceApplicationId) { |
| | |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null) return "0.00"; |
| | | return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| | | const parts = Number(value).toFixed(4).split("."); |
| | | parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| | | return parts.join("."); |
| | | }; |
| | | |
| | | const calculateTax = () => { |
| | | form.taxAmount = Number((form.amount * form.taxRate / 100).toFixed(2)); |
| | | form.totalAmount = Number((form.amount + form.taxAmount).toFixed(2)); |
| | | form.taxAmount = Number((form.amount * form.taxRate / 100).toFixed(4)); |
| | | form.totalAmount = Number((form.amount + form.taxAmount).toFixed(4)); |
| | | }; |
| | | |
| | | const handleInvoiceTypeChange = () => { |
| | |
| | | accountInvoiceApplicationId: undefined, |
| | | storageAttachmentId: undefined, |
| | | }); |
| | | applyCodeDisplay.value = ""; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | |
| | | isView.value = true; |
| | | dialogTitle.value = "查看发票"; |
| | | fillFormFromRow(row); |
| | | applyCodeDisplay.value = row.invoiceApplicationNo || ""; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |