import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Select, Form, Input, Button, Modal, Spin, notification } from 'antd'
|
import { EllipsisOutlined, LeftOutlined } from '@ant-design/icons'
|
import moment from 'moment'
|
import md5 from 'md5'
|
|
import Api from '@/api'
|
import UtilsDM from '@/utils/utils-datamanage.js'
|
import Utils from '@/utils/utils.js'
|
import MKEmitter from '@/utils/events.js'
|
import InvoiceTable from './invoiceTable'
|
import SubTable from './subTable'
|
import './index.scss'
|
|
const { confirm } = Modal
|
|
class InvoiceModule extends Component {
|
static propTpyes = {
|
config: PropTypes.object
|
}
|
|
state = {
|
BID: '',
|
ID: Utils.getguid(),
|
io: '',
|
invTypes: [],
|
invoice_type: '',
|
business_type: '',
|
date: moment().format('YYYY年MM月DD日'),
|
from_to_name: '',
|
from_to_tax_no: '',
|
from_to_addr: '',
|
from_to_tel: '',
|
from_to_bank_name: '',
|
from_to_account_no: '',
|
from_to_mob: '',
|
from_to_email: '',
|
from_to_code: '',
|
orgname: '',
|
tax_no: '',
|
addr: '',
|
tel: '',
|
bank_name: '',
|
account_no: '',
|
remark: '',
|
payee: '',
|
reviewer: '',
|
drawer: '',
|
details: [],
|
oriDetails: [],
|
book: null,
|
loading: false,
|
saveType: '',
|
tax_type: '',
|
reqfields: [],
|
requireds: [],
|
timestamp: new Date().getTime() + ''
|
}
|
|
UNSAFE_componentWillMount () {
|
const { config } = this.props
|
|
let _config = fromJS(config).toJS()
|
let BID = ''
|
let BData = ''
|
|
if (_config.setting.supModule) {
|
BData = window.GLOB.CacheData.get(_config.setting.supModule)
|
} else {
|
BData = window.GLOB.CacheData.get(_config.$pageId)
|
}
|
if (BData) {
|
BID = BData.$BID || ''
|
}
|
|
if (_config.wrap.invColor) {
|
_config.style['--inv-color'] = _config.wrap.invColor
|
}
|
|
_config.buyer = this.formatSetting(_config.buyer, 'buyer')
|
_config.detail = this.formatSetting(_config.detail, 'detail')
|
|
let book = null
|
let pas = {}
|
if (config.wrap.supBook) {
|
book = window.GLOB.CacheData.get(config.wrap.supBook) || null
|
|
if (book) {
|
pas = this.resetParam(book)
|
}
|
}
|
|
this.setState({
|
BID: BID || '',
|
config: _config,
|
book,
|
...pas
|
})
|
}
|
|
componentDidMount () {
|
const { config } = this.props
|
|
MKEmitter.addListener('reloadData', this.reloadData)
|
MKEmitter.addListener('resetSelectLine', this.resetParentParam)
|
|
if (config.wrap.datatype === 'dynamic' && config.setting.onload === 'true') {
|
setTimeout(() => {
|
this.loadData()
|
}, config.setting.delay || 0)
|
}
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
/**
|
* @description 组件销毁,清除state更新,清除快捷键设置
|
*/
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
MKEmitter.removeListener('reloadData', this.reloadData)
|
MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
|
}
|
|
formatSetting = (item, type) => {
|
item.setting.arr_field = item.columns.map(col => col.field).join(',')
|
item.setting.laypage = item.setting.laypage === 'true'
|
|
if (item.refreshTab && item.refreshTab.length) {
|
item.reTabId = item.refreshTab.pop()
|
}
|
if (item.syncComponent && item.syncComponent.length) {
|
item.syncComId = item.syncComponent.pop()
|
}
|
|
if (type === 'buyer') {
|
item.columns = item.columns.map(cell => {
|
if (['from_to_tel', 'from_to_account_no', 'from_to_code'].includes(cell.field)) {
|
cell.Hide = 'true'
|
} else if (['from_to_email', 'from_to_mob'].includes(cell.field)) {
|
cell.Width = 80
|
}
|
return cell
|
})
|
} else {
|
item.columns = item.columns.map(cell => {
|
if (cell.field === 'general_tax_rate') {
|
cell.field = 'tax_rate'
|
cell.label = '税率'
|
}
|
if (['Description', 'id', 'small_tax_rate', 'free_tax_mark', 'vat_special_management'].includes(cell.field)) {
|
cell.Hide = 'true'
|
} else if (['spec'].includes(cell.field)) {
|
cell.Width = 150
|
} else if (['unit', 'unitprice', 'tax_rate'].includes(cell.field)) {
|
cell.Width = 80
|
}
|
|
return cell
|
})
|
}
|
|
if (item.setting.interType !== 'system') {
|
item.setting.dataresource = ''
|
return item
|
}
|
|
let regs = [
|
{ reg: /@userName@/ig, value: `'${sessionStorage.getItem('User_Name') || ''}'` },
|
{ reg: /@fullName@/ig, value: `'${sessionStorage.getItem('Full_Name') || ''}'` }
|
]
|
|
if (window.GLOB.externalDatabase !== null) {
|
regs.push({
|
reg: /@db@/ig,
|
value: window.GLOB.externalDatabase
|
})
|
}
|
|
let _customScript = ''
|
let _tailScript = ''
|
item.scripts && item.scripts.forEach(script => {
|
if (script.status === 'false') return
|
if (script.position !== 'back') {
|
_customScript += `
|
${script.sql}
|
`
|
} else {
|
_tailScript += `
|
${script.sql}
|
`
|
}
|
})
|
delete item.scripts
|
|
item.setting.execute = item.setting.execute !== 'false'
|
|
if (!item.setting.execute) {
|
item.setting.dataresource = ''
|
}
|
if (/\s/.test(item.setting.dataresource)) {
|
item.setting.dataresource = '(' + item.setting.dataresource + ') tb'
|
}
|
|
if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
|
item.setting.dataresource = item.setting.dataresource.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
|
_customScript = _customScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
|
_tailScript = _tailScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
|
} else {
|
item.setting.dataresource = item.setting.dataresource.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
|
_customScript = _customScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
|
_tailScript = _tailScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
|
}
|
|
regs.forEach(cell => {
|
item.setting.dataresource = item.setting.dataresource.replace(cell.reg, cell.value)
|
_customScript = _customScript.replace(cell.reg, cell.value)
|
_tailScript = _tailScript.replace(cell.reg, cell.value)
|
})
|
|
item.setting.customScript = _customScript // 整理后自定义脚本
|
item.setting.tailScript = _tailScript // 后置自定义脚本
|
|
item.setting.custompage = /@pageSize@|@orderBy@/i.test(item.setting.dataresource + item.setting.customScript)
|
|
return item
|
}
|
|
resetParentParam = (MenuID, id, data) => {
|
const { config } = this.state
|
|
if (config.wrap.supBook === MenuID) {
|
let pas = this.resetParam(data)
|
|
this.setState({ book: data, ...pas }, () => {
|
this.loadData()
|
})
|
return
|
}
|
|
if (!config.wrap.supModule || config.wrap.supModule !== MenuID) return
|
if (id !== this.state.BID || id !== '') {
|
this.setState({ BID: id }, () => {
|
this.loadData()
|
})
|
}
|
}
|
|
resetParam = (book) => {
|
let invTypes = book.invoice_type || []
|
let invoice_type = sessionStorage.getItem('pre_invoice_type') || ''
|
if (invoice_type && invTypes.findIndex(item => item.value === invoice_type) === -1) {
|
invoice_type = ''
|
}
|
|
this.getRequired(invoice_type)
|
|
return {
|
invoice_type,
|
invTypes: invTypes,
|
orgname: book.orgname || '',
|
tax_no: book.tax_no || '',
|
addr: book.addr || '',
|
tel: book.tel || '',
|
bank_name: book.bank_name || '',
|
account_no: book.account_no || '',
|
payee: book.payee || '',
|
reviewer: book.reviewer || '',
|
drawer: book.drawer || '',
|
tax_type: book.tax_type || ''
|
}
|
}
|
|
reloadData = (menuId) => {
|
const { config } = this.state
|
|
if (config.uuid !== menuId) return
|
|
this.loadData()
|
}
|
|
async loadData() {
|
const { config, BID, book } = this.state
|
|
if (config.wrap.datatype !== 'dynamic' || !book) return
|
if (!BID) {
|
this.clearData()
|
return
|
}
|
|
let param = UtilsDM.getQueryDataParams(config.setting, [], config.setting.order, 1, 1, BID)
|
|
this.setState({
|
loading: true
|
})
|
|
let result = await Api.genericInterface(param)
|
if (result.status) {
|
if (!result.data[0]) {
|
this.clearData()
|
this.setState({
|
loading: false
|
})
|
return
|
}
|
|
let line = result.data[0]
|
let details = result.data.map(item => {
|
let tax_name = item.tax_rate * 100 + '%'
|
|
if (item.vat_special_management && item.free_tax_mark === 'true') {
|
tax_name = item.vat_special_management
|
}
|
|
return {
|
uuid: item.jskey,
|
productname: item.productname,
|
productcode: item.productcode,
|
spec: item.spec,
|
unit: item.unit,
|
bill_count: item.bill_count,
|
unitprice: item.unitprice,
|
tax_rate: item.tax_rate,
|
free_tax_mark: item.free_tax_mark,
|
vat_special_management: item.vat_special_management,
|
tax_classify_code: item.tax_classify_code,
|
tax_classify_name: item.tax_classify_name,
|
amount_line: item.amount_line,
|
tax_amount: item.tax_amount,
|
invoice_lp: item.invoice_lp,
|
tax_item: item.tax_item,
|
tax_method: item.tax_method,
|
tax_name: tax_name
|
}
|
})
|
|
this.setState({
|
ID: line[config.setting.primaryKey] || Utils.getguid(),
|
io: line.io,
|
invoice_type: line.invoice_type,
|
business_type: line.business_type,
|
from_to_name: line.from_to_name,
|
from_to_tax_no: line.from_to_tax_no,
|
from_to_addr: line.from_to_addr,
|
from_to_tel: line.from_to_tel,
|
from_to_bank_name: line.from_to_bank_name,
|
from_to_account_no: line.from_to_account_no,
|
from_to_mob: line.from_to_mob,
|
from_to_email: line.from_to_email,
|
from_to_code: line.from_to_code,
|
orgname: line.orgname,
|
tax_no: line.tax_no,
|
addr: line.addr,
|
tel: line.tel,
|
bank_name: line.bank_name,
|
account_no: line.account_no,
|
remark: line.remark,
|
payee: line.payee,
|
reviewer: line.reviewer,
|
drawer: line.drawer,
|
details: details,
|
oriDetails: fromJS(details).toJS(),
|
timestamp: new Date().getTime() + '',
|
loading: false
|
})
|
|
this.getRequired(line.invoice_type)
|
|
UtilsDM.querySuccess(result)
|
} else {
|
this.setState({
|
loading: false
|
})
|
this.timer && this.timer.stop()
|
|
UtilsDM.queryFail(result)
|
}
|
}
|
|
clearData = () => {
|
const { from_to_tax_no, oriDetails, details } = this.state
|
|
if (from_to_tax_no || oriDetails.length || details.length) {
|
this.setState({
|
from_to_name: '',
|
from_to_tax_no: '',
|
from_to_addr: '',
|
from_to_tel: '',
|
from_to_bank_name: '',
|
from_to_account_no: '',
|
from_to_mob: '',
|
from_to_email: '',
|
from_to_code: '',
|
business_type: '',
|
details: [],
|
oriDetails: [],
|
timestamp: new Date().getTime() + '',
|
})
|
}
|
}
|
|
changeType = (val) => {
|
sessionStorage.setItem('pre_invoice_type', val)
|
this.setState({invoice_type: val})
|
this.getRequired(val)
|
}
|
|
getRequired = (invoice_type) => {
|
if (!invoice_type) {
|
this.setState({
|
reqfields: [],
|
requireds: []
|
})
|
return
|
}
|
|
let reqfields = []
|
let requireds = []
|
let rds = [
|
{value: 'from_to_name', label: '购买方名称'},
|
{value: 'from_to_tax_no', label: '购买方纳税人识别号'},
|
{value: 'from_to_addr', label: '购买方地址'},
|
{value: 'from_to_tel', label: '购买方电话'},
|
{value: 'from_to_bank_name', label: '购买方开户行'},
|
{value: 'from_to_account_no', label: '购买方账号'},
|
{value: 'from_to_mob', label: '购买方手机号'},
|
{value: 'from_to_email', label: '购买方邮箱'},
|
|
{value: 'orgname', label: '销售方名称'},
|
{value: 'tax_no', label: '销售方纳税人识别号'},
|
{value: 'addr', label: '销售方地址'},
|
{value: 'tel', label: '销售方电话'},
|
{value: 'bank_name', label: '销售方开户行'},
|
{value: 'account_no', label: '销售方账号'},
|
]
|
if (invoice_type === 'e_general') {
|
reqfields = ['from_to_name', 'from_to_tax_no', 'orgname', 'tax_no']
|
rds.forEach(item => {
|
if (reqfields.includes(item.value)) {
|
requireds.push(item)
|
}
|
})
|
} else if (invoice_type === 'e_special') {
|
reqfields = ['from_to_name', 'from_to_tax_no', 'from_to_addr', 'from_to_tel', 'from_to_bank_name', 'from_to_account_no', 'orgname', 'tax_no', 'addr', 'tel', 'bank_name', 'account_no']
|
rds.forEach(item => {
|
if (reqfields.includes(item.value)) {
|
requireds.push(item)
|
}
|
})
|
}
|
|
this.setState({
|
reqfields,
|
requireds
|
})
|
}
|
|
saveBill = () => {
|
const { config, BID, saveType } = this.state
|
|
if (saveType) return
|
|
setTimeout(() => {
|
this.getBillMsg().then(() => {
|
let sql = this.getPreSql(config.billSaveBtn)
|
|
let param = {
|
func: 'sPC_TableData_InUpDe',
|
LText: sql,
|
exec_type: window.GLOB.execType || 'y',
|
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
|
BID: BID
|
}
|
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
param.LText = Utils.formatOptions(param.LText, param.exec_type)
|
|
this.setState({
|
saveType: 'bill'
|
})
|
|
Api.genericInterface(param).then(res => {
|
this.setState({
|
saveType: ''
|
})
|
if (res.status) {
|
const that = this
|
|
confirm({
|
title: '保存成功。',
|
okText: '继续填开',
|
cancelText: '关闭',
|
onOk() {
|
if (config.billSaveBtn.reTabId) {
|
MKEmitter.emit('reloadMenuView', config.billSaveBtn.reTabId, 'table')
|
}
|
if (config.billSaveBtn.syncComId) {
|
MKEmitter.emit('reloadData', config.billSaveBtn.syncComId)
|
}
|
that.clearData()
|
},
|
onCancel() {
|
if (config.billSaveBtn.reTabId) {
|
MKEmitter.emit('reloadMenuView', config.billSaveBtn.reTabId, 'table')
|
}
|
if (config.billSaveBtn.syncComId) {
|
MKEmitter.emit('reloadData', config.billSaveBtn.syncComId)
|
}
|
MKEmitter.emit('closeTabView', config.$pageId)
|
}
|
})
|
} else {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
}
|
})
|
}, (error) => {
|
notification.warning({
|
top: 92,
|
message: error,
|
duration: 5
|
})
|
})
|
}, 20)
|
}
|
|
outBill = () => {
|
const { config, BID, saveType } = this.state
|
|
if (window.GLOB.systemType === 'production' && !config.billOutBtn.proInterface) {
|
notification.warning({
|
top: 92,
|
message: '尚未设置正式系统接口地址!',
|
duration: 5
|
})
|
return
|
}
|
|
if (saveType) return
|
|
setTimeout(() => {
|
this.getBillMsg().then(() => {
|
let sql = this.getPreSql(config.billOutBtn)
|
|
let param = {
|
func: 'sPC_TableData_InUpDe',
|
LText: sql,
|
script_type: 'Y',
|
exec_type: window.GLOB.execType || 'y',
|
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
|
BID: BID
|
}
|
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
param.LText = Utils.formatOptions(param.LText, param.exec_type)
|
|
this.setState({
|
saveType: 'out'
|
})
|
|
Api.genericInterface(param).then(res => {
|
if (res.status) {
|
this.outPutBill(res)
|
} else {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
this.setState({
|
saveType: ''
|
})
|
}
|
})
|
}, (error) => {
|
notification.warning({
|
top: 92,
|
message: error,
|
duration: 5
|
})
|
return
|
})
|
})
|
}
|
|
goback = () => {
|
const { config } = this.state
|
MKEmitter.emit('closeTabView', config.$pageId)
|
}
|
|
getPreSql = (btn) => {
|
const { config, book, ID, BID, io, details, oriDetails, business_type, invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, from_to_code, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee } = this.state
|
|
let userName = sessionStorage.getItem('User_Name') || ''
|
let fullName = sessionStorage.getItem('Full_Name') || ''
|
let RoleID = sessionStorage.getItem('role_id') || ''
|
let departmentcode = sessionStorage.getItem('departmentcode') || ''
|
let organization = sessionStorage.getItem('organization') || ''
|
let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
|
let nation = sessionStorage.getItem('nation') || ''
|
let province = sessionStorage.getItem('province') || ''
|
let city = sessionStorage.getItem('city') || ''
|
let district = sessionStorage.getItem('district') || ''
|
let address = sessionStorage.getItem('address') || ''
|
let options = fromJS(oriDetails).toJS()
|
let price = 0
|
let tax = 0
|
|
let lines = []
|
details.forEach(line => {
|
if (!line.productcode) return
|
|
let _sql = `Select '${line.productcode}', '${line.productname}', '${line.spec}', '${line.unit}', ${line.bill_count}, ${line.unitprice}, ${line.amount_line}, '${line.tax_classify_code}', '${line.tax_classify_name}', ${line.tax_rate}, ${line.tax_amount}, '${line.free_tax_mark || ''}', '${line.vat_special_management || ''}', '${line.invoice_lp || ''}', '${line.tax_item}', '${line.tax_method}', '${line.uuid}'`
|
let data_type = 'add'
|
|
price += line.amount_line * 100
|
tax += line.tax_amount * 100
|
|
if (options.length) {
|
options = options.filter(option => {
|
if (option.uuid === line.uuid) {
|
data_type = 'upt'
|
return false
|
}
|
return true
|
})
|
}
|
|
lines.push(_sql + `, '${data_type}'`)
|
})
|
|
let _total = (price - tax) / 100
|
price = price / 100
|
tax = tax / 100
|
|
if (options.length) {
|
options.forEach(line => {
|
lines.push(`Select '${line.productcode}', '${line.productname}', '${line.spec}', '${line.unit}', ${line.bill_count}, ${line.unitprice}, ${line.amount_line}, '${line.tax_classify_code}', '${line.tax_classify_name}', ${line.tax_rate}, ${line.tax_amount}, '${line.free_tax_mark || ''}', '${line.vat_special_management || ''}', '${line.invoice_lp || ''}', '${line.tax_item}', '${line.tax_method}', '${line.uuid}', 'del'`)
|
})
|
}
|
|
lines = lines.join(' union all ')
|
|
let _script = ''
|
btn.scripts.forEach(item => {
|
if (item.status === 'false') return
|
_script += `
|
${item.sql}
|
`
|
})
|
|
let sql = `/* 系统字段 */
|
Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50)
|
|
Select @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @ErrorCode='', @retmsg='', @account_id='${book.account_id || ''}', @account_year_id='${book.account_year_id || ''}', @account_code='${book.account_code || ''}', @account_year_code='${book.account_year_code || ''}', @bid='${BID}'
|
|
/* 发票主表字段 */
|
Declare @invoice_type Nvarchar(50), @from_to_name Nvarchar(50), @from_to_tax_no Nvarchar(50), @from_to_addr Nvarchar(100), @from_to_tel Nvarchar(50), @from_to_bank_name Nvarchar(50), @from_to_account_no Nvarchar(50), @from_to_mob Nvarchar(50), @from_to_email Nvarchar(50), @from_to_code Nvarchar(50), @orgname Nvarchar(50), @tax_no Nvarchar(50), @addr Nvarchar(100), @tel Nvarchar(50), @bank_name Nvarchar(50), @account_no Nvarchar(50), @remark Nvarchar(512), @payee Nvarchar(50), @reviewer Nvarchar(50), @drawer Nvarchar(50), @io Nvarchar(50), @orgcode Nvarchar(50), @total_net_amount Decimal(18,2), @total_tax Decimal(18,2), @total_amount Decimal(18,2), @business_type Nvarchar(20)
|
|
Select @invoice_type='${invoice_type}', @from_to_name='${from_to_name}', @from_to_tax_no='${from_to_tax_no}', @from_to_addr='${from_to_addr}', @from_to_tel='${from_to_tel}', @from_to_bank_name='${from_to_bank_name}', @from_to_account_no='${from_to_account_no}', @from_to_mob='${from_to_mob}', @from_to_email='${from_to_email}', @from_to_code='${from_to_code}', @orgname='${orgname}', @tax_no='${tax_no}', @addr='${addr}', @tel='${tel}', @bank_name='${bank_name}', @account_no='${account_no}', @remark='${remark}', @payee='${payee}', @reviewer='${reviewer}', @drawer='${drawer}', @io='${io}', @orgcode='${book.orgcode || ''}', @total_net_amount=${_total}, @total_tax=${tax}, @total_amount=${price}, @business_type='${business_type || config.wrap.business_type || ''}'
|
|
/* 发票明细临时表 */
|
|
Declare @details_list table (productcode Nvarchar(50), productname Nvarchar(50), spec Nvarchar(50), unit Nvarchar(50), bill_count Decimal(18,10), unitprice Decimal(18,10), amount_line Decimal(18,2), tax_classify_code Nvarchar(50), tax_classify_name Nvarchar(50), tax_rate Decimal(18,2), tax_amount Decimal(18,2), free_tax_mark Nvarchar(50), vat_special_management Nvarchar(50), invoice_lp Nvarchar(50), tax_item Nvarchar(50), tax_method Nvarchar(50), jskey Nvarchar(50), data_type Nvarchar(50))
|
|
Insert into @details_list (productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount, free_tax_mark, vat_special_management, invoice_lp, tax_item, tax_method, jskey, data_type)
|
|
${lines}
|
|
/* 自定义脚本 */
|
${_script}
|
`
|
|
if (btn.type === 'billout') {
|
sql += `aaa: if @ErrorCode!=''
|
insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg, @UserID@`
|
} else {
|
sql += `aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
|
}
|
|
sql = sql.replace(/@ID@/ig, `'${ID}'`)
|
sql = sql.replace(/@BID@/ig, `'${BID}'`)
|
sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
|
sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
|
sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
|
sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
|
sql = sql.replace(/@typename@/ig, `'admin'`)
|
|
if (window.GLOB.externalDatabase !== null) {
|
sql = sql.replace(/@db@/ig, window.GLOB.externalDatabase)
|
}
|
|
if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
|
sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
|
} else {
|
sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
|
}
|
|
if (window.GLOB.debugger === true) {
|
console.info(sql.replace(/\n\s{6}/ig, '\n'))
|
}
|
|
return sql
|
}
|
|
getBillMsg = () => {
|
const { requireds, invoice_type, details, remark, from_to_addr, addr } = this.state
|
|
return new Promise((resolve, reject) => {
|
let error = ''
|
|
if (!invoice_type) {
|
error = '请选择发票类型!'
|
}
|
|
if (!error) {
|
requireds.forEach(item => {
|
if (!this.state[item.value] && !error) {
|
error = '请输入' + item.label + '!'
|
}
|
})
|
}
|
|
if (!error && remark.length > 512) {
|
error = '备注不可超过512个字符!'
|
}
|
if (!error && from_to_addr.length > 100) {
|
error = '购买方地址不可超过100个字符!'
|
}
|
if (!error && addr.length > 100) {
|
error = '销售方地址不可超过100个字符!'
|
}
|
|
if (!error) {
|
if (details.length === 0 || details.filter(line => !!line.productcode).length === 0) {
|
error = '请添加明细!'
|
} else {
|
details.forEach((line, index) => {
|
if (error) return
|
if (line.productcode) {
|
if (!line.bill_count) {
|
error = '明细第' + (index + 1) + '行,请输入数量!'
|
} else if (!line.unitprice) {
|
error = '明细第' + (index + 1) + '行,请输入单价!'
|
}
|
}
|
})
|
}
|
}
|
|
if (error) {
|
reject(error)
|
} else {
|
resolve()
|
}
|
})
|
}
|
|
outPutBill = (res) => {
|
const { config } = this.state
|
|
if (!res.data_invoice || !res.sellerName || !res.taxNo) {
|
notification.warning({
|
top: 92,
|
message: '缺少开票参数!',
|
duration: 5
|
})
|
this.setState({
|
saveType: ''
|
})
|
}
|
|
let param = {
|
data: res.data_invoice,
|
sellerName: res.sellerName,
|
taxNo: res.taxNo
|
}
|
|
let trans = {
|
e_general: '02',
|
e_special: '01'
|
}
|
|
param.data.invoiceTypeCode = trans[param.data.invoiceTypeCode] || ''
|
|
let url = ''
|
if (window.GLOB.systemType === 'production') {
|
url = config.billOutBtn.proInterface
|
} else {
|
url = config.billOutBtn.interface
|
}
|
|
let _params = {
|
url: url,
|
method: 'post',
|
headers: { 'Content-Type': 'application/json' },
|
data: param
|
}
|
|
Api.directRequest(_params).then(result => {
|
result.mk_api_key = res.mk_api_key || ''
|
this.callBackBill(result)
|
})
|
}
|
|
callBackBill = (result) => {
|
const { config, BID, ID } = this.state
|
|
let btn = config.billOutBtn
|
let lines = []
|
let pre = '@'
|
|
let getDefaultSql = (obj, tb, bid, level) => {
|
let keys = []
|
let vals = []
|
let subObjs = []
|
let id = Utils.getuuid()
|
let tbName = pre + tb
|
|
delete obj.$$key
|
|
Object.keys(obj).forEach(key => {
|
let val = obj[key]
|
if (val === null || val === undefined) return
|
if (typeof(val) === 'object') {
|
if (Array.isArray(val)) {
|
val.forEach(item => {
|
if (typeof(item) !== 'object' || Array.isArray(item)) return
|
if (Object.keys(item).length > 0) {
|
item.$$key = tb + '_' + key
|
subObjs.push(item)
|
}
|
})
|
} else if (Object.keys(val).length > 0) {
|
val.$$key = tb + '_' + key
|
subObjs.push(val)
|
}
|
} else {
|
if (typeof(val) === 'string') {
|
val = val.replace(/'/ig, '"')
|
}
|
keys.push('[' + key + ']')
|
vals.push(`'${val}'`)
|
}
|
})
|
|
keys = keys.join(',')
|
|
lines.push({
|
table: md5(tb + keys),
|
insert: `Insert into ${tbName} (${keys},[mk_level],[mk_id],[mk_bid])`,
|
select: `Select ${vals.join(',')},'${level}','${id}','${bid}'`
|
})
|
|
subObjs.forEach(item => {
|
getDefaultSql(item, item.$$key, id, level + 1)
|
})
|
}
|
|
getDefaultSql(result, btn.cbTable, '', 1)
|
|
let lineMap = new Map()
|
lines.forEach(line => {
|
if (lineMap.has(line.table)) {
|
let _line = lineMap.get(line.table)
|
_line.selects.push(line.select)
|
lineMap.set(line.table, _line)
|
} else {
|
lineMap.set(line.table, {
|
table: line.table,
|
insert: line.insert,
|
selects: [line.select]
|
})
|
}
|
})
|
|
let param = {
|
func: 'sPC_TableData_InUpDe',
|
BID: BID,
|
menuname: config.name + '(回调)'
|
}
|
|
let callbacksql = this.getBackSql()
|
let _prevCustomScript = `${callbacksql}
|
`
|
let _backCustomScript = ''
|
|
btn.cbScripts.forEach(script => {
|
if (script.status === 'false') return
|
|
if (script.position === 'front') {
|
_prevCustomScript += `
|
/* 自定义脚本 */
|
${script.sql}
|
`
|
} else {
|
_backCustomScript += `
|
/* 自定义脚本 */
|
${script.sql}
|
`
|
}
|
})
|
|
_backCustomScript += `
|
aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
|
|
let sql = [...lineMap.values()].map(item => (`
|
${item.insert}
|
${item.selects.join(` union all
|
`)}
|
`))
|
sql = sql.join('')
|
sql = _prevCustomScript + sql
|
sql = sql + _backCustomScript
|
|
sql = sql.replace(/@ID@/ig, `'${ID || ''}'`)
|
sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
|
sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
|
sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
|
sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
|
sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
|
sql = sql.replace(/@typename@/ig, `'admin'`)
|
|
if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
|
sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
|
} else {
|
sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
|
}
|
|
if (window.GLOB.debugger === true) {
|
console.info('%c' + config.name + '(回调)', 'color: blue')
|
console.info(sql.replace(/\n\s{8}/ig, '\n'))
|
}
|
|
param.LText = sql
|
param.exec_type = window.GLOB.execType || 'y' // 后台解码
|
param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
param.LText = Utils.formatOptions(param.LText, param.exec_type)
|
|
if (window.GLOB.probation) {
|
param.s_debug_type = 'Y'
|
}
|
|
Api.genericInterface(param).then(res => {
|
if (res.status) {
|
const that = this
|
|
confirm({
|
title: '保存成功。',
|
okText: '继续填开',
|
cancelText: '关闭',
|
onOk() {
|
if (config.billOutBtn.reTabId) {
|
MKEmitter.emit('reloadMenuView', config.billOutBtn.reTabId, 'table')
|
}
|
if (config.billOutBtn.syncComId) {
|
MKEmitter.emit('reloadData', config.billOutBtn.syncComId)
|
}
|
that.clearData()
|
},
|
onCancel() {
|
if (config.billOutBtn.reTabId) {
|
MKEmitter.emit('reloadMenuView', config.billOutBtn.reTabId, 'table')
|
}
|
if (config.billOutBtn.syncComId) {
|
MKEmitter.emit('reloadData', config.billOutBtn.syncComId)
|
}
|
MKEmitter.emit('closeTabView', config.$pageId)
|
}
|
})
|
} else {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
this.setState({
|
saveType: ''
|
})
|
}
|
})
|
}
|
|
getBackSql = () => {
|
const { book, BID } = this.state
|
|
let userName = sessionStorage.getItem('User_Name') || ''
|
let fullName = sessionStorage.getItem('Full_Name') || ''
|
let RoleID = sessionStorage.getItem('role_id') || ''
|
let departmentcode = sessionStorage.getItem('departmentcode') || ''
|
let organization = sessionStorage.getItem('organization') || ''
|
let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
|
let nation = sessionStorage.getItem('nation') || ''
|
let province = sessionStorage.getItem('province') || ''
|
let city = sessionStorage.getItem('city') || ''
|
let district = sessionStorage.getItem('district') || ''
|
let address = sessionStorage.getItem('address') || ''
|
|
let sql = `/* 系统字段 */
|
Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50)
|
|
Select @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @ErrorCode='', @retmsg='', @account_id='${book.account_id || ''}', @account_year_id='${book.account_year_id || ''}', @account_code='${book.account_code || ''}', @account_year_code='${book.account_year_code || ''}', @bid='${BID || ''}'
|
|
`
|
|
return sql
|
}
|
|
changeBuyer = (item) => {
|
this.setState({
|
visible: false,
|
from_to_name: item.from_to_name || '',
|
from_to_tax_no: item.from_to_tax_no || '',
|
from_to_addr: item.from_to_addr || '',
|
from_to_tel: item.from_to_tel || '',
|
from_to_bank_name: item.from_to_bank_name || '',
|
from_to_account_no: item.from_to_account_no || '',
|
from_to_mob: item.from_to_mob || '',
|
from_to_email: item.from_to_email || '',
|
from_to_code: item.from_to_code || '',
|
})
|
}
|
|
render() {
|
const { config, book, loading, invTypes, reqfields, saveType, date, timestamp, invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee, details, visible, tax_type } = this.state
|
|
if (!book || (config.wrap.datatype === 'dynamic' && !tax_no)) {
|
return <div className="menu-invoice-wrap" style={config.style}>
|
<div className="loading-mask">
|
<div className="ant-spin-blur"></div>
|
<Spin />
|
</div>
|
</div>
|
}
|
|
return (
|
<div className="menu-invoice-wrap" style={config.style}>
|
{loading ?
|
<div className="loading-mask">
|
<div className="ant-spin-blur"></div>
|
<Spin />
|
</div> : null
|
}
|
<div className="inv-action">
|
{config.wrap.backBtn === 'show' ? <Button className="mk-back" onClick={this.goback}><LeftOutlined />返回</Button> : null}
|
<Button className="mk-bill" loading={saveType === 'bill'} onClick={this.saveBill}>保存单据</Button>
|
<Button className="mk-submit" loading={saveType === 'out'} onClick={this.outBill}>提交开票</Button>
|
</div>
|
<div className="inv-header">
|
{invoice_type ? <Select value={invoice_type} onChange={this.changeType} dropdownClassName="inv-type-select">
|
{invTypes.map(item => (
|
<Select.Option key={item.value} value={item.value}>{item.label}</Select.Option>
|
))}
|
</Select> : <Select placeholder="请选择发票种类" onChange={this.changeType} dropdownClassName="inv-type-select">
|
{invTypes.map(item => (
|
<Select.Option key={item.value} value={item.value}>{item.label}</Select.Option>
|
))}
|
</Select>}
|
<div className="date">开票日期:{date}</div>
|
</div>
|
<div className="inv-body">
|
<div className="inv-main-content">
|
<div className="inv-buyer">
|
<div className="inv-label">购买方</div>
|
<div className="inv-content">
|
<Form.Item required={reqfields.includes('from_to_name')} label={<>名<span></span>称</>} extra={<EllipsisOutlined onClick={() => this.setState({visible: true})}/>}>
|
<Input placeholder="请输入购买方名称" allowClear value={from_to_name} autoComplete="off" onChange={(e) => this.setState({from_to_name: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('from_to_tax_no')} label="纳税人识别号">
|
<Input placeholder="请输入购买方纳税人识别号" allowClear value={from_to_tax_no} autoComplete="off" onChange={(e) => this.setState({from_to_tax_no: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('from_to_addr')} className="mutil-input" label={<>地<span></span>址<span></span>、<span></span>电<span></span>话</>}>
|
<Input placeholder="请输入购买方地址" allowClear value={from_to_addr} autoComplete="off" onChange={(e) => this.setState({from_to_addr: e.target.value})}/>
|
<Input placeholder="请输入购买方电话" allowClear value={from_to_tel} autoComplete="off" onChange={(e) => this.setState({from_to_tel: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('from_to_bank_name')} className="mutil-input" label="开户行及账号">
|
<Input placeholder="请输入购买方开户行" allowClear value={from_to_bank_name} autoComplete="off" onChange={(e) => this.setState({from_to_bank_name: e.target.value})}/>
|
<Input placeholder="请输入购买方账号" allowClear value={from_to_account_no} autoComplete="off" onChange={(e) => this.setState({from_to_account_no: e.target.value})}/>
|
</Form.Item>
|
</div>
|
</div>
|
<div className="inv-notice">
|
<div className="inv-label">通知到</div>
|
<div className="inv-content">
|
<Form.Item required={reqfields.includes('from_to_mob')} label={<>手<span></span>机<span></span>号</>}>
|
<Input placeholder="请输入购买方手机号" allowClear value={from_to_mob} autoComplete="off" onChange={(e) => this.setState({from_to_mob: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('from_to_email')} label={<>邮<span></span>箱</>}>
|
<Input placeholder="请输入购买方邮箱" allowClear value={from_to_email} autoComplete="off" onChange={(e) => this.setState({from_to_email: e.target.value})}/>
|
</Form.Item>
|
</div>
|
</div>
|
</div>
|
<div className="inv-details">
|
<InvoiceTable data={details} timestamp={timestamp} config={config.detail} tax_type={tax_type} onChange={(details) => this.setState({details})}/>
|
</div>
|
<div className="inv-main-content">
|
<div className="inv-buyer">
|
<div className="inv-label">销售方</div>
|
<div className="inv-content">
|
<Form.Item required={reqfields.includes('orgname')} label={<>名<span></span>称</>}>
|
<Input placeholder="请输入销售方名称" value={orgname} autoComplete="off" onChange={(e) => this.setState({orgname: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('tax_no')} label="纳税人识别号">
|
<Input placeholder="请输入销售方纳税人识别号" disabled value={tax_no} autoComplete="off"/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('addr')} className="mutil-input" label={<>地<span></span>址<span></span>、<span></span>电<span></span>话</>}>
|
<Input placeholder="请输入销售方地址" value={addr} autoComplete="off" onChange={(e) => this.setState({addr: e.target.value})}/>
|
<Input placeholder="请输入销售方电话" value={tel} autoComplete="off" onChange={(e) => this.setState({tel: e.target.value})}/>
|
</Form.Item>
|
<Form.Item required={reqfields.includes('bank_name')} className="mutil-input" label="开户行及账号">
|
<Input placeholder="请输入销售方开户行" value={bank_name} autoComplete="off" onChange={(e) => this.setState({bank_name: e.target.value})}/>
|
<Input placeholder="请输入销售方账号" value={account_no} autoComplete="off" onChange={(e) => this.setState({account_no: e.target.value})}/>
|
</Form.Item>
|
</div>
|
</div>
|
<div className="inv-notice">
|
<div className="inv-label">备注</div>
|
<div className="inv-content" style={{paddingTop: '30px'}}>
|
<Form.Item label="">
|
<Input.TextArea placeholder="请输入备注" autoSize={{ minRows: 4, maxRows: 4 }} value={remark} autoComplete="off" onChange={(e) => this.setState({remark: e.target.value})}/>
|
</Form.Item>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div className="inv-tail">
|
<Form.Item label="收款人">
|
<Input placeholder="收款人" value={payee} autoComplete="off" onChange={(e) => this.setState({payee: e.target.value})}/>
|
</Form.Item>
|
<Form.Item label="复核人">
|
<Input placeholder="复核人" value={reviewer} autoComplete="off" onChange={(e) => this.setState({reviewer: e.target.value})}/>
|
</Form.Item>
|
<Form.Item label="开票人">
|
<Input placeholder="开票人" value={drawer} autoComplete="off" onChange={(e) => this.setState({drawer: e.target.value})}/>
|
</Form.Item>
|
</div>
|
<Modal
|
title="客户信息"
|
visible={visible}
|
width="70vw"
|
maskClosable={false}
|
onCancel={() => { this.setState({ visible: false }) }}
|
footer={null}
|
>
|
<SubTable config={config.buyer} onChange={this.changeBuyer}/>
|
</Modal>
|
</div>
|
)
|
}
|
}
|
|
export default InvoiceModule
|