395 lines
19 KiB
JavaScript
395 lines
19 KiB
JavaScript
import * as React from 'react';
|
|
import moment from 'moment';
|
|
import { connect } from "react-redux";
|
|
import { Divider } from 'react-native-elements'
|
|
import {
|
|
TouchableOpacity,
|
|
View,
|
|
Text,
|
|
Alert,
|
|
ScrollView,
|
|
Image,
|
|
Modal,
|
|
StyleSheet,
|
|
} from 'react-native';
|
|
import CustomHeader from '../../components/header.js';
|
|
import Assets from '../../components/assets.manager.js';
|
|
import Theme from '../../components/theme.style.js';
|
|
import REQUEST_POST_PAY from '../../components/api/postpayapi';
|
|
import DB from '../../components/storage';
|
|
import Elements from '../../components/elements';
|
|
import CustomSafeArea from '../../components/safeArea.component';
|
|
import { returnIcon } from '../../utils/card.js';
|
|
|
|
class PayatpumpStationTransactionDetails extends React.Component {
|
|
|
|
constructor(props) {
|
|
super(props)
|
|
}
|
|
|
|
state = {
|
|
loading: false,
|
|
session: null,
|
|
card_number: null,
|
|
selectedPoints: null,
|
|
selectedPaymentCard: null,
|
|
claimId: null,
|
|
data: [],
|
|
storeName: null,
|
|
showModal: false,
|
|
totalPrice: 3000
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.init();
|
|
}
|
|
|
|
init = async () => {
|
|
let session = await DB.session()
|
|
let user_profile = await DB.profile()
|
|
let selectedCard = await DB.get("pumpPaymentCards");
|
|
this.setState({
|
|
card_number: user_profile.data.card_number,
|
|
session: session,
|
|
claimId: this.props.route.params.response.claimId,
|
|
data: this.props.route.params.response.saleItems,
|
|
storeName: this.props.route.params.storeName,
|
|
selectedPumpNumber: this.props.route.params.selectedPump,
|
|
selectedPaymentCard: JSON.parse(selectedCard)
|
|
})
|
|
}
|
|
|
|
onSelectedPointsAmount = (point_amount) => {
|
|
this.setState({ selectedPoints: point_amount })
|
|
}
|
|
|
|
onSelectedPaymentCard = (payment_card) => {
|
|
this.setState({ selectedPaymentCard: payment_card })
|
|
}
|
|
|
|
getTransactionDetails = async (claimId, fundingProviderName, userPaymentSourceId, onSuccess, onError) => {
|
|
let cardNumber = this.state.selectedPaymentCard.firstSix.replace(" ", "") + this.state.selectedPaymentCard.lastFour;
|
|
|
|
if(claimId == null) {
|
|
Alert.alert("Error", "No transaction id exist.")
|
|
return
|
|
}
|
|
|
|
let params = {
|
|
claimId: claimId,
|
|
currencyCode: "PHP",
|
|
partnerTransactionId: "93931",
|
|
walletRequests: [{
|
|
fundingProviderName: fundingProviderName,
|
|
fundingPayload: {
|
|
userPaymentSourceId: userPaymentSourceId
|
|
}
|
|
}, {
|
|
fundingProviderName: "loyalty_points",
|
|
fundingPayload: {
|
|
"paymentToken": cardNumber,
|
|
"points": 0
|
|
}
|
|
}],
|
|
userPreference: {
|
|
receiptPreference: "doNotPrintReceipt", //printReceipt, doNotPrintReceipt
|
|
},
|
|
fraudContext: {}
|
|
}
|
|
|
|
let USER_PROFILE = await DB.profile();
|
|
|
|
REQUEST_POST_PAY('postpay', 'post', {
|
|
token: USER_PROFILE.data.auth_p97,
|
|
language: 'en-US'
|
|
}, {}, params, async (res) => {
|
|
if(res.success && res.response != undefined && res.response.status == "success") {
|
|
REQUEST_POST_PAY('getTransactionStatusDetails', "get", {
|
|
token: USER_PROFILE.data.auth_p97,
|
|
language: 'en-US'
|
|
}, {transactionID: res.response.transaction_id}, {}, res2 => {
|
|
if(res2.success && res2.response != undefined) {
|
|
this.requestTransactionDetails(res, res2, onSuccess, onError)
|
|
} else {
|
|
onError(res2)
|
|
}
|
|
}, (error) => {
|
|
onError(error);
|
|
})
|
|
} else {
|
|
onError(res)
|
|
}
|
|
}, (error) => {
|
|
onError(error)
|
|
})
|
|
}
|
|
|
|
requestTransactionDetails = async (res, res2, onSuccess, onError) => {
|
|
let USER_PROFILE = await DB.profile();
|
|
|
|
REQUEST_POST_PAY("getTransactionDetails/" + res2.response.transactionId, "get", {
|
|
token: USER_PROFILE.data.auth_p97,
|
|
language: 'en-US'
|
|
}, {}, {}, res3 => {
|
|
if(res3.success && res3.response !== undefined) {
|
|
if(res3.response.appChannel !== "ThirdPartyMobile" || res3.response.totalDiscount === 0) {
|
|
setTimeout(() => {
|
|
this.requestTransactionDetails(res, res2, onSuccess, onError);
|
|
}, 2000);
|
|
} else {
|
|
onSuccess({ res: res, onSuccess: res2, newDetails: res3 })
|
|
}
|
|
}
|
|
}, err => {
|
|
onError(err);
|
|
})
|
|
}
|
|
|
|
submitPayment = () => {
|
|
this.setState({ showModal: false, loading: true })
|
|
|
|
this.getTransactionDetails(this.state.claimId, "p97token", this.state.selectedPaymentCard.userPaymentSourceId, onSuccess => {
|
|
this.setState({ loading: false })
|
|
|
|
if(onSuccess.res.success) {
|
|
let payment = { totalPayment: this.state.data[0]?.originalAmount.amount, cardPayment: this.state.data[0].originalAmount.amount, transactionId: onSuccess.res.response.transaction_id, storeName: this.state.storeName };
|
|
this.props.navigation.navigate('PayatpumpPaymentSuccess', { transactionData: payment, transactionDetails: onSuccess.onSuccess, newDetails: onSuccess.newDetails })
|
|
} else {
|
|
setTimeout(() => {
|
|
Alert.alert('Error', "Failed to initiate transaction. Try again.")
|
|
}, 300)
|
|
}
|
|
}, onError => {
|
|
this.setState({ loading: false })
|
|
setTimeout(() => {
|
|
Alert.alert('Error', "Failed to initiate transaction. Try again.")
|
|
}, 300)
|
|
})
|
|
}
|
|
|
|
renderModal = () => {
|
|
return (
|
|
<Modal
|
|
animationType="none"
|
|
transparent={true}
|
|
visible={this.state.showModal}>
|
|
<TouchableOpacity activeOpacity={1} onPress={() => {}} style={styles.centeredView}>
|
|
<View style={[styles.modalView, { backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.colors.border : Theme.colors.white }]}>
|
|
|
|
{this.state.selectedPoints == null && this.state.selectedPaymentCard == null ?
|
|
<>
|
|
<Image source={Assets.icons.points_balance} style={{ width: 85, height: 85, resizeMode: 'contain' }} />
|
|
<Text style={{ fontSize: 18, color: this.props.app_theme?.theme.colors.text, marginVertical: 30 }}>{'Please select payment method...'}</Text>
|
|
<TouchableOpacity onPress={() => this.setState({ showModal: false })} style={{ width: 80, height: 30, backgroundColor: Theme.colors.primary, alignItems: 'center', justifyContent: 'center' }}>
|
|
<Text style={{ fontSize: 18, color: Theme.colors.white, textAlign: 'center' }}>Ok</Text>
|
|
</TouchableOpacity>
|
|
</> :
|
|
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
|
|
<Text style={{ fontSize: 16, fontWeight: 'bold', color: this.props.app_theme?.theme.colors.text, marginTop: 10, textAlign: 'center' }}>{`You are about to pay \n ${"\u20B1"} ${Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)}?`}</Text>
|
|
<Text style={{ fontSize: 16, fontWeight: 'bold', color: this.props.app_theme?.theme.colors.text, marginTop: 30, marginBottom: 25, textAlign: 'center' }}>{`If your transaction is valid for\ndiscount, it will be reflected after final payment.`}</Text>
|
|
<View style={{ justifyContent: 'center', alignItems: 'center', flexDirection: 'row', marginBottom: 10 }}>
|
|
<TouchableOpacity
|
|
style={{ flex: 1, height: 30, backgroundColor: 'transparent', borderColor: Theme.colors.primary, borderWidth: 1, alignItems: 'center', justifyContent: 'center', borderRadius: 5, marginRight: 10, marginLeft: 20 }}
|
|
onPress={() => {
|
|
this.setState({ showModal: false })
|
|
}}>
|
|
<Text style={{ fontSize: 18, color: Theme.colors.primary, textAlign: 'center' }}>Cancel</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity
|
|
style={{ flex: 1, height: 30, backgroundColor: Theme.colors.primary, alignItems: 'center', borderColor: Theme.colors.primary, borderWidth: 1, justifyContent: 'center', borderRadius: 5, marginLeft: 10, marginRight: 20 }}
|
|
onPress={() => this.submitPayment()}>
|
|
<Text style={{ fontSize: 18, color: Theme.colors.white, textAlign: 'center' }}>Continue</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
}
|
|
</View>
|
|
</TouchableOpacity>
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
transactionTable = () => {
|
|
const renderItem = () => {
|
|
return this.state.data?.map((item, index) => {
|
|
return (
|
|
<View key={index} style={{flex: 1, flexDirection: 'row', paddingLeft: 15, paddingRight: 15, paddingTop: 10, paddingBottom: 15, alignItems: 'center'}}>
|
|
<Text style={{flex: 4, fontFamily: 'Arial', textAlign: 'left', fontSize: 13, color: this.props.app_theme?.theme.colors.text}}>{item.description}</Text>
|
|
<Text style={{flex: 3, fontFamily: 'Arial', fontWeight: 'bold', textAlign: 'center', fontSize: 13, color: this.props.app_theme?.theme.colors.text}}>{`${item.quantity} ${item.unitMeasure}`}</Text>
|
|
<Text style={{flex: 3, fontFamily: 'Arial', fontWeight: 'bold', textAlign: 'center', fontSize: 13, color: this.props.app_theme?.theme.colors.text}}>{"\u20B1"}{Theme.formatter.CRNCY(item.originalAmount.unitPrice)}</Text>
|
|
<Text style={{flex: 3, fontFamily: 'Arial', fontWeight: 'bold', textAlign: 'right', fontSize: 13, color: this.props.app_theme?.theme.colors.text}}>{"\u20B1"}{Theme.formatter.CRNCY(item.originalAmount.amount)}</Text>
|
|
</View>
|
|
)
|
|
})
|
|
}
|
|
|
|
return (
|
|
<View style={{width: '100%'}}>
|
|
<Divider />
|
|
<View style={{flex: 1, flexDirection: 'row', padding: 15, marginTop: 8, alignItems: 'center'}}>
|
|
<Text style={{flex: 4, height: 18, fontWeight: 'bold', fontFamily: 'Arial', color: this.props.app_theme?.theme.colors.text, textAlign: 'left', fontSize: 14}}>Product</Text>
|
|
<Text style={{flex: 3, height: 18, fontWeight: 'bold', fontFamily: 'Arial', color: this.props.app_theme?.theme.colors.text, textAlign: 'center', fontSize: 14}}>Qty</Text>
|
|
<Text style={{flex: 3, height: 18, fontWeight: 'bold', fontFamily: 'Arial', color: this.props.app_theme?.theme.colors.text, textAlign: 'center', fontSize: 14}}>Price</Text>
|
|
<Text style={{flex: 3, height: 18, fontWeight: 'bold', fontFamily: 'Arial', color: this.props.app_theme?.theme.colors.text, textAlign: 'right', fontSize: 14}}>Total</Text>
|
|
</View>
|
|
<Divider />
|
|
<ScrollView style={{ width: '100%', height: 150}}>
|
|
{renderItem()}
|
|
<View style={{padding: 10}}></View>
|
|
</ScrollView>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
onBackConfirmation = () => {
|
|
Alert.alert(
|
|
'',
|
|
'Do you want to cancel this transaction?',
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
style: 'cancel',
|
|
},
|
|
{
|
|
text: 'OK',
|
|
onPress: () => this.props.navigation.goBack(),
|
|
},
|
|
],
|
|
{cancelable: true},
|
|
);
|
|
}
|
|
|
|
renderSelectedCard = () => {
|
|
return (
|
|
<View style={{flexDirection: 'row', paddingHorizontal: 30}}>
|
|
<View style={{flex: 1, alignItems: 'center', flexDirection: 'row', borderRightWidth: 1, borderColor: "rgba(0,0,0,.1)"}}>
|
|
<Image source={this.state.selectedPaymentCard ? returnIcon(this.state.selectedPaymentCard.brandName) : Assets.icons.stpunlabeled} style={{height: 40, width: 40, resizeMode: 'contain'}} />
|
|
|
|
{
|
|
this.state.selectedPaymentCard ?
|
|
<>
|
|
<View style={{flex: 1, alignItems: 'center', paddingRight: 20}}>
|
|
<TouchableOpacity
|
|
onPress={() => this.props.navigation.navigate('PayatpumpPaymentList', { onSelectedPaymentCard: (payment_card) => this.onSelectedPaymentCard(payment_card), storeId: this.props.route?.params.storeId})}
|
|
>
|
|
<Text style={{ color: Theme.colors.primary, fontSize: 14 }}>Change</Text>
|
|
</TouchableOpacity>
|
|
<Text style={{ color: this.props.app_theme?.theme.colors.text, fontSize: 14 }}>{this.state.selectedPaymentCard.lastFour}</Text>
|
|
</View>
|
|
</>
|
|
:
|
|
<View style={{flex: 1, justifyContent: 'center', marginLeft: 10}}>
|
|
<TouchableOpacity
|
|
onPress={() => this.props.navigation.navigate('PayatpumpPaymentList', { onSelectedPaymentCard: (payment_card) => this.onSelectedPaymentCard(payment_card), storeId: this.props.route?.params.storeId})}
|
|
>
|
|
<Text style={{ color: Theme.colors.primary, fontSize: 14}}>Add Card</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
}
|
|
</View>
|
|
<View style={{flex: 1, justifyContent: 'center', alignItems: 'flex-end', paddingVertical: 25}}>
|
|
<Text style={{color: this.props.app_theme?.theme.colors.text, fontWeight: '700'}}>{"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)}</Text>
|
|
</View>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<CustomSafeArea>
|
|
<CustomHeader
|
|
customTitle={
|
|
<>
|
|
<Text style={{fontWeight: 'bold'}}>{this.state.storeName}</Text>
|
|
<Text>{'\n'}Pump No. {this.state.selectedPumpNumber}</Text>
|
|
</>
|
|
}
|
|
height={75}
|
|
onBackPress={() => this.onBackConfirmation()}
|
|
back={true}
|
|
customTitleStyle={{fontWeight: 'bold'}}
|
|
customLeftContainerStyle={{justifyContent: 'flex-start'}}
|
|
menu={false}
|
|
navigation={this.props.navigation}
|
|
/>
|
|
<Elements.loaderView
|
|
title="Validating"
|
|
message="Please wait..."
|
|
isDarkMode={this.props.app_theme?.theme.dark}
|
|
backgroundColor={this.props.app_theme?.theme.colors.border}
|
|
color={this.props.app_theme?.theme.colors.text}
|
|
visible={this.state.loading} />
|
|
<View style={{flex: 1}}>
|
|
<View style={{flexDirection: 'row', padding: 13, backgroundColor: Theme.colors.darkerGray}}>
|
|
<View style={{flex: 1}}>
|
|
<Text style={{fontFamily: 'Arial', fontSize: 14, color: '#fff'}}>Transaction Date</Text>
|
|
</View>
|
|
<View style={{flex: 1, textAlign: 'right', alignItems: 'flex-end'}}>
|
|
<Text style={{fontFamily: 'Arial', fontSize: 14, color: '#fff'}}>{moment(new Date()).format('DD MMM YYYY hh:mm A')}</Text>
|
|
</View>
|
|
</View>
|
|
{this.renderModal()}
|
|
{this.transactionTable()}
|
|
<View style={{ padding: 10 }}>
|
|
<Text style={{ fontSize: 15, color: "gray", fontWeight: '700' }}>Payment Method</Text>
|
|
</View>
|
|
<View style={{flex: 1}}>
|
|
<Divider />
|
|
|
|
<View style={{flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 30, paddingVertical: 15}}>
|
|
<Text style={{fontWeight: 'bold', fontSize: 15, color: "gray" }}>Total</Text>
|
|
<Text style={{fontWeight: 'bold', fontSize: 15, color: this.props.app_theme?.theme.colors.text }}>{"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)}</Text>
|
|
</View>
|
|
|
|
<Divider />
|
|
|
|
{this.renderSelectedCard()}
|
|
|
|
<Divider />
|
|
|
|
<View style={{flex: 1, justifyContent: 'flex-end', marginBottom: 15}}>
|
|
<View style={{ alignItems: 'center', justifyContent: 'center', marginBottom: 15 }}>
|
|
<Text style={{ color: "gray", fontSize: 15, fontWeight: 'bold' }}>Review the details before proceeding.</Text>
|
|
</View>
|
|
|
|
<TouchableOpacity onPress={() => this.setState({ showModal: true })} style={{ height: 50, backgroundColor: Theme.colors.primary, alignItems: 'center', justifyContent: 'center', borderRadius: 10, marginHorizontal: 16 }}>
|
|
<Text style={{ color: Theme.colors.white, fontSize: 23 }}>Pay {"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)}</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
</View>
|
|
</View>
|
|
</CustomSafeArea>
|
|
);
|
|
}
|
|
}
|
|
|
|
const mapStateToProps = (state) => {
|
|
return {
|
|
app_theme: state.appThemeReducer.theme
|
|
}
|
|
}
|
|
|
|
export default connect(mapStateToProps, null)(PayatpumpStationTransactionDetails)
|
|
|
|
const styles = StyleSheet.create({
|
|
centeredView: {
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
backgroundColor: '#00000090',
|
|
},
|
|
modalView: {
|
|
margin: 25,
|
|
backgroundColor: "white",
|
|
padding: 20,
|
|
alignItems: "center",
|
|
shadowColor: "#000",
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 2
|
|
},
|
|
shadowOpacity: 0.25,
|
|
shadowRadius: 4,
|
|
elevation: 5
|
|
},
|
|
}) |