openInvoice.vue 12 KB
Newer Older
我在何方's avatar
我在何方 committed
1 2
<template>
  <div class="app-container">
吴滔's avatar
吴滔 committed
3
    <div slot="header" class="card-title">{{ $t('开票') }}</div>
我在何方's avatar
我在何方 committed
4
    <!-- 搜索工作栏 -->
吴滔's avatar
吴滔 committed
5 6 7 8 9 10 11 12 13
    <el-form
      :model="invoiceData"
      ref="queryForm"
      size="small"
      :inline="true"
      label-width="120px"
      class="card"
    >
      <el-card class="card">
吴滔's avatar
吴滔 committed
14
        <el-form-item :label="$t('发票号码')" prop="invoiceNumber" :rules="{ required: true, trigger: ['blur'], message: $t('发票号码不能为空') }">
吴滔's avatar
吴滔 committed
15 16
          <el-input v-model="invoiceData.invoiceNumber"></el-input>
        </el-form-item>
吴滔's avatar
吴滔 committed
17
        <el-form-item :label="$t('开票类型')" prop="invoicingTypeId" :rules="{ required: true, trigger: ['blur', 'change'], message: $t('开票类型不能为空') }">
吴滔's avatar
吴滔 committed
18 19 20 21 22 23 24
          <dict-selector
            :type="DICT_TYPE.ECW_INVOICING_TYPE"
            v-model="invoiceData.invoicingTypeId"
          />
        </el-form-item>
      </el-card>
      <el-card class="card">
吴滔's avatar
吴滔 committed
25
        <div slot="header" class="card-title">{{ $t('开票资料') }}</div>
吴滔's avatar
吴滔 committed
26
        <el-descriptions title="" direction="vertical" :column="6" border>
吴滔's avatar
吴滔 committed
27 28 29 30
          <el-descriptions-item :label="$t('发票抬头')">{{ invoiceData.invoice }}</el-descriptions-item>
          <el-descriptions-item :label="$t('纳税人识别号')">{{ invoiceData.taxpayer }}</el-descriptions-item>
          <el-descriptions-item :label="$t('地址')">{{ invoiceData.addressPhone }}</el-descriptions-item>
          <el-descriptions-item :label="$t('开户行')">{{ invoiceData.accountBank }}</el-descriptions-item>
我在何方's avatar
我在何方 committed
31
          <el-descriptions-item :label="$t('税率')+'%'">
吴滔's avatar
吴滔 committed
32
            <el-form-item label="">
33
              <el-input v-model="invoiceData.taxRate"></el-input>
吴滔's avatar
吴滔 committed
34 35
            </el-form-item>
          </el-descriptions-item>
吴滔's avatar
吴滔 committed
36
          <el-descriptions-item :label="$t('项目')">
吴滔's avatar
吴滔 committed
37
            <el-form-item label="">
38
              <el-input v-model="invoiceData.projectName"></el-input>
吴滔's avatar
吴滔 committed
39 40 41 42 43 44 45 46 47 48 49 50 51
            </el-form-item>
          </el-descriptions-item>
        </el-descriptions>
      </el-card>
      <el-card class="card">
        <el-table
          v-loading="loading"
          :data="list"
          border
          class="card"
          show-summary
          :summary-method="getSummaries"
        >
吴滔's avatar
吴滔 committed
52 53
          <el-table-column :label="$t('订单号')" align="center" prop="orderNo" />
          <el-table-column :label="$t('品名')" align="center" prop="titleZh">
我在何方's avatar
我在何方 committed
54
            <template slot-scope="scope">
吴滔's avatar
吴滔 committed
55
              {{ scope.row.titleZh || scope.row.titleEn ? scope.row.titleZh + "(" + scope.row.titleEn + ")" : '' }}
我在何方's avatar
我在何方 committed
56
            </template>
吴滔's avatar
吴滔 committed
57
          </el-table-column>
吴滔's avatar
吴滔 committed
58
          <el-table-column :label="$t('箱数')" align="center" prop="num" />
59 60 61 62 63
          <el-table-column :label="$t('体积/重量')" align="center" prop="weight">
            <template slot-scope="scope">
              {{ scope.row.volume?(scope.row.volume + '/'+scope.row.weight):'' }}
            </template>
          </el-table-column>
吴滔's avatar
吴滔 committed
64
          <el-table-column :label="$t('收入类型')" align="center" prop="feeType">
吴滔's avatar
吴滔 committed
65 66
            <template slot-scope="scope">
              <dict-tag
67
                :type="DICT_TYPE.FEE_TYPE"
吴滔's avatar
吴滔 committed
68 69 70 71
                :value="scope.row.feeType"
              ></dict-tag>
            </template>
          </el-table-column>
吴滔's avatar
吴滔 committed
72
          <el-table-column :label="$t('单价金额')" align="center" prop="unitPrice">
73
          <template slot-scope="scope">
我在何方's avatar
我在何方 committed
74 75
            <span>{{ scope.row.unitPrice }}{{getCurrencyLabel(scope.row.currencyId)}}</span>
            <!-- <dict-tag :type="DICT_TYPE.BOX_SHIPPING_PRICE_UNIT" :value="scope.row.currencyId" /> -->
76 77
          </template>
        </el-table-column>
吴滔's avatar
吴滔 committed
78
        <el-table-column :label="$t('总金额')" align="center" prop="totalAmount">
79
          <template slot-scope="scope">
我在何方's avatar
我在何方 committed
80 81
            <span>{{ scope.row.totalAmount }}{{getCurrencyLabel(scope.row.currencyId)}}</span>
            <!-- <dict-tag :type="DICT_TYPE.BOX_SHIPPING_PRICE_UNIT" :value="scope.row.currencyId" /> -->
82
          </template>
83 84 85 86 87 88 89 90 91 92
        </el-table-column>
        <el-table-column :label="$t('优惠金额')" align="center">
          <template slot-scope="scope">
            {{ scope.row.discountTotal ?scope.row.discountTotal : '' }}
          </template>
        </el-table-column>
        <el-table-column :label="$t('优惠后金额')" align="center">
          <template slot-scope="scope">
            {{ scope.row.disCountAmount ?scope.row.disCountAmount :0 }}
          </template>
93
        </el-table-column>
吴滔's avatar
吴滔 committed
94
          <el-table-column :label="$t('税额')" align="center" prop="tax">
吴滔's avatar
吴滔 committed
95
            <template slot-scope="scope">
我在何方's avatar
我在何方 committed
96 97
              <span>{{ scope.row.tax }}{{getCurrencyLabel(scope.row.currencyId)}}</span>
              <!-- <dict-tag :type="DICT_TYPE.BOX_SHIPPING_PRICE_UNIT" :value="scope.row.currencyId" /> -->
吴滔's avatar
吴滔 committed
98 99
            </template>
          </el-table-column>
吴滔's avatar
吴滔 committed
100
          <el-table-column :label="$t('价税合计')" align="center" prop="taxAndTotalAmount">
吴滔's avatar
吴滔 committed
101
            <template slot-scope="scope">
我在何方's avatar
我在何方 committed
102 103
              <span>{{ scope.row.taxAndTotalAmount }}{{getCurrencyLabel(scope.row.currencyId)}}</span>
              <!-- <dict-tag :type="DICT_TYPE.BOX_SHIPPING_PRICE_UNIT" :value="scope.row.currencyId" /> -->
吴滔's avatar
吴滔 committed
104 105 106 107 108
            </template>
          </el-table-column>
        </el-table>
      </el-card>
      <el-descriptions class="card" style="width: 50%">
吴滔's avatar
吴滔 committed
109
        <el-descriptions-item :label="$t('备注')">
吴滔's avatar
吴滔 committed
110 111 112 113 114 115 116 117 118 119
          <el-input
            v-model="invoiceData.invoicingRemark"
            type="text"
            placeholder=""
            clearable
          ></el-input>
        </el-descriptions-item>
      </el-descriptions>
    </el-form>
    <div slot="footer" class="card">
吴滔's avatar
吴滔 committed
120
      <el-button type="primary" @click="submitForm">{{ $t('确定') }}</el-button>
吴滔's avatar
吴滔 committed
121
    </div>
我在何方's avatar
我在何方 committed
122 123 124 125
  </div>
</template>

<script>
吴滔's avatar
吴滔 committed
126 127
import { DICT_TYPE } from "@/utils/dict";
import { getReceiptInvoicing, getInvoicingItem, updateReceiptInvoicing } from "@/api/ecw/financial";
128
import NP from 'number-precision'
我在何方's avatar
我在何方 committed
129

我在何方's avatar
我在何方 committed
130

吴滔's avatar
吴滔 committed
131 132 133 134 135 136 137 138
export default {
  name: "OpenInvoice",
  components: {},
  data() {
    return {
      loading: false,
      invoiceData: {},
      id: 0,
我在何方's avatar
我在何方 committed
139 140 141 142 143 144
      list: [],
	  params:{
	       page:1,
	       rows:20,
	   },
	  currencyList:[]
吴滔's avatar
吴滔 committed
145 146 147 148 149 150 151
    };
  },
  created() {
    if (this.$route.query.id) {
      this.id = this.$route.query.id;
      this.getData();
    }
我在何方's avatar
我在何方 committed
152
	 getCurrencyPage(this.params).then(res => this.currencyList = res.data.list)
吴滔's avatar
吴滔 committed
153 154
  },
  methods: {
我在何方's avatar
我在何方 committed
155 156
	  getCurrencyLabel(id){
	    var label = this.currencyList.filter(item=>item.id == id)
我在何方's avatar
我在何方 committed
157
	    if(label.length>0) return this.$i18n.locale=='zh_CN'?label[0].titleZh:label[0].titleEn
我在何方's avatar
我在何方 committed
158 159
	    return ''
	  },
160
    async getData() {
吴滔's avatar
吴滔 committed
161
      this.loading = true;
162
      await getReceiptInvoicing(this.id).then((res) => {
吴滔's avatar
吴滔 committed
163 164 165 166 167 168 169 170
        this.invoiceData = res.data;
        this.invoiceData.invoicingTypeId = this.invoiceData.invoicingTypeId || ''
        // if (!this.invoiceData.info || this.invoiceData.info.length == 0) {
        //   this.$modal.msgError("客户开票资料不能为空,请完善客户开票信息");
        // }
        this.loading = false;
      });
      getInvoicingItem({ id: this.id }).then(res => {
171 172 173
        res.data.map(v => {
          v.tax = NP.times(v.totalAmount, this.invoiceData.taxRate/100)
          v.taxAndTotalAmount = NP.plus(v.totalAmount, NP.times(v.totalAmount, this.invoiceData.taxRate/100))
174 175 176 177 178 179
          if(v.discountTotal){
            v.disCountAmount = NP.minus(v.totalAmount,v.discountTotal)
          }else{
            v.disCountAmount = v.totalAmount
          }

180
        })
吴滔's avatar
吴滔 committed
181
        const t = {
吴滔's avatar
吴滔 committed
182
          orderNo: this.$t('合计'),
183
          totalAmount: res.data.reduce((total, curr) => NP.plus(total, curr.totalAmount), 0),
184
          disCountAmount:res.data.reduce((total, curr) => NP.plus(total, curr.disCountAmount), 0),
185 186
          tax: res.data.reduce((total, curr) => NP.plus(total, curr.tax), 0),
          taxAndTotalAmount: res.data.reduce((total, curr) => NP.plus(total, curr.taxAndTotalAmount), 0)
吴滔's avatar
吴滔 committed
187 188
        }
        this.list = [...res.data, t]
189
        console.log(this.list)
吴滔's avatar
吴滔 committed
190 191 192 193 194 195 196
      })
    },
    submitForm() {
      this.$refs.queryForm.validate(valid => {
        if (valid) {
          updateReceiptInvoicing(this.invoiceData).then(res => {
            this.open = false;
吴滔's avatar
吴滔 committed
197
            this.$modal.msgSuccess(this.$t('操作成功'));
吴滔's avatar
吴滔 committed
198 199 200 201 202 203
            this.$router.back();
          })
        }
      })
    },
    getSummaries(param) {
204
      const t = this.list[this.list.length - 1].taxAndTotalAmount
205
      return [this.$t('收款人'), this.invoiceData.salesmanName, this.$t('核销人'), this.invoiceData.writeOffName, this.$t('开票人'), this.invoiceData.issuerName, '', this.$t('价税合计大写'), this.convertCurrency(t)];
吴滔's avatar
吴滔 committed
206
    },
207 208
    convertCurrency(money) {
      //汉字的数字
Marcus's avatar
Marcus committed
209
      var cnNums = new Array('', this.$t(''), this.$t(''), this.$t(''), this.$t(''), this.$t(''), this.$t(''), this.$t(''), this.$t(''), '');
210
      //基本单位
Marcus's avatar
Marcus committed
211
      var cnIntRadice = new Array('', this.$t(''), this.$t(''), '');
212
      //对应整数部分扩展单位
Marcus's avatar
Marcus committed
213
      var cnIntUnits = new Array('', this.$t(''), this.$t('亿'), '');
214
      //对应小数部分单位
Marcus's avatar
Marcus committed
215
      var cnDecUnits = new Array('', this.$t(''), this.$t(''), '');
216
      //整数金额时后面跟的字符
Marcus's avatar
Marcus committed
217
      var cnInteger = this.$t('');
218
      //整型完以后的单位
Marcus's avatar
Marcus committed
219
      var cnIntLast = this.$t('');
220 221 222 223 224 225 226 227 228 229
      //最大处理的数字
      var maxNum = 999999999999999.9999;
      //金额整数部分
      var integerNum;
      //金额小数部分
      var decimalNum;
      //输出的中文金额字符串
      var chineseStr = '';
      //分离金额后用的数组,预定义
      var parts;
230
      // 传入的参数为空情况
231 232 233 234 235 236 237
      if(money === '') {
        return '';
      }
      money = parseFloat(money)
      if(money >= maxNum){
        return ''
      }
238
      // 传入的参数为0情况
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
      if (money === 0) {
        chineseStr = cnNums[0] + cnIntLast + cnInteger;
        return chineseStr
      }
      // 转为字符串
      money = money.toString();
      // indexOf 检测某字符在字符串中首次出现的位置 返回索引值(从0 开始) -1 代表无
      if (money.indexOf('.') == -1) {
        integerNum = money;
        decimalNum = ''
      }else{
        parts = money.split('.');
        integerNum = parts[0];
        decimalNum = parts[1].substr(0,4);
      }
      //转换整数部分
      if(parseInt(integerNum,10) > 0){
        let zeroCount  = 0;
        let IntLen = integerNum.length
        for(let i = 0; i < IntLen; i++){
          let n = integerNum.substr(i,1);
          let p = IntLen - i - 1;
          let q = p / 4;
          let m = p % 4;
          if( n == '0'){
            zeroCount ++ ;
          }else{
            if(zeroCount > 0){
                chineseStr += cnNums[0]
            }
            zeroCount = 0;
            chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
          }
          if(m == 0 && zeroCount < 4){
273
            chineseStr += cnIntUnits[q];
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
          }
        }
        // 最后+ 元
        chineseStr += cnIntLast;
      }
      // 转换小数部分
      if(decimalNum != ''){
        let decLen = decimalNum.length;
        for(let i = 0; i <decLen; i++){
          let n = decimalNum.substr(i,1);
          if(n != '0'){
            chineseStr += cnNums[Number(n)] + cnDecUnits[i]
          }
        }
      }
      if(chineseStr == ''){
        chineseStr += cnNums[0] + cnIntLast + cnInteger;
      }else if(decimalNum == ''){
        chineseStr += cnInteger;
      }
      return chineseStr
    }
吴滔's avatar
吴滔 committed
296 297 298
  },
};
</script>
我在何方's avatar
我在何方 committed
299

吴滔's avatar
吴滔 committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
 <style scoped lang="scss">
.card {
  margin-top: 20px;
}
.dialog-footer {
  padding: 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  height: 160px;
}
.card-title {
  font-size: 18px;
  font-weight: bold;
}
.lastRow {
  border-top: 1px solid #dfe6ec;
  display: flex;
  width: 100%;
  height: 44px;
  text-align: center;
  align-items: center;
}
.lastRow div {
  flex: 1;
  height: 44px;
  line-height: 44px;
  border-right: 1px solid #dfe6ec;
}
::v-deep .el-form-item--small.el-form-item {
  margin-bottom: 0;
}
</style>