irc_web/.svn/pristine/cc/cca7288713a472142994e1afcd1...

1268 lines
37 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="monthly-payment data-list">
<div class="filter-container">
<el-date-picker
v-model="listQuery.StatisticsDate"
class="mr"
type="month"
value-format="yyyy-MM"
format="yyyy-MM"
placeholder="Select Month"
:picker-options="pickerOption"
:clearable="false"
size="small"
/>
<el-select v-model="listQuery.Nation" placeholder="Nation" size="small" style="width:120px;margin-right:5px;" clearable>
<el-option label="CN" value="0" />
<el-option label="US" value="1" />
</el-select>
<el-input
v-model="listQuery.KeyWord"
placeholder="ID or Name"
style="width:150px;margin-right:5px;"
class="handle-select"
size="small"
/>
<el-button type="text" size="small" style="margin-left:5px;" @click="handleReset">Reset</el-button>
<el-button type="primary" size="small" @click="handleSearch">Search</el-button>
<el-button
type="primary"
:disabled="unlockCount==0||!exchangeRate > 0 || arrID.length == 0"
size="small"
:loading="lockLoading"
@click="handleLock"
>Lock</el-button>
<el-button
type="primary"
:disabled="arrID.length == 0 || unlockCount==0"
size="small"
:loading="calcLoading"
@click="handleCalculate"
>Calculate</el-button>
<el-button
type="primary"
size="small"
:disabled="!exchangeRate > 0 || arrID.length == 0"
:loading="exportLoading"
@click="handleExportExcel"
>Export Summary</el-button>
<el-button
type="primary"
size="small"
:disabled="!exchangeRate > 0 || arrID.length == 0"
:loading="exportDetailLoading"
@click="handleExportDetail"
>Export Details</el-button>
<el-button
type="primary"
size="small"
:disabled="!exchangeRate > 0 || arrID.length == 0"
:loading="exportPayrollLoading"
@click="handleExportPayroll"
>Export Payrolls</el-button>
<el-button
style="margin-left:auto"
type="primary"
size="small"
@click="handleAdjustment"
>Adjustment</el-button>
<el-button
style="margin-left: 5px"
type="primary"
size="small"
@click="handleSetting"
>Settings</el-button>
</div>
<div class="data-table">
<el-table
ref="table"
v-loading="listLoading"
size="small"
height="99%"
:data="list"
stripe
:cell-style="cellStyle"
:summary-method="getSummaries"
show-summary
@sort-change="handleSortChange"
@selection-change="handleSelectChange"
>
<el-table-column type="selection" :selectable="handleSelectTable" />
<el-table-column type="index" width="40" />
<el-table-column
prop="LastName"
label="Name"
show-overflow-tooltip
min-width="140"
sortable="custom"
>
<template slot-scope="scope">{{ scope.row.LastName + ' / ' + scope.row.FirstName }}</template>
</el-table-column>
<el-table-column
prop="DoctorNameInBank"
label="Name CN"
show-overflow-tooltip
min-width="110"
sortable="custom"
>
<template
slot-scope="scope"
>{{ scope.row.DoctorNameInBank?scope.row.DoctorNameInBank:scope.row.ChineseName }}</template>
</el-table-column>
<el-table-column
prop="Code"
label="ID"
show-overflow-tooltip
min-width="90"
sortable="custom"
/>
<el-table-column prop="RankName" label="Rank" show-overflow-tooltip min-width="80" />
<el-table-column prop="IDCard" label="Resident ID" show-overflow-tooltip min-width="100" />
<el-table-column prop="Phone" label="Phone Number" show-overflow-tooltip min-width="115" />
<el-table-column prop="BankName" label="Bank" show-overflow-tooltip min-width="80" />
<el-table-column
prop="BankCardNumber"
label="Account Number"
show-overflow-tooltip
min-width="125"
/>
<el-table-column
prop="TotalPaymentUSD"
label="Payment ($)"
min-width="130"
sortable="custom"
>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" placement="top">
<div slot="content">
{{ 'Current month: ' + scope.row.PaymentUSD }}
<br>
{{ 'Adjustment: ' + scope.row.AdjustPaymentUSD }}
</div>
<div>
{{
!scope.row.IDCard || !scope.row.BankCardNumber || !scope.row.RankName
? 'Setting Needed'
: scope.row.TotalPaymentUSD.toFixed(2)
}}
<!-- {{
!scope.row.IDCard || !scope.row.BankCardNumber || !scope.row.RankName
? 'Setting Needed'
: scope.row.TotalPaymentUSD
}} -->
</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="ExchangeRate" label="Exchange Rate" min-width="110">
<template slot-scope="scope">
<span>{{ scope.row.ExchangeRate | rounding }}</span>
</template>
</el-table-column>
<el-table-column
prop="TotalPaymentCNY"
label="Payment(¥)"
min-width="110"
sortable="custom"
:formatter="paymentCNFormatter"
>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" placement="top">
<div slot="content">
{{ 'Current month: ' + scope.row.PaymentCNY }}
<br>
{{ 'Adjustment: ' + scope.row.AdjustPaymentCNY }}
</div>
<!-- <div>{{ scope.row.ExchangeRate > 0 ? scope.row.TotalPaymentCNY.toFixed(2) : 'Setting Needed' }}</div> -->
<div>{{ scope.row.ExchangeRate > 0 ? scope.row.TotalPaymentCNY : 'Setting Needed' }}</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Status" prop="IsLock" sortable="custom">
<template slot-scope="scope">{{ scope.row.IsLock?'Locked':'Pending' }}</template>
</el-table-column>
<el-table-column label="Action" min-width="120">
<template slot-scope="scope">
<el-button
size="small"
type="text"
:disabled="!(scope.row.IDCard && scope.row.BankCardNumber)"
@click="handleDetail(scope.row)"
>Detail</el-button>
<el-button
v-if="!scope.row.IDCard || !scope.row.BankCardNumber || !scope.row.RankName"
size="small"
type="text"
style="color:red;"
@click="handleSettingDoctor(scope.row)"
>Setting</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination">
<pagination
:total="total"
:page.sync="listQuery.PageIndex"
:limit.sync="listQuery.PageSize"
@pagination="getList"
/>
</div>
<el-dialog
:key="form.DoctorId"
title="Edit"
:visible.sync="dialogVisible"
width="500px"
:close-on-click-modal="false"
size="small"
>
<el-form ref="reviewerDataForm" label-width="170px" :rules="rules" :model="form" size="small">
<el-form-item label="Name: ">
<el-input v-model="form.Name" readonly />
</el-form-item>
<el-form-item label="Name CN: " prop="DoctorNameInBank">
<el-input v-model="form.DoctorNameInBank" />
</el-form-item>
<el-form-item label="ID: " prop="Code">
<el-input v-model="form.Code" readonly />
</el-form-item>
<el-form-item label="Rank: " prop="Rank">
<el-select v-model="form.RankId" style="width:100%;">
<el-option
v-for="(item) in rankList"
:key="item.Id"
:label="item.RankName"
:value="item.Id"
/>
</el-select>
</el-form-item>
<el-form-item label="Personal Adjustment ($): " prop="Additional">
<el-input v-model="form.Additional" type="number" />
</el-form-item>
<el-form-item label="Resident ID: " prop="IDCard">
<el-input v-model="form.IDCard" />
</el-form-item>
<el-form-item label="Bank: " prop="BankName">
<el-input v-model="form.BankName" />
</el-form-item>
<el-form-item label="Account Number: " prop="BankCardNumber">
<el-input v-model="form.BankCardNumber" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" :disabled="btnDisabled" size="small" @click="handleSave">Ok</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { num2Money } from '@/utils/formatter'
import floatObj from '@/utils/float-operation'
import {
getMonthlyPaymentList,
lockMonthlyPayment,
calculateMonthlyPayment,
addOrUpdateReviewerPayInfo,
getReviewersPaymentDetailList,
getMonthlyPayroll
} from '@/api/financials'
import store from '@/store'
import { mapGetters, mapMutations } from 'vuex'
import Excel from 'exceljs'
import Zip from 'jszip'
import { saveAs } from 'file-saver'
const getListQueryDefault = () => {
return {
StatisticsDate: '',
KeyWord: '',
PageSize: 20,
PageIndex: 1,
Asc: true,
SortField: ''
}
}
export default {
name: 'EnrollmentsStats',
components: { Pagination },
filters: {
rounding(value) {
// return value ? Number(value).toFixed(2) : value
return value
}
},
data() {
return {
listQuery: getListQueryDefault(),
list: [],
listLoading: false,
total: 0,
exchangeRate: '',
arrID: '',
excelData: [], // 支付费用详情Excel数据
excelDataCount: 0,
excelDataPayroll: [], // 公司单汇总及明细 Excel数据
excelDataPayrollCount: 0,
lockLoading: false,
calcLoading: false,
exportLoading: false,
exportDetailLoading: false,
exportPayrollLoading: false,
form: {},
rules: {
DoctorNameInBank: [
{ required: true, message: 'Please specify', trigger: 'blur' }
],
BankName: [
{ required: true, message: 'Please specify', trigger: 'blur' }
],
BankCardNumber: [
{ required: true, message: 'Please specify', trigger: 'blur' }
],
IDCard: [
{ required: true, message: 'Please specify', trigger: 'blur' },
{
pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
message: 'Incorrect ID card format'
}
],
Rank: [{ required: true, message: 'Please select', trigger: ['blur', 'change'] }]
},
btnDisabled: false,
dialogVisible: false,
pickerOption: {
disabledDate: (time) => {
const _now = Date.now()
return time.getTime() > _now
}
}
}
},
computed: {
...mapGetters(['rankList', 'paymentQuery']),
unlockCount: function() {
var tempCount = 0
this.list.forEach((item) => {
if (this.arrID.indexOf(item.DoctorId) > -1) {
if (!item.IsLock) {
tempCount++
}
}
})
return tempCount
}
},
mounted() {
this.listQuery.StatisticsDate = new Date(
new Date().setMonth(new Date().getMonth() - 1)
).format('yyyy-MM')
this.paymentQuery ? (this.listQuery = this.paymentQuery) : ''
this.getList()
},
destroyed() {},
methods: {
getList() {
this.listLoading = true
this.setQueryParam(this.listQuery)
getMonthlyPaymentList(this.listQuery)
.then((res) => {
this.listLoading = false
this.list = res.Result.CostList.CurrentPageData
this.total = res.Result.CostList.TotalCount
this.exchangeRate = res.Result.ExchangeRate
})
.catch(() => {
this.listLoading = false
})
},
handleSearch() {
this.listQuery.PageIndex = 1
this.getList()
},
handleReset() {
this.listQuery = getListQueryDefault()
this.listQuery.StatisticsDate = new Date(
new Date().setMonth(new Date().getMonth() - 1)
).format('yyyy-MM')
this.getList()
},
handleLock() {
const param = {
ReviewerIdList: this.arrID,
Month: this.listQuery.StatisticsDate
}
this.lockLoading = true
lockMonthlyPayment(param)
.then((res) => {
this.lockLoading = false
this.getList()
this.$message.success('Locked successfully')
})
.catch(() => {
this.lockLoading = false
})
},
handleCalculate() {
const param = {
CalculateMonth: this.listQuery.StatisticsDate,
NeedCalculateReviewers: this.arrID
}
this.calcLoading = true
calculateMonthlyPayment(param)
.then((res) => {
this.calcLoading = false
this.getList()
this.$message.success('Calculate successfully')
})
.catch(() => {
this.calcLoading = false
})
},
handleAdjustment() {
this.$router.push({
name: 'Adjustment',
query: {
exchangeRate: this.exchangeRate,
date: this.listQuery.StatisticsDate
}
})
},
handleSetting() {
this.$router.push({ name: 'PaymentSettings' })
},
handleDetail(row) {
this.$router.push({ name: 'PaymentDetail', query: row })
},
handleSettingDoctor(row) {
store.dispatch('financials/getRank')
this.form = (({
FirstName,
LastName,
ChineseName,
Code,
DoctorId,
DoctorNameInBank,
IDCard,
BankCardNumber,
BankName,
RankId,
Additional
}) => ({
FirstName,
LastName,
ChineseName,
Code,
DoctorId,
DoctorNameInBank,
IDCard,
BankCardNumber,
BankName,
RankId,
Additional
}))(row)
this.form.Name = `${row.LastName} / ${row.FirstName}`
this.form.DoctorNameInBank = this.form.DoctorNameInBank
? this.form.DoctorNameInBank
: this.form.ChineseName
this.dialogVisible = true
},
handleSave() {
this.btnDisabled = true
const param = (({
DoctorId,
DoctorNameInBank,
IDCard,
BankCardNumber,
BankName,
RankId,
Additional
}) => ({
DoctorId,
DoctorNameInBank,
IDCard,
BankCardNumber,
BankName,
RankId,
Additional
}))(this.form)
addOrUpdateReviewerPayInfo(param)
.then((res) => {
this.btnDisabled = false
this.dialogVisible = false
this.getList()
this.$message.success('Updated successfully')
})
.catch(() => {
this.btnDisabled = false
})
},
handleSortChange(column) {
if (column.order === 'ascending') {
this.listQuery.Asc = true
} else {
this.listQuery.Asc = false
}
this.listQuery.SortField = column.prop
this.listQuery.PageIndex = 1
this.getList()
},
handleSelectChange(val) {
const arr = []
for (let index = 0; index < val.length; index++) {
arr.push(val[index].DoctorId)
}
this.arrID = arr
},
getSummaries(param) {
const { columns, data } = param
const sums = []
// const scope = this
columns.forEach((column, index) => {
if (index === 2) {
sums[index] = 'Total (Current Page)'
return
}
if (column.property === 'TotalPaymentUSD') {
const values = data.map((item) => Number(item[column.property]))
if (!values.every((value) => isNaN(value))) {
sums[index] = values
.reduce((prev, curr) => {
const value = Number(curr)
if (!isNaN(value)) {
return floatObj.add(prev, curr)
} else {
return prev
}
}, 0)
}
}
if (column.property === 'TotalPaymentCNY') {
const values = data.map((item) => Number(item[column.property]))
if (!values.every((value) => isNaN(value))) {
sums[index] = values
.reduce((prev, curr) => {
const value = Number(curr)
if (!isNaN(value)) {
return floatObj.add(prev, curr)
} else {
return prev
}
}, 0)
}
}
})
return sums
},
addNum(n1, n2) {
var s1, s2, m
try {
s1 = n1.toString().split('.')[1].length
} catch (e) {
s1 = 0
}
try {
s2 = n2.toString().split('.')[1].length
} catch (e) {
s2 = 0
}
m = Math.pow(10, Math.max(s1, s2))
console.log(n1 + '===' + n2 + '===' + m + '===' + (n1 * m + n2 * m) / m)
return (n1 * m + n2 * m) / m
},
handleSelectTable(row) {
return !!(row.IDCard && row.BankCardNumber && row.BankName)
},
onSelected(e) {
const obj = this.rankOption.find((item) => {
return item.Id === e
})
this.form.Rank = obj.RankName
},
cellStyle({ row, column, rowIndex, columnIndex }) {
if (
(row.TotalPaymentCNY === 0 && columnIndex === 12) ||
(columnIndex === 10 &&
(!row.IDCard || !row.BankCardNumber || !row.RankName))
) {
return 'color:red'
}
},
paymentCNFormatter(row, column) {
return row.ExchangeRate > 0
? num2Money(row.PaymentCNY + row.AdjustPaymentCNY, 2, 0)
: 'Setting Needed'
},
handleExportDetail() {
var that = this
that.excelData = []
var queryArray = []
this.list.forEach((item) => {
if (this.arrID.indexOf(item.DoctorId) > -1) {
queryArray.push({
PaymentId: item.Id,
ReviewerId: item.DoctorId,
YearMonth: item.YearMonth
})
}
})
that.exportDetailLoading = true
getReviewersPaymentDetailList(queryArray)
.then((res) => {
that.excelDataCount = res.Result.length
res.Result.forEach((element) => {
that.exportDetailExcel(element.DoctorInfo, element.DetailList)
})
})
.catch(() => {
that.exportDetailLoading = false
})
},
handleExportPayroll() {
var that = this
that.excelDataPayroll = []
var doctorIds = []
this.list.forEach((item) => {
if (this.arrID.indexOf(item.DoctorId) > -1) doctorIds.push(item.Id)
})
that.exportPayrollLoading = true
getMonthlyPayroll(doctorIds)
.then((res) => {
that.ExportExcelPayroll(res.Result)
})
.catch(() => {
that.exportPayrollLoading = false
})
},
ExportExcelPayroll(payrollDataList) {
var workbook = new Excel.Workbook()
var sheet = workbook.addWorksheet(this.listQuery.StatisticsDate)
sheet.properties.defaultRowHeight = 22
sheet.columns = [
{ key: 'ChineseName', width: 15 },
{ key: 'ResidentId', width: 30 },
{ key: 'Phone', width: 15 },
{ key: 'AccountNumber', width: 20 },
{ key: 'Bank', width: 30 },
{ key: 'PaymentCNY', width: 20 },
{ key: 'TaxCNY', width: 20 },
{ key: 'ActuallyPaidCNY', width: 20 }
]
var that = this
// 处理标题
sheet.mergeCells('A1', 'H2')
sheet.getCell('A1').value =
that.listQuery.StatisticsDate + ' Payroll Summary'
sheet.getCell('A1').alignment = {
vertical: 'middle',
horizontal: 'center'
}
sheet.getCell('A1').font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.mergeCells('A3', 'H3')
sheet.getCell('A3').value = 'Month' + that.listQuery.StatisticsDate
sheet.getCell('A3').alignment = {
vertical: 'middle',
horizontal: 'right'
}
sheet.getRow(4).values = [
'Name CN',
'Resident ID',
'Phone Number',
'Account Number',
'Bank',
'劳务费总计',
'应付税额',
'实付劳务费'
]
sheet.getRow(4).font = {
name: 'SimSun',
family: 4,
size: 11,
bold: true
}
sheet.getRow(4).alignment = { vertical: 'middle', horizontal: 'left' }
sheet.addRows(payrollDataList)
sheet.getColumn(6).numFmt = '#,##0.00'
sheet.getColumn(7).numFmt = '#,##0.00'
sheet.getColumn(8).numFmt = '#,##0.00'
sheet.eachRow((row, number) => {
if (number > 3) {
row.eachCell((cell, rowNumber) => {
cell.alignment = { vertical: 'center', horizontal: 'left' }
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
})
}
})
workbook.xlsx
.writeBuffer({
base64: true
})
.then(function(xls64) {
var data = new Blob([xls64], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
that.excelDataPayrollCount = payrollDataList.length + 1
that.excelDataPayroll.push({
data: data,
fileName:
'Payroll Summary_' + that.listQuery.StatisticsDate + '.xlsx'
})
payrollDataList.forEach((element) => {
that.ExportExcelPayrollDeatil(element)
})
})
},
ExportExcelPayrollDeatil(payrollItem) {
var that = this
var workbook = new Excel.Workbook()
var sheet = workbook.addWorksheet(
payrollItem.ChineseName + ' ' + this.listQuery.StatisticsDate
)
sheet.properties.defaultRowHeight = 25
sheet.properties.defaultColWidth = 30
// 处理标题
sheet.mergeCells('A1', 'E1')
sheet.getCell('A1').value = '上海致准信息科技有限公司'
sheet.getCell('A1').alignment = {
vertical: 'middle',
horizontal: 'center'
}
sheet.getCell('A1').font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.mergeCells('A2', 'E2')
sheet.getCell('A2').value = '劳务支付单'
sheet.getCell('A2').alignment = {
vertical: 'middle',
horizontal: 'center'
}
sheet.getCell('A2').font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.getRow(3).values = ['姓名', '身份证号', '', '工作月份', '发放月份']
sheet.mergeCells('B3', 'C3')
var myDate = new Date()
var tYear = myDate.getFullYear()
var tMonth = myDate.getMonth() + 1
if (tMonth < 10) tMonth = '0' + tMonth
sheet.getRow(4).values = [
payrollItem.ChineseName,
payrollItem.ResidentId,
'',
payrollItem.YearMonth,
tYear + '-' + tMonth
]
sheet.mergeCells('B4', 'C4')
sheet.getRow(5).values = [
'应付金额',
'代扣税金',
'实付金额',
'银行转账',
''
]
sheet.getRow(6).values = [
payrollItem.PaymentCNY,
payrollItem.TaxCNY,
payrollItem.ActuallyPaidCNY,
payrollItem.ActuallyPaidCNY,
''
]
sheet.mergeCells('D5', 'E5')
sheet.mergeCells('D6', 'E6')
sheet.getRow(7).values = ['审核', '', '经办', '', '']
sheet.mergeCells('A7', 'B7')
sheet.mergeCells('C7', 'E7')
sheet.eachRow((row, number) => {
if (number > 2) {
row.eachCell((cell, rowNumber) => {
if (number < 7) {
cell.alignment = { vertical: 'center', horizontal: 'center' }
}
cell.numFmt = '#,##0.00'
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
})
}
})
workbook.xlsx
.writeBuffer({
base64: true
})
.then(function(xls64) {
var data = new Blob([xls64], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
that.excelDataPayroll.push({
data: data,
fileName:
payrollItem.ChineseName + '_paystub_' + payrollItem.YearMonth + '.xlsx'
})
if (that.excelDataPayrollCount === that.excelDataPayroll.length) {
var zip = new Zip()
that.excelDataPayroll.forEach((element) => {
zip.file(element.fileName, element.data)
})
zip.generateAsync({ type: 'blob' }).then(function(content) {
saveAs(
content,
'Monthly Payroll ' + payrollItem.YearMonth + '.zip'
)
})
}
that.exportPayrollLoading = false
})
},
exportDetailExcel(basicInfo, list) {
var workbook = new Excel.Workbook()
var sheet = workbook.addWorksheet(
basicInfo.ChineseName + ' ' + basicInfo.YearMonth
)
sheet.properties.defaultRowHeight = 22
sheet.columns = [
{ header: 'Project ID', key: 'TrialCode', width: 15 },
{ header: 'Type', key: 'PaymentType', width: 30 },
{ header: 'Count', key: 'Count', width: 15 },
{ header: 'Base Price', key: 'BasePrice', width: 15 },
{ header: 'Personal Additional', key: 'PersonalAdditional', width: 22 },
{ header: 'Trial Additional', key: 'TrialAdditional', width: 22 },
{ header: 'Total Price', key: 'TotalUnitPrice', width: 22 },
{ header: 'Total Fee', key: 'PaymentUSD', width: 22 },
{ header: 'Subtotal(¥)', key: 'PaymentCNY', width: 22 }
]
var that = this
var tempTotalFee = 0
var tempTotalFeeInCN = 0
list.forEach((element) => {
tempTotalFee += parseFloat(element.PaymentUSD)
tempTotalFeeInCN += parseFloat(element.PaymentCNY)
})
var rowsCount = Number(list.length + 1)
// 处理标题
var titleRows = 4
sheet.mergeCells('A1', 'I2')
sheet.getCell('A1').value = 'Monthly Payment' // that.basicInfo.DoctorChineseName + ' ' + that.date + ' 费用明细'
sheet.getCell('A1').alignment = {
vertical: 'middle',
horizontal: 'center'
}
sheet.getCell('A1').font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.mergeCells('A3', 'D3')
// that.basicInfo.FirstName + ' ' + that.basicInfo.LastName + ' Name CN:'+
sheet.getCell('A3').value =
'Name' + basicInfo.ChineseName + ' ID:' + basicInfo.Code
sheet.mergeCells('E3', 'I3')
sheet.getCell('E3').value =
' Rank' +
basicInfo.PayTitle +
' Month' +
basicInfo.YearMonth +
' Exchange Rate: ' +
Number(list[0].ExchangeRate).toFixed(2)
sheet.getCell('A3').alignment = {
vertical: 'middle',
horizontal: 'left'
}
sheet.getCell('E3').alignment = {
vertical: 'middle',
horizontal: 'right'
}
// heet.mergeCells('A4', 'H4')
sheet.getCell('A4').value = 'Project ID'
sheet.getCell('B4').value = 'Read Type'
sheet.getCell('C4').value = 'Volume'
sheet.getCell('D4').value = 'Base Rate($)'
sheet.getCell('E4').value = 'Personal Adjustment($)'
sheet.getCell('F4').value = 'Project Adjustment($)'
sheet.getCell('G4').value = 'Adjusted Rate($)'
sheet.getCell('H4').value = 'Subtotal($)'
sheet.getCell('I4').value = 'Subtotal(¥)'
sheet.getRow(4).font = {
name: 'SimSun',
family: 4,
size: 11,
bold: true
}
sheet.addRows(list)
// 合并项目编号单元格
var projectCount = Math.floor(Number(list.length / 9)) // 项目个数
for (let i = 0; i < projectCount; i++) {
var tempR1 = 'A' + (10 * i + titleRows + 1)
var tempR2 = 'A' + (10 * (i + 1) + titleRows)
if (10 * (i + 1) < rowsCount) {
sheet.mergeCells(tempR1, tempR2)
sheet.getCell(tempR1).alignment = {
vertical: 'middle',
horizontal: 'center'
}
}
}
// 合并奖励单元格
var awardCount = list.filter((t) => t.TrialCode === 'Volume Reward')
.length
var adjustMentCount = list.filter((t) => t.TrialCode === 'Adjustment')
.length
if (awardCount > 0) {
var R1 = 'A' + (projectCount * 10 + titleRows + 1)
var R2 = 'A' + (projectCount * 10 + titleRows + awardCount)
sheet.mergeCells(R1, R2)
sheet.getCell(R1).alignment = {
vertical: 'middle',
horizontal: 'center'
}
}
if (adjustMentCount > 0) {
// 处理调整行列合并
var R3 = 'A' + (projectCount * 10 + titleRows + awardCount + 1)
var R4 = 'A' + (rowsCount + titleRows - 1)
sheet.mergeCells(R3, R4)
sheet.getCell(R3).alignment = {
vertical: 'middle',
horizontal: 'center'
}
// 行合并
var i = 0
for (i = 0; i < adjustMentCount; i++) {
var adjustMentCell1 =
'B' + (projectCount * 10 + titleRows + awardCount + 1 + i)
var adjustMentCell2 =
'C' + (projectCount * 10 + titleRows + awardCount + 1 + i)
var adjustMentCell3 =
'G' + (projectCount * 10 + titleRows + awardCount + 1 + i)
sheet.mergeCells(adjustMentCell2, adjustMentCell3)
var index = projectCount * 10 + awardCount + i
sheet.getCell(adjustMentCell1).value =
list[index].AdjustmentView.AdjustType
sheet.getCell(adjustMentCell2).value =
list[index].AdjustmentView.Note
}
}
var tempCell = 'A' + (rowsCount + 1 + titleRows - 1)
var tempCell1 = 'B' + (rowsCount + 1 + titleRows - 1)
var tempCell2 = 'G' + (rowsCount + 1 + titleRows - 1)
var tempCell3 = 'H' + (rowsCount + 1 + titleRows - 1)
var tempCell4 = 'I' + (rowsCount + 1 + titleRows - 1)
sheet.mergeCells(tempCell1, tempCell2)
sheet.getCell(tempCell).value = 'Total' // that.date + ' 费用总计: '
sheet.getCell(tempCell3).value = tempTotalFee
sheet.getCell(tempCell4).value = tempTotalFeeInCN
sheet.getCell(tempCell3).font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.getRow(rowsCount + titleRows).font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.getColumn(7).numFmt = '#,##0.00'
sheet.getColumn(8).numFmt = '#,##0.00'
sheet.getColumn(9).numFmt = '#,##0.00'
sheet.eachRow((row, number) => {
if (number > 3) {
row.eachCell((cell, rowNumber) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
})
}
})
workbook.xlsx
.writeBuffer({
base64: true
})
.then(function(xls64) {
var data = new Blob([xls64], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
that.excelData.push({
data: data,
fileName:
basicInfo.ChineseName + '_detail_ ' + basicInfo.YearMonth + '.xlsx'
})
if (that.excelDataCount === that.excelData.length) {
var zip = new Zip()
that.excelData.forEach((element) => {
zip.file(element.fileName, element.data)
})
zip.generateAsync({ type: 'blob' }).then(function(content) {
saveAs(
content,
'Monthly Payment Detail_' + basicInfo.YearMonth + '.zip'
)
})
that.exportDetailLoading = false
}
})
},
handleExportExcel() {
var workbook = new Excel.Workbook()
var sheet = workbook.addWorksheet(this.listQuery.StatisticsDate)
sheet.properties.defaultRowHeight = 22
sheet.columns = [
{ key: 'Index', width: 5 },
{ key: 'LastName', width: 15 },
{ key: 'FirstName', width: 15 },
{ key: 'DoctorNameInBank', width: 15 },
{ key: 'Code', width: 15 },
{ key: 'IDCard', width: 20 },
{ key: 'Phone', width: 15 },
{ key: 'BankCardNumber', width: 25 },
{ key: 'BankName', width: 30 },
{ key: 'PaymentUSD', width: 20 },
{ key: 'ExchangeRate', width: 20 },
{ key: 'PaymentCNY', width: 20 },
{ key: 'IsLock', width: 20 }
]
var that = this
var tempTotalFee = 0
var tempTotalFeeCNY = 0
let index = 1
var exportExcelData = this.list.filter(
(item) => this.arrID.indexOf(item.DoctorId) > -1
)
exportExcelData.forEach((element) => {
element.Index = index
element.PaymentUSD = element.PaymentUSD + element.AdjustPaymentUSD
element.PaymentCNY = element.PaymentCNY + element.AdjustPaymentCNY
tempTotalFee += element.PaymentUSD
tempTotalFeeCNY += element.PaymentCNY
element.IsLock = element.IsLock ? 'Locked' : 'Pending'
index++
})
// 处理标题
sheet.mergeCells('A1', 'M2')
sheet.getCell('A1').value =
that.listQuery.StatisticsDate + ' Payment Summary'
sheet.getCell('A1').alignment = {
vertical: 'middle',
horizontal: 'center'
}
sheet.getCell('A1').font = {
name: 'SimSun',
family: 4,
size: 13,
bold: true
}
sheet.mergeCells('A3', 'M3')
sheet.getCell('A3').value = 'Month' + that.listQuery.StatisticsDate
sheet.getCell('A3').alignment = {
vertical: 'middle',
horizontal: 'right'
}
sheet.getRow(4).values = [
'',
'Surname',
'Given Name',
'Name CN',
'ID',
'Resident ID',
'Phone Number',
'Account Number',
'Bank',
'Payment($)',
'Exchange Rate',
'Payment(¥)',
'Status'
]
sheet.getRow(4).font = {
name: 'SimSun',
family: 4,
size: 11,
bold: true
}
sheet.getRow(4).alignment = { vertical: 'middle', horizontal: 'left' }
sheet.addRows(exportExcelData)
sheet.addRow([
'',
'Total',
'',
'',
'',
'',
'',
'',
'',
tempTotalFee,
'',
tempTotalFeeCNY,
''
])
sheet.getRow(exportExcelData.length + 5).font = {
name: 'SimSun',
family: 4,
size: 11,
bold: true
}
sheet.getColumn(10).numFmt = '#,##0.00'
sheet.getColumn(11).numFmt = '#,##0.00'
sheet.getColumn(12).numFmt = '#,##0.00'
sheet.eachRow((row, number) => {
if (number > 3) {
row.eachCell((cell, rowNumber) => {
cell.alignment = { vertical: 'center', horizontal: 'left' }
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
})
}
})
workbook.xlsx
.writeBuffer({
base64: true
})
.then(function(xls64) {
var data = new Blob([xls64], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
if ('msSaveOrOpenBlob' in navigator) {
// ie使用的下载方式
window.navigator.msSaveOrOpenBlob(
data,
'Payment Summary_' + that.listQuery.StatisticsDate + '.xlsx'
)
} else {
var a = document.createElement('a')
var url = URL.createObjectURL(data)
a.href = url
a.download =
'Payment Summary_' + that.listQuery.StatisticsDate + '.xlsx'
document.body.appendChild(a)
a.click()
setTimeout(function() {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
}, 0)
}
})
},
...mapMutations({
setQueryParam: 'financials/SET_PAYMENTQUERYPARAM'
})
}
}
</script>
<style lang="scss" scoped>
.monthly-payment {
height: 100%;
.filter-container {
display: flex;
align-items: center;
}
.mr {
margin-right: 5px;
width: 150px;
}
.el-table {
overflow: visible !important;
}
.el-table .cell {
white-space: nowrap;
}
.list-container {
margin-top: 10px;
height: calc(100% - 100px);
}
}
</style>