| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| <template> | |
| <div> | |
| <filter-quota-data-by-period-view @fetchData="fetchData"/> | |
| <div v-if="dataSource.length > 0"> | |
| <export-to-csv-button :action="exportDataToCsv" /> | |
| <bar-chart :chart-options="getCreditsChartOptions()" :chart-data="getCreditsChartData()"/> | |
| <a-table | |
| size="small" | |
| :loading="loading" | |
| :columns="columns" | |
| :dataSource="dataSource" | |
| :rowKey="record => record.creditedon" | |
| :pagination="false" | |
| :scroll="{ y: '55vh' }"> | |
| <template #title> | |
| {{ $t('label.currency') }}: <b>{{ currency }}</b> | |
| </template> | |
| <template #creditedOn="{ text }"> | |
| {{ $toLocaleDate(text) }} | |
| </template> | |
| <template #credit="{ text }"> | |
| {{ parseFloat(text).toFixed(2) }} | |
| </template> | |
| <template #creditor="{ text, record }"> | |
| <router-link v-if="this.userAccess[record.creditoruserid]" :to="{ path: '/accountuser/' + record.creditoruserid }"> | |
| {{ text }} | |
| </router-link> | |
| <span v-else>{{ text }}</span> | |
| </template> | |
| </a-table> | |
| </div> | |
| </div> | |
| </template> | |
| <script> | |
| import { getAPI } from '@/api' | |
| import BarChart from '@/components/view/charts/BarChart.vue' | |
| import * as dateUtils from '@/utils/date' | |
| import { downloadDataAsCsv } from '@/utils/util.js' | |
| import FilterQuotaDataByPeriodView from './FilterQuotaDataByPeriodView.vue' | |
| import ExportToCsvButton from '@/components/view/buttons/ExportToCsvButton.vue' | |
| import * as chartUtils from '@/utils/chart' | |
| export default { | |
| name: 'QuotaCreditTab', | |
| components: { | |
| FilterQuotaDataByPeriodView, | |
| BarChart, | |
| ExportToCsvButton | |
| }, | |
| data () { | |
| return { | |
| loading: false, | |
| currency: '', | |
| dataSource: [], | |
| startDate: undefined, | |
| endDate: undefined, | |
| userAccess: {} | |
| } | |
| }, | |
| computed: { | |
| columns () { | |
| return [ | |
| { | |
| title: this.$t('label.date'), | |
| dataIndex: 'creditedon', | |
| width: 'calc(100% / 3)', | |
| sorter: (a, b) => a.creditedon.localeCompare(b.creditedon), | |
| defaultSortOrder: 'descend', | |
| slots: { customRender: 'creditedOn' } | |
| }, | |
| { | |
| title: this.$t('label.credit'), | |
| dataIndex: 'credit', | |
| width: 'calc(100% / 3)', | |
| sorter: (a, b) => a.credit - b.credit, | |
| slots: { customRender: 'credit' } | |
| }, | |
| { | |
| title: this.$t('label.creditor'), | |
| dataIndex: 'creditorusername', | |
| width: 'calc(100% / 3)', | |
| sorter: (a, b) => a.creditorusername.localeCompare(b.creditorusername), | |
| slots: { customRender: 'creditor' } | |
| } | |
| ] | |
| } | |
| }, | |
| methods: { | |
| async fetchData (startDate, endDate) { | |
| if (this.loading) return | |
| this.startDate = dateUtils.parseDayJsObject({ value: startDate }) | |
| this.endDate = dateUtils.parseDayJsObject({ value: endDate }) | |
| this.dataSource = [] | |
| this.loading = true | |
| try { | |
| const data = await this.getQuotaCreditsList() | |
| if (!data) { | |
| return | |
| } | |
| this.currency = data[0]?.currency | |
| this.dataSource = data.map(row => ({ | |
| ...row, | |
| date: dateUtils.parseDayJsObject({ value: row.creditedon, keepMoment: false }) | |
| })) | |
| const uniqueCreditorUserIds = [...new Set( | |
| this.dataSource | |
| .map(row => row.creditoruserid) | |
| .filter(Boolean) | |
| )] | |
| await Promise.all(uniqueCreditorUserIds.map(userid => this.checkUserAccess(userid))) | |
| } finally { | |
| this.loading = false | |
| } | |
| }, | |
| async getQuotaCreditsList () { | |
| const params = { | |
| accountid: this.$route.params?.id, | |
| startdate: this.startDate, | |
| enddate: this.endDate | |
| } | |
| return await getAPI('quotaCreditsList', params) | |
| .then(json => json.quotacreditslistresponse.credit || []) | |
| .catch(error => { error && this.$notification.info({ message: this.$t('message.request.no.data') }) }) | |
| }, | |
| async checkUserAccess (userid) { | |
| if (userid === undefined) { | |
| return | |
| } | |
| if (Object.prototype.hasOwnProperty.call(this.userAccess, userid)) { | |
| return | |
| } | |
| if (this.$router.resolve('/accountuser/' + userid).matched[0].redirect === '/exception/404') { | |
| return | |
| } | |
| const params = { id: userid } | |
| const json = await getAPI('listUsers', params) | |
| const response = json.listusersresponse.user || [] | |
| if (response?.[0]) { | |
| this.userAccess[userid] = true | |
| } else { | |
| this.userAccess[userid] = false | |
| } | |
| }, | |
| exportDataToCsv () { | |
| downloadDataAsCsv({ | |
| data: this.dataSource, | |
| keys: ['date', 'credit', 'creditorusername'], | |
| fileName: `credits-of-account-${this.$route.params.id}-between-${this.startDate}-and-${this.endDate}` | |
| }) | |
| }, | |
| getCreditsChartData () { | |
| const datasets = [] | |
| const data = [] | |
| const res = {} | |
| this.dataSource.map(value => { | |
| const date = this.$toLocalDate(value.creditedon).split('T')[0] | |
| if (!res[date]) { | |
| res[date] = { date, credit: 0 } | |
| data.push(res[date]) | |
| } | |
| res[date].credit += value.credit | |
| return res | |
| }) | |
| datasets.push({ | |
| label: this.$t('label.credit'), | |
| data: data.map(row => row.credit), | |
| ...chartUtils.getChartColorObject() | |
| }) | |
| return { | |
| labels: data.map(row => row.date), | |
| datasets | |
| } | |
| }, | |
| getCreditsChartOptions () { | |
| return { | |
| scales: { | |
| xAxis: { | |
| type: 'time', | |
| time: { | |
| unit: chartUtils.getUnitToTimeCartesianAxis('day', this.dataSource.length), | |
| displayFormats: chartUtils.defaultDisplayFormats | |
| } | |
| } | |
| }, | |
| plugins: { | |
| tooltip: { | |
| callbacks: { | |
| title: (tooltipItem) => dateUtils.dayjs(tooltipItem[0].label).format(chartUtils.defaultDisplayFormats.day), | |
| label: (tooltipItem) => parseFloat(tooltipItem.raw).toFixed(2) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style lang="scss" scoped> | |
| @import '@/style/common/common.scss'; | |
| </style> |