565 lines
20 KiB
JavaScript
565 lines
20 KiB
JavaScript
import React, { Component } from 'react'
|
|
import Icon from '../../components/Icon'
|
|
import {
|
|
Accordion,
|
|
Badge,
|
|
Body,
|
|
Button,
|
|
Content,
|
|
Header,
|
|
Left,
|
|
List,
|
|
ListItem,
|
|
Right,
|
|
Title,
|
|
View
|
|
} from 'native-base'
|
|
import { Dimensions, FlatList, ScrollView, StyleSheet, TouchableOpacity, SafeAreaView, Alert } from 'react-native'
|
|
import LinearGradient from 'react-native-linear-gradient'
|
|
import Text from '../../components/Text';
|
|
import { payment } from '../../api/UserApi'
|
|
import { connect } from "react-redux";
|
|
import {bindActionCreators} from "redux";
|
|
import {appSetDevice, appSetPushToken, appSetToken, appSetUser} from "../../redux/app/action";
|
|
import moment from "moment";
|
|
import IndicatorLoading from '../../components/IndicatorLoading';
|
|
import { t } from 'src/utils/i18n'
|
|
|
|
const { height, width } = Dimensions.get('window')
|
|
|
|
function ItemOrder({title,cost,description,type}){
|
|
|
|
let iconShow = ''
|
|
let iconColor = ''
|
|
switch(type){
|
|
case 0:
|
|
iconShow = 'ic_event_note'
|
|
iconColor = '#00000080'
|
|
break;
|
|
case 1:
|
|
iconShow = 'ic_bed'
|
|
iconColor = '#FF6122'
|
|
break;
|
|
case 2:
|
|
iconShow = 'ic_water'
|
|
iconColor = '#5AC8FA'
|
|
break;
|
|
case 3:
|
|
iconShow = 'ic_thunder'
|
|
iconColor = '#FFCC00'
|
|
break;
|
|
case 4:
|
|
iconShow = 'ic_event_note'
|
|
iconColor = '#00000080'
|
|
break;
|
|
case 5:
|
|
iconShow = 'ic_water'
|
|
iconColor = '#5AC8FA'
|
|
break;
|
|
case 6:
|
|
iconShow = 'ic_thunder'
|
|
iconColor = '#FFCC00'
|
|
break;
|
|
case 7:
|
|
iconShow = 'ic_event_note'
|
|
iconColor = '#00000080'
|
|
break;
|
|
}
|
|
|
|
return <View style={{flexDirection:'row',height:64,width:'100%',borderBottomWidth:1,alignItems:'center',borderColor:'#EAEAF4',paddingHorizontal:16}}>
|
|
<View style={{ ...styles.circleShapeView, backgroundColor: iconColor,marginRight:16 }}>
|
|
<Icon active name={iconShow} size={20} color="white" />
|
|
</View>
|
|
<View style={{flex:1}}>
|
|
<View style={{ flexDirection: 'row' }}>
|
|
<Text style={{ flex: 1 }}>{title}</Text>
|
|
<Text style={{ ...styles.colorTextPayment, textAlign: 'center' }}>{cost} {t('baht')}</Text>
|
|
</View>
|
|
<Text style={{ color: '#00000080', fontSize: 12, marginLeft: 5}}>{description != '' ? description : '-'}</Text>
|
|
</View>
|
|
</View>
|
|
}
|
|
|
|
class BillScreen extends Component {
|
|
constructor(props) {
|
|
super(props)
|
|
this.state = {
|
|
isLoading:false,
|
|
payment: [],
|
|
sum_payment: [],
|
|
activePage: 0,
|
|
isCanPay: true,
|
|
all_payment : [],
|
|
room_number_array : [],
|
|
};
|
|
|
|
this._onCarouselScroll = this._onCarouselScroll.bind(this)
|
|
this.checkDueDate = this.checkDueDate.bind(this)
|
|
this.checkstatusBill = this.checkstatusBill.bind(this)
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.setState({isLoading: true})
|
|
if(this.props.user){
|
|
payment(this.props.user.id)
|
|
.then(res => {
|
|
if(res.ok){
|
|
let sum_payment = [];
|
|
let array_payment = [];
|
|
let sum_cost_room = res.data.sum_cost_room;
|
|
if(Object.keys(sum_cost_room).length > 0) {
|
|
Object.keys(sum_cost_room).map((sum_cost) => {
|
|
sum_payment.push({
|
|
total_cost : sum_cost_room[sum_cost].total_cost,
|
|
room: sum_cost_room[sum_cost].room,
|
|
project: sum_cost_room[sum_cost].project,
|
|
due_at: sum_cost_room[sum_cost].due_at,
|
|
}
|
|
)
|
|
})
|
|
}
|
|
|
|
let payment = res.data.payment_room_period
|
|
if(Object.keys(payment).length > 0){
|
|
Object.keys(payment).map((pay) => {
|
|
if(Object.keys(payment[pay]).length > 0){
|
|
Object.keys(payment[pay]).map((detail) => {
|
|
this.state.room_number_array.push(pay)
|
|
array_payment.push({
|
|
room_id: pay,
|
|
period: detail,
|
|
// total_cost: payment[pay][detail].total_cost,
|
|
// details: payment[pay][detail].details,
|
|
// status: payment[pay][detail].status,
|
|
// created_at: payment[pay][detail].created_at,
|
|
// payment_id: payment[pay][detail].id,
|
|
// enable_qr: payment[pay][detail].enable_qr
|
|
...payment[pay][detail]
|
|
})
|
|
})
|
|
}
|
|
})
|
|
}
|
|
let all_payment_data = array_payment;
|
|
let array_room_no = this.state.room_number_array;
|
|
this.setState({
|
|
room_number_array: array_room_no.filter((item, i, ar) => ar.indexOf(item) === i)
|
|
});
|
|
|
|
|
|
let first_room = this.state.room_number_array[0];
|
|
array_payment = array_payment.filter((obj)=>{
|
|
return Object.keys(obj).reduce((acc, curr)=>{
|
|
return obj.room_id === first_room
|
|
}, false);
|
|
});
|
|
|
|
|
|
let date_now = moment()
|
|
let findTimeout = array_payment.find((item) => {return moment(item.due_at) == date_now})
|
|
//check bill timeout
|
|
if(findTimeout !== undefined){
|
|
this.setState({
|
|
isCanPay: false
|
|
})
|
|
}
|
|
|
|
|
|
if(sum_payment.length > 0){
|
|
this.setState({
|
|
room_number_array: sum_payment.map(function(item){
|
|
return item.room
|
|
})
|
|
});
|
|
}
|
|
|
|
this.setState({
|
|
isLoading:false,
|
|
payment: array_payment,
|
|
sum_payment: sum_payment,
|
|
all_payment: all_payment_data
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
getMonth(period_month){
|
|
let new_month = 'มกราคม'
|
|
switch (period_month) {
|
|
case '01':
|
|
new_month = 'มกราคม';
|
|
break;
|
|
case '02':
|
|
new_month = 'กุมภาพันธ์';
|
|
break;
|
|
case '03':
|
|
new_month = 'มีนาคม';
|
|
break;
|
|
case '04':
|
|
new_month = 'เมษายน';
|
|
break;
|
|
case '05':
|
|
new_month = 'พฤษภาคม';
|
|
break;
|
|
case '06':
|
|
new_month = 'มิถุนายน';
|
|
break;
|
|
case '07':
|
|
new_month = 'กรกฎาคม';
|
|
break;
|
|
case '08':
|
|
new_month = 'สิงหาคม';
|
|
break;
|
|
case '09':
|
|
new_month = 'กันยายน';
|
|
break;
|
|
case '10':
|
|
new_month = 'ตุลาคม';
|
|
break;
|
|
case '11':
|
|
new_month = 'พฤศจิกายน';
|
|
break;
|
|
case '12':
|
|
new_month = 'ธันวาคม';
|
|
break;
|
|
default:
|
|
new_month = 'มกราคม';
|
|
break;
|
|
}
|
|
|
|
return new_month;
|
|
}
|
|
|
|
getTitle (period) {
|
|
let period_month = moment(period, "MM/Y").format('MM');
|
|
let period_year = parseInt(moment(period, "MM/Y").format('Y')) + 543;
|
|
let new_month = 'มกราคม';
|
|
let new_period = new_month + ' ' + period_year;
|
|
|
|
new_month = this.getMonth(period_month)
|
|
|
|
new_period = new_month + ' ' + period_year;
|
|
return new_period;
|
|
}
|
|
|
|
checkDueDate(date){
|
|
// console.log('date -------- ',moment(date))
|
|
// console.log('now -------- ',moment())
|
|
let due_date = moment(date)
|
|
let now = moment()
|
|
if(due_date < now){
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
checkstatusBill(data,boolDate){
|
|
if(data.status == 'paid'){
|
|
return <TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white',
|
|
height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5,
|
|
borderColor: data.status !== 'pending' ? 'grey' : '',
|
|
borderWidth: data.status !== 'pending' ? 1 : 0}}
|
|
disabled={data.status === 'pending' ? false : true}
|
|
onPress={() => {
|
|
this.state.isCanPay ?
|
|
data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
|
|
: Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}])
|
|
}}>
|
|
<Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'จ่ายเงิน' : 'จ่ายแล้ว'}</Text>
|
|
</TouchableOpacity>
|
|
}else{
|
|
if(!boolDate){
|
|
return <View>
|
|
<Text style={{ color: 'red',borderWidth:1,borderColor:'#00000040',borderRadius:5,paddingHorizontal:6}}>{'เกินกำหนดชำระ'}</Text>
|
|
</View>
|
|
}else{
|
|
return <TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white',
|
|
height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5,
|
|
borderColor: data.status !== 'pending' ? 'grey' : '',
|
|
borderWidth: data.status !== 'pending' ? 1 : 0}}
|
|
disabled={data.status === 'pending' ? false : true}
|
|
onPress={() => {
|
|
this.state.isCanPay ?
|
|
data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
|
|
: Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}])
|
|
}}>
|
|
<Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'จ่ายเงิน' : 'จ่ายแล้ว'}</Text>
|
|
</TouchableOpacity>
|
|
}
|
|
}
|
|
}
|
|
|
|
_renderHeader(data, expanded) {
|
|
// if(data.room_id == this.state.sum_payment[this.state.activePage].room.id){
|
|
let checkBool = this.checkDueDate(data.due_at == null || data.due_at == undefined ? moment() : data.due_at)
|
|
return (
|
|
<View style={{flex:1,flexDirection:'row',backgroundColor:'#B8DAAA',height: 64,borderBottomWidth:1,borderBottomColor:'white',alignItems:'center',justifyContent:'space-between',paddingHorizontal:16}}>
|
|
<View style={{justifyContent:'center',flex:1}}>
|
|
<Text>{t('month')} {this.getTitle(data.period)}</Text>
|
|
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between'}}>
|
|
{expanded || data.status != 'pending' ? <Text /> : <Text note style={styles.colorTextPayment}>{t('outstanding_balance')} {data.total_cost}</Text>}
|
|
{expanded || <Text style={{fontSize:10,marginRight:16}}>{t('view_more')}</Text>}
|
|
</View>
|
|
</View>
|
|
{
|
|
this.checkstatusBill(data,checkBool)
|
|
}
|
|
{/* {
|
|
checkBool ?
|
|
data.enable_qr &&
|
|
<TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white',
|
|
height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5,
|
|
borderColor: data.status !== 'pending' ? 'grey' : '',
|
|
borderWidth: data.status !== 'pending' ? 1 : 0}}
|
|
disabled={data.status === 'pending' ? false : true}
|
|
onPress={() => {
|
|
this.state.isCanPay ?
|
|
data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
|
|
: Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}])
|
|
}}>
|
|
<Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'จ่ายเงิน' : 'จ่ายแล้ว'}</Text>
|
|
</TouchableOpacity>
|
|
:
|
|
<View>
|
|
<Text style={{ color: 'red',borderWidth:1,borderColor:'#00000040',borderRadius:5,paddingHorizontal:6}}>{'เกินกำหนดชำระ'}</Text>
|
|
</View>
|
|
} */}
|
|
</View>
|
|
)
|
|
// }
|
|
}
|
|
|
|
_renderContent(data) {
|
|
let water_cost = 0;
|
|
let electrict_cost = 0;
|
|
let room_cost = 0;
|
|
let service_cost = 0;
|
|
let date_payment = '';
|
|
let extra_info = '';
|
|
let d = moment(data.created_at).format('D')
|
|
let m = moment(data.created_at).format('MM')
|
|
let y = parseInt(moment(data.created_at).format('Y')) + 543
|
|
date_payment = d + ' ' + this.getMonth(m) + ' ' + y
|
|
|
|
let descriptionRoom = '-'
|
|
let descriptionWater = '-'
|
|
let descriptionElec = '-'
|
|
let descriptionService = '-'
|
|
|
|
// console.log('check data ----------> ',data)
|
|
|
|
if(data.details){
|
|
data.details.map((det) => {
|
|
if(det.sequence === 1){
|
|
room_cost = det.cost
|
|
room_extra_info = det.extra_info != null ? det.extra_info : ''
|
|
descriptionRoom = det.descript == '' ? '-' : det.descript
|
|
}
|
|
|
|
if(det.sequence === 2){
|
|
water_cost = det.cost
|
|
water_extra_info = det.extra_info != null ? det.extra_info : ''
|
|
descriptionWater = det.descript == '' ? '-' : det.descript
|
|
}
|
|
|
|
if(det.sequence === 3){
|
|
electrict_cost = det.cost
|
|
electrict_extra_info = det.extra_info != null ? det.extra_info : ''
|
|
descriptionElec = det.descript == '' ? '-' : det.descript
|
|
}
|
|
|
|
if(det.sequence === 4){
|
|
service_cost = det.cost
|
|
service_extra_info = det.extra_info != null ? det.extra_info : ''
|
|
descriptionService = det.descript == '' ? '-' : det.descript
|
|
}
|
|
})
|
|
}
|
|
|
|
return (
|
|
<View>
|
|
{
|
|
data.details.map((info,index) => {
|
|
return <ItemOrder title={info.name} cost={info.cost} description={info.descript} key={'order_info_'+index} type={info.type}/>
|
|
})
|
|
}
|
|
<View style={{ height:50,width:'100%', backgroundColor:'#8BC34A',alignItems: 'flex-end',justifyContent:'center' }}>
|
|
<Text style={{ color: 'white',marginRight:15,fontSize:18 }}>รวม {data.total_cost} {t('baht')}</Text>
|
|
</View>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
getDueDate (date) {
|
|
if(date){
|
|
let d = moment(date).format('D')
|
|
let m = moment(date).format('MM')
|
|
let y = parseInt(moment(date).format('Y')) + 543
|
|
let new_month = 'ม.ค.';
|
|
let new_date = d + ' ' + new_month + ' ' + y;
|
|
switch (m) {
|
|
case '01':
|
|
new_month = 'ม.ค.';
|
|
break;
|
|
case '02':
|
|
new_month = 'ก.พ.';
|
|
break;
|
|
case '03':
|
|
new_month = 'มี.ค.';
|
|
break;
|
|
case '04':
|
|
new_month = 'เม.ย.';
|
|
break;
|
|
case '05':
|
|
new_month = 'พ.ค.';
|
|
break;
|
|
case '06':
|
|
new_month = 'มิ.ย.';
|
|
break;
|
|
case '07':
|
|
new_month = 'ก.ค.';
|
|
break;
|
|
case '08':
|
|
new_month = 'ส.ค.';
|
|
break;
|
|
case '09':
|
|
new_month = 'ก.ย.';
|
|
break;
|
|
case '10':
|
|
new_month = 'ต.ค.';
|
|
break;
|
|
case '11':
|
|
new_month = 'พ.ย.';
|
|
break;
|
|
case '12':
|
|
new_month = 'ธ.ค.';
|
|
break;
|
|
default:
|
|
new_month = 'ม.ค.';
|
|
break;
|
|
}
|
|
|
|
new_date = d + ' ' + new_month + ' ' + y;
|
|
return new_date;
|
|
}else{
|
|
return '';
|
|
}
|
|
}
|
|
|
|
renderNativeItemImages = (item) => {
|
|
// console.log('check data item ',item)
|
|
return <View style={{width: width, alignItems: 'center', paddingTop: 10, paddingBottom: 40,height: 177,}}>
|
|
<View style={{width: '60%', height: '100%', backgroundColor: '#06ADB8', borderRadius: 5 }}>
|
|
<LinearGradient colors={['#4BAF3B', '#0e5e29']} style={{ flex:1, borderRadius: 5, height: 120,paddingBottom:10, justifyContent:'space-between'}}>
|
|
<View style={{ padding: 16,paddingBottom: 5,paddingTop:10 , borderRadius: 5}}>
|
|
<Text style={{ color: 'white', fontSize: 18 }}>{t('room')} {item.room}</Text>
|
|
<Text style={{ color: 'rgba(255, 255, 255, 0.65)', fontSize: 14 }}>{item.project && item.project.name}</Text>
|
|
<Text style={{ color: 'white' }}>{t('outstanding_balance')} <Text style={{ color: 'white' ,fontSize:18 }}>{item.total_cost} {t('baht')}</Text></Text>
|
|
</View>
|
|
|
|
{
|
|
item.due_at !== null
|
|
? (
|
|
<View style={{height:24,backgroundColor: '#FF2D55',justifyContent:'center',alignItems:'center'}}>
|
|
<Text style={{ fontSize: 12, color: 'white'}}>{t('please_pay_before')} {this.getDueDate(item.due_at)}</Text>
|
|
</View>
|
|
)
|
|
: null
|
|
}
|
|
|
|
</LinearGradient>
|
|
</View>
|
|
</View>
|
|
}
|
|
_onCarouselScroll(e) {
|
|
const scrollX = e.nativeEvent.contentOffset.x
|
|
this.setState({
|
|
activePage: Math.ceil(scrollX / width)
|
|
})
|
|
// console.log(e);
|
|
}
|
|
|
|
groupArrayOfObjects(list, key) {
|
|
return list.reduce(function(rv, x) {
|
|
(rv[x[key]] = rv[x[key]] || []).push(x);
|
|
return rv;
|
|
}, {});
|
|
}
|
|
|
|
roomFilter(index){
|
|
let payment_exits = this.state.all_payment;
|
|
let another_room = this.state.room_number_array[index];
|
|
let payment_array = payment_exits.filter((obj)=>{
|
|
return Object.keys(obj).reduce((acc, curr)=>{
|
|
return obj.room_id === another_room
|
|
}, false);
|
|
});
|
|
this.state.payment = payment_array;
|
|
}
|
|
|
|
_keyExtractor = (item, index) => 'bill_'+index
|
|
|
|
render() {
|
|
return (
|
|
<SafeAreaView style={{flex: 1}}>
|
|
<ScrollView contentContainerStyle={styles.contentContainer}>
|
|
<View style={{ alignItems: 'center'}}>
|
|
{
|
|
this.state.sum_payment.length == 0 &&
|
|
<View style={{margin:16,width: '90%', height: 55,backgroundColor:'#00000080',justifyContent:'center',alignItems:'center',borderRadius:5}}>
|
|
<Text style={{fontSize:14,color:'white',textAlign:'center'}}>{this.props.user.room} {t('no_outstanding_balance')}</Text>
|
|
</View>
|
|
}
|
|
<FlatList
|
|
data={this.state.sum_payment}
|
|
renderItem={({ item }) => this.renderNativeItemImages(item)}
|
|
horizontal={true}
|
|
onScroll={this._onCarouselScroll}
|
|
onScrollEndDrag={this.roomFilter(this.state.activePage)}
|
|
pagingEnabled={true}
|
|
extraData={this.state}
|
|
keyExtractor={this._keyExtractor}
|
|
/>
|
|
<View style={{ position: 'absolute', bottom: 10, width: '100%', justifyContent: 'center', flexDirection: 'row' }}>
|
|
{this.state.sum_payment.map((item, i) => <View key={'sum_payment_'+i} style={[{ width: 10, height: 10, borderRadius: 5, backgroundColor: this.state.activePage == i ? '#269A21' : 'rgba(124, 187, 51, 0.3)', marginHorizontal: 4 }]}></View>)}
|
|
</View>
|
|
</View>
|
|
<View style={{flex:1}}>
|
|
<Accordion
|
|
dataArray={ this.state.payment }
|
|
expanded={this.state.payment.length - 1}
|
|
renderHeader={(data, expanded) => { return this._renderHeader(data, expanded) }}
|
|
renderContent={(data) => { return this._renderContent(data) }} />
|
|
</View>
|
|
</ScrollView>
|
|
<IndicatorLoading loadingVisible={this.state.isLoading}/>
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
circleShapeView: {
|
|
width: 32,
|
|
height: 32,
|
|
borderRadius: 100,
|
|
justifyContent: 'center',
|
|
alignItems: 'center'
|
|
},
|
|
contentContainer: {
|
|
backgroundColor: '#EEFFD7',
|
|
paddingVertical: 0,
|
|
flexGrow: 1,
|
|
},
|
|
colorTextPayment: {
|
|
color: '#3AA40C'
|
|
}
|
|
})
|
|
|
|
const mapDisPatchToProps = state => ({
|
|
user: state.app.user
|
|
})
|
|
|
|
export default connect(mapDisPatchToProps)(BillScreen)
|