ttk-app-core
Version:
enterprise develop framework
690 lines (641 loc) • 27 kB
JavaScript
import React from 'react'
import { action as MetaAction, AppLoader } from 'edf-meta-engine'
import config from './config'
import { FormDecorator, Select, DatePicker, Cascader, Form, Button } from 'edf-component'
import {fetch, date, number, environment} from 'edf-utils'
import { Map, fromJS, toJS } from 'immutable'
import moment from 'moment'
import utils from 'edf-utils'
const browser = environment.getBrowserVersion()
const Option = Select.Option
const FormItem = Form.Item
class action {
constructor(option) {
this.metaAction = option.metaAction
this.config = config.current
this.webapi = this.config.webapi
this.voucherAction = option.voucherAction
}
onInit = ({ component, injections }) => {
this.voucherAction.onInit({ component, injections })
this.component = component
this.injections = injections
let addEventListener = this.component.props.addEventListener
if (addEventListener) {
addEventListener('enlargeClick', () => this.onResize({}))
addEventListener('onTabFocus', :: this.onTabFocus)
}
injections.reduce('init')
this.load()
}
onTabFocus = async (params) => {
//this.load(params.toJS())
let {reconciliatioIds, bankAccountId} = params.toJS()
let response = await this.webapi.getList({reconciliatioIds, bankAccountId})
let{ bankReconciliatios } = response
let list = [], oldBankReconciliatios = this.metaAction.gf('data.bankReconciliatios').toJS()
oldBankReconciliatios.map(item => {
let bankReconcArr = bankReconciliatios.filter(option => item.id == option.id)
if(bankReconcArr.length) list.push(item)
})
bankReconciliatios.map(item=>{
let bankReconcArr = oldBankReconciliatios.filter(option => item.id == option.id)
if(!bankReconcArr.length) list = list.concat(item, item)
})
this.metaAction.sf('data.bankReconciliatios', fromJS(list))
this.initOption()
}
initOption = async() => {
const list = [
this.webapi.customer({ entity: { isEnable: true } }),
this.webapi.supplier({ entity: { isEnable: true } }),
this.webapi.person({ entity: { isEnable: true } }),
this.voucherAction.getDepartment({ entity: { isEnable: true } }, 'data.other.department'),
this.voucherAction.getProject({ entity: { isEnable: true } }, 'data.other.project'),
]
const [ customerList, supplierList, personList ] = await Promise.all(list)
const { department, project } = this.metaAction.gf('data.other').toJS()
//const receiveBusinessType = this.metaAction.gf('data.other.receiveBusinessType').toJS()
//const payBusinessType = this.metaAction.gf('data.other.payBusinessType').toJS()
let bankReconciliatios = this.metaAction.gf('data.bankReconciliatios').toJS()
bankReconciliatios.forEach((item) => {
let {
departmentId, departmentName, projectId, projectName,
} = item
item = this.checkDetailsOptionIsHave({
item,
arr: department,
id: departmentId,
name: departmentName,
key: 'department'
})
item = this.checkDetailsOptionIsHave({
item,
arr: project,
id: projectId,
name: projectName,
key: 'project'
})
if(item.supplierCustomerId){
let arr=[], isHasValue
if(item.required == "person"){
arr = personList.list
}else if(item.required == "customer"){
arr = customerList.list
}else if(item.required == "supplier"){
arr = supplierList.list
}
arr.map(m => { if(m.id == item.supplierCustomerId){ isHasValue = true } })
if(!isHasValue) item.supplierCustomerId = ''
}
})
this.metaAction.sf('data.bankReconciliatios', fromJS(bankReconciliatios))
}
checkDetailsOptionIsHave = ({item, arr, id, name, key}) => {
if(!id) return item
let isHasValue
arr.map(m => { if(m.id == item[key+'Id']) isHasValue = true })
if(!isHasValue){
item[key+'Id'] = ''
item[key+'Name'] = ''
}
return item
}
load = async (props) => {
this.metaAction.sf('data.loading', true)
let {reconciliatioIds, bankAccountId} = props || this.component.props
let response = await this.webapi.getList({reconciliatioIds, bankAccountId})
let{bankAccount, bankReconciliatios, payBusinessType, receiveBusinessType, EnableDate, SystemDate} = response
let list = [],
customerList = await this.webapi.customer({entity:{isEnable:true}}),
supplierList = await this.webapi.supplier({entity:{isEnable:true}})
bankReconciliatios = bankReconciliatios.map((item, index) => {
// item.index = index+1
item.accountDate = date.transformMomentDate(item.businessDate)
if(item.defaultBusinessType) {
let pid = item.defaultBusinessType.pid, id = item.defaultBusinessType.id
item.businessTypeId = [pid, id]
item = this.getDefaultSupplierCustomer(item, customerList, supplierList)
}
return list = list.concat(item, item)
})
payBusinessType = this.formatData(payBusinessType)
receiveBusinessType = this.formatData(receiveBusinessType)
let contextDate = SystemDate,
currentOrg = this.metaAction.context.get("currentOrg")
if(currentOrg.periodDate){
contextDate = moment(currentOrg.periodDate).endOf('month')
}
this.metaAction.sfs({
'data.bankReconciliatios': fromJS(list),
'data.payBusinessType': fromJS(payBusinessType),
'data.receiveBusinessType': fromJS(receiveBusinessType),
'data.name': bankAccount.name,
'data.bankAccountId': bankAccount.id,
'data.disabledDate': date.transformMomentDate(EnableDate),
'data.systemDate': date.transformMomentDate(SystemDate),
'data.businessDate': date.transformMomentDate(contextDate),
'data.loading': false
})
setTimeout(() => {
this.onResize()
}, 20)
// console.log(list)
// this.injections.reduce('load', )
}
getDefaultSupplierCustomer = (item, customerList, supplierList) => {
let supplierCustomer
if(item.defaultBusinessType && item.defaultBusinessType.calcObject){
item.required = item.defaultBusinessType.calcObject
if(item.required == 'customer' && item.defaultCustomer){
supplierCustomer = customerList
item['supplierCustomerId'] = item.defaultCustomer.id
}else if(item.required == 'supplier' && item.defaultSupplier){
supplierCustomer = supplierList
item['supplierCustomerId'] = item.defaultSupplier.id
}
}
if(supplierCustomer && supplierCustomer.list){
item.supplierCustomerList = supplierCustomer.list
}
return item
}
//日期组件不可用日期
getDisabledDate = (current) => {
var disabledDate = this.metaAction.gf('data.disabledDate')
return current && current.valueOf() < disabledDate
}
returnSep = (record, index) => {
let obj = {
children: record.seq,
props: {},
};
if (index%2 == 0) {
obj.props.rowSpan = 2;
}else {
obj.props.rowSpan = 0;
}
return obj
}
//记账日期
accountDate = (record, index) => {
let _this = this
return <DatePicker
placeholder='记账日期'
disabledDate={this.getDisabledDate}
value={record.accountDate}
onChange={function(e){
_this.injections.reduce('accountDateChange', {e, record, index})
}}/>
}
changeDate = (date) => {
let list = this.metaAction.gf('data.bankReconciliatios').toJS()
list.map(item => item.accountDate = date)
this.metaAction.sf('data.businessDate', date)
this.injections.reduce('load', list)
setTimeout(() => {
this.onResize()
}, 20)
}
//收支类型
businessType = (record, index) => {
let options = []
if(record.inAmount) {
options = this.metaAction.gf('data.receiveBusinessType').toJS()
}else {
options = this.metaAction.gf('data.payBusinessType').toJS()
}
return <FormItem className='business-type-label' label={this.getBusinessType(record, options, index)} required={true}></FormItem>
}
getPopupContainer = () => {
return document.querySelector('.ant-table-body table')
}
getBusinessType = (record, options, index) => {
return <Cascader placeholder='收支类型'
value={record.businessTypeId}
options={options}
getPopupContainer={ this.getPopupContainer}
popupClassName= "ttk-scm-app-batch-orders-Cascader"
allowClear={false}
onChange={(value) => this.onFieldChange(index, value, 'businessType')}>
</Cascader>
}
//供应商、客户、部门、项目、个人
renderCell = (type, record, index) => {
let placeholder = ''
switch (type) {
case 'department':
placeholder = '部门'
break;
case 'project':
placeholder = '项目'
break;
}
return <div style={{width: '95%'}}>
<Select style={{width: '100%'}} placeholder={placeholder}
value={record[type+'Id']}
onFocus={() => this.getList(type)}
onChange={(value) => this.onFieldChange(index, value, type)}
optionFilterProp="children"
filterOption={this.filterOptionSummary}
dropdownFooter={
<Button type='primary'
style={{ width: '100%', borderRadius: '0' }}
onClick={this.addArchives(index, type)}>新增
</Button>
}
>
{this.selectOption(type)}
</Select>
</div>
}
renderUnit = (record, index) => {
if(!record.required) return <div style={{width: '95%'}}><Select style={{width: '100%'}} placeholder='往来单位及个人' value='' disabled={true}/></div>
return <div style={{width: '95%'}}>
<Select style={{width: '100%'}} placeholder='往来单位及个人'
value={record['supplierCustomerId']}
onFocus={() => this.getList(record.required, index)}
// disabled={!record.required}
onChange={(value) => this.onFieldChange(index, value, record.required, true)}
optionFilterProp="children"
filterOption={this.filterOptionSummary}
dropdownFooter={
<Button type='primary'
style={{ width: '100%', borderRadius: '0' }}
onClick={this.addArchives(index, record.required, true)}>新增
</Button>
}
>
{record.required ? this.selectOption(record.required, true, index) : null}
</Select>
</div>
}
addArchives = (rowIndex, type, isSupplierCustomer) => async () => {
let title = '客户', path = 'app-card-customer', width = 700
if(type == 'supplier'){
path = 'app-card-vendor'
title = '供应商'
}else if(type == 'department'){
path = 'app-card-department'
title = '部门'
width = 400
}else if(type == 'project'){
path = 'app-card-project'
title = '项目'
width = 400
}else if(type == 'person'){
path = 'app-card-person'
title = '人员'
width = 720
}
const ret = await this.metaAction.modal('show', {
title: title,
width: width,
children: this.metaAction.loadApp(path, {
store: this.component.props.store
}),
})
if(type != 'department'){
if (ret && ret.isEnable) {
this.injections.reduce("addArchives", type, rowIndex, ret, isSupplierCustomer)
}
}else{
if (ret) {
this.injections.reduce("addArchives", type, rowIndex, ret, isSupplierCustomer)
}
}
}
filterOptionSummary = (input, option) => {
if (option && option.props && option.props.children) {
return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
return true
}
returnTitle = (title) => {
return <span className="td_ellipsis" title={title}>{title}</span>
}
//修改选择数据
onFieldChange = async (index, value, type, isSupplierCustomer) => {
let list = this.metaAction.gf('data.bankReconciliatios').toJS()
if(isSupplierCustomer){
list[index]['supplierCustomerId'] = value
}else{
list[index][type+'Id'] = value
}
if(type == 'businessType') {
let record = list[index]
let required = ''
let options = []
list[index]['supplierCustomerId'] = ''
if(record.inAmount) {
options = this.metaAction.gf('data.receiveBusinessType').toJS()
}else {
options = this.metaAction.gf('data.payBusinessType').toJS()
}
if(!options || !record.businessTypeId) return
let option = options.filter(item => item.id == record.businessTypeId[0])[0].children.filter(o => o.id == record.businessTypeId[1]),
supplierCustomer = []
record.required = option[0].calcObject
if(record.required=='customer' && record.defaultCustomer){
supplierCustomer = await this.webapi.customer({entity:{isEnable:true}})
list[index]['supplierCustomerId'] = record.defaultCustomer.id
}else if(record.required=='supplier' && record.defaultSupplier){
supplierCustomer = await this.webapi.supplier({entity:{isEnable:true}})
list[index]['supplierCustomerId'] = record.defaultSupplier.id
}else if(record.required=='person'){
supplierCustomer = await this.webapi.person({entity:{isEnable:true}})
}
if(supplierCustomer && supplierCustomer.list){
list[index].supplierCustomerList = supplierCustomer.list
}else{
this.metaAction.sf(`data.other.supplierCustomerList`, fromJS([]))
}
}
// console.log(list[index])
this.metaAction.sf(`data.bankReconciliatios`, fromJS(list))
setTimeout(() => {
this.onResize()
}, 20)
}
//获取相应档案列表
getList = async(type, index) => {
switch (type) {
case 'customer':
await this.voucherAction.getCustomer({entity:{isEnable:true}}, `data.bankReconciliatios.${index}.supplierCustomerList`)
break;
case 'supplier':
await this.voucherAction.getSupplier({entity:{isEnable:true}}, `data.bankReconciliatios.${index}.supplierCustomerList`)
break;
case 'department':
await this.voucherAction.getDepartment({entity:{isEnable:true}}, `data.other.department`)
break;
case 'project':
await this.voucherAction.getProject({entity:{isEnable:true}}, `data.other.project`)
break;
case 'person':
await this.voucherAction.getPerson({entity:{isEnable:true}}, `data.bankReconciliatios.${index}.supplierCustomerList`)
break;
}
}
selectOption = (path, isSupplierCustomer, index) => {
let list = this.metaAction.gf(`data.bankReconciliatios`).toJS()
if(isSupplierCustomer){
list = list[index].supplierCustomerList
}else{
list = this.metaAction.gf(`data.other.${path}`).toJS()
}
if(!list) return
return list.map(item => {
return <Option value={item.id}>{item.name}</Option>
})
}
//格式化收付款类型数据
formatData = (list) => {
list.map(item => {
item.value = item.id
item.label = item.name
if(item.children) {
this.formatData(item.children)
}
})
return list
}
save = async() => {
let list = this.metaAction.gf('data.bankReconciliatios').toJS()
let businessType = []
let correspondentUnits = [] //往来单位及个人
let reconciliatioBatchMaintenanceDtos = list.filter((item, index) => {
if(index%2 != 0) {
item[`${item.required}Id`] = item.supplierCustomerId
// 收支类型未填处理及往来单位及个人未填
if(!item.businessTypeId) {
businessType.push(item.seq)
return false
}
if(item.required && !item[`${item.required}Id`]) {
correspondentUnits.push(item.seq)
return false
}
item.accountDate = item.accountDate.format('YYYY-MM-DD')
item.businessTypeId = item.businessTypeId.slice(-1)[0]
delete item.attachments
delete item.supplierCustomerId
delete item.bankId
delete item.ts
delete item.details
delete item.required
return true
}
return false
})
if(reconciliatioBatchMaintenanceDtos.length != list.length/2) {
if(businessType.length != 0) {
this.metaAction.toast('warning', `第${this.getNumberFormat(businessType)}条收支类型未填`)
}
if(correspondentUnits.length != 0) {
this.getNumberFormat(correspondentUnits)
this.metaAction.toast('warning', `第${this.getNumberFormat(correspondentUnits)}条往来单位及个人未填`)
}
return false
}
let bankAccountId = this.metaAction.gf('data.bankAccountId')
reconciliatioBatchMaintenanceDtos.map(item=>{
if(!item.personId) item.personId = ''
if(!item.customerId) item.customerId = ''
if(!item.supplierId) item.supplierId = ''
})
let response = await this.webapi.save({reconciliatioBatchMaintenanceDtos, bankAccountId})
if(response.fail && response.fail.length){
this.metaAction.toast('warning', this.getContent(response.fail))
}else{
this.metaAction.toast('success', '生成单据成功')
this.component.props.onlyCloseContent('ttk-scm-app-batch-orders')
this.component.props.setPortalContent('银行对账单', 'ttk-scm-add-bank-statement-list', { accessType: 1,initData: { type: 'orders' } })
}
}
getContent = (fail) => {
if(fail.length){
return <div style={{ textAlign: 'left' }}>
{
fail.map(item => {
return <p style={{ marginBottom: '0' }}>{item.message}</p>
})
}
</div>
}
}
getNumberFormat = (data) => {
const arr = data.map(item => parseInt(item))
let a = -1
let b = 0
const sumArr = []
if(arr.length == 1) return arr[0]
arr.forEach((item, index) => {
if( a == -1 ) {
a = index
b = 1
}else{
if( item == arr[index - 1] + 1 && index != arr.length -1 ) {
b++
}else {
if( index == arr.length - 1 ) {
b++
}
let lens = arr.slice(a, a + b)
if( lens.length > 1 ) {
sumArr.push(`${lens[0]}-${lens[lens.length -1]}`)
}else if( lens.length == 1 ) {
sumArr.push(`${lens[0]}`)
}
a = index
b = 1
}
}
})
return sumArr.join(',')
}
onResize = (e) => {
if( browser.edge ) {
const dom = document.querySelector('.ttk-scm-app-batch-orders-body')
if( dom ) {
dom.style.overflow = 'auto'
}
return
}
let keyRandomTab = Math.floor(Math.random() * 10000)
this.keyRandomTab = keyRandomTab
setTimeout(() => {
if (keyRandomTab == this.keyRandomTab) {
this.getTableScroll('ttk-scm-app-batch-orders-body', 'ant-table-thead', 2, 'ant-table-body', 'data.tableOption', e)
}
}, 200)
}
getTableScroll = (contaienr, head, num, target, path, e) => {
try {
const tableCon = document.getElementsByClassName(contaienr)[0]
if (!tableCon) {
if (e) {
return
}
setTimeout(() => {
this.getTableScroll(contaienr, head, num, target, path)
}, 500)
return
}
// const header = tableCon.getElementsByClassName(head)[0]
// const body = tableCon.getElementsByClassName(target)[0].getElementsByTagName('table')[0]
// const pre = this.metaAction.gf(path).toJS()
// const y = tableCon.offsetHeight - header.offsetHeight - num
// const bodyHeight = body.offsetHeight
// if (bodyHeight > y && y != pre.y) {
// this.metaAction.sf(path, fromJS({ ...pre, y }))
// } else if (bodyHeight < y && pre.y != null) {
// this.metaAction.sf(path, fromJS({ ...pre, y: null }))
// } else {
// return false
// }
let tbody = document.getElementsByClassName('ant-table-tbody')[0]
let tableOption = this.metaAction.gf('data.tableOption').toJS()
if (tableCon && tbody) {
const num = tableCon.offsetHeight - tbody.offsetHeight
if (num < 36) {
const height = tableCon.offsetHeight - 36
tableOption = {
...tableOption,
y: height
}
this.metaAction.sf(path, fromJS(tableOption))
} else {
delete tableOption.y
this.metaAction.sf(path, fromJS(tableOption))
}
}
} catch (err) {
console.log(err)
}
}
componentDidMount = () => {
if (window.addEventListener) {
window.addEventListener('resize', this.onResize, false)
} else if (window.attachEvent) {
window.attachEvent('onresize', this.onResize)
} else {
window.onresize = this.onResize
}
}
renderFixedNumber = (text) => {
if(!text) return ''
return <span className='td_ellipsis'>{number.format(text, 2)}</span>
}
renderColumns = () => {
return [{
title: '序号',
dataIndex: 'sep',
key: 'sep',
rowSpan: 2,
width: 43,
className: 'table-seq',
render: (text, record, index) => this.returnSep(record, index)
}, {
title: '交易日期',
dataIndex: 'businessDate',
key: 'businessDate',
width: "15%",
render: (text, record, index) => {
return index%2 == 0 ? record.businessDate : this.accountDate(record, index)
}
}, {
title: '摘要',
dataIndex: 'memo',
key: 'memo',
width: 218,
render: (text, record, index) => {
return index%2 == 0 ? this.returnTitle(record.memo) : this.businessType(record, index)
}
}, {
title: '对方户名',
dataIndex: 'reciprocalAccountName',
key: 'reciprocalAccountName',
width: 222,
render: (text, record, index)=>{
return index%2 == 0 ? this.returnTitle(record.reciprocalAccountName) : this.renderUnit(record, index)
}
}, {
title: '收入',
dataIndex: 'inAmount',
className: 'amount-right',
key: 'inAmount',
className: 'table-align-right',
width: "15%",
render: (text, record, index)=>{
return index%2 == 0 ? this.renderFixedNumber(record.inAmount) : this.renderCell('department',record, index)
}
}, {
title: '支出',
dataIndex: 'outAmount',
className: 'amount-right',
key: 'outAmount',
className: 'table-align-right',
width: "15%",
render: (text, record, index) => {
return index%2 == 0 ? this.renderFixedNumber(record.outAmount) : this.renderCell('project',record, index)
}
}, {
title: '回单号',
dataIndex: 'receiveCode',
key: 'receiveCode',
width: "20%",
render: (text, record, index)=>{
return index%2 == 0 ? record.receiveCode : ''
}
}]
}
}
export default function creator(option) {
const metaAction = new MetaAction(option),
voucherAction = FormDecorator.actionCreator({ ...option, metaAction }),
o = new action({ ...option, metaAction, voucherAction }),
ret = { ...metaAction, ...voucherAction, ...o }
metaAction.config({ metaHandlers: ret })
return ret
}