UNPKG

ttk-app-core

Version:
1,156 lines (992 loc) 90.7 kB
import React from 'react' import ReactDOM from 'react-dom' import config from './config' import moment from 'moment' import extend from './extend' import * as data from './data' import utils, { fetch } from 'edf-utils' import { action as MetaAction, AppLoader, } from 'edf-meta-engine' import { Popover, Button, Link } from 'antd' import { PrintOption, Modal } from 'edf-component' import { Map, fromJS, List, is } from 'immutable' import { consts } from 'edf-consts' class action { constructor(option) { this.metaAction = option.metaAction this.extendAction = option.extendAction this.config = config.current this.webapi = this.config.webapi } onInit = ({ component, injections }) => { this.extendAction.gridAction.onInit({ component, injections }) this.component = component this.injections = injections injections.reduce('init') let initData = this.component.props.initData let addEventListener = this.component.props.addEventListener if (addEventListener) { addEventListener('onTabFocus', :: this.onTabFocus) } this.setrowsCount() this.load(initData) } load = async (initData) => { const subjectList = await this.getSubjectList() const currencyList = await this.webapi.currency.queryList({entity: {isEnable:true}}) const enabledYearMonth = this.getEnabledYearMonth() if (!initData) { let initCertificateData = await this.webapi.certificate.init({ isReturnValue: true }) if (initCertificateData.result == false && initCertificateData.error && initCertificateData.error.code == '70002') { this.metaAction.toast('error', initCertificateData.error.message) this.injections.reduce('initNewCertificate', undefined, subjectList, enabledYearMonth, currencyList.list) } else { this.injections.reduce('initNewCertificate', initCertificateData, subjectList, enabledYearMonth, currencyList.list) this.extendAction.gridAction.cellAutoFocus() } } else if (initData.id) { const certificateData = await this.webapi.certificate.findById({ docId: initData.id }) this.injections.reduce('initLoadCertificate', fromJS(certificateData), enabledYearMonth, subjectList, currencyList.list) //凭证管理中插入凭证时 } else if (initData && initData.code) { if (initData.code == '9999') { this.metaAction.toast('error', '凭证号达到9999,不能再增加凭证!') return } this.checkEditStatusBeforeLoadNewVoucher(() => { initData.isInsert = true this.injections.reduce('clearAndNewCertificate', initData, subjectList, currencyList.list, enabledYearMonth) }) //凭证管理中新增凭证时 } else if (initData && initData.newCertificate) { this.checkEditStatusBeforeLoadNewVoucher(async () => { let initCertificateData = await this.webapi.certificate.init({ isReturnValue: true }) if (initCertificateData.result == false && initCertificateData.error && initCertificateData.error.code == '70002') { this.metaAction.toast('error', initCertificateData.error.message) this.injections.reduce('clearAndNewCertificate', { code: initCertificateData.docCode, voucherDate: initCertificateData.voucherDate }, subjectList, currencyList.list, enabledYearMonth) } else { this.injections.reduce('clearAndNewCertificate', { code: initCertificateData.docCode, voucherDate: initCertificateData.voucherDate }, subjectList, currencyList.list, enabledYearMonth) this.extendAction.gridAction.cellAutoFocus() } }) } //设置凭证当前单据状态,供单据页签关闭用 false:关闭不提醒 true 关闭提醒 //this.component.props.editing(this.component.props.appName, false); this.editCloseTips(false) } //当前app的 "tab被点击" (从其他app切换到当前app) onTabFocus = async (props) => { let initData = props ? props.initData : undefined const subjectList = await this.getSubjectList() const currencyList = await this.webapi.currency.queryList({entity: {isEnable:true}}) //查看凭证 if (initData && initData.id) { this.checkEditStatusBeforeLoadNewVoucher(async () => { let certificateData = await this.webapi.certificate.findById({ docId: initData.id }) this.injections.reduce('initLoadCertificate', fromJS(certificateData), undefined, subjectList, currencyList.list) }) } //凭证管理中插入凭证时 else if (initData && initData.code) { if (initData.code == '9999') { this.metaAction.toast('error', '凭证号达到9999,不能再增加凭证!') return } this.checkEditStatusBeforeLoadNewVoucher(() => { initData.isInsert = true this.injections.reduce('clearAndNewCertificate', initData, subjectList, currencyList.list) this.extendAction.gridAction.cellAutoFocus() }) //凭证管理中新增凭证时 } else if (initData && initData.newCertificate) { this.checkEditStatusBeforeLoadNewVoucher(async () => { let initCertificateData = await this.webapi.certificate.init({ isReturnValue: true }) if (initCertificateData.result == false && initCertificateData.error && initCertificateData.error.code == '70002') { this.metaAction.toast('error', initCertificateData.error.message) this.injections.reduce('clearAndNewCertificate', { code: initCertificateData.docCode, voucherDate: initCertificateData.voucherDate }, subjectList, currencyList.list) } else { this.injections.reduce('clearAndNewCertificate', { code: initCertificateData.docCode, voucherDate: initCertificateData.voucherDate }, subjectList, currencyList.list) this.extendAction.gridAction.cellAutoFocus() } }) } else { let details = this.metaAction.gf('data.form.details'), editStatus = this.metaAction.gf('data.other.editStatus') this.upgradeDetails(details, subjectList, fromJS(currencyList.list)) if (editStatus == data.VIEW_STATUS) { let id = this.metaAction.gf('data.form.id') const certificateData = await this.webapi.certificate.findById({ docId: id, isReturnValue: true }) if (certificateData.result == false && certificateData.error.code == data.NOT_FOUND_CERTIFICATE) { this.newCertificate(subjectList) } else { const enabledYearMonth = this.getEnabledYearMonth() this.injections.reduce('initLoadCertificate', fromJS(certificateData), enabledYearMonth, subjectList, currencyList.list) } } } } //关闭附件时机 windowClick = (e) => { if (!document.getElementsByClassName('fixedDataTableLayout_rowsContainer')) return this.injections.reduce('attachmentVisible', false) } componentDidMount = () => { const win = window if (win.addEventListener) { document.getElementById("app").addEventListener('click', this.windowClick, false) document.body.addEventListener('keydown', this.bodyKeydownEvent, false) } else if (win.attachEvent) { document.getElementById("app").attachEvent('onclick', this.windowClick) document.body.attachEvent('onkeydown', this.bodyKeydownEvent) } } bodyKeydownEvent = (e) => { const dom = document.getElementById('ttk-voucher-app-document') const modalBody = document.getElementsByClassName('ant-modal-body') if (dom && modalBody && modalBody.length<1){ this.keyDownCickEvent({event:e}) } } onMouseDown = (e) => { const path = utils.path.findPathByEvent(e) if (path.indexOf('cell.cell.dropdownFooter.add') > -1) return true if (path.indexOf('.cell.cell,') != -1) { this.extendAction.gridAction.mousedown(e) } } getSubjectList = async () => { let subjectList = await this.webapi.accountingSubject.query({ isEndNode: true }), subjectListEnable = [] subjectList.glAccounts.map(item => { if (!!item.isEnable) { subjectListEnable.push(item) } }) subjectList.glAccountsAll = subjectList.glAccounts subjectList.glAccounts = subjectListEnable return subjectList } setrowsCount = () => { let charge = document.getElementsByClassName("edfx-app-portal-content-main"), data = this.metaAction.gf('data').toJS(), details = data.form.details, length = details.length, height, value = [] if(charge.length != 0){ height = charge[0].clientHeight - 311 length = Math.ceil(height/60) > 5 ? Math.ceil(height/60) : 5 const blankVoucherItem = { summary: '', accountingSubject: undefined, debitAmount: undefined, creditAmount: '' } value = Array(length - 5).fill(blankVoucherItem); } details = details.concat(value) this.injections.reduce('setrowsCount',details, details.length) } //监听键盘事件 keyDownCickEvent = (keydown) => { if (keydown && keydown.event) { let e = keydown.event if (e.ctrlKey && e.altKey && (e.key == 'n' || e.keyCode == 78)) { if (this.isDisplayButton('add')) { //新增 this.newCertificate() } if (e.preventDefault) { e.preventDefault() } if (e.stopPropagation) { e.stopPropagation() } } else if (e.ctrlKey && !e.altKey && (e.key == 's' || e.keyCode == 83)) { //保存 防止并发 if (!this.metaAction.gf('data.other.btnStatus') && this.isDisplayButton('save')) { this.backCaculateAmount() this.save() } if (e.preventDefault) { e.preventDefault() } if (e.stopPropagation) { e.stopPropagation() } } else if (e.ctrlKey && !e.altKey && (e.key == '/' || e.keyCode == 191)) { //保存并新增 防止并发 if (!this.metaAction.gf('data.other.btnStatus') && this.isDisplayButton('save')) { this.backCaculateAmount() this.saveAndNew() } if (e.preventDefault) { e.preventDefault() } if (e.stopPropagation) { e.stopPropagation() } } else if (e.ctrlKey && !e.altKey && (e.key == 'y' || e.keyCode == 89)) { //审核 if (this.isDisplayButton('audit')) { this.audit() } if (e.preventDefault) { e.preventDefault() } if (e.stopPropagation) { e.stopPropagation() } } else if (e.ctrlKey && !e.altKey && (e.key == ";" || e.keyCode == 186)) { //打印 if (this.isDisplayButton('print')) { this.print() } } else if ((e.key == "Enter" || e.keyCode == 13) && this.metaAction.gf('data.other.focusFieldPath') == 'root.children.formHeader.children.date.children.date') { this.metaAction.sf('data.other.focusFieldPath', 'root.children.formHeader.children.attachment.children.attachment') } //判断设备是否为mac else if (navigator.userAgent.indexOf('Mac OS X') !== -1) { if (!e.ctrlKey && !e.altKey && (e.key == "" || e.keyCode == 8 || e.keyCode == 46)) { //删除 if (!this.metaAction.gf('data.other.btnStatus') && !this.isDisplayButton('del')) { this.del() } } else if (e.ctrlKey && !e.altKey && (e.key == "[" || e.keyCode == 219)) { //上一张 this.loadPrevCertificate() } else if (e.ctrlKey && !e.altKey && (e.key == "]" || e.keyCode == 221)) { //下一张 this.loadNextCertificate() } } else { if (!e.ctrlKey && !e.altKey && (e.key == "Delete" || e.keyCode == 46)) { //删除 if (!this.metaAction.gf('data.other.btnStatus') && !this.isDisplayButton('del')) { this.del() } } else if (e.ctrlKey && !e.altKey && (e.key == "[" || e.keyCode == 37 || e.keyCode == 219)) { //219 win7 IE11下的keyCode //上一张 this.loadPrevCertificate() } else if (e.ctrlKey && !e.altKey && (e.key == "]" || e.keyCode == 39 || e.keyCode == 221)) { //221 win7 IE11下的keyCode //下一张 this.loadNextCertificate() } } } } //光标闪烁时不起作用 componentWillReceiveProps = ({ keydown }) => { // this.keyDownCickEvent(keydown) } selfGridKeydown = (e) => { if (document.getElementsByClassName('accountQuantityEdit').length > 0 && document.activeElement.className.indexOf('ant-select-selection') > -1) { // 当有数量外币框时,并且焦点在币种框上时,将不执行grid的gridKeydown return } this.keyDownCickEvent({event: e}) this.extendAction.gridAction.gridKeydown(e) if (e.keyCode == 40) { //40:向下键keycode this.extendAction.gridAction.cellAutoFocus() } } // 升级科目信息 upgradeDetails = (details, subjectList, currencys) => { let curAccountingSubject, lastestSubject, resCurrency, quantityAndForeignCurrency, glAccounts = fromJS(subjectList.glAccounts), editStatus = this.metaAction.gf('data.other.editStatus') this.metaAction.sf('data.other.calcDict', Map(subjectList.calcDict)) this.metaAction.sf('data.other.accountingSubjects', fromJS(subjectList.glAccounts)) this.metaAction.sf('data.other.accountingSubjectsAll', fromJS(subjectList.glAccountsAll)) this.metaAction.sf('data.other.currencyDS', currencys) for (var i = 0; i < details.size; i++) { curAccountingSubject = details.get(i).get('accountingSubject') /*场景描述:解决页签切换,停用币种的问题,先录入分录,然后在币种档案停用对应的币种,页签切换回来后更新停用的币种,把停用的币种清空 */ quantityAndForeignCurrency = details.get(i).get('quantityAndForeignCurrency') ? details.get(i).get('quantityAndForeignCurrency').toJS() : undefined if (currencys && curAccountingSubject) { if (quantityAndForeignCurrency && quantityAndForeignCurrency.currency){ if (quantityAndForeignCurrency.currency.id != curAccountingSubject.get('currencyId')) { resCurrency = currencys.find(x => x.get('id') == quantityAndForeignCurrency.currency.id) } else { resCurrency = currencys.find(x => x.get('id') == curAccountingSubject.get('currencyId')) } } } //页签切换,查找币种是否存在 if (quantityAndForeignCurrency && !resCurrency) { quantityAndForeignCurrency.currency = null details = details.update(i, item => item.set('quantityAndForeignCurrency', fromJS(quantityAndForeignCurrency))) } if (curAccountingSubject != undefined) { lastestSubject = glAccounts.filter(item => { return item.get('id') == curAccountingSubject.get('id') }).toArray() // 余额的保持 if (editStatus == data.ADD_STATUS && curAccountingSubject.get('balance') != undefined) { lastestSubject[0] = lastestSubject[0].set('balance', curAccountingSubject.get('balance')).set('initBalance', curAccountingSubject.get('balance')) } // 若最新科目去除所有辅助核算 if (!!curAccountingSubject.get('isCalc') && lastestSubject[0] && !lastestSubject[0].get('isCalc') || !curAccountingSubject.get('isCalc') && lastestSubject[0] && !!lastestSubject[0].get('isCalc')) { curAccountingSubject = lastestSubject[0] details = details.update(i, item => item.set('accountingSubject', lastestSubject[0])) } else if (!!curAccountingSubject.get('isCalc') && lastestSubject[0] && !!lastestSubject[0].get('isCalc')) { let auxAccountSubjects = curAccountingSubject.get('auxAccountSubjects'), auxAccountSubjectsPreSelected = curAccountingSubject.get('auxAccountSubjectsPreSelected') lastestSubject[0] = lastestSubject[0].set('auxAccountSubjects', auxAccountSubjects) lastestSubject[0] = lastestSubject[0].set('auxAccountSubjectsPreSelected', auxAccountSubjectsPreSelected) details = details.update(i, item => item.set('accountingSubject', lastestSubject[0])) } else if (!curAccountingSubject.get('isCalc') && lastestSubject[0] && !lastestSubject[0].get('isCalc')) { details = details.update(i, item => item.set('accountingSubject', lastestSubject[0])) } } } this.metaAction.sf('data.form.details', details) } getEnabledYearMonth = () => { let currentOrg = this.metaAction.context.get("currentOrg") let enabledYearMonth = currentOrg.enabledYear + '-' + currentOrg.enabledMonth.toString().padStart(2, '0') return enabledYearMonth } getCurrentUser = () => { return this.metaAction.context.get("currentUser") } isDisplayButton = (btnName) => { let editStatus = this.metaAction.gf('data.other.editStatus'), certificateStatus = this.metaAction.gf('data.form.certificateStatus'), isDisplay = true if (btnName == 'add') { isDisplay = (editStatus == data.VIEW_STATUS ? true : false) } else if (btnName == 'del') { isDisplay = ((certificateStatus == data.STATUS_VOUCHER_AUDITED) || (certificateStatus == data.STATUS_VOUCHER_NOT_AUDITED && editStatus != data.VIEW_STATUS)) } else if (btnName == 'save') { isDisplay = (editStatus != data.VIEW_STATUS ? true : false) } else if (btnName == 'audit') { isDisplay = (editStatus == data.VIEW_STATUS ? true : false) } else if (btnName == 'print') { isDisplay = (editStatus == data.VIEW_STATUS ? true : false) } else if (btnName == 'more') { isDisplay = (editStatus != data.ADD_STATUS ? true : false) } return isDisplay } getDynamicComponent = (_ctrlPath) => { let _isReadOnly = this.metaAction.isReadOnly(_ctrlPath), _isAccountFocus = this.isFocusOnAccount(_ctrlPath), _focusFieldPath = this.metaAction.gf('data.other.focusFieldPath'), _cancelEditAuxAccount = this.metaAction.gf('data.other.cancelEditAuxAccount'), _rowIndex = 0 if (_focusFieldPath) { if (_focusFieldPath.indexOf('.cell.cell') != -1) { _rowIndex = _focusFieldPath.split('.cell.cell,')[1] } } else { return 'SubjectDisplay' } if (_ctrlPath) { if (_ctrlPath.indexOf('.cell.cell,' + _rowIndex) > -1) { if (_isReadOnly) { return 'SubjectDisplay' } else { if (_isAccountFocus || _cancelEditAuxAccount) { this.metaAction.sf('data.other.cancelEditAuxAccount', null) return 'Select' } else { return 'SubjectDisplay' } } } return 'SubjectDisplay' } } getDisabledDate = (current) => { var disabledDate = new Date(this.metaAction.gf('data.other.disabledDate')) return current && current.valueOf() < disabledDate } isFocusOnAccount = (ctrlPath) => { let activeElement = document.getElementById('auxItemConfirm') let isFocus = this.metaAction.isFocus(ctrlPath) return isFocus && (activeElement == null || activeElement == undefined) } onFieldFocus = async (path) => { if (path.indexOf('root.children.details.columns.summary') > -1) { let rowIndex = parseInt(path.split(',')[1]), detail = this.metaAction.gf('data.form.details').get(rowIndex) this.backCaculateAmount() const summaryList = await this.webapi.summary.query() const templateList = await this.webapi.commonDoc.query() this.metaAction.sf('data.other.summarys', fromJS([...summaryList.summarys, ...this.translateTemplate(templateList)])) this.extendAction.gridAction.cellAutoFocus() } else if (path.indexOf('accountingSubject') > -1) { // 当凭证中的科目被停用后,再次点击科目时,显示科目名及辅助项目 START 0110 let rowIndex = parseInt(path.split(',')[1]), detail = this.metaAction.gf('data.form.details').get(rowIndex), accountingSubject = detail.get('accountingSubject') if (!!accountingSubject) { let codeAndName = accountingSubject.get('codeAndName'), accountId = accountingSubject.get('id'), dom = document.getElementsByClassName('ant-select-selection-selected-value'), accountingSubjects = this.metaAction.gf('data.other.accountingSubjects'), itemData = accountingSubjects.find(o => o.get('id') == accountId), auxAccountSubjects = accountingSubject.get('auxAccountSubjectsPreSelected') if (!itemData) { if (dom && dom.length > 0) { let subjectWidthAuxName = this.getSubjectWithAuxName(codeAndName, accountingSubject, auxAccountSubjects) dom[0].innerHTML = subjectWidthAuxName dom[0].title = subjectWidthAuxName } } } // 当凭证中的科目被停用后,再次点击科目时,显示科目名及辅助项目 END 0110 this.backCaculateAmount() } this.injections.reduce('onFieldFocus', path) // 实现借方金额、贷方金额的onBlur之用 if (this.metaAction.gf('data.other.originalFieldPath') == undefined) { this.metaAction.sf('data.other.originalFieldPath', path) } //数量外币PopOver框打开时 if (this.isVisibleQuanAndCurrCom()) { let btnQuantityCancels = document.getElementsByClassName('btnQuantityCancel') for (var i = btnQuantityCancels.length - 1; i > -1; i--) { let btnQuantityCancel = btnQuantityCancels[i], popOver = btnQuantityCancels[i].parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement if (popOver && popOver.className.indexOf('ant-popover-hidden') == -1 && btnQuantityCancel) { btnQuantityCancel.click() } } } } getSubjectWithAuxName(subjectName, accountingSubject, auxAccountSubjects) { if (!accountingSubject.get('isCalc')) return subjectName let subjectWithAuxName = '' if (accountingSubject.get('isCalcCustomer') && auxAccountSubjects.get('customer') && auxAccountSubjects.get('customer').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('customer').get('name') } if (accountingSubject.get('isCalcSupplier') && auxAccountSubjects.get('supplier') && auxAccountSubjects.get('supplier').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('supplier').get('name') } if (accountingSubject.get('isCalcProject') && auxAccountSubjects.get('project') && auxAccountSubjects.get('project').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('project').get('name') } if (accountingSubject.get('isCalcDepartment') && auxAccountSubjects.get('department') && auxAccountSubjects.get('department').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('department').get('name') } if (accountingSubject.get('isCalcPerson') && auxAccountSubjects.get('person') && auxAccountSubjects.get('person').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('person').get('name') } if (accountingSubject.get('isCalcInventory') && auxAccountSubjects.get('inventory') && auxAccountSubjects.get('inventory').get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get('inventory').get('name') } //自定义档案 let calcDict = this.metaAction.gf('data.other.calcDict'), userDefineItemName for (var j = 1; j <= 10; j++) { if (accountingSubject.get(`isExCalc${j}`) && auxAccountSubjects.get(`exCalc${j}`) && auxAccountSubjects.get(`exCalc${j}`).get('name')) { subjectWithAuxName = subjectWithAuxName + "_" + auxAccountSubjects.get(`exCalc${j}`).get('name') } } return subjectName + '_' + subjectWithAuxName } backCaculateAmount = () => { if (this.metaAction.gf('data.other.originalFieldPath')) { //处理某一分录行填写表格中的金额后,再点击该行数量外币列时,弹出框的金额没有被反算的问题 0310 let originalFieldPath = this.metaAction.gf('data.other.originalFieldPath'), lastEditRowIndex = originalFieldPath.split(',')[1], detail = this.metaAction.gf('data.form.details').get(lastEditRowIndex) if(!detail) return let quantityAndForeignCurrency = detail.get('quantityAndForeignCurrency') if (!quantityAndForeignCurrency) return let amount = quantityAndForeignCurrency.get('amount'), lastFocusPath = this.metaAction.gf('data.other.originalFieldPath'), lastEditField if (lastFocusPath && lastFocusPath.indexOf('debitAmount') != -1) { lastEditField = 'debitAmount' } else if (lastFocusPath && lastFocusPath.indexOf('creditAmount') != -1) { lastEditField = 'creditAmount' } else { lastEditField = undefined } if (lastEditField && amount != detail.get(lastEditField)) { this.injections.reduce('onEvent', 'onBlur', { path: originalFieldPath }) } } } //公共方法 isVisibleQuanAndCurrCom = () => { let ret = false if (document.getElementsByClassName) { let accountQuantityEdit = document.getElementsByClassName('accountQuantityEdit')[0], quantityPopOver = document.getElementsByClassName('ant-popover') if (accountQuantityEdit) { if (quantityPopOver && quantityPopOver.length > 0) { for (var i = 0; i < quantityPopOver.length; i++) { if (quantityPopOver[i] && quantityPopOver[i].className.indexOf('ant-popover-hidden') == -1) { ret = true break } } } } } return ret } onEvent = async (eventName, option) => { if (!option.path) { return } if (eventName === 'accountQuantityIsShow') { this.injections.reduce('accountQuantityIsShow', option) this.extendAction.gridAction.cellAutoFocus() } else if (eventName === 'cancelEditAuxAccount') { this.injections.reduce('cancelEditAuxAccount', option) this.metaAction.focus(option.path) this.extendAction.gridAction.cellAutoFocus() } else if (eventName === 'endEditAuxAccount') { let curIndex = option.path.split(',')[1], details = this.metaAction.gf('data.form.details'), curAccountSubject = details.get(curIndex).get('accountingSubject'), editStatus = this.metaAction.gf('data.other.editStatus'), balance if (editStatus == data.ADD_STATUS || editStatus == data.EDIT_STATUS) { balance = await this.getAccountBalance(option.path, undefined, option) option.balance = balance option.initBalance = balance } this.injections.reduce('endEditAuxAccount', option, balance) this.extendAction.gridAction.cellAutoFocus() } else { this.injections.reduce('onEvent', eventName, option) } } //把服务端返回的字段名, 做转换 translateTemplate = (templates) => { let templateList = List() for (let i = 0; i < templates.length; i++) { templateList = templateList.push({ id: templates[i].docTemplateId, code: templates[i].docTemplateCode, name: templates[i].docTemplateName + ' [模板]', type: 'template' }) } return templateList.toJS() } filterOption = (inputValue, option) => { if (option && option.props && option.props.value) { let accountingSubjects = this.metaAction.gf('data.other.accountingSubjects') let itemData = accountingSubjects.find(o => o.get('id') == option.props.value) if ((itemData.get('code') && itemData.get('code').indexOf(inputValue) == 0) || (itemData.get('gradeName') && itemData.get('gradeName').indexOf(inputValue) != -1) || (itemData.get('codeAndName') && itemData.get('codeAndName').indexOf(inputValue) == 0) || (itemData.get('helpCode') && itemData.get('helpCode').indexOf(inputValue.toUpperCase()) != -1) || (itemData.get('helpCodeFull') && itemData.get('helpCodeFull').indexOf(inputValue) != -1)) { //将滚动条置顶 let select = document.getElementsByClassName('ant-select-dropdown-menu') if (select.length > 0 && select[0].scrollTop > 0) { select[0].scrollTop = 0 } return true } else { return false } } return true } filterOptionSummary = (input, option) => { if (option && option.props && option.props.children) { return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 } return true } clearGridFocus = () => { this.metaAction.sf('data.other.focusFieldPath', undefined) } certificateManagement = () => { this.component.props.setPortalContent && this.component.props.setPortalContent('凭证管理', 'app-proof-of-list') } getAudited = () => { return (this.metaAction.gf('data.form.certificateStatus') == consts.VOUCHERSTATUS_Approved) } isRowOperation = () => { return this.metaAction.gf('data.form.certificateStatus') == data.STATUS_VOUCHER_NOT_AUDITED } audit = async () => { let id = this.metaAction.gf('data.form.id'), ts = this.metaAction.gf('data.form.ts'), certificateStatus = this.metaAction.gf('data.form.certificateStatus') if (!id || !ts) { this.metaAction.toast('success', '请先保存凭证!') return } if (certificateStatus == data.STATUS_VOUCHER_NOT_AUDITED) { const response = await this.webapi.certificate.audit({ docId: id, ts: ts }) if (response) { this.metaAction.toast('success', '凭证审核成功!') this.injections.reduce('changeAuditStatus', data.STATUS_VOUCHER_AUDITED, this.getCurrentUser(), response) } } else { const response = await this.webapi.certificate.antiAudit({ docId: id, ts: ts }) if (response) { this.metaAction.toast('success', '凭证反审核成功!') this.injections.reduce('changeAuditStatus', data.STATUS_VOUCHER_NOT_AUDITED, this.getCurrentUser(), response) } } } commonMenuClick = (e) => { switch (e.key) { case 'useCommon': this.uesCommon() break; case 'saveCommon': this.saveCommon() break; } } uesCommon = () => { this.checkEditStatusBeforeLoadNewVoucher(async () => { const ret = await this.metaAction.modal('show', { title: '凭证模版', width: 880, height: 425, okText: '使用凭证模版', bodyStyle: {padding: '10px 50px'}, children: this.metaAction.loadApp('ttk-voucher-app-document-common', { store: this.component.props.store, columnCode: "common" }), }) if (ret) { let certificateTemplate = await this.webapi.commonDoc.findById({ docTemplateId: ret.docTemplateId }) certificateTemplate.entrys = await this.getMultiAccountBalance(certificateTemplate.entrys) //设置凭证当前单据状态,供单据页签关闭用 false:关闭不提醒 true 关闭提醒 // this.component.props.editing(this.component.props.appName, true) this.editCloseTips(true) this.injections.reduce('applyCertificateTemplate', fromJS(certificateTemplate), data.ADD_STATUS) } }) } editCloseTips=(istip)=>{ if (this.component.props.editing){ //设置凭证当前单据状态,供单据页签关闭用 false:关闭不提醒 true 关闭提醒 this.component.props.editing(this.component.props.appName, istip) } } saveCommon = async () => { if (!this.canSaveAsTemplate()) { this.metaAction.toast('warning', '没有填写科目的凭证不能存为模板!') return } const ret = await this.metaAction.modal('show', { title: '存为凭证模版', width: 340, children: this.metaAction.loadApp('ttk-voucher-app-document-common-add', { store: this.component.props.store, columnCode: "common", initData: { certificateData: this.metaAction.gf('data.form') } }), }) } //能否存为模板(空凭证不能存为模板) canSaveAsTemplate = () => { let details = this.metaAction.gf('data.form.details') for (let item of details) { let itemForServer = this.convertVoucherItemForServer(item) if (itemForServer) { return true } } return false } getAccountBalance = async (path, accountingSubject, option) => { let balance if (this.metaAction.gf('data.other.editStatus') == data.ADD_STATUS) { let index = path.split(',')[1], subjectValue = this.metaAction.gf('data.form.details').get(index).get('accountingSubject') let queryParams = {}, auxAccountSubjects if (option) { auxAccountSubjects = option.data.get('auxAccountSubjects') queryParams.accountId = subjectValue.get('id') } else { queryParams.accountId = accountingSubject.get('id') } if (!!auxAccountSubjects) { queryParams.departmentId = auxAccountSubjects.get('department') ? auxAccountSubjects.get('department').get('id') : undefined queryParams.personId = auxAccountSubjects.get('person') ? auxAccountSubjects.get('person').get('id') : undefined queryParams.customerId = auxAccountSubjects.get('customer') ? auxAccountSubjects.get('customer').get('id') : undefined queryParams.supplierId = auxAccountSubjects.get('supplier') ? auxAccountSubjects.get('supplier').get('id') : undefined queryParams.inventoryId = auxAccountSubjects.get('inventory') ? auxAccountSubjects.get('inventory').get('id') : undefined queryParams.projectId = auxAccountSubjects.get('project') ? auxAccountSubjects.get('project').get('id') : undefined for (var j = 1; j <= 10; j++) { queryParams[`exCalc${j}`] = auxAccountSubjects.get(`exCalc${j}`) ? auxAccountSubjects.get(`exCalc${j}`).get('id') : undefined } } const response = await this.webapi.certificate.getAccountBalance(queryParams) if (response != undefined) { balance = response } } else { balance = 0 } return balance } // 获取多个科目的余额 getMultiAccountBalance = async (entrys) => { let balance if (this.metaAction.gf('data.other.editStatus') == data.ADD_STATUS) { let queryParams = [], param, entry for (var i = 0; i < entrys.length; i++) { entry = entrys[i] param = {} param.accountId = entry.accountId param.departmentId = entry.departmentId ? entry.departmentId : undefined param.personId = entry.personId ? entry.personId : undefined param.customerId = entry.customerIdcustomerId ? entry.customerId : undefined param.supplierId = entry.supplierId ? entry.supplierId : undefined param.inventoryId = entry.inventoryId ? entry.inventoryId : undefined param.projectId = entry.projectId ? entry.projectId : undefined for (var j = 1; j <= 10; j++) { param[`exCalc${j}`] = entry[`exCalc${j}`] ? entry[`exCalc${j}`] : undefined } queryParams.push(param) } const response = await this.webapi.certificate.getAccountsBalance(queryParams) if (response != undefined) { for (var i = 0; i < entrys.length; i++) { entrys[i].balance = response[i].balance } } } else { entrys } return entrys } print = async () => { let _this = this const { height, maxLineNum, printAuxAccCalc, type, width } = await this.webapi.certificate.getPrintConfig() this.metaAction.modal('show', { title: '打印', width: 400, footer: null, iconType: null, okText: '打印', className: 'print-modal-container', children: <PrintOption height={height} maxLineNum={maxLineNum} printAuxAccCalc={printAuxAccCalc} type={type} width={width} callBack={ _this.submitPrintOption } /> }) } submitPrintOption = async (form, target) => { let id = this.metaAction.gf('data.form.id') let option = { "type": parseInt(form.state.value), "printAuxAccCalc": form.state.printAccountChecked, "docIdsStr": `${id}` } if (form.state.value == "0") { Object.assign(option, { "maxLineNum": form.state.pageSize }) } else if (form.state.value == "2") { Object.assign(option, { "height": form.state.height, "width": form.state.width }) } let res = await this.webapi.certificate.print(option) } checkVoucherDataBeforeSave(form) { let msg = [], allItemEmpty = true, isBackCaculate = false, details = this.metaAction.gf('data.form.details') this.backCaculateAmount() //凭证号校验 if (!form.code) { msg.push('凭证号不能为空') } else if (!/^\d+$/.test(form.code)) { msg.push('凭证号必须为纯数字,请修改') } if (form.code === '0') msg.push('凭证号不能为0,请修改') if (!form.date) msg.push('日期不能为空') form.details.forEach((detail, i) => { if (!detail || (!detail.accountingSubject && !detail.summary && !detail.creditAmount && !detail.debitAmount) || (!detail.accountingSubject && detail.summary && !detail.creditAmount && !detail.debitAmount)) { return } allItemEmpty = false //凭证号校验 //2) 摘要、科目和金额 同时填写或不填 let emptyItemNames = List() if (!detail.summary) { emptyItemNames = emptyItemNames.push('摘要') } if (!detail.accountingSubject) { emptyItemNames = emptyItemNames.push('科目') } if (!detail.debitAmount && !detail.creditAmount) { emptyItemNames = emptyItemNames.push('金额') } if (emptyItemNames.size > 0) { let rowError if (emptyItemNames.size > 2) { rowError = "摘要、科目和金额" } else if (emptyItemNames.size == 2) { rowError = emptyItemNames.get(0) + '和' + emptyItemNames.get(1) } else { rowError = emptyItemNames.get(0) } msg.push("第" + (i + 1) + "行,请填写" + rowError) return } if (detail.summary && detail.summary.length > 200) msg.push("第" + (i + 1) + "行,摘要输入过长,请调整") //3) 数量/外币 核算 if (detail.accountingSubject.isCalcQuantity && (!detail.quantityAndForeignCurrency || !detail.quantityAndForeignCurrency.amount)) { let lastFocusPath = this.metaAction.gf('data.other.originalFieldPath'), rowIndex = lastFocusPath ? lastFocusPath.split(',')[1] : -1, lastEditField // 解决360、IE、Edge浏览器下保存时借贷方金额未反算的问题 TTK-3055 if (lastFocusPath && rowIndex == i) { if (lastFocusPath && lastFocusPath.indexOf('debitAmount') != -1) { lastEditField = 'debitAmount' } else if (lastFocusPath && lastFocusPath.indexOf('creditAmount') != -1) { lastEditField = 'creditAmount' } else { lastEditField = undefined } details = details.update(rowIndex, item=>item.setIn(['quantityAndForeignCurrency', 'amount'], detail[lastEditField])) isBackCaculate = true } else { msg.push("第" + (i + 1) + "行,请填写数量核算") return } } if (detail.accountingSubject.isCalcMulti && (!detail.quantityAndForeignCurrency || !detail.quantityAndForeignCurrency.currency)) { msg.push("第" + (i + 1) + "行,请填写外币核算") return } //4) 启用辅助核算 if (detail.accountingSubject.isCalc) { if (!detail.accountingSubject.auxAccountSubjects) { msg.push("第" + (i + 1) + "行,请填写科目辅助核算") return } let auxAccountSubjects = detail.accountingSubject.auxAccountSubjects //部门 if (detail.accountingSubject.isCalcDepartment && !(auxAccountSubjects.department && auxAccountSubjects.department.id)) { msg.push("第" + (i + 1) + "行,请填写部门辅助核算") return } //人员 if (detail.accountingSubject.isCalcPerson && !(auxAccountSubjects.person && auxAccountSubjects.person.id)) { msg.push("第" + (i + 1) + "行,请填写人员辅助核算") return } //客户 if (detail.accountingSubject.isCalcCustomer && !(auxAccountSubjects.customer && auxAccountSubjects.customer.id)) { msg.push("第" + (i + 1) + "行,请填写客户辅助核算") return } //供应商 if (detail.accountingSubject.isCalcSupplier && !(auxAccountSubjects.supplier && auxAccountSubjects.supplier.id)) { msg.push("第" + (i + 1) + "行,请填写供应商辅助核算") return } //存货 if (detail.accountingSubject.isCalcInventory && !(auxAccountSubjects.inventory && auxAccountSubjects.inventory.id)) { msg.push("第" + (i + 1) + "行,请填写存货辅助核算") return } //项目 if (detail.accountingSubject.isCalcProject && !(auxAccountSubjects.project && auxAccountSubjects.project.id)) { msg.push("第" + (i + 1) + "行,请填写项目辅助核算") return } //自定义档案 let calcDict = this.metaAction.gf('data.other.calcDict') for (var j = 1; j <= 10; j++) { if (detail.accountingSubject[`isExCalc${j}`] && !(auxAccountSubjects[`exCalc${j}`] && auxAccountSubjects[`exCalc${j}`].id)) { let userDefineItemName = calcDict.get(`isExCalc${j}`) msg.push("第" + (i + 1) + `行,请填写${userDefineItemName}辅助核算`) return } } } }) if (isBackCaculate){ this.metaAction.sf('data.form.details', details) } //5) 不能全为空行 if (allItemEmpty) { msg.push("请填写凭证分录") } else { //6) 借贷平衡 let debitSum = 0, creditSum = 0 for (let item of form.details) { let debitAmountItem = parseInt((parseFloat(item.debitAmount || 0) * 100).toFixed(0)), creditAmountItem = parseInt((parseFloat(item.creditAmount || 0) * 100).toFixed(0)) debitSum = (parseInt((debitSum * 100).toFixed(0)) + debitAmountItem) / 100 creditSum = (parseInt((creditSum * 100).toFixed(0)) + creditAmountItem) / 100 } if (debitSum.toFixed(2) !== creditSum.toFixed(2)) { msg.push("凭证借贷不平") } } return msg } save = async (callback) => { let form = this.metaAction.gf('data.form').toJS() const msg = this.checkVoucherDataBeforeSave(form), checkStyle = { textAlign: 'left', fontSize: '14px', display: 'inline-block', verticalAlign: 'top' } if (msg.length > 0) { this.metaAction.toast('warning', <div style={checkStyle}> {msg.map((o, index) => <p style={{ marginBottom: '0' }}>{(index+1) + '.' + o}</p>)} </div> ) return } let certificateData = this.getCertificateData() //让保存按钮置灰,防止并发 置灰 this.injections.reduce('showBtnState', {path: 'data.other.btnStatus',value: true}) //新增 if (this.metaAction.gf('data.other.editStatus') == data.ADD_STATUS || !certificateData.docId) { const response = await this.webapi.certificate.create(certificateData) if (response) { this.metaAction.toast('success', '凭证保存成功') this.injections.reduce('loadCertificate', fromJS(response), data.VIEW_STATUS) if (callback && typeof callback == 'function') callback() //设置凭证当前单据状态,供单据页签关闭用 false:关闭不提醒 true 关闭提醒 // this.component.props.editing(this.component.props.appNam