123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- <script setup lang="ts">
- import { reactive, ref, watch, nextTick, onMounted } from "vue";
- import { FormRules, ElForm, ElMessage } from "element-plus";
- import { httpAdd } from "/@/api/InvoiceSales/invoiceApply";
- import RemoteSelect from "/@/components/RemoteSelect";
- import { httpInvoiceList } from "/@/api/InvoiceSales/invoiceApply";
- import { httpList as httpCompanylist } from "/@/api/parameter/finance";
- import OrderDialog from "./order-dialog.vue";
- import EditOrder from "./edit-order.vue";
- import { useResponseHandle } from "/@/hooks";
- import { useRouter } from "vue-router";
- import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
- import InvoiceTitle from "./invoice-title.vue";
- import { convertInvoiceTitle, convertInvoiceTitleData } from "./columns";
- import { useCompany } from "/@/hooks/core/useCompany";
- import { addition } from "/@/utils/calc";
- import { ADD_EDIT_FORM_RULES } from "./../../config/configs";
- import { xs_inv_type_list, useTypeOptions } from "/@/utils/status";
- enum FROM_TYPE {
- order = "order",
- invoice = "invoice"
- }
- const TYPE = ref<FROM_TYPE>(FROM_TYPE.order);
- const { companyList } = useCompany();
- const { push } = useRouter();
- const modelRef = ref<InstanceType<typeof OrderDialog>>(null);
- const editOrderRef = ref<InstanceType<typeof EditOrder>>(null);
- const formRef = ref<InstanceType<typeof ElForm>>(null);
- const mapSequenceNoToInvfee = ref<Record<string, any>>({});
- const responseHandle = useResponseHandle();
- const loading = ref(false);
- const orderList = ref([]);
- const { currentCompany } = useCompany();
- //最大开票金额
- const denomination = ref(0);
- const max = 150;
- const initform = {
- companyNo: "", //销售方公司抬头
- buy_id: "", //购买方公司抬头
- invtype: "", //开票类型
- email: "", //邮箱
- remark: "", //发票备注
- exam_remark: "", //申请备注
- orderArr: [], //开票销售订单明细 obj:sequenceNo//销售订单编码 inv_fee//销售订单开票金额,
- companyType: "01",
- platform_type: ""
- };
- const ruleForm = ref({ ...initform });
- const invoiceTypes = ref([]);
- const rules = reactive<FormRules>({ ...ADD_EDIT_FORM_RULES });
- function handleShowEditModal(_, row: any) {
- editOrderRef.value.onDisplay({
- row
- });
- }
- function handleEdit({ row, inv_fee, num }) {
- mapSequenceNoToInvfee.value[row.sequenceNo] = {
- inv_fee,
- num,
- platform_type: row.platform_type
- };
- }
- const removeRemarkPo = (poCode: string, index: number) => {
- const isLast = index === orderList.value.length - 1;
- const isOnly = orderList.value.length === 1;
- if (isOnly)
- return (ruleForm.value.remark = ruleForm.value.remark
- .split(poCode)
- .join(""));
- ruleForm.value.remark = ruleForm.value.remark
- .split(isLast ? ";" + poCode : poCode + ";")
- .join("");
- };
- const handleDelete = (index: number) => {
- const { sequenceNo, poCode } = orderList.value[index];
- removeRemarkPo(poCode, index);
- delete mapSequenceNoToInvfee.value[sequenceNo];
- orderList.value.splice(index, 1);
- };
- function generatorOrderArr() {
- const keys = Object.keys(mapSequenceNoToInvfee.value);
- const orderArr = keys.map(sequenceNo => {
- const { inv_fee, num, platform_type } =
- mapSequenceNoToInvfee.value[sequenceNo];
- return {
- platform_type,
- sequenceNo,
- inv_fee,
- num
- };
- });
- return { orderArr };
- }
- function handleSave() {
- formRef.value.validate(async isValid => {
- if (!isValid) return;
- if (ruleForm.value.remark.length > 184) {
- return ElMessage.error("发票备注不能超过184个字符");
- }
- if (orderList.value.length > max) {
- return ElMessage.error(`订单数量不能超过${max}个`);
- }
- const { orderArr } = generatorOrderArr();
- const total = orderArr.reduce(
- (prev, { inv_fee }) => prev + Number(inv_fee),
- 0
- );
- if (ruleForm.value.invtype === "fully_digitalized_special_electronic" || ruleForm.value.invtype === "fully_digitalized_normal_electronic") {
- if (total > (1000 * 10000)) {
- return ElMessage.error("订单总金额不能超过1000万");
- }
- } else {
- if (total > denomination.value) {
- return ElMessage.error(`订单总金额超过最大开票面额`);
- }
- }
- const { code, message } = await httpAdd({
- relaComNo: ruleForm.value.companyNo,
- ...ruleForm.value,
- ...generatorOrderArr(),
- is_comon:'0'
- });
- responseHandle({
- code,
- message,
- handler: () => push("/InvoiceSales/invoiceApply")
- });
- });
- }
- function menu_type_change() {
- const { invtype } = ruleForm.value;
- rules.email[0].required = (
- invtype === "special_electronic" ||
- invtype === "electronic" ||
- invtype === "fully_digitalized_special_electronic" ||
- invtype === "fully_digitalized_normal_electronic");
- }
- function handleAddModalShow() {
- const { companyNo, platform_type } = ruleForm.value;
- if (!companyNo) return ElMessage.warning("请选择销售公司抬头");
- if (!platform_type) return ElMessage.warning("请选择平台类型");
- modelRef.value.show(companyNo, platform_type);
- }
- function handleAddOrder(list) {
- ruleForm.value.remark = "";
- list.forEach((item, index) => {
- const { sequenceNo, platform_type, winv_fee, winv_num, poCode } = item;
- if (!mapSequenceNoToInvfee.value[sequenceNo]) {
- mapSequenceNoToInvfee.value[sequenceNo] = {
- inv_fee: winv_fee,
- num: winv_num,
- platform_type
- };
- orderList.value.push(item);
- ruleForm.value.remark += index === 0 ? poCode : ";" + poCode;
- }
- });
- }
- //设置发票抬头详情
- const sellerInvoiceTitle = ref<Record<string, string>>({});
- const purchaserInvoiceTitle = ref<Record<string, string>>({});
- function handleInvoiceTitle(
- _isSeller: boolean,
- invoiceTitle: Record<string, string>
- ) {
- if (!invoiceTitle) {
- if (_isSeller) {
- return (sellerInvoiceTitle.value = {});
- }
- return (purchaserInvoiceTitle.value = {});
- }
- if (_isSeller) {
- //支持的开票方式
- const { invoiceType, denomination: _denomination } = invoiceTitle;
- denomination.value = Number(_denomination) * 10000;
- const chunks = invoiceType.split(",");
- ruleForm.value.invtype = "";
- invoiceTypes.value = xs_inv_type_list.filter(({ value }) =>
- chunks.includes(value)
- );
- // invoiceTypes.value = [
- // ...invoiceTypes.value,
- // { label: "全电专用发票", value: "fully_digitalized_special_electronic", scanValue: "31" },
- // { label: "全电普通发票", value: "fully_digitalized_normal_electronic", scanValue: "32" }
- // ];
- // console.log(chunks);
- }
- _isSeller
- ? (sellerInvoiceTitle.value = convertInvoiceTitleData(
- convertInvoiceTitle(invoiceTitle)
- ))
- : (purchaserInvoiceTitle.value = convertInvoiceTitleData(invoiceTitle));
- }
- const setSellerInvoiceTitle = handleInvoiceTitle.bind(null, true);
- const setPurchaserInvoiceTitle = handleInvoiceTitle.bind(null, false);
- async function handleCompanyChange(companyNo) {
- ruleForm.value.companyNo = companyNo;
- const { code, data, message } = await httpCompanylist({
- companyNo
- });
- nextTick(() => {
- if (formRef.value) {
- formRef.value.validateField("companyNo");
- }
- });
- responseHandle({
- code,
- message,
- handler: () => setSellerInvoiceTitle(data.list[0])
- });
- }
- watch(
- () => ruleForm.value.platform_type,
- () => {
- ruleForm.value.remark = "";
- orderList.value = [];
- mapSequenceNoToInvfee.value = {};
- },
- {
- immediate: true
- }
- );
- onMounted(() => {
- handleCompanyChange(currentCompany.value.companyNo);
- });
- const totalPrice = ref('0.00')
- watch(() => mapSequenceNoToInvfee.value, (newVal) => {
- totalPrice.value = '0.00'
- const keys = Object.keys(mapSequenceNoToInvfee.value);
- const orderArr = keys.map(sequenceNo => {
- const { inv_fee } = mapSequenceNoToInvfee.value[sequenceNo];
- totalPrice.value = Number(addition(totalPrice.value, inv_fee)).toFixed(2)
- })
- }, {
- deep: true
- })
- </script>
- <template>
- <div class="addEditForm">
- <el-form
- ref="formRef"
- v-loading="loading"
- :model="ruleForm"
- :rules="rules"
- status-icon
- size="small"
- >
- <el-row>
- <el-col :span="12">
- <el-form-item
- label="销售方公司抬头"
- prop="companyNo"
- >
- <el-select
- style="width: 100%"
- placeholder="销售方公司抬头"
- disabled
- v-model="ruleForm.companyNo"
- >
- <el-option
- v-for="c in companyList"
- :key="c.companyCode"
- :value="c.companyCode"
- :label="c.companyName"
- />
- </el-select>
- </el-form-item>
- <InvoiceTitle :detail="sellerInvoiceTitle" />
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="购买方公司抬头"
- prop="buy_id"
- >
- <RemoteSelect
- is-root
- v-model:value="ruleForm.buy_id"
- :api="httpInvoiceList"
- style="width: 100%"
- placeholder="购买方公司抬头"
- request-prop="name"
- response-label-prop="invoice_title"
- response-val-prop="id"
- @item-change="setPurchaserInvoiceTitle"
- />
- </el-form-item>
- <InvoiceTitle :detail="purchaserInvoiceTitle" />
- </el-col>
-
- <el-col :span="6">
- <el-form-item label="发票类型" prop="invtype">
- <el-select
- v-model="ruleForm.invtype"
- style="width: 100%"
- @change="menu_type_change"
- placeholder="发票类型"
- no-data-text="请选择其他销售方公司"
- >
- <el-option
- v-for="si in invoiceTypes"
- :key="si.value"
- :label="si.label"
- :value="si.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="电子邮箱" prop="email">
- <el-input v-model="ruleForm.email" placeholder="电子邮箱" />
- </el-form-item>
- <el-form-item
- label="平台类型"
- prop="platform_type"
- >
- <el-switch
- v-model="ruleForm.platform_type"
- size="small"
- active-text="toC"
- inactive-text="toB"
- active-value="2"
- inactive-value="1"
- />
- </el-form-item>
- </el-col>
- <el-col :span="18">
- <el-form-item label="申请备注" prop="exam_remark">
- <el-input
- w-full
- v-model="ruleForm.exam_remark"
- :rows="5"
- type="textarea"
- maxlength="2000"
- placeholder="申请备注"
- show-word-limit
- />
- </el-form-item>
- </el-col>
- <el-col :span="24" v-show="TYPE === 'order'">
- <el-form-item label="订单列表">
- <div flex justify-between w-full mb-2>
- <div class="flex">
- <el-tag :type="orderList.length > max ? 'danger' : 'info'">
- {{ orderList.length }} / {{ max }}
- </el-tag>
- <el-tag style="margin-left: 10px" type="primary" size="small">{{totalPrice}}元</el-tag>
- </div>
- <el-button type="primary" @click="handleAddModalShow">添加</el-button>
- </div>
- <el-table :data="orderList" stripe border max-height="300">
- <el-table-column
- prop="sequenceNo"
- label="销售订单编码"
- show-overflow-tooltip
- width="150"
- />
- <el-table-column
- prop="sequenceNo"
- label="销售订单主编码"
- show-overflow-tooltip
- width="150"
- />
- <el-table-column
- prop="poCode"
- label="平台订单编码"
- show-overflow-tooltip
- width="150"
- />
- <el-table-column
- prop="customerNo"
- label="购买方公司编码"
- width="150"
- show-overflow-tooltip
- />
- <el-table-column
- prop="inv_cat_code"
- label="类目编码"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- prop="inv_cat_name"
- label="货物和劳务名称"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- prop="inv_good_name"
- label="开票商品名称"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- prop="inv_tax"
- label="开票税率"
- show-overflow-tooltip
- width="80"
- >
- <template #="{ row }">
- {{ row.inv_tax ? (Number(row.inv_tax) * 100) + '%' : '' }}
- </template>
- </el-table-column>
- <el-table-column
- prop="customerName"
- label="购买方公司名称"
- show-overflow-tooltip
- width="200"
- />
- <el-table-column
- prop="winv_num"
- label="未开票数量"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- prop="winv_fee"
- label="未开票金额"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- label="平台类型"
- width="110"
- show-overflow-tooltip
- >
- <template #="{ row }">
- <el-tag size="small">{{
- useTypeOptions.find(
- p => p.value === String(row.platform_type)
- )?.label
- }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="开票金额"
- width="110"
- show-overflow-tooltip
- >
- <template #="{ row }">{{
- mapSequenceNoToInvfee[row.sequenceNo].inv_fee
- }}</template>
- </el-table-column>
- <el-table-column label="开票数量" show-overflow-tooltip>
- <template #="{ row }">{{
- mapSequenceNoToInvfee[row.sequenceNo].num
- }}</template>
- </el-table-column>
- <el-table-column
- label="业务员"
- show-overflow-tooltip
- prop="ownerName"
- width="80"
- />
- <el-table-column fixed="right" width="70">
- <template #header>
- <span>操作</span>
- </template>
- <template #default="scope">
- <el-button
- size="small"
- type="primary"
- link
- :icon="useRenderIcon('edits')"
- @click="handleShowEditModal(scope.$index, scope.row)"
- />
- <el-button
- size="small"
- type="danger"
- link
- :icon="useRenderIcon('delete')"
- @click="handleDelete(scope.$index)"
- />
- </template>
- </el-table-column>
- </el-table>
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="发票备注" prop="remark">
- <div w-full>
- <el-input
- w-full
- v-model="ruleForm.remark"
- :rows="3"
- type="textarea"
- maxlength="2000"
- show-word-limit
- placeholder="发票备注"
- />
- </div>
- </el-form-item>
- </el-col>
- <el-col :span="24" flex justify-end>
- <el-button :loading="loading" type="primary" @click="handleSave"
- >保存</el-button
- >
- </el-col>
- </el-row>
- </el-form>
- <OrderDialog ref="modelRef" @save-btn-click="handleAddOrder" />
- <EditOrder ref="editOrderRef" @save-btn-click="handleEdit" />
- </div>
- </template>
- <style lang="scss" scoped>
- :deep(.el-descriptions) {
- padding: 0px !important;
- padding-left: 30px !important;
- padding-bottom: 10px !important;
- }
- </style>
|