Procházet zdrojové kódy

发票明细导入、模板下载

lizhenhao před 2 roky
rodič
revize
bb3f0bac7f

+ 14 - 0
src/api/finance/invoice/FinanceInvoiceService.js

@@ -71,4 +71,18 @@ export default class FinanceInvoiceService {
       params: {id: id}
     })
   }
+  importDetail (data) {
+    return request({
+      url: '/finance/invoice/importDetail',
+      method: 'post',
+      data: data
+    })
+  }
+  exportTemplate () {
+    return request({
+      url: '/finance/invoice/importDetail/template',
+      method: 'get',
+      responseType: 'blob'
+    })
+  }
 }

+ 3 - 0
src/utils/common.js

@@ -67,6 +67,9 @@ export default {
     }
     return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
   },
+  isNotEmpty (value) {
+    return !this.isEmpty(value)
+  },
   /**
    * @param {string} value
    */

+ 139 - 1
src/views/modules/finance/invoice/InvoiceFormTask.vue

@@ -372,6 +372,40 @@
         <el-button style="margin-left: 20px" type="primary" :disabled="status === 'audit'?false:true" size="mini" @click="insertEvent('detail')" plain>
           新增
         </el-button>
+        <el-popover
+          placement="top"
+          width="400"
+          v-model="importVisible">
+          <p>请先下载模板,然后再进行导入操作</p>
+          <el-row :gutter="1">
+            <el-col :span="6">
+              <el-button type="success" size="small" @click="downloadTpl">下载模板</el-button>
+            </el-col>
+            <el-col :span="6">
+              <el-upload
+                action=""
+                :auto-upload="false"
+                :on-change="beforeUploadDetail"
+                :show-file-list="false">
+                <el-button size="small" type="primary">导入全部</el-button>
+              </el-upload>
+            </el-col>
+            <el-col :span="6">
+              <el-upload
+                action=""
+                :auto-upload="false"
+                :on-change="beforeUploadDetailCode"
+                :show-file-list="false">
+                <el-button size="small" type="primary">仅导入当前纳税人识别号</el-button>
+              </el-upload>
+            </el-col>
+          </el-row>
+          <div style="text-align: right; margin-top: 10px;margin-right: 10px;">
+            <el-button size="mini" type="default" @click="importVisible = false" plain>取消</el-button>
+<!--            <el-button type="primary" size="mini" @click="importVisible = false">确定</el-button>-->
+          </div>
+          <el-button style="margin-left: 20px" slot="reference" :disabled="status === 'audit'?false:true" type="warning" size="mini" plain>导入</el-button>
+        </el-popover>
       </el-divider>
       <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="status !== 'audit'"
                label-width="160px" @submit.native.prevent>
@@ -622,7 +656,8 @@
         programRow: '',
         bankList: [],
         err: '',
-        keyWatch: ''
+        keyWatch: '',
+        importVisible: false
       }
     },
     financeInvoiceService: null,
@@ -671,6 +706,7 @@
         this.keyWatch = keyWatch
       },
       init (method, id) {
+        this.importVisible = false
         this.method = method
         this.inputForm = {
           id: '',
@@ -1143,6 +1179,108 @@
             this.financeInvoiceService.updateStatusById(param)
           }
         }
+      },
+      // 下载模板
+      downloadTpl () {
+        this.loading = true
+        this.financeInvoiceService.exportTemplate().then((res) => {
+          // 将二进制流文件写入excel表,以下为重要步骤
+          this.$utils.downloadExcel(res.data, '发票明细导入模板')
+          this.loading = false
+        }).catch(function (err) {
+          this.loading = false
+          if (err.response) {
+            console.log(err.response)
+          }
+        })
+      },
+      async detailPush (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          await data.forEach(item => {
+            this.getAmount(item)
+            this.getTax(item)
+            this.inputForm.financeInvoiceDetailDTOList.push(item)
+          })
+        }
+        this.$message.success('导入完成')
+      },
+      beforeUploadDetail (file) {
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async (result) => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          await this.detailPush(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      checkIdentificationNo () {
+        if (this.commonJS.isEmpty(this.inputForm.taxpayerIdentificationNo)) {
+          this.$message.error('当前纳税人识别号为空,导入失败')
+          throw new Error()
+        }
+      },
+      async beforeUploadDetailCode (file) {
+        console.log('110', this.inputForm.taxpayerIdentificationNo)
+        await this.checkIdentificationNo()
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async result => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            await this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          this.detailPushCode(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      detailPushCode (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          data.forEach(item => {
+            if (this.commonJS.isNotEmpty(item.taxpayerIdentificationNo)) {
+              if (item.taxpayerIdentificationNo === this.inputForm.taxpayerIdentificationNo) {
+                this.getAmount(item)
+                this.getTax(item)
+                this.inputForm.financeInvoiceDetailDTOList.push(item)
+              }
+            }
+          })
+        }
+        this.$message.success('导入完成')
       }
     }
   }

+ 4 - 4
src/views/modules/finance/invoice/InvoiceFormTaskInvalid.vue

@@ -143,7 +143,7 @@
                           :rules="[
                       {required: true, message:'开户银行不能为空', trigger:'blur'},{required: true, message:'开户银行不能为空', trigger:'change'}
              ]">
-              <el-select v-model="inputForm.openBank" @change="changeBank" placeholder="请选择开户银行" clearable style="width: 100%;"clearable>
+              <el-select v-model="inputForm.openBank" @change="changeBank" placeholder="请选择开户银行" clearable style="width: 100%;">
                 <el-option
                   v-for="item in bankList"
                   :key="item.id"
@@ -188,7 +188,7 @@
             <el-form-item label="开户银行" prop="openBank"
                           :rules="[
              ]">
-              <el-select v-model="inputForm.openBank" @change="changeBank" placeholder="请选择开户银行" clearable style="width: 100%;"clearable>
+              <el-select v-model="inputForm.openBank" @change="changeBank" placeholder="请选择开户银行" clearable style="width: 100%;">
                 <el-option
                   v-for="item in bankList"
                   :key="item.id"
@@ -212,7 +212,7 @@
                         :rules="[
                         {required: true, message:'收款类型不能为空', trigger:'blur'}
                ]">
-            <el-select v-model="inputForm.receivablesType" placeholder="请选择收款类型" clearable style="width: 100%;"clearable>
+            <el-select v-model="inputForm.receivablesType" placeholder="请选择收款类型" clearable style="width: 100%;">
               <el-option
                 v-for="item in $dictUtils.getDictList('invoice_receivables_type')"
                 :key="item.value"
@@ -227,7 +227,7 @@
                         :rules="[
                         {required: true, message:'开票内容不能为空', trigger:'blur'}
                ]">
-            <el-select v-model="inputForm.billingContent" placeholder="请选择开票内容" clearable style="width: 100%;"clearable>
+            <el-select v-model="inputForm.billingContent" placeholder="请选择开票内容" clearable style="width: 100%;">
               <el-option
                 v-for="item in $dictUtils.getDictList('invoice_billing_content')"
                 :key="item.value"

+ 117 - 10
src/views/modules/finance/invoice/InvoiceList.vue

@@ -3,9 +3,73 @@
     <el-form size="small" :inline="true" class="query-form" ref="searchForm" :model="searchForm" @keyup.enter.native="refreshList()" @submit.native.prevent>
       <!-- 搜索框-->
       <el-row :gutter="0">
+        <el-form-item prop="no" label="发票申请编号">
+          <el-input size="small" v-model="searchForm.no" placeholder="请输入发票申请编号" clearable></el-input>
+        </el-form-item>
         <el-form-item prop="number" label="发票号">
           <el-input size="small" v-model="searchForm.number" placeholder="请输入发票号" clearable></el-input>
         </el-form-item>
+        <el-form-item prop="programName" label="项目名称">
+          <el-input size="small" v-model="searchForm.programName" placeholder="请输入项目名称" clearable @clear="clearProgram">
+            <el-button slot="append" @click="openProgramPageForm()" icon="el-icon-search"></el-button>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="reconciliationPeople" label="对账人">
+          <UserSelect :limit='1' :readonly="true" :value="searchForm.reconciliationPeople" @getValue='(value) => {searchForm.reconciliationPeople = value}'></UserSelect>
+        </el-form-item>
+        <el-form-item prop="billingWorkplaceReal" label="开票单位">
+          <el-input size="small" v-model="searchForm.billingWorkplaceReal" placeholder="请输入开票单位" clearable></el-input>
+        </el-form-item>
+        <el-form-item prop="receivablesStatus" label="是否收款">
+          <el-select v-model="searchForm.receivablesStatus" placeholder="请选择是否收款" clearable>
+            <el-option label="是" value="1"></el-option>
+            <el-option label="否" value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="type" label="发票类型">
+          <el-select v-model="searchForm.type" placeholder="请选择发票类型" clearable>
+            <el-option
+              v-for="item in this.$dictUtils.getDictList('invoice_type')"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="receivablesType" label="收款类型">
+          <el-select v-model="searchForm.receivablesType" placeholder="请选择收款类型"clearable>
+            <el-option
+              v-for="item in $dictUtils.getDictList('invoice_receivables_type')"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="billingContent" label="开票内容">
+          <el-select v-model="searchForm.billingContent" placeholder="请选择开票内容"clearable>
+            <el-option
+              v-for="item in $dictUtils.getDictList('invoice_billing_content')"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="reconciliationArea" label="对账地区">
+          <SelectTree
+            ref="areaTree"
+            :props="{
+                    value: 'id',             // ID字段名
+                    label: 'name',         // 显示名称
+                    children: 'children'    // 子级字段名
+                  }"
+            url="/sys/area/treeData"
+            :value="searchForm.reconciliationArea"
+            :clearable="true"
+            :accordion="true"
+            @getValue="(value) => {searchForm.reconciliationArea=value}"/>
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
           <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
@@ -45,6 +109,7 @@
         <el-form-item prop="billingDateList" label="开票日期">
           <el-date-picker
             size="small"
+            @change="changeBillingDateList"
             v-model="searchForm.billingDateList"
             type="daterange"
             value-format="yyyy-MM-dd"
@@ -165,6 +230,7 @@
       </div>
     </div>
     <InvoiceForm  ref="invoiceForm" @refreshDataList="refreshList"></InvoiceForm>
+    <ProgramPageForm ref="programPageForm" @getProgram="getProgram"></ProgramPageForm>
   </div>
 </template>
 
@@ -175,6 +241,10 @@
   import TaskService from '@/api/flowable/TaskService'
   import ProcessService from '@/api/flowable/ProcessService'
   import UserService from '@/api/sys/UserService'
+  import UserSelect from '@/components/userSelect'
+  import SelectUserTree from '@/views/modules/utils/treeUserSelect'
+  import SelectTree from '@/components/treeSelect/treeSelect.vue'
+  import ProgramPageForm from '@/views/modules/finance/invoice/ProgramPageForm'
   export default {
     data () {
       return {
@@ -189,7 +259,8 @@
           remittanceDateBegin: '',
           remittanceDateEnd: '',
           programName: '',
-          programId: ''
+          programId: '',
+          reconciliationPeople: ''
         },
         dataList: [],
         tablePage: {
@@ -221,7 +292,11 @@
       this.userService = new UserService()
     },
     components: {
-      InvoiceForm
+      InvoiceForm,
+      UserSelect,
+      SelectUserTree,
+      SelectTree,
+      ProgramPageForm
     },
     mounted () {
       this.refreshList()
@@ -253,12 +328,18 @@
             this.searchForm.billingDateBegin = this.searchForm.billingDateList[0]
             this.searchForm.billingDateEnd = this.searchForm.billingDateList[1]
           }
+        } else {
+          this.searchForm.billingDateBegin = ''
+          this.searchForm.billingDateEnd = ''
         }
         if (!this.commonJS.isEmpty(this.searchForm.remittanceDateList)) {
           if (!this.commonJS.isEmpty(this.searchForm.remittanceDateList[0]) && !this.commonJS.isEmpty(this.searchForm.remittanceDateList[1])) {
-            this.searchForm.remittanceDateBegin = this.moment(this.searchForm.remittanceDateList[0]).format('YYYY-MM-DD')
-            this.searchForm.remittanceDateEnd = this.moment(this.searchForm.remittanceDateList[1]).format('YYYY-MM-DD')
+            this.searchForm.remittanceDateBegin = this.searchForm.remittanceDateList[0]
+            this.searchForm.remittanceDateEnd = this.searchForm.remittanceDateList[1]
           }
+        } else {
+          this.searchForm.remittanceDateBegin = ''
+          this.searchForm.remittanceDateEnd = ''
         }
         this.financeInvoiceService.list({
           'current': this.tablePage.currentPage,
@@ -350,12 +431,20 @@
         })
       },
       resetSearch () {
-        this.searchForm.billingDateList = []
-        this.searchForm.remittanceDateList = []
-        this.searchForm.billingDateBegin = ''
-        this.searchForm.billingDateEnd = ''
-        this.searchForm.remittanceDateBegin = ''
-        this.searchForm.remittanceDateEnd = ''
+        this.searchForm = {
+          number: '',
+          accountBegin: undefined,
+          accountEnd: undefined,
+          billingDateList: [],
+          billingDateBegin: '',
+          billingDateEnd: '',
+          remittanceDateList: [],
+          remittanceDateBegin: '',
+          remittanceDateEnd: '',
+          programName: '',
+          programId: '',
+          reconciliationPeople: ''
+        }
         this.$refs.searchForm.resetFields()
         this.refreshList()
       },
@@ -551,6 +640,24 @@
             this.refreshList()
           })
         })
+      },
+      changeBillingDateList (event) {
+        if (this.commonJS.isNotEmpty(this.searchForm.billingDateList)) {
+          console.log('event', event)
+        }
+      },
+      openProgramPageForm () {
+        this.$refs.programPageForm.init('1', false)
+      },
+      getProgram (rows) {
+        if (this.commonJS.isNotEmpty(rows)) {
+          this.searchForm.programName = rows[0].name
+          this.searchForm.programId = rows[0].id
+        }
+      },
+      clearProgram () {
+        this.searchForm.programName = ''
+        this.searchForm.programId = ''
       }
     }
   }

+ 3 - 0
src/views/modules/finance/invoice/ProgramPageForm.vue

@@ -130,6 +130,9 @@
             this.isShow = false
             this.checkType = '1'
             this.$message({message: '第一条为项目后面新增只能选择项目', type: 'warning', customClass: 'messageZindex'})
+          } else if (isShow === '1') {
+            this.isShow = false
+            this.checkType = '1'
           } else {
             this.isShow = false
             this.checkType = '2'