Commit 53607081 by peii

分销申请

(cherry picked from commit d4f7fa46)
parent 277611d3
......@@ -33,6 +33,10 @@ import SettlementDetail from '../src/pages/settlement/detail';
import SettlementSaleDetail from '../src/pages/settlement/saleDetail';
import SettlementReject from '../src/pages/settlement/reject';
// 分销开票
import DistributeInvoice from '../src/pages/invoice/distribution';
import DistributeInvoiceApplyDetail from '../src/pages/invoice/distribution/detail';
const Router = createAppContainer(createStackNavigator({
LoginPage: { screen: LoginPage },
......@@ -61,6 +65,8 @@ const Router = createAppContainer(createStackNavigator({
SettlementReject: {screen: SettlementReject},
SettlementDetail: {screen: SettlementDetail},
SettlementSaleDetail: {screen: SettlementSaleDetail},
DistributeInvoice: {screen: DistributeInvoice},
DistributeInvoiceApplyDetail: {screen: DistributeInvoiceApplyDetail},
}, {
navigationOptions: {
gesturesEnabled: true
......
......@@ -64,9 +64,9 @@ class HomePage extends Component {
page: 'Settlement',
},
MOBILE_DISTRIBUTION_INVOICE_APPLICATION: {
icon: require('../../images/quick_order.png'),
icon: require('../../images/invoice_apply_icon.png'),
title: '分销-开票申请',
page: '',
page: 'DistributeInvoice',
},
MOBILE_DISTRIBUTION_SETTLEMENT_GATHER: {
icon: require('../../images/settle_gather.png'),
......@@ -74,7 +74,7 @@ class HomePage extends Component {
page: 'SettlementCollection',
},
MOBILE_DISTRIBUTION_INVOICE_GATHER: {
icon: require('../../images/quick_order.png'),
icon: require('../../images/invoice_list_icon.png'),
title: '分销-开票汇总',
page: '',
},
......
......@@ -34,4 +34,4 @@ font_family_semibold = 'PingFangSC-Semibold'
font_family_medium = 'PingFangSC-Medium'
font_family_regular = 'PingFangSC-Regular'
font_family_light = 'PingFangSC-Light'
header_height = 62px
header_height = 60px
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/collection.tsx
* @Author: peii
* @Date: 2021-12-27 10:14:31
* @LastEditTime: 2021-12-27 10:14:32
* @LastEditors: peii
* @Vision: 1.0
* @Description: 分销开票申请汇总
*/
@import '../../../../assets/styles/base.styl'
@import '../../../../assets/styles/variable.styl'
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/components/filter.tsx
* @Author: peii
* @Date: 2021-12-19 10:49:42
* @LastEditTime: 2021-12-31 15:49:49
* @LastEditors: peii
* @Vision: 1.0
* @Description: 过滤弹窗
*/
// @ts-nocheck
import React from 'react'
import { View, Text, TouchableOpacity, FlatList, Image, ScrollView } from 'react-native'
import { connect } from 'react-redux'
import * as R from 'ramda'
import { IFormField } from 'bonehouse'
import api from '../../../../services/api'
import { isNotBlank, g, getFormItem } from '../../../../utils/utils'
import { FieldType } from '../../../../enums'
import FilterModal from '../../../../components/modals/filter/filter'
import styles from './filter.styl'
type IProps = {
onClose?: Function
userInfo: any
sysProfiles: {
OBS_SHOW_ORG_FLAG: string
}
otherFilterItems: IFromField[]
}
type IState = {
action: number
data: { [key: string]: string }
formItems: IFormField[]
}
class Filter extends React.Component<IProps, IState> {
constructor(props) {
super(props)
this.onClose = this.onClose.bind(this)
this.setData = this.setData.bind(this)
this.resetHandler = this.resetHandler.bind(this)
this.filterHandler = this.filterHandler.bind(this)
}
state = {
isAutoOpen: true,
data: {
seller_code: this.props.userInfo.user_name,
},
filterItems: [
{
field: 'seller_code',
label: '销售员',
disabled: true,
type: FieldType.SELECT,
options: [
{
value: this.props.userInfo.user_name,
label: this.props.userInfo.person_name,
},
],
rules: [{ required: true, message: '请选择客户' }],
},
{
field: 'customer_code',
label: '客户',
type: FieldType.SELECT,
rules: [{ required: true, message: '请选择客户' }],
},
],
}
componentDidMount() {
this.setFieldItems()
setTimeout(() => {
this.getCustomers()
}, 0)
}
onClose() {
this.props.onClose && this.props.onClose()
}
/**
* @description: 输入
* @param {*} key 输入项
* @param {*} value 输入值
* @return {*}
*/
setData(key: string, value: any) {
const { data, isAutoOpen } = this.state
data[key] = value
this.setState({ data }, () => {
if (!isAutoOpen) return
const isAllParamSet = R.compose(
R.all(isNotBlank),
R.map(k => data[k]),
)(['org_code', 'seller_code', 'customer_code'])
if (!isAllParamSet) return
this.setState({ isAutoOpen: false })
this.filterHandler()
})
}
/**
* @description: 设置动态搜索项
* @param {*}
* @return {*}
*/
setFieldItems() {
let { filterItems, data } = this.state
const { userInfo, sysProfiles, otherFilterItems = [] } = this.props
const showOrg = sysProfiles.OBS_SHOW_ORG_FLAG !== 'N'
data.org_code = userInfo.department_code && R.take(3, userInfo.department_code)
filterItems = R.concat(filterItems)(otherFilterItems)
this.setState({ filterItems, data })
if (!showOrg) return
const item = {
field: 'org_code',
label: '组织',
type: FieldType.SELECT,
options: [],
rules: [{ required: true, message: '请选择组织' }],
}
filterItems = R.insert(1, item, filterItems)
this.getOrganizations()
this.setState({ filterItems, data })
}
/**
* @description: 请求组织信息
* @param {*}
* @return {*}
*/
async getOrganizations() {
const res = await api.getOrganizations()
if (res.error_code) return
const { filterItems } = this.state
const item = getFormItem(filterItems, 'org_code')
item.options = R.compose(
R.map(
R.applySpec({
value: R.compose(R.take(3), R.prop('org_code')),
label: R.prop('org_name'),
}),
),
R.pathOr([], ['data', 'organizations']),
)(res)
this.setState({ filterItems })
}
/**
* @description: 请求客户信息
* @param {*}
* @return {*}
*/
async getCustomers() {
const { data, filterItems } = this.state
const params = {
org_code: data.org_code,
seller_code: data.seller_code,
}
const res = await api.getCustomers(params)
if (res.error_code) return
const item = getFormItem(filterItems, 'customer_code')
item.options = R.compose(
R.map(
R.applySpec({
value: R.prop('customer_code'),
label: R.prop('customer_name'),
bill_to_sites: R.prop('bill_to_sites'),
}),
),
R.pathOr([], ['data', 'customers']),
)(res)
this.setState({ filterItems, customers: item.options })
}
/**
* @description: 重置搜索项
* @param {*}
* @return {*}
*/
resetHandler() {
const { userInfo } = this.props
this.setState(
{
data: {
seller_code: userInfo.user_name,
org_code: R.take(3, userInfo.department_code),
},
},
() => {},
)
}
/**
* @description: 搜索操作
* @param {*}
* @return {*}
*/
filterHandler() {
const { data, customers } = this.state
this.props.searchHandler && this.props.searchHandler(data, customers)
this.onClose()
}
render() {
const { filterItems, data } = this.state
const { visible } = this.props
return (
<FilterModal
style={g(styles, 'filter-modal')}
visible={visible}
data={data}
filterItems={filterItems}
onClose={this.onClose}
setData={this.setData}
resetHandler={this.resetHandler}
filterHandler={this.filterHandler}
/>
)
}
}
const mapStateToProps = state => ({
userInfo: state.login.userInfo,
sysProfiles: state.login.sysProfiles,
})
const mapDispatchToProps = dispatch => ({})
export default connect(mapStateToProps, mapDispatchToProps)(Filter)
@import '../../../../assets/styles/base.styl'
@import '../../../../assets/styles/variable.styl'
.list
flex 1
width 100%
padding-top 20px
&-inner
min-height 100%
.item
background-color #fff
margin-left 20px
margin-right 20px
padding 15px
margin-bottom 15px
&-line
@extend .row
justify-content space-between
align-items center
&-text
font-size 16px
line-height 22px
margin-bottom 6px
&-full
flex 1
&__status
font-size 16px
font-weight bold
color #000
&-left
width 70%
&-select-box
justify-content flex-end
width 80px
height @width
.text
&-red
color #f00
&-black
color #000
&-blue
color primary_color
&-gray
color #999
\ No newline at end of file
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/components/list.tsx
* @Author: peii
* @Date: 2021-12-19 10:44:15
* @LastEditTime: 2021-12-30 16:54:47
* @LastEditors: peii
* @Vision: 1.0
* @Description: 汇总列表
*/
// @ts-nocheck
import React, { Component } from 'react'
import { View, Text, TouchableOpacity, FlatList, RefreshControl } from 'react-native'
import * as R from 'ramda'
import { connect } from 'react-redux'
import { INavigation } from 'navigation'
import debounce from 'debounce'
import dayjs from 'dayjs'
import Empty from '../../../../components/empty'
import { Checkbox } from '../../../../components/checkbox/checkbox'
import { isNotBlank, isBlank, g } from '../../../../utils/utils'
import styles from './list.styl'
type IProps = {
data: any[]
navigation: INavigation
getData: Function
itemClickHandler: Function
checkedHandler: Function
isCollection: boolean
}
class DistributeInvoiceList extends Component<IProps> {
constructor(props) {
super(props)
this.renderItem = this.renderItem.bind(this)
this.itemPressHandler = this.itemPressHandler.bind(this)
this.onRefreshHandler = debounce(this.onRefreshHandler.bind(this), 200)
this.onEndReachedHandler = debounce(this.onEndReachedHandler.bind(this), 500)
}
state = {
refreshing: false,
checked: true,
}
refreshing = false
/**
* @description:
* @param {*} item
* @return {*}
*/
itemPressHandler(item) {
this.props.itemClickHandler && this.props.itemClickHandler(item)
}
/**
* @description: 映射状态
* @param {*} statusCode
* @return {*}
*/
mapStatus(statusCode) {
const { status = [] } = this.props
return R.compose(R.propOr('未知状态', 'value_name'), R.find(R.propEq('value_code', statusCode)))(status)
}
/**
* @description: 状态显示类
* @param {*}
* @return {*}
*/
mapStatusClass = R.cond([
[R.includes(R.__, ['ENTERED']), R.always('text-black')],
[R.includes(R.__, ['USER_REJECTED']), R.always('text-red')],
[R.includes(R.__, ['USER_CONFIRMED']), R.always('text-blue')],
[R.T, R.always('text-gray')],
])
/**
* @description: 下拉刷新
* @param {*}
* @return {*}
*/
async onRefreshHandler() {
if (this.state.refreshing) return
this.refreshing = true
this.setState({ refreshing: true })
await this.props.getData(null, true)
this.refreshing = false
this.setState({ refreshing: false })
}
async onEndReachedHandler() {
if (this.refreshing || isBlank(this.props.data)) return
this.refreshing = true
await this.props.getData(null, false, true)
this.refreshing = false
}
/**
* @description: 选择操作
* @param {*} checked
* @param {*} item
* @return {*}
*/
async checkedHandler(checked, order) {
order._checked = checked
this.props.checkedHandler && (await this.props.checkedHandler(checked, order))
this.setState({ checked })
}
countAndSum(order) {
const list = R.compose(R.filter(R.propEq('_checked', true)), R.propOr([], 'lines'))(order)
const count = R.compose(R.sum, R.pluck('quantity'))(list)
// const sum = R.compose(R.sum, R.map(R.converge(R.multiply, [R.prop('quantity'), R.prop('settlement_price')])))(list)
const sum = R.compose(R.sum, R.pluck('settlement_amount'))(list)
return { count, sum: sum.toFixed(2) }
}
/**
* @description: 结算单单项
* @param {*} param1
* @return {*}
*/
renderItem({ item, index }) {
const { isCollection } = this.props
// 开票汇总
if (isCollection) {
return this.renderCollectionItem.call(this, item, index)
}
// 分销开票申请单项
return (
<TouchableOpacity style={g(styles, 'item')} activeOpacity={0.8} onPress={() => this.itemPressHandler(item)}>
<View style={g(styles, 'item-line')}>
<Text style={g(styles, 'item-text')}>{item.settlement_number}</Text>
{/* <Text style={g(styles, ['item-text__rigth', 'item-text__status', this.mapStatusClass(item.header_status)])}>
{this.mapStatus(item.header_status)}
</Text> */}
</View>
<View style={g(styles, 'item-line')}>
<View style={g(styles, 'item-left')}>
<Text style={g(styles, 'item-text', 'item-left-text')}>结算总数量: {item.sum_quantity}</Text>
<Text style={g(styles, 'item-text', 'item-left-text')}>结算总金额: {item.sum_settlement_amount}</Text>
<Text style={g(styles, 'item-text')}>
结算日期: {item.settled_date && dayjs(item.settled_date).format('YYYY-MM-DD')}
</Text>
</View>
<View style={g(styles, 'item-select')}>
<Checkbox
style={g(styles, 'item-select-box')}
checked={item._checked}
indeterminate={item._indeterminate}
onChange={checked => this.checkedHandler(checked, item)}
/>
</View>
</View>
<View style={g(styles, 'item-line')}>
<Text style={g(styles, 'item-text', 'item-text-full')}>选择开票总数量: {item._quantity || 0}</Text>
</View>
<View style={g(styles, 'item-line')}>
<Text style={g(styles, 'item-text', 'item-text-full')}>选择开票总金额: {item._amount || '0.00'}</Text>
</View>
<View style={g(styles, 'item-line')}>
<Text style={g(styles, 'item-text', 'item-text-full')}>备注: {item.header_remark}</Text>
</View>
</TouchableOpacity>
)
}
/**
* @description: 开票汇总单项渲染
* @param {*} item
* @param {*} index
* @return {*}
*/
renderCollectionItem(item, index) {
return <View style={g(styles, 'item')}></View>
}
render() {
const { data = [] } = this.props
const { refreshing, checked } = this.state
return (
<View style={g(styles, 'list')}>
<FlatList
data={data}
renderItem={this.renderItem}
ListEmptyComponent={Empty}
style={g(styles, 'list-inner')}
keyExtractor={it => it.settlement_number}
refreshControl={<RefreshControl onRefresh={this.onRefreshHandler} refreshing={refreshing} />}
onEndReached={this.onEndReachedHandler}
extraData={checked}
></FlatList>
</View>
)
}
}
const mapStateToProps = state => ({
status: state.settlement.headerStatus,
})
export default connect(mapStateToProps)(DistributeInvoiceList)
@import '../../../assets/styles/base.styl'
@import '../../../assets/styles/variable.styl'
.body
background-color home_background_color
flex 1
.title-select__text
color title_text_color
font-size first_text_size
font-family font_family_regular
text-align right
.card-info
padding 15px
background-color #fff
&-line
@extend .row
@extend .center
&__text
font-size 16px
font-family font_family_regular
line-height 24px
&__key
width 120px
text-align right
padding-right 15px
.list
padding 15px
margin-bottom 30px
.item
@extend .row
padding 15px
background-color #fff
margin-bottom 15px
&-info
flex 1
&-line
@extend .row
justify-content space-between
&__text
width 50%
flex-wrap nowrap
&__text
font-size 14px
line-height 22px
&-select
&-box
width 80px
flex 1
justify-content flex-end
align-items center
\ No newline at end of file
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/detail.tsx
* @Author: peii
* @Date: 2021-12-29 11:26:53
* @LastEditTime: 2021-12-30 15:42:53
* @LastEditors: peii
* @Vision: 1.0
* @Description: 开票申请详情
*/
// @ts-nocheck
import React, { Component } from 'react'
import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native'
import { connect } from 'react-redux'
import * as R from 'ramda'
import { INavigation } from 'navigation'
import debounce from 'debounce'
import dayjs from 'dayjs'
import Header from '../../../components/header/header'
import Resolution from '../../../components/common/Resolution'
import { Checkbox } from '../../../components/checkbox/checkbox'
import { isBlank, g, isNotBlank } from '../../../utils/utils'
import api from '../../../services/api'
import styles from './detail.styl'
type IProps = {
navigation: INavigation
}
type IState = {}
class InvoiceApplyDetail extends Component<IProps> {
constructor(props) {
super(props)
this.renderItem = this.renderItem.bind(this)
this.checkedHandler = this.checkedHandler.bind(this)
this.selectAllHandler = this.selectAllHandler.bind(this)
this.countAndSum = this.countAndSum.bind(this)
}
state = {
order: {},
}
componentDidMount() {
const order = this.props.navigation.getParam('order')
this.setState({ order })
}
/**
* @description:
* @param {*} checked
* @param {*} item
* @return {*}
*/
checkedHandler(checked, item) {
const { order } = this.state
item._checked = checked
const checkLen = R.compose(R.length, R.filter(R.propEq('_checked', true)))(order.lines)
if (checkLen === 0) {
order._checked = false
order._indeterminate = false
} else if (checkLen < R.length(order.lines)) {
order._checked = false
order._indeterminate = true
} else {
order._checked = true
order._indeterminate = false
}
this.setState({ order }, () => {
this.countAndSum()
})
}
/**
* @description: 全选操作
* @param {*}
* @return {*}
*/
selectAllHandler() {
const { order } = this.state
if (order._checked) {
order._checked = false
order._indeterminate = false
R.map(item => {
item._checked = false
})(order.lines || [])
} else {
order._checked = true
order._indeterminate = false
R.map(item => {
item._checked = true
})(order.lines || [])
}
this.setState({ order }, () => {
this.countAndSum()
})
}
/**
* @description: 计算总数
* @param {*}
* @return {*}
*/
countAndSum() {
const { order } = this.state
const list = R.compose(R.filter(R.propEq('_checked', true)))(order.lines || [])
order._quantity = R.compose(R.sum, R.pluck('quantity'))(list)
order._amount = R.compose(R.sum, R.pluck('settlement_amount'))(list).toFixed(2)
this.setState({ order })
}
/**
* @description: 单项渲染
* @param {*} param1
* @return {*}
*/
renderItem({ item, index }) {
return (
<View style={g(styles, 'item')}>
<View style={g(styles, 'item-info')}>
<Text style={g(styles, 'item-info__text')}>销售单号: {item.order_number}</Text>
<Text style={g(styles, 'item-info__text')}>出库单号: {item.source_header_number}</Text>
<Text style={g(styles, 'item-info__text')}>物料名称: {item.customer_item_name}</Text>
<Text style={g(styles, 'item-info__text')}>通用名称: {item.customer_general_name}</Text>
<Text style={g(styles, 'item-info__text')}>规格型号: {item.customer_specification}</Text>
<Text style={g(styles, 'item-info__text')}>存储条件: {item.storage_condition_name}</Text>
<Text style={g(styles, 'item-info__text')}>注册证号: {item.reg_number}</Text>
<View style={g(styles, 'item-info-line')}>
<Text style={g(styles, 'item-info__text', 'item-info-line__text')}>
批号: {item.production_batch_number}
</Text>
<Text style={g(styles, 'item-info__text', 'item-info-line__text')}>
序号: {item.production_serial_number}
</Text>
</View>
<View style={g(styles, 'item-info-line')}>
<Text style={g(styles, 'item-info__text', 'item-info-line__text')}>数量: {item.quantity}</Text>
<Text style={g(styles, 'item-info__text', 'item-info-line__text')}>金额: {item.settlement_amount}</Text>
</View>
</View>
<View style={g(styles, 'item-select')}>
<Checkbox
checked={item._checked}
onChange={checked => this.checkedHandler(checked, item)}
style={g(styles, 'item-select-box')}
/>
</View>
</View>
)
}
render() {
const title = this.props.navigation.getParam('title')
const { order } = this.state
return (
<View style={g(styles, 'container')}>
<Resolution.FixWidthView>
<Header
title={title}
backCallback={() => {
this.props.navigation.goBack()
this.props.navigation.state.params.refreshHandler()
}}
>
<TouchableOpacity style={g(styles, 'title-select')} activeOpacity={0.8} onPress={this.selectAllHandler}>
<Text style={g(styles, 'title-select__text')}>{order._checked ? '取消' : '全选'}</Text>
</TouchableOpacity>
</Header>
<View style={g(styles, 'body')}>
<View style={g(styles, 'card-info')}>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>客户名称:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order.customer_name}</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>结算日期:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>
{order.settled_date && dayjs(order.settled_date).format('YYYY-MM-DD')}
</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>结算总数量:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order.sum_quantity}</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>结算总金额:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order.sum_settlement_amount}</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>结算备注:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order.header_remark}</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>勾选开票数量:</Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order._quantity || 0}</Text>
</View>
<View style={g(styles, 'card-info-line')}>
<Text style={g(styles, 'card-info__text', 'card-info__key')}>勾选开票金额: </Text>
<Text style={g(styles, 'card-info__text', 'card-info__val')}>{order._amount || '0.00'}</Text>
</View>
</View>
<FlatList
data={order.lines}
keyExtractor={item => item._key}
renderItem={this.renderItem}
style={g(styles, 'list')}
/>
</View>
</Resolution.FixWidthView>
</View>
)
}
}
export default connect()(InvoiceApplyDetail)
@import '../../../assets/styles/base.styl'
@import '../../../assets/styles/variable.styl'
.filter
width 100%
align-items flex-end
&-icon
width 30px
height @width
margin-top 5px
.body
flex 1
background-color home_background_color
&-ft
padding-top 10px
padding-left 20px
padding-right 20px
justify-content flex-start
height 100px
background-color #fff
&-statistic
@extend .row
margin-bottom 8px
justify-content space-between
&__text
font-size 16px
font-family font_family_regular
&-btn
align-items center
.btn
@extend .center
@extend .middle
height 40px
border-radius 4px
&-submit
width 100%
background-color primary_color
&__text
color #fff
font-size 18px
font-family font_family_regular
&-select
width 30%
background-color #fff
border-width 1px
border-color #ccc
&__text
color #444
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/index.tsx
* @Author: peii
* @Date: 2021-12-27 09:59:21
* @LastEditTime: 2021-12-31 15:55:36
* @LastEditors: peii
* @Vision: 1.0
* @Description: 分销开票申请
*/
// @ts-nocheck
import React, { Component } from 'react'
import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native'
import { connect } from 'react-redux'
import * as R from 'ramda'
import { INavigation } from 'navigation'
import debounce from 'debounce'
import Loading from '../../../../app/containers/common/LodingModel'
import Header from '../../../components/header/header'
import Resolution from '../../../components/common/Resolution'
import FilterModal from './components/filter'
import InvoiceList from './components/list'
import { isBlank, g, isNotBlank, show } from '../../../utils/utils'
import api from '../../../services/api'
import styles from './index.styl'
type IProps = {
navigation: INavigation
status: any[]
}
type IState = {
visible: boolean
}
class Distribution extends Component<IProps, IState> {
constructor(props) {
super(props)
this.toggleModalVisible = this.toggleModalVisible.bind(this)
this.getData = this.getData.bind(this)
this.getLineData = this.getLineData.bind(this)
this.selectAllHandler = this.selectAllHandler.bind(this)
this.submitHandler = debounce(this.submitHandler.bind(this), 200)
this.itemClickHandler = this.itemClickHandler.bind(this)
this.checkedHandler = this.checkedHandler.bind(this)
this.countAndSum = this.countAndSum.bind(this)
}
state = {
visible: false,
loading: false,
data: [],
pagination: {
start_index: 0,
limit: 10,
},
filterData: {},
isEnd: false,
fresh: 0,
statistic: {
count: 0,
sum: 0,
},
customers: [],
}
componentDidMount() {
this.toggleModalVisible()
}
toggleModalVisible() {
const { visible } = this.state
this.setState({ visible: !visible })
}
/**
* @description: 请求分销结算数据
* @param {object} args 过滤参数
* @param {boolean} isRefresh 是否刷新类型
* @param {boolean} isNext 是否下一页
* @return {*}
*/
async getData(args, isRefresh = false, isNext = false) {
// 确认页面只过滤出已输入的那些
let { pagination, filterData, data, isEnd } = this.state
if (isRefresh || isNotBlank(args)) {
pagination.start_index = 0
}
if (isNext) {
pagination.start_index += pagination.limit
if (isEnd) return
}
if (isBlank(args)) {
args = filterData
}
const status = R.compose(
R.join(','),
R.reject(R.includes(R.__, ['ENTERED', 'REJECTED', 'CANCELED'])),
R.pluck('value_code'),
R.propOr([], 'status'),
)(this.props)
args.header_status = status
const params = {
...args,
...pagination,
}
if (!isRefresh && !isNext) {
this.setState({ loading: true })
}
const res = await api.getSettlements(params)
this.setState({ loading: false })
if (res.error_code !== 0) return
const newData = R.propOr([], 'data')(res)
if (isBlank(newData) || newData.length < pagination.limit) {
isEnd = true
} else {
isEnd = false
}
if (isNext) {
data = R.concat(data, newData)
} else {
data = newData
}
this.setState({ data, filterData: args, isEnd })
}
/**
* @description: 开票行
* @param {*}
* @return {*}
*/
async getLineData(order, loading = false) {
const params = {
settlement_number: order.settlement_number,
}
this.setState({ loading })
const res = await api.getSettlementLines(params)
this.setState({ loading: false })
if (res.error_code) return
order.lines = R.compose(
R.addIndex(R.map)((item, idx) => {
return { ...item, _key: idx.toString() }
}),
R.sort(R.ascend(R.prop('order_number'))),
R.propOr([], 'data'),
)(res)
}
/**
* @description: 单项点击
* @param {*} order
* @return {*}
*/
async itemClickHandler(order) {
if (isBlank(order.lines)) {
await this.getLineData(order, true)
}
const title = this.props.navigation.getParam('title')
this.props.navigation.navigate('DistributeInvoiceApplyDetail', {
title,
order,
refreshHandler: () => {
this.setState({ fresh: this.state.fresh + 1 })
this.countAndSum(order)
},
})
}
/**
* @description: 全选操作
* @param {*}
* @return {*}
*/
selectAllHandler() {}
/**
* @description: 单项选择
* @param {*}
* @return {*}
*/
async checkedHandler(checked, order) {
if (isBlank(order.lines)) {
await this.getLineData(order)
}
order._indeterminate = false
if (isNotBlank(order.lines)) {
R.map(item => {
item._checked = checked
})(order.lines)
}
this.countAndSum(order)
}
/**
* @description: 计算总数
* @param {*}
* @return {*}
*/
countAndSum(order) {
const { data } = this.state
const list = R.compose(R.filter(R.propEq('_checked', true)))(order.lines || [])
order._quantity = R.compose(R.sum, R.pluck('quantity'))(list)
order._amount = R.compose(R.sum, R.pluck('settlement_amount'))(list).toFixed(2)
const count = R.compose(R.sum, R.filter(isNotBlank), R.pluck('_quantity'))(data)
const sum = R.compose(R.sum, R.filter(isNotBlank), R.pluck('_amount'))(data).toFixed(2)
this.setState({ data, statistic: { count, sum } })
}
/**
* @description: 获取当前客户的收货地址
* @param {string} customer_code
* @return {*}
*/
getBillToSite(customer_code: string) {
const { customers = [] } = this.state
const customer = R.find(R.propEq('value', customer_code))(customers)
return R.pathOr(null, ['bill_to_sites', 0])(customer)
}
/**
* @description: 提交
* @param {*}
* @return {*}
*/
async submitHandler() {
const { data, filterData } = this.state
const list = R.filter(R.anyPass([R.propEq('_checked', true), R.propEq('_indeterminate', true)]))(data)
const len = R.compose(
R.length,
R.keys,
R.groupBy(it => it.org_code + it.customer_code + it.bill_to_site_code),
)(list)
if (len === 0) {
return show('请选择要开票的物料')
}
if (len > 1) {
return show('存在不同的开票')
}
const lines = R.compose(
R.unnest,
R.map(item => {
return R.compose(
R.map(
R.applySpec({
settlement_number: R.always(item.settlement_number),
line_number: R.prop('line_number'),
invoice_quantity: R.prop('quantity'),
}),
),
R.filter(R.propEq('_checked', true)),
R.propOr([], 'lines'),
)(item)
}),
)(list)
const bill_to_site = this.getBillToSite(filterData.customer_code)
const bill_to_site_code = bill_to_site && bill_to_site.bill_to_site_code
const params = {
org_code: filterData.org_code,
customer_code: filterData.customer_code,
bill_to_site_code,
lines,
}
const res = await api.postArInvoiceCreate(params)
if (res.error_code) return
}
render() {
const title = this.props.navigation.getParam('title')
const { visible, loading, data, fresh, statistic } = this.state
return (
<View style={g(styles, 'container')}>
<Resolution.FixWidthView>
<Header
title={title}
backCallback={() => {
this.props.navigation.goBack()
}}
>
<TouchableOpacity style={g(styles, 'filter')} activeOpacity={0.8} onPress={this.toggleModalVisible}>
<Image source={require('../../../assets/images/filter_icon.png')} style={g(styles, 'filter-icon')} />
</TouchableOpacity>
</Header>
<View style={g(styles, 'body')}>
{/* 过滤弹窗 */}
<FilterModal
visible={visible}
onClose={this.toggleModalVisible}
searchHandler={(filterData, customers) => {
this.setState({ customers })
this.getData(filterData)
}}
/>
{/* 显示列表 */}
{loading ? (
<Loading show={loading} />
) : (
<InvoiceList
data={data}
{...this.props}
fresh={fresh}
getData={this.getData}
itemClickHandler={this.itemClickHandler}
checkedHandler={this.checkedHandler}
isCollection={false}
/>
)}
{isNotBlank(data) && (
<View style={g(styles, 'body-ft')}>
<View style={g(styles, 'body-ft-statistic')}>
<Text style={g(styles, 'body-ft-statistic__text')}>申请开票总数量: {statistic.count}</Text>
<Text style={g(styles, 'body-ft-statistic__text')}>申请开票总金额: {statistic.sum}</Text>
</View>
<View style={g(styles, 'body-ft-btn')}>
<TouchableOpacity
style={g(styles, 'btn', 'btn-submit')}
activeOpacity={0.8}
onPress={this.submitHandler}
>
<Text style={g(styles, 'btn__text', 'btn-submit__text')}>申请开票</Text>
</TouchableOpacity>
{/* <TouchableOpacity
style={g(styles, 'btn', 'btn-select')}
activeOpacity={0.8}
onPress={this.selectAllHandler}
>
<Text style={g(styles, 'btn__text', 'btn-select__text')}>全选</Text>
</TouchableOpacity> */}
</View>
</View>
)}
</View>
</Resolution.FixWidthView>
</View>
)
}
}
const mapStateToProps = state => ({
status: state.settlement.headerStatus,
})
const mapDispatchToProps = dispatch => ({})
export default connect(mapStateToProps, mapDispatchToProps)(Distribution)
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/invoice/distribution/utils.ts
* @Author: peii
* @Date: 2021-12-30 10:55:50
* @LastEditTime: 2021-12-30 10:55:51
* @LastEditors: peii
* @Vision: 1.0
* @Description: 模块工具函数
*/
......@@ -6,6 +6,9 @@
padding-top 20px
padding-bottom 25px
&-inner
min-height 100%
.item
background-color #fff
margin-left 20px
......
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/services/api.ts
* @Author: peii
* @Date: 2021-12-19 16:06:26
* @LastEditTime: 2021-12-23 12:18:34
* @LastEditTime: 2021-12-31 11:47:52
* @LastEditors: peii
* @Vision: 1.0
* @Description: 未重构完全暂用的所有请求
......@@ -82,4 +82,13 @@ export default {
}
return download(url, config)
},
/**
* @description: 开票申请
* @param {object} data
* @return {*}
*/
postArInvoiceCreate(data: { org_code: string; customer_code: string; bill_to_site_code: string; lines: any[] }) {
return request({ url: `${v}/ar_invoice/create`, data: { data } })
},
}
......@@ -116,7 +116,7 @@ export const request = (args: Partial<RequestConfig>) => {
() => {
reject(e)
},
)
)()
return
}
if (requestTimes < options.reTries && !e.error_code) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment