import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Table, Form, Input, InputNumber, notification, AutoComplete, Select, Popover, Button } from 'antd'
|
import { PlusOutlined, CloseOutlined } from '@ant-design/icons'
|
|
import Utils from '@/utils/utils.js'
|
import MKEmitter from '@/utils/events.js'
|
import './index.scss'
|
|
class BodyRow extends React.Component {
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.props.data), fromJS(nextProps.data))
|
}
|
|
render() {
|
let { data, ...resProps } = this.props
|
let style = {}
|
let className = ''
|
|
return <tr {...resProps} className={className} style={style}/>
|
}
|
}
|
|
class Accounting extends React.Component {
|
state = {
|
subAccounts: []
|
}
|
|
UNSAFE_componentWillMount() {
|
const { data, tableId } = this.props
|
let subAccounts = fromJS(data.supAccounts).toJS()
|
let msg = window.GLOB.CacheVoucher.get(tableId) || {}
|
|
subAccounts = subAccounts.map(item => {
|
if (msg[item.field]) {
|
item.options = msg[item.field]
|
} else if (msg.others) {
|
item.options = msg.others.filter(cell => cell.parentId === item.field)
|
} else {
|
item.options = []
|
}
|
|
return item
|
})
|
|
this.setState({subAccounts: subAccounts})
|
}
|
|
selectChange = (option, key) => {
|
this.setState({
|
subAccounts: fromJS(this.state.subAccounts).toJS().map(cell => {
|
if (key === cell.field) {
|
cell.value = option ? option.props.value : ''
|
cell.name = option ? option.props.name : ''
|
}
|
return cell
|
})
|
})
|
}
|
|
getFields() {
|
const { subAccounts } = this.state
|
|
const fields = []
|
|
subAccounts.forEach((item) => {
|
fields.push(
|
<Form.Item label={item.label} key={item.field}>
|
<Select
|
showSearch
|
allowClear
|
defaultValue={item.initval}
|
dropdownMatchSelectWidth={false}
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
onChange={(val, option) => this.selectChange(option, item.field)}
|
>
|
{item.options.map((option, i) =>
|
<Select.Option key={i} name={option.label} value={option.value}>{option.label}</Select.Option>
|
)}
|
</Select>
|
</Form.Item>
|
)
|
})
|
|
return fields
|
}
|
|
confirm = () => {
|
const { data } = this.props
|
const { subAccounts } = this.state
|
|
let empty = ''
|
subAccounts.forEach(item => {
|
if (!empty && !item.value) {
|
empty = item.label
|
}
|
})
|
|
if (empty) {
|
notification.warning({
|
top: 92,
|
message: '请选择' + empty,
|
duration: 5
|
})
|
} else {
|
let line = fromJS(data).toJS()
|
let account = {}
|
|
subAccounts.forEach(item => {
|
if (item.field === 'supplier') {
|
account[item.field] = {suppliercode: item.value, suppliername: item.name}
|
} else if (item.field === 'logistics') {
|
account[item.field] = {logistics_code: item.value, logistics_name: item.name}
|
} else if (item.field === 'lessor') {
|
account[item.field] = {lessor_code: item.value, lessor_name: item.name}
|
} else if (item.field === 'customer') {
|
account[item.field] = {customercode: item.value, customername: item.name}
|
} else if (item.field === 'department') {
|
account[item.field] = {co_pro_code: item.value, co_pro_name: item.name}
|
} else if (item.field === 'project') {
|
account[item.field] = {projectcode: item.value, projectname: item.name}
|
} else if (item.field === 'inventory') {
|
account[item.field] = {productcode: item.value, productname: item.name}
|
} else if (item.field === 'employee') {
|
account[item.field] = {workercode: item.value, workername: item.name}
|
} else if (item.field === 'cash_flow') {
|
account[item.field] = {cash_flow_code: item.value, cash_flow_name: item.name}
|
} else {
|
account[item.field] = {sup_acc_code: item.value, sup_acc_name: item.name}
|
}
|
})
|
|
line.supAccounts = line.supAccounts.map(item => {
|
if (account[item.field]) {
|
item = {...item, ...account[item.field]}
|
}
|
return item
|
})
|
|
this.props.confirm(line)
|
}
|
}
|
|
render() {
|
return <div>
|
{this.getFields()}
|
<div className="footer">
|
<Button onClick={this.props.cancel}>取消</Button>
|
<Button onClick={this.confirm}>确定</Button>
|
</div>
|
</div>
|
}
|
}
|
|
class BodyCell extends React.Component {
|
state = {
|
editing: false,
|
visible: false,
|
counting: false,
|
priceing: false,
|
curring: false,
|
ratioing: false,
|
origining: false,
|
}
|
|
componentDidMount () {
|
MKEmitter.addListener('tdFocus', this.tdFocus)
|
}
|
|
/**
|
* @description 组件销毁,清除state更新,清除快捷键设置
|
*/
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
MKEmitter.removeListener('tdFocus', this.tdFocus)
|
}
|
|
tdFocus = (id) => {
|
const { col, record } = this.props
|
|
if (id !== col.uuid + record.uuid) return
|
|
this.focus()
|
}
|
|
enterPress = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({editing: false})
|
|
let line = {...record}
|
line[col.field] = value
|
|
if (col.field === 'subject_voucher_text') {
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
setTimeout(() => {
|
let cl = {subject_voucher_text: 'subject_code', subject_code: 'debit', debit: 'credit'}
|
MKEmitter.emit('tdFocus', cl[col.uuid] + record.uuid)
|
}, 50)
|
return
|
}
|
|
if (col.field === 'debit') {
|
line.credit = ''
|
if (isNaN(line.debit)) {
|
line.debit = ''
|
}
|
} else {
|
line.debit = ''
|
if (isNaN(line.credit)) {
|
line.credit = ''
|
}
|
}
|
|
if (line.count_type === 'Y' && line.fcc_count) {
|
if (line.debit) {
|
line.net_unitprice = Math.round(line.debit / line.fcc_count * 10000) / 10000
|
} else if (line.credit) {
|
line.net_unitprice = Math.round(line.credit / line.fcc_count * 10000) / 10000
|
}
|
}
|
|
if (line.foreign_currency_type === 'Y' && line.foreign_amount) {
|
if (line.debit) {
|
line.unitratio = Math.round(line.debit / line.foreign_amount * 100000) / 100000
|
} else if (line.credit) {
|
line.unitratio = Math.round(line.credit / line.foreign_amount * 100000) / 100000
|
}
|
}
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
setTimeout(() => {
|
if (col.field === 'debit' && (line.debit || line.debit === 0)) {
|
MKEmitter.emit('nextVoucher', col, record)
|
} else if (col.field === 'credit') {
|
MKEmitter.emit('nextVoucher', col, record)
|
} else {
|
let cl = {subject_voucher_text: 'subject_code', subject_code: 'debit', debit: 'credit'}
|
MKEmitter.emit('tdFocus', cl[col.uuid] + record.uuid)
|
}
|
}, 50)
|
}
|
|
focus = () => {
|
const { col, record } = this.props
|
|
if (record.type === 'total') return
|
|
if (col.field === 'subject_code') {
|
this.setState({editing: true}, () => {
|
let node = document.getElementById(col.uuid + record.uuid)
|
node && node.click()
|
})
|
} else {
|
this.setState({editing: true, value: record[col.field]}, () => {
|
let node = document.getElementById(col.uuid + record.uuid)
|
node && node.select()
|
})
|
}
|
}
|
|
onBlur = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({editing: false})
|
|
if (value !== record[col.field]) {
|
let line = {...record, [col.field]: value}
|
|
if (col.field === 'subject_voucher_text') {
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
return
|
}
|
|
if (col.field === 'debit') {
|
line.credit = ''
|
if (isNaN(line.debit)) {
|
line.debit = ''
|
}
|
} else {
|
line.debit = ''
|
if (isNaN(line.credit)) {
|
line.credit = ''
|
}
|
}
|
|
if (line.count_type === 'Y' && line.fcc_count) {
|
if (line.debit) {
|
line.net_unitprice = Math.round(line.debit / line.fcc_count * 10000) / 10000
|
} else if (line.credit) {
|
line.net_unitprice = Math.round(line.credit / line.fcc_count * 10000) / 10000
|
}
|
}
|
|
if (line.foreign_currency_type === 'Y' && line.foreign_amount) {
|
if (line.debit) {
|
line.unitratio = Math.round(line.debit / line.foreign_amount * 100000) / 100000
|
} else if (line.credit) {
|
line.unitratio = Math.round(line.credit / line.foreign_amount * 100000) / 100000
|
}
|
}
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
}
|
}
|
|
onChange = (val) => {
|
this.setState({value: val})
|
}
|
|
complete = (val) => {
|
this.setState({value: val}, () => {
|
this.onBlur()
|
})
|
}
|
|
plusLine = () => {
|
const { col, record } = this.props
|
|
MKEmitter.emit('plusLine', col.tableId, record)
|
}
|
|
delVoucher = () => {
|
const { col, record } = this.props
|
|
MKEmitter.emit('delVoucher', col.tableId, record)
|
}
|
|
onSelectBlur = () => {
|
const { visible } = this.state
|
|
if (visible) return
|
|
this.setState({editing: false})
|
}
|
|
onSelectChange = (val, option) => {
|
const { col, record } = this.props
|
|
let line = {...record, ...option.props.extra}
|
|
line.supAccounts = []
|
|
if (line.sup_accounting) {
|
let msg = window.GLOB.CacheVoucher.get(col.tableId) || {}
|
let names = msg.names || {}
|
|
line.supAccounts = line.sup_accounting.split(',').map(item => {
|
return {
|
uuid: Utils.getguid(),
|
sup_acc_type: item,
|
field: item,
|
label: names[item] || item,
|
initval: ''
|
}
|
})
|
}
|
|
if (line.foreign_currency_type === 'Y' && line.foreign_currency) {
|
let msg = window.GLOB.CacheVoucher.get(col.tableId)
|
let cur = msg ? msg.currency.filter(n => n.exratename === line.foreign_currency)[0] : null
|
if (cur) {
|
line = {...line, ...cur}
|
}
|
|
this.currencyChange(line)
|
}
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
if (line.sup_accounting) {
|
setTimeout(() => {
|
this.setState({visible: true})
|
}, 100)
|
} else if (line.count_type === 'Y') {
|
this.setState({counting: true, value: line.fcc_count || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'count')
|
node && node.select()
|
})
|
} else if (line.foreign_currency_type === 'Y') {
|
this.setState({curring: true}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'currency')
|
node && node.click()
|
})
|
} else {
|
this.setState({editing: false, visible: false, counting: false, priceing: false})
|
setTimeout(() => {
|
MKEmitter.emit('tdFocus', 'debit' + record.uuid)
|
}, 50)
|
}
|
}
|
|
confirm = (res) => {
|
const { col } = this.props
|
|
MKEmitter.emit('changeRecord', col.tableId, fromJS(res).toJS())
|
|
this.setState({editing: false, visible: false})
|
|
if (res.count_type === 'Y') {
|
this.setState({counting: true, value: res.fcc_count || 0}, () => {
|
let node = document.getElementById(col.uuid + res.uuid + 'count')
|
node && node.select()
|
})
|
} else {
|
setTimeout(() => {
|
MKEmitter.emit('tdFocus', 'debit' + res.uuid)
|
}, 50)
|
}
|
}
|
|
cancel = () => {
|
const { col } = this.props
|
let record = fromJS(this.props.record).toJS()
|
record.balance_direction = ''
|
record.count_type = ''
|
record.foreign_currency_type = ''
|
record.mnemonic_code = ''
|
record.subject_code = ''
|
record.subject_name = ''
|
record.sup_accounting = ''
|
record.supAccounts = []
|
|
MKEmitter.emit('changeRecord', col.tableId, record)
|
|
this.setState({editing: false, visible: false})
|
}
|
|
editCount = (e) => {
|
const { col, record } = this.props
|
e.stopPropagation()
|
|
this.setState({counting: true, value: record.fcc_count || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'count')
|
node && node.select()
|
})
|
}
|
|
editPrice = (e) => {
|
const { col, record } = this.props
|
e.stopPropagation()
|
|
this.setState({priceing: true, value: record.net_unitprice || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'price')
|
node && node.select()
|
})
|
}
|
|
countPress = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
let line = {...record}
|
line.fcc_count = value || 0
|
|
if (isNaN(line.fcc_count)) {
|
line.fcc_count = 0
|
}
|
|
this.countChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
this.setState({counting: false, priceing: true, value: line.net_unitprice || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'price')
|
node && node.select()
|
})
|
}
|
|
countBlur = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({counting: false})
|
|
let line = {...record}
|
line.fcc_count = value || 0
|
|
if (isNaN(line.fcc_count)) {
|
line.fcc_count = 0
|
}
|
|
this.countChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
}
|
|
pricePress = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
let line = {...record}
|
line.net_unitprice = value || 0
|
|
if (isNaN(line.net_unitprice)) {
|
line.net_unitprice = 0
|
}
|
|
this.countChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
this.setState({priceing: false})
|
setTimeout(() => {
|
MKEmitter.emit('tdFocus', 'debit' + record.uuid)
|
}, 50)
|
}
|
|
priceBlur = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({priceing: false})
|
|
let line = {...record}
|
line.net_unitprice = value || 0
|
|
if (isNaN(line.net_unitprice)) {
|
line.net_unitprice = 0
|
}
|
|
this.countChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
}
|
|
editCurrency = (e) => {
|
const { col, record } = this.props
|
e.stopPropagation()
|
|
this.setState({curring: true}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'currency')
|
node && node.click()
|
})
|
}
|
|
onCurrSelectChange = (val, option) => {
|
const { col, record } = this.props
|
|
let line = {...record, ...option.props.extra}
|
|
this.currencyChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
if (line.exratename === 'CNY') {
|
this.setState({curring: false, origining: true, value: line.foreign_amount || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'origin')
|
node && node.select()
|
})
|
} else {
|
this.setState({curring: false, ratioing: true, value: line.unitratio || 1}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'ratio')
|
node && node.select()
|
})
|
}
|
}
|
|
editRatio = (e) => {
|
const { col, record } = this.props
|
e.stopPropagation()
|
|
this.setState({ratioing: true, value: record.unitratio || 1}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'ratio')
|
node && node.select()
|
})
|
}
|
|
ratioPress = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
let line = {...record}
|
line.unitratio = value || 1
|
|
if (isNaN(line.unitratio)) {
|
line.unitratio = 1
|
}
|
|
this.currencyChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
this.setState({ratioing: false, origining: true, value: line.foreign_amount || 0}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'origin')
|
node && node.select()
|
})
|
}
|
|
ratioBlur = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({ratioing: false})
|
|
let line = {...record}
|
line.unitratio = value || 1
|
|
if (isNaN(line.unitratio)) {
|
line.unitratio = 1
|
}
|
|
this.currencyChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
}
|
|
editOrigin = (e) => {
|
const { col, record } = this.props
|
e.stopPropagation()
|
|
this.setState({origining: true, value: record.foreign_amount || 1}, () => {
|
let node = document.getElementById(col.uuid + record.uuid + 'origin')
|
node && node.select()
|
})
|
}
|
|
originPress = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
let line = {...record}
|
line.foreign_amount = value || 0
|
|
if (isNaN(line.foreign_amount)) {
|
line.foreign_amount = 0
|
}
|
|
this.currencyChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
|
this.setState({origining: false})
|
|
setTimeout(() => {
|
MKEmitter.emit('tdFocus', 'debit' + record.uuid)
|
}, 50)
|
}
|
|
originBlur = () => {
|
const { col, record } = this.props
|
const { value } = this.state
|
|
this.setState({origining: false})
|
|
let line = {...record}
|
line.foreign_amount = value || 0
|
|
if (isNaN(line.foreign_amount)) {
|
line.foreign_amount = 0
|
}
|
|
this.currencyChange(line)
|
|
MKEmitter.emit('changeRecord', col.tableId, line)
|
}
|
|
countChange = (line) => {
|
if (line.fcc_count && line.net_unitprice) {
|
if (line.credit) {
|
line.credit = Math.round(line.fcc_count * line.net_unitprice * 100) / 100
|
} else {
|
line.debit = Math.round(line.fcc_count * line.net_unitprice * 100) / 100
|
}
|
|
if (line.foreign_currency_type === 'Y' && line.foreign_amount) {
|
if (line.debit) {
|
line.unitratio = Math.round(line.debit / line.foreign_amount * 100000) / 100000
|
} else if (line.credit) {
|
line.unitratio = Math.round(line.credit / line.foreign_amount * 100000) / 100000
|
}
|
}
|
}
|
}
|
|
currencyChange = (line) => {
|
if (line.unitratio && line.foreign_amount) {
|
if (line.credit) {
|
line.credit = Math.round(line.unitratio * line.foreign_amount * 100) / 100
|
} else {
|
line.debit = Math.round(line.unitratio * line.foreign_amount * 100) / 100
|
}
|
|
if (line.count_type === 'Y' && line.fcc_count) {
|
if (line.debit) {
|
line.net_unitprice = Math.round(line.debit / line.fcc_count * 10000) / 10000
|
} else if (line.credit) {
|
line.net_unitprice = Math.round(line.credit / line.fcc_count * 10000) / 10000
|
}
|
}
|
}
|
}
|
|
render() {
|
let { col, record, className } = this.props
|
const { editing, visible, counting, priceing, curring, ratioing, origining } = this.state
|
|
let children = null
|
let colSpan = 1
|
let extra = null
|
|
if (col.field === 'subject_voucher_text') {
|
let val = record.subject_voucher_text || ''
|
|
if (record.type === 'total') {
|
children = <div className="content-wrap" style={{lineHeight: '60px'}}>合计: {val}</div>
|
colSpan = 2
|
} else if (record.$disabled) {
|
children = <div className="content-wrap">{val}</div>
|
} else {
|
extra = <PlusOutlined onClick={this.plusLine}/>
|
|
if (editing) {
|
let options = localStorage.getItem(window.GLOB.sysSign + '_voucher_extract')
|
options = options ? JSON.parse(options) : []
|
|
children = <AutoComplete
|
dataSource={options.map((cell, i) => <AutoComplete.Option value={cell} key={i}>
|
{cell}
|
</AutoComplete.Option>)}
|
filterOption={(input, option) => option.props.children.indexOf(input) > -1}
|
onSelect={this.complete}
|
defaultValue={val}
|
onChange={(val) => this.onChange(val)}
|
defaultOpen={true}
|
>
|
<Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
|
</AutoComplete>
|
} else {
|
children = <div className="content-wrap" onClick={this.focus}>{val}</div>
|
}
|
}
|
} else if (col.field === 'subject_code') {
|
if (record.type === 'total') {
|
colSpan = 0
|
} else {
|
if (editing) {
|
let msg = window.GLOB.CacheVoucher.get(col.tableId)
|
let subjects = msg ? msg.subjects : []
|
|
children = <>
|
<Select
|
showSearch
|
defaultValue={record.subject_code || ''}
|
dropdownClassName="edit-table-dropdown"
|
id={col.uuid + record.uuid}
|
onBlur={this.onSelectBlur}
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
onSelect={this.onSelectChange}
|
>
|
{subjects.map((item, i) => (<Select.Option key={i} extra={item} value={item.subject_code}>{item.subject_code + ' ' + item.subject_name}</Select.Option>))}
|
</Select>
|
<Popover overlayClassName="subject-pop-wrap" placement="bottom" title="" visible={visible} content={<Accounting confirm={this.confirm} cancel={this.cancel} tableId={col.tableId} data={record}/>}>
|
<span className="pop-anchor"></span>
|
</Popover>
|
</>
|
} else {
|
let val = ''
|
if (record.subject_code) {
|
val = (record.subject_code || '') + ' ' + (record.subject_name || '')
|
|
if (record.sup_accounting && record.supAccounts) {
|
record.supAccounts.forEach(item => {
|
if (item.sup_acc_type === 'supplier') {
|
val += item.suppliercode ? '_' + item.suppliercode + ' ' + item.suppliername : ''
|
} else if (item.sup_acc_type === 'logistics') {
|
val += item.logistics_code ? '_' + item.logistics_code + ' ' + item.logistics_name : ''
|
} else if (item.sup_acc_type === 'lessor') {
|
val += item.lessor_code ? '_' + item.lessor_code + ' ' + item.lessor_name : ''
|
} else if (item.sup_acc_type === 'customer') {
|
val += item.customercode ? '_' + item.customercode + ' ' + item.customername : ''
|
} else if (item.sup_acc_type === 'department') {
|
val += item.co_pro_code ? '_' + item.co_pro_code + ' ' + item.co_pro_name : ''
|
} else if (item.sup_acc_type === 'project') {
|
val += item.projectcode ? '_' + item.projectcode + ' ' + item.projectname : ''
|
} else if (item.sup_acc_type === 'inventory') {
|
val += item.productcode ? '_' + item.productcode + ' ' + item.productname : ''
|
} else if (item.sup_acc_type === 'employee') {
|
val += item.workercode ? '_' + item.workercode + ' ' + item.workername : ''
|
} else if (item.sup_acc_type === 'cash_flow') {
|
val += item.cash_flow_code ? '_' + item.cash_flow_code + ' ' + item.cash_flow_name : ''
|
} else if (item.sup_acc_code) {
|
val += '_' + item.sup_acc_code + ' ' + item.sup_acc_name
|
}
|
})
|
}
|
}
|
|
let countNode = null
|
let currencyNode = null
|
|
if (record.count_type === 'Y') {
|
if (counting) {
|
countNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
|
<span>数量:</span>
|
<span><InputNumber precision={4} className="inner-input" id={col.uuid + record.uuid + 'count'} defaultValue={record.fcc_count || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.countPress} onBlur={this.countBlur}/></span>
|
</span>
|
<span onClick={this.editPrice}>
|
<span>单价:</span>
|
<span>{record.net_unitprice || 0}</span>
|
</span>
|
</div>
|
} else if (priceing) {
|
countNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={this.editCount}>
|
<span>数量:</span>
|
<span>{record.fcc_count || 0}</span>
|
</span>
|
<span onClick={(e) => e.stopPropagation()}>
|
<span>单价:</span>
|
<span><InputNumber precision={4} className="inner-input" id={col.uuid + record.uuid + 'price'} defaultValue={record.net_unitprice || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.pricePress} onBlur={this.priceBlur}/></span>
|
</span>
|
</div>
|
} else if (record.$disabled) {
|
countNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}}>
|
<span>数量:</span>
|
<span>{record.fcc_count || 0}</span>
|
</span>
|
<span>
|
<span>单价:</span>
|
<span>{record.net_unitprice || 0}</span>
|
</span>
|
</div>
|
} else {
|
countNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={this.editCount}>
|
<span>数量:</span>
|
<span>{record.fcc_count || 0}</span>
|
</span>
|
<span onClick={this.editPrice}>
|
<span>单价:</span>
|
<span>{record.net_unitprice || 0}</span>
|
</span>
|
</div>
|
}
|
}
|
|
if (record.foreign_currency_type === 'Y') {
|
if (curring) {
|
let msg = window.GLOB.CacheVoucher.get(col.tableId)
|
let currency = msg ? msg.currency : []
|
|
currencyNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
|
<span>货币:</span>
|
<span>
|
<Select
|
className="currency-select"
|
defaultValue={record.exratename || ''}
|
dropdownClassName="edit-table-dropdown"
|
id={col.uuid + record.uuid + 'currency'}
|
onBlur={() => this.setState({curring: false})}
|
onSelect={this.onCurrSelectChange}
|
>
|
{currency.map((item, i) => (<Select.Option key={i} extra={item} value={item.exratename}>{item.exratename}</Select.Option>))}
|
</Select>
|
</span>
|
</span>
|
<span style={{marginRight: '5px'}} onClick={this.editRatio}>
|
<span>汇率:</span>
|
<span>{record.unitratio || 1}</span>
|
</span>
|
<span onClick={this.editOrigin}>
|
<span>原币:</span>
|
<span>{record.foreign_amount || 0}</span>
|
</span>
|
</div>
|
} else if (ratioing) {
|
currencyNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={this.editCurrency}>
|
<span>货币:</span>
|
<span>{record.exratename || ''}</span>
|
</span>
|
<span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
|
<span>汇率:</span>
|
<span><InputNumber precision={5} className="inner-input" id={col.uuid + record.uuid + 'ratio'} defaultValue={record.unitratio || 1} onChange={(val) => this.onChange(val)} onPressEnter={this.ratioPress} onBlur={this.ratioBlur}/></span>
|
</span>
|
<span onClick={this.editOrigin}>
|
<span>原币:</span>
|
<span>{record.foreign_amount || 0}</span>
|
</span>
|
</div>
|
} else if (origining) {
|
currencyNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={this.editCurrency}>
|
<span>货币:</span>
|
<span>{record.exratename || ''}</span>
|
</span>
|
<span style={{marginRight: '5px'}} onClick={this.editRatio}>
|
<span>汇率:</span>
|
<span>{record.unitratio || 1}</span>
|
</span>
|
<span onClick={(e) => e.stopPropagation()}>
|
<span>原币:</span>
|
<span><InputNumber precision={2} className="inner-input" id={col.uuid + record.uuid + 'origin'} defaultValue={record.foreign_amount || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.originPress} onBlur={this.originBlur}/></span>
|
</span>
|
</div>
|
} else if (record.$disabled) {
|
currencyNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}}>
|
<span>货币:</span>
|
<span>{record.exratename || ''}</span>
|
</span>
|
<span style={{marginRight: '5px'}}>
|
<span>汇率:</span>
|
<span>{record.unitratio || 1}</span>
|
</span>
|
<span>
|
<span>原币:</span>
|
<span>{record.foreign_amount || 0}</span>
|
</span>
|
</div>
|
} else {
|
currencyNode = <div className="count-wrap">
|
<span style={{marginRight: '5px'}} onClick={this.editCurrency}>
|
<span>货币:</span>
|
<span>{record.exratename || ''}</span>
|
</span>
|
<span style={{marginRight: '5px'}} onClick={this.editRatio}>
|
<span>汇率:</span>
|
<span>{record.unitratio || 1}</span>
|
</span>
|
<span onClick={this.editOrigin}>
|
<span>原币:</span>
|
<span>{record.foreign_amount || 0}</span>
|
</span>
|
</div>
|
}
|
}
|
|
if (record.$disabled) {
|
children = <div className="content-wrap">
|
{val}
|
{countNode}
|
{currencyNode}
|
</div>
|
} else {
|
children = <div className="content-wrap" onClick={this.focus}>
|
{val}
|
{countNode}
|
{currencyNode}
|
</div>
|
}
|
}
|
}
|
} else if (col.field === 'debit') {
|
if (editing) {
|
children = <InputNumber id={col.uuid + record.uuid} precision={2} defaultValue={record.debit} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
|
} else {
|
let val = record.debit
|
let down = false
|
let vals = []
|
if (!isNaN(val) && val !== '') {
|
if (val < 0) {
|
down = true
|
val = Math.abs(val)
|
}
|
vals = (val * 100).toFixed(0).split('').reverse()
|
}
|
|
if (record.$disabled) {
|
children = <div className={'money-uint' + (down ? ' down' : '')}>
|
<span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
|
<span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
|
</div>
|
} else {
|
children = <div className={'money-uint' + (down ? ' down' : '')} onClick={this.focus}>
|
<span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
|
<span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
|
</div>
|
}
|
}
|
} else if (col.field === 'credit') {
|
if (record.type !== 'total' && !record.$disabled) {
|
extra = <CloseOutlined onClick={this.delVoucher}/>
|
}
|
|
if (editing) {
|
children = <InputNumber id={col.uuid + record.uuid} precision={2} defaultValue={record.credit} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
|
} else {
|
let val = record.credit
|
let down = false
|
let vals = []
|
if (!isNaN(val) && val !== '') {
|
if (val < 0) {
|
down = true
|
val = Math.abs(val)
|
}
|
vals = (val * 100).toFixed(0).split('').reverse()
|
}
|
|
if (record.$disabled) {
|
children = <div className={'money-uint' + (down ? ' down' : '')}>
|
<span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
|
<span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
|
</div>
|
} else {
|
children = <div className={'money-uint' + (down ? ' down' : '')} onClick={this.focus}>
|
<span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
|
<span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
|
</div>
|
}
|
}
|
}
|
|
if (!colSpan) return null
|
|
return (<td colSpan={colSpan} className={className}>{children}{extra}</td>)
|
}
|
}
|
|
class VoucherTable extends Component {
|
static propTpyes = {
|
config: PropTypes.object,
|
data: PropTypes.any,
|
loading: PropTypes.bool,
|
onChange: PropTypes.func
|
}
|
|
state = {
|
data: [],
|
edData: [],
|
tableId: '',
|
columns: null,
|
}
|
|
UNSAFE_componentWillMount () {
|
const { config, data } = this.props
|
|
let columns = [
|
{
|
title: '摘要',
|
dataIndex: 'subject_voucher_text',
|
key: 'subject_voucher_text',
|
width: '22%',
|
onCell: record => ({
|
record,
|
col: {uuid: 'subject_voucher_text', field: 'subject_voucher_text', tableId: config.uuid},
|
})
|
},
|
{
|
title: '会计科目',
|
dataIndex: 'subject_code',
|
key: 'subject_code',
|
width: '34%',
|
onCell: record => ({
|
record,
|
col: {uuid: 'subject_code', field: 'subject_code', tableId: config.uuid},
|
})
|
},
|
{
|
title: () => (<>
|
<div className="money-title">借方金额</div>
|
<div className="money-uint">
|
<span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
|
<span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
|
</div>
|
</>),
|
dataIndex: 'debit',
|
key: 'debit',
|
width: '22%',
|
onCell: record => ({
|
record,
|
col: {uuid: 'debit', field: 'debit', tableId: config.uuid},
|
})
|
},
|
{
|
title: () => (<>
|
<div className="money-title">贷方金额</div>
|
<div className="money-uint">
|
<span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
|
<span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
|
</div>
|
</>),
|
dataIndex: 'credit',
|
key: 'credit',
|
width: '22%',
|
onCell: record => ({
|
record,
|
col: {uuid: 'credit', field: 'credit', tableId: config.uuid},
|
})
|
}
|
]
|
|
this.setState({
|
edData: this.resetData(fromJS(data).toJS()),
|
columns,
|
tableId: config.uuid
|
})
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
componentDidMount () {
|
MKEmitter.addListener('plusLine', this.plusLine)
|
MKEmitter.addListener('delVoucher', this.delVoucher)
|
MKEmitter.addListener('cleartable', this.cleartable)
|
MKEmitter.addListener('nextVoucher', this.nextVoucher)
|
MKEmitter.addListener('changeRecord', this.changeRecord)
|
}
|
|
/**
|
* @description 组件销毁,清除state更新
|
*/
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
MKEmitter.removeListener('plusLine', this.plusLine)
|
MKEmitter.removeListener('delVoucher', this.delVoucher)
|
MKEmitter.removeListener('cleartable', this.cleartable)
|
MKEmitter.removeListener('nextVoucher', this.nextVoucher)
|
MKEmitter.removeListener('changeRecord', this.changeRecord)
|
}
|
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
|
this.resetData(fromJS(nextProps.data).toJS())
|
}
|
}
|
|
cleartable = (tbid) => {
|
const { tableId } = this.state
|
|
if (tbid !== tableId) return
|
|
this.resetData([])
|
}
|
|
resetData = (data) => {
|
data = this.initData(data)
|
data.push(this.getTotalLine(data))
|
|
this.setState({
|
edData: []
|
}, () => {
|
this.setState({
|
edData: data
|
})
|
})
|
}
|
|
initData = (data) => {
|
let _data = data.map((item, i) => {
|
// item.uuid = Utils.getguid()
|
item.index = i
|
|
return item
|
})
|
|
let disabled = _data[0] && _data[0].$disabled ? true : false
|
|
if (_data.length < 4) {
|
for (let i = _data.length - 1; i < 4; i++) {
|
_data.push({uuid: Utils.getguid(), $disabled: disabled, index: i + 1, subject_voucher_text: '', subject_code: '', subject_name: '', debit: '', credit: ''})
|
}
|
}
|
return _data
|
}
|
|
getTotalLine = (data) => {
|
let totalLine = {uuid: Utils.getguid(), type: 'total'}
|
let debit = ''
|
let credit = ''
|
|
data.forEach(item => {
|
if (!isNaN(item.debit) && item.debit !== '') {
|
if (debit === '') {
|
debit = 0
|
}
|
|
debit += item.debit
|
} else if (!isNaN(item.credit) && item.credit !== '') {
|
if (debit === '') {
|
debit = 0
|
}
|
if (credit === '') {
|
credit = 0
|
}
|
credit += item.credit
|
}
|
})
|
|
let _total = debit
|
if (debit === 0) {
|
debit = ''
|
}
|
|
if (_total === '' && credit !== '') {
|
_total = 0
|
}
|
|
if (credit === 0) {
|
credit = ''
|
}
|
|
totalLine.debit = debit
|
totalLine.credit = credit
|
|
totalLine.subject_voucher_text = this.changeMoneyToChinese(_total)
|
|
return totalLine
|
}
|
|
changeMoneyToChinese = (money) => {
|
let cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
|
let cnIntRadice = ['', '拾', '佰', '仟']
|
let cnIntUnits = ['', '万', '亿', '兆']
|
let cnDecUnits = ['角', '分', '毫', '厘']
|
let cnInteger = '整'
|
let cnIntLast = '元'
|
let maxNum = 999999999999999.9999 // 最大处理的数字
|
let IntegerNum = null
|
let DecimalNum = null
|
let ChineseStr = ''
|
let parts = null // 分离金额后用的数组,预定义
|
let Symbol = '' // 正负值标记
|
|
if (money === '') return ''
|
|
if (money >= maxNum) return '超出最大处理数字'
|
|
if (money === 0) {
|
ChineseStr = cnNums[0] + cnIntLast + cnInteger;
|
return ChineseStr
|
}
|
if(money < 0) {
|
money = -money
|
Symbol = '负'
|
}
|
money = money.toString() // 转换为字符串
|
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) {
|
ChineseStr += cnIntUnits[q]
|
}
|
}
|
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
|
}
|
|
ChineseStr = Symbol + ChineseStr
|
|
return ChineseStr
|
}
|
|
nextVoucher = (col, record) => {
|
const { edData, tableId } = this.state
|
|
if (col.tableId !== tableId) return
|
|
if (record.index < edData.length - 2) {
|
MKEmitter.emit('tdFocus', 'subject_voucher_text' + edData[record.index + 1].uuid)
|
} else {
|
let _data = fromJS(edData).toJS()
|
let line = {uuid: Utils.getguid(), index: _data.length - 1, subject_voucher_text: record.subject_voucher_text || '', subject_code: '', subject_name: '', debit: '', credit: ''}
|
|
_data.splice(_data.length - 1, 0, line)
|
|
this.setState({edData: _data}, () => {
|
MKEmitter.emit('tdFocus', 'subject_voucher_text' + line.uuid)
|
})
|
this.props.onChange(_data)
|
}
|
}
|
|
plusLine = (tid, record) => {
|
const { edData, tableId } = this.state
|
|
if (tid !== tableId) return
|
|
let _data = fromJS(edData).toJS()
|
let line = {uuid: Utils.getguid(), index: 0, subject_voucher_text: '', subject_code: '', subject_name: '', debit: '', credit: ''}
|
|
_data.splice(record.index, 0, line)
|
_data = _data.map((item, index) => {
|
item.index = index
|
return item
|
})
|
|
this.setState({edData: _data})
|
this.props.onChange(_data)
|
}
|
|
delVoucher = (id, record) => {
|
const { tableId, edData } = this.state
|
|
if (id !== tableId) return
|
|
let _data = fromJS(edData).toJS().filter(item => item.uuid !== record.uuid)
|
|
_data.pop()
|
|
if (_data.length < 4) {
|
for (let i = _data.length; i < 4; i++) {
|
_data.push({uuid: Utils.getguid(), index: 0, subject_voucher_text: '', subject_code: '', subject_name: '', debit: '', credit: ''})
|
}
|
}
|
|
_data = _data.map((item, index) => {
|
item.index = index
|
return item
|
})
|
|
_data.push(this.getTotalLine(_data))
|
|
this.setState({edData: _data})
|
this.props.onChange(_data)
|
}
|
|
changeRecord = (tableId, record) => {
|
if (tableId !== this.state.tableId) return
|
|
let _data = this.state.edData.map(item => {
|
if (item.uuid === record.uuid) {
|
return record
|
} else {
|
return item
|
}
|
})
|
|
_data.pop()
|
|
if (record.index === _data.length - 1) {
|
_data.push({uuid: Utils.getguid(), index: record.index + 1, subject_voucher_text: '', subject_code: '', subject_name: '', debit: '', credit: ''})
|
}
|
|
_data.push(this.getTotalLine(_data))
|
|
this.setState({edData: _data})
|
this.props.onChange(_data)
|
}
|
|
render() {
|
const { edData, columns} = this.state
|
|
const components = {
|
body: {
|
row: BodyRow,
|
cell: BodyCell
|
}
|
}
|
|
return (
|
<div className="voucher-table-wrap">
|
<Table
|
rowKey="uuid"
|
components={components}
|
columns={columns}
|
dataSource={edData}
|
bordered={true}
|
loading={this.props.loading}
|
onRow={(record, index) => {
|
return {
|
data: record
|
}
|
}}
|
pagination={false}
|
/>
|
</div>
|
)
|
}
|
}
|
|
export default VoucherTable
|