| | |
| | | }) |
| | | } |
| | | |
| | | onChange = (value, key) => { |
| | | onChange = (value, key, nextkey) => { |
| | | let line = {...this.props.line} |
| | | |
| | | if (['bill_count', 'unitprice', 'amount_line'].includes(key)) { |
| | | line[key] = value || 0 |
| | | if (isNaN(line[key])) { |
| | | line[key] = 0 |
| | | } |
| | | if (line[key]) { |
| | | if (key === 'bill_count') { |
| | | line[key] = Math.round(line[key] * 10000000000) / 10000000000 |
| | |
| | | line.bill_count = Math.round(line.amount_line / line.unitprice * 10000000000) / 10000000000 |
| | | } |
| | | } |
| | | } else if (key === 'amount_line') { |
| | | line.bill_count = 0 |
| | | } |
| | | |
| | | if (line.amount_line) { |
| | | line.tax_amount = line.amount_line - line.amount_line / (line.tax_rate + 1) |
| | | line.tax_amount = Math.round(line.tax_amount * 100) / 100 |
| | | } else { |
| | | line.tax_amount = 0 |
| | | } |
| | | } else { |
| | | line[key] = value |
| | |
| | | }) |
| | | |
| | | this.props.changeLine(line, key) |
| | | |
| | | if (nextkey) { |
| | | let node = document.getElementById(nextkey) |
| | | if (node) { |
| | | if (node.select) { |
| | | node.select() |
| | | } else if (node.focus) { |
| | | node.focus() |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | onSkip = (key) => { |
| | | let node = document.getElementById(key) |
| | | if (node) { |
| | | if (node.select) { |
| | | node.select() |
| | | } else if (node.focus) { |
| | | node.focus() |
| | | } |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { line, delLine, trigger } = this.props |
| | | const { line, delLine, trigger, field, pid } = this.props |
| | | const { bill_count, unitprice, amount_line } = this.state |
| | | |
| | | return <div className="mk-tr active"> |
| | |
| | | <div className="mk-input">{line.productname || ''}<EllipsisOutlined onClick={trigger}/></div> |
| | | </div> |
| | | <div className="mk-td"> |
| | | <Input defaultValue={line.spec || ''} onChange={(e) => this.onChange(e.target.value, 'spec')}/> |
| | | <Input defaultValue={line.spec || ''} autoFocus={field === 'spec'} onChange={(e) => this.onChange(e.target.value, 'spec')} onPressEnter={() => this.onSkip(pid + 'mk-invoice-unit')}/> |
| | | </div> |
| | | <div className="mk-td"> |
| | | <Input defaultValue={line.unit || ''} onChange={(e) => this.onChange(e.target.value, 'unit')}/> |
| | | <Input id={pid + 'mk-invoice-unit'} defaultValue={line.unit || ''} autoFocus={field === 'unit'} onChange={(e) => this.onChange(e.target.value, 'unit')} onPressEnter={() => this.onSkip(pid + 'mk-invoice-billcount')}/> |
| | | </div> |
| | | <div className="mk-td"> |
| | | <InputNumber value={bill_count} onChange={(val) => this.setState({bill_count: val})} onBlur={(e) => this.onChange(e.target.value, 'bill_count')}/> |
| | | <InputNumber id={pid + 'mk-invoice-billcount'} value={bill_count} autoFocus={field === 'bill_count'} formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/,*/g, '')} onChange={(val) => this.setState({bill_count: val})} onPressEnter={() => this.onChange(bill_count, 'bill_count', pid + 'mk-invoice-unitprice')} onBlur={() => this.onChange(bill_count, 'bill_count')}/> |
| | | </div> |
| | | <div className="mk-td"> |
| | | <InputNumber value={unitprice} onChange={(val) => this.setState({unitprice: val})} onBlur={(e) => this.onChange(e.target.value, 'unitprice')}/> |
| | | <InputNumber id={pid + 'mk-invoice-unitprice'} value={unitprice} autoFocus={field === 'unitprice'} formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/,*/g, '')} onChange={(val) => this.setState({unitprice: val})} onPressEnter={() => this.onChange(unitprice, 'unitprice', pid + 'mk-invoice-amount')} onBlur={() => this.onChange(unitprice, 'unitprice')}/> |
| | | </div> |
| | | <div className="mk-td"> |
| | | <InputNumber value={amount_line} onChange={(val) => this.setState({amount_line: val})} onBlur={(e) => this.onChange(e.target.value, 'amount_line')}/> |
| | | <InputNumber id={pid + 'mk-invoice-amount'} value={amount_line} autoFocus={field === 'amount_line'} formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/,*/g, '')} onChange={(val) => this.setState({amount_line: val})} onPressEnter={() => this.onChange(amount_line, 'amount_line')} onBlur={() => this.onChange(amount_line, 'amount_line')}/> |
| | | </div> |
| | | <div className="mk-td">{line.tax_name}</div> |
| | | <div className="mk-td mk-right">{line.tax_amount} <span className="del-line" onClick={() => delLine(line.uuid)}></span> </div> |
| | | <div className="mk-td mk-right">{line.tax_name}</div> |
| | | <div className="mk-td mk-right">{line.tax_amount.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')} <span className="del-line" onClick={(e) => delLine(line.uuid, e)}></span> </div> |
| | | </div> |
| | | } |
| | | } |
| | |
| | | class InvoiceTable extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, |
| | | timestamp: PropTypes.string, |
| | | data: PropTypes.any, |
| | | onChange: PropTypes.func |
| | | } |
| | |
| | | state = { |
| | | data: [], |
| | | editKey: '', |
| | | key: '', |
| | | total: {} |
| | | } |
| | | |
| | |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('resetDetails', this.resetDetails) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps(nextProps) { |
| | | if (this.props.timestamp !== nextProps.timestamp) { |
| | | let _data = fromJS(nextProps.data).toJS() |
| | | if (!_data.length) { |
| | | _data = [{uuid: Utils.getguid(), productname: '', spec: '', unit: '', bill_count: '', unitprice: 0, amount_line: 0, tax_rate: '', tax_name: '', tax_amount: 0}] |
| | | } |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.getTotal(_data) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | data.forEach(item => { |
| | | if (!item.productcode) return |
| | | |
| | | price += item.amount_line |
| | | tax += item.tax_amount |
| | | price += item.amount_line * 100 |
| | | tax += item.tax_amount * 100 |
| | | }) |
| | | |
| | | this.setState({total: {price, tax, sum: price + tax, sumName: this.changeMoneyToChinese(price + tax)}}) |
| | | price = price / 100 |
| | | tax = tax / 100 |
| | | |
| | | this.setState({total: {price, tax, sum: price, sumName: this.changeMoneyToChinese(price)}}) |
| | | } |
| | | |
| | | resetDetails = (data) => { |
| | |
| | | this.setState({data: [...data, line]}) |
| | | } |
| | | |
| | | delLine = () => { |
| | | const { editKey, data } = this.state |
| | | delLine = (uuid, e) => { |
| | | const { data } = this.state |
| | | |
| | | e.stopPropagation() |
| | | |
| | | if (data.length === 1) { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | return |
| | | } |
| | | |
| | | let _data = data.filter(item => item.uuid !== editKey) |
| | | let _data = data.filter(item => item.uuid !== uuid) |
| | | |
| | | this.setState({data: _data}, () => { |
| | | this.getTotal(_data) |
| | |
| | | this.props.onChange(_data) |
| | | } |
| | | |
| | | checkLine = (uuid) => { |
| | | this.setState({editKey: uuid}) |
| | | checkLine = (uuid, key, e) => { |
| | | e && e.stopPropagation() |
| | | this.setState({editKey: uuid, key: key || ''}, () => { |
| | | if (key === 'productname') { |
| | | this.setState({visible: true}) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | changeDetail = (prod) => { |
| | |
| | | item.spec = prod.spec |
| | | item.unit = prod.unit |
| | | item.unitprice = prod.unitprice |
| | | item.tax_rate = prod.tax_rate |
| | | item.tax_name = prod.tax_rate |
| | | item.tax_rate = prod.tax_rate || 0 |
| | | item.tax_name = prod.tax_rate * 100 + '%' |
| | | item.free_tax_mark = prod.free_tax_mark || '' |
| | | item.vat_special_management = prod.vat_special_management || '' |
| | | item.tax_item = prod.tax_item || '' |
| | | item.tax_method = prod.tax_method || '' |
| | | |
| | | if (prod.vat_special_management && prod.free_tax_mark === 'true') { |
| | | item.tax_name = prod.vat_special_management |
| | | } |
| | | |
| | | item.productcode = prod.productcode |
| | | item.Description = prod.Description |
| | |
| | | if (item.bill_count && item.unitprice) { |
| | | item.amount_line = Math.round(item.unitprice * item.bill_count * 100) / 100 |
| | | } |
| | | // item.tax_amount = prod.productname |
| | | if (item.amount_line) { |
| | | item.tax_amount = item.amount_line - item.amount_line / (item.tax_rate + 1) |
| | | item.tax_amount = Math.round(item.tax_amount * 100) / 100 |
| | | } else { |
| | | item.tax_amount = 0 |
| | | } |
| | | } |
| | | |
| | | return item |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { editKey, data, total, visible } = this.state |
| | | const { config, tax_type } = this.props |
| | | const { editKey, key, data, total, visible } = this.state |
| | | |
| | | return ( |
| | | <div className="detail-wrap"> |
| | |
| | | </div> |
| | | {data.map(item => { |
| | | if (editKey === item.uuid) { |
| | | return <DetailLine key={item.uuid} line={item} changeLine={this.changeLine} delLine={this.delLine} trigger={() => this.setState({visible: true})}/> |
| | | return <DetailLine key={item.uuid} pid={config.uuid} line={item} field={key} changeLine={this.changeLine} delLine={this.delLine} trigger={() => this.setState({visible: true})}/> |
| | | } |
| | | |
| | | return <div className="mk-tr" key={item.uuid} onClick={() => this.checkLine(item.uuid)}> |
| | | <div className="mk-td mk-left">{item.productname || '**'}</div> |
| | | <div className="mk-td mk-left">{item.spec || ''}</div> |
| | | <div className="mk-td mk-left">{item.unit || ''}</div> |
| | | <div className="mk-td mk-right">{item.bill_count || ''}</div> |
| | | <div className="mk-td mk-right">{item.unitprice || ''}</div> |
| | | <div className="mk-td mk-right">{item.amount_line || ''}</div> |
| | | <div className="mk-td mk-left" onClick={(e) => this.checkLine(item.uuid, item.productname ? '' : 'productname', e)}>{item.productname || ''}</div> |
| | | <div className="mk-td mk-left" onClick={(e) => this.checkLine(item.uuid, 'spec', e)}>{item.spec || ''}</div> |
| | | <div className="mk-td mk-left" onClick={(e) => this.checkLine(item.uuid, 'unit', e)}>{item.unit || ''}</div> |
| | | <div className="mk-td mk-right" onClick={(e) => this.checkLine(item.uuid, 'bill_count', e)}>{`${item.bill_count || ''}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | <div className="mk-td mk-right" onClick={(e) => this.checkLine(item.uuid, 'unitprice', e)}>{`${item.unitprice || ''}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | <div className="mk-td mk-right" onClick={(e) => this.checkLine(item.uuid, 'amount_line', e)}>{`${item.amount_line || ''}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | <div className="mk-td mk-right">{item.tax_name}</div> |
| | | <div className="mk-td mk-right">{item.tax_amount}</div> |
| | | <div className="mk-td mk-right">{item.tax_amount.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}<span className="del-line" onClick={(e) => this.delLine(item.uuid, e)}></span></div> |
| | | </div> |
| | | })} |
| | | <div className="mk-total"> |
| | |
| | | <div className="mk-td"></div> |
| | | <div className="mk-td"></div> |
| | | <div className="mk-td"></div> |
| | | <div className="mk-td">¥{total.price}</div> |
| | | <div className="mk-td">¥{`${total.price}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | <div className="mk-td"></div> |
| | | <div className="mk-td">¥{total.tax}</div> |
| | | <div className="mk-td">¥{`${total.tax}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | </div> |
| | | <div className="mk-upcase"> |
| | | <div className="mk-td">价税合计(大写)</div> |
| | | <div className="mk-td">{total.sumName}</div> |
| | | <div className="mk-td">(小写)¥{total.sum}</div> |
| | | <div className="mk-td">(小写)¥{`${total.sum}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div> |
| | | </div> |
| | | <Modal |
| | | title="商品信息" |
| | |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | footer={null} |
| | | > |
| | | <SubTable config={config} onChange={this.changeDetail}/> |
| | | <SubTable config={config} tax_type={tax_type} onChange={this.changeDetail}/> |
| | | </Modal> |
| | | </div> |
| | | ) |