441 lines
22 KiB
TypeScript
441 lines
22 KiB
TypeScript
|
import React, { useEffect, useRef, useState } from 'react';
|
||
|
import { ScrollView, View, Text, Image, TouchableOpacity, BackHandler, Dimensions, ImageBackground, Alert } from 'react-native';
|
||
|
import { Ionicons } from '@expo/vector-icons';
|
||
|
import config from '../../components/data/config.json'
|
||
|
import { styles } from '@/components/style/style';
|
||
|
import { useNavigation, NavigationProp, useFocusEffect } from '@react-navigation/native';
|
||
|
import { GestureHandlerRootView, NativeViewGestureHandler, TextInput } from 'react-native-gesture-handler';
|
||
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||
|
import { cfg, getStorage } from '@/components/lib/cfg';
|
||
|
import { DB } from '@/components/lib/db';
|
||
|
import DetailOrder from '@/components/pageComponent/detailOrder';
|
||
|
|
||
|
const formatNumber = function (number: any) {
|
||
|
return number.toLocaleString('id-ID', {
|
||
|
minimumFractionDigits: 0,
|
||
|
maximumFractionDigits: 0
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
function formatDate(dateString: any) {
|
||
|
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||
|
|
||
|
// Parse the date string
|
||
|
const date = new Date(dateString);
|
||
|
|
||
|
// Extract year, month, and date
|
||
|
const year = date.getFullYear();
|
||
|
const month = months[date.getMonth()];
|
||
|
const day = String(date.getDate()).padStart(2, '0');
|
||
|
|
||
|
// Format the date string
|
||
|
const formattedDate = `${day} ${month} ${year}`;
|
||
|
|
||
|
// Return the object with the desired structure
|
||
|
return {
|
||
|
bulan: month,
|
||
|
tanggal: day,
|
||
|
tahun: year,
|
||
|
date: formattedDate
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const Contact = ({ setData, setForm, data: mapOfData, setDataOrder, setDataOrderList, setShowDetail }: any) => {
|
||
|
return (
|
||
|
<>
|
||
|
{(Array.isArray(mapOfData) ? mapOfData : []).map((data: any, key: number) =>
|
||
|
<View key={key} style={{
|
||
|
paddingLeft: 10,
|
||
|
backgroundColor: "green",
|
||
|
marginBottom: 10,
|
||
|
overflow: 'hidden',
|
||
|
borderRadius: 5
|
||
|
}}>
|
||
|
<View style={[
|
||
|
{ padding: 10, backgroundColor: 'white' }
|
||
|
, { flexDirection: "row", alignItems: "center" }
|
||
|
]}>
|
||
|
<View style={[{ flexDirection: "row" }, { flex: 1 }]}>
|
||
|
<View style={{ width: 38 }}>
|
||
|
<Text style={{
|
||
|
fontSize: 14
|
||
|
, textAlign: 'center'
|
||
|
, fontWeight: 'bold'
|
||
|
}}>{formatDate(data?.date_order).bulan}</Text>
|
||
|
<Text style={{
|
||
|
fontSize: 24
|
||
|
, textAlign: 'center'
|
||
|
, fontWeight: '900'
|
||
|
}}>{formatDate(data?.date_order).tanggal}</Text>
|
||
|
<Text style={{
|
||
|
fontSize: 14
|
||
|
, textAlign: 'center'
|
||
|
, fontWeight: 'bold'
|
||
|
}}>{formatDate(data?.date_order).tahun}</Text>
|
||
|
</View>
|
||
|
<View style={{ paddingHorizontal: 10, flexDirection: 'column' }}>
|
||
|
<Text ellipsizeMode='tail' style={[{
|
||
|
flex: 1
|
||
|
, fontWeight: '700'
|
||
|
, fontSize: 16
|
||
|
}]}>
|
||
|
Order : {data?.name}
|
||
|
</Text>
|
||
|
<Text ellipsizeMode='tail' style={[{
|
||
|
flex: 1
|
||
|
, fontWeight: '700'
|
||
|
, fontSize: 18
|
||
|
}]}>
|
||
|
{data?.cus.toUpperCase()}
|
||
|
</Text>
|
||
|
<Text ellipsizeMode='tail' style={[{
|
||
|
flex: 1,
|
||
|
color: 'red',
|
||
|
fontWeight: 'bold'
|
||
|
, fontSize: 18
|
||
|
}]}>
|
||
|
Rp {formatNumber(Number(data?.amount_total))}
|
||
|
</Text>
|
||
|
</View>
|
||
|
</View>
|
||
|
<View style={{ width: 120, flexDirection: 'column' }}>
|
||
|
<View style={{ height: '100%', flex: 1 }}>
|
||
|
<TouchableOpacity onPress={ ()=>{
|
||
|
setForm(true);
|
||
|
setData(data)
|
||
|
} }>
|
||
|
<Text style={{paddingVertical:10, backgroundColor:"orange", paddingHorizontal:5, color: 'black', textAlign: 'center', borderRadius:10, fontSize: 16, fontWeight: '800' }}>{(`Bayar\n Tagihan`)}</Text>
|
||
|
</TouchableOpacity>
|
||
|
</View>
|
||
|
</View>
|
||
|
</View>
|
||
|
</View>
|
||
|
)}
|
||
|
</>
|
||
|
)
|
||
|
}
|
||
|
|
||
|
const PelunasanSreen = () => {
|
||
|
const [bgHead, setBgHead] = useState<any>(null)
|
||
|
const [nama, setNama] = useState('John Doe');
|
||
|
const [Id, setId] = useState('John Doe');
|
||
|
const [formTitle, setFormTitle] = useState('Perusahaan');
|
||
|
const [formArea, setFormArea] = useState('none');
|
||
|
const [email, setEmail] = useState('example@mail.com');
|
||
|
const [inputVal, setInputVal] = useState('');
|
||
|
const [formName, setFormName] = useState('');
|
||
|
const [datatext, setDataText] = useState('example@mail.com');
|
||
|
const inputRef = useRef<TextInput>(null); // Create a ref for the TextInput
|
||
|
let heightWIndow = Dimensions.get('window').height + 80;
|
||
|
const [contact, setContact] = useState<any>([]);
|
||
|
const [salesTotal, setSalesTotal] = useState(0);
|
||
|
const [showDetail, setShowDetail] = useState(false);
|
||
|
const [dataOrder, setDataOrder] = useState<any>({})
|
||
|
const [dataOrderList, setDataOrderList] = useState<any>([])
|
||
|
const [dataForm, setDataForm] = useState(false);
|
||
|
const [dataPaan, setDataPaan] = useState<any>({});
|
||
|
const [produk, setProduk] = useState<{
|
||
|
name: string
|
||
|
, value: string
|
||
|
}[]>([]);
|
||
|
const [timer, setTimer] = useState(60); // Initialize timer state
|
||
|
|
||
|
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||
|
|
||
|
|
||
|
useFocusEffect(
|
||
|
React.useCallback(() => {
|
||
|
|
||
|
const onBackPress = () => {
|
||
|
if (showDetail === true) {
|
||
|
setShowDetail(false)
|
||
|
} else {
|
||
|
if (dataForm){
|
||
|
setDataForm(false);
|
||
|
}else{
|
||
|
navigation.navigate("home");
|
||
|
}
|
||
|
}
|
||
|
return true; // Prevent default behavior (exit app)
|
||
|
};
|
||
|
|
||
|
BackHandler.addEventListener('hardwareBackPress', onBackPress);
|
||
|
navigation.setOptions({ headerLeft: () => null }); // Remove back button
|
||
|
|
||
|
return () => {
|
||
|
BackHandler.removeEventListener('hardwareBackPress', onBackPress);
|
||
|
};
|
||
|
}, [navigation, showDetail, setShowDetail, setDataForm, dataForm])
|
||
|
);
|
||
|
|
||
|
|
||
|
const callData = async () => {
|
||
|
let data: any = await AsyncStorage.getItem('login');
|
||
|
data = JSON.parse(data);
|
||
|
data = data.length > 0 ? data[0] : {};
|
||
|
await DB(`CREATE TABLE IF NOT EXISTS sort_payment (
|
||
|
name VARCHAR(100),
|
||
|
data JSON
|
||
|
)`);
|
||
|
console.log("hallo")
|
||
|
let sales: any = await DB(`
|
||
|
SELECT
|
||
|
sa.write_date,
|
||
|
sa.date_order,
|
||
|
sa.name,
|
||
|
sa.access_token as token,
|
||
|
sa.partner_id,
|
||
|
rp.name as cus,
|
||
|
sa.id,
|
||
|
rp.email,
|
||
|
rp.street,
|
||
|
sa.amount_total,
|
||
|
sa.amount_tax,
|
||
|
sa.amount_untaxed,
|
||
|
sa.amount_to_invoice
|
||
|
FROM sale_order sa
|
||
|
LEFT JOIN res_partner rp ON sa.partner_id = rp.id
|
||
|
ORDER BY sa.name DESC LIMIT 10
|
||
|
`);
|
||
|
let salesTotalNumber: any = await DB(`
|
||
|
SELECT
|
||
|
count(*) as total
|
||
|
FROM sale_order sa
|
||
|
`);
|
||
|
|
||
|
setSalesTotal(salesTotalNumber.length > 0 ? Number(salesTotalNumber[0].total) : 0)
|
||
|
|
||
|
setId(data?.id)
|
||
|
setNama(data?.name)
|
||
|
setEmail("Salesman")
|
||
|
|
||
|
let country = 'Indonesia';
|
||
|
if (data?.country_id) {
|
||
|
const negara: any = await getStorage('negara')
|
||
|
const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id);
|
||
|
country = name;
|
||
|
}
|
||
|
|
||
|
setContact(sales);
|
||
|
};
|
||
|
|
||
|
cfg.action['history'] = () => {
|
||
|
callData()
|
||
|
}
|
||
|
|
||
|
useEffect(() => {
|
||
|
(function () {
|
||
|
callData()
|
||
|
})();
|
||
|
}, [])
|
||
|
|
||
|
const customerBack = function () {
|
||
|
navigation.navigate('home')
|
||
|
}
|
||
|
|
||
|
const fabAction = function () {
|
||
|
// console.log("action")
|
||
|
}
|
||
|
|
||
|
const onScroll = (event: any) => {
|
||
|
const yOffset = event.nativeEvent.contentOffset.y;
|
||
|
if (yOffset > 80) {
|
||
|
setBgHead(config.color.primary)
|
||
|
} else {
|
||
|
setBgHead(null)
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const [pembayaran, setPembayaran] = useState('')
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
{
|
||
|
showDetail === true ?
|
||
|
<DetailOrder order={dataOrder} orderlist={dataOrderList} config={config} act={setShowDetail} />
|
||
|
: <>
|
||
|
{dataForm?<>
|
||
|
|
||
|
<GestureHandlerRootView>
|
||
|
<NativeViewGestureHandler>
|
||
|
<View>
|
||
|
<View style={{
|
||
|
overflow: "hidden",
|
||
|
height: 120,
|
||
|
flexDirection: "row",
|
||
|
alignItems: "flex-end"
|
||
|
}}>
|
||
|
<ImageBackground
|
||
|
source={require('../../assets/images/bg/SORT_bg_Order.png')}
|
||
|
style={{
|
||
|
flexDirection: "row"
|
||
|
, alignItems: 'flex-end'
|
||
|
, top: 0
|
||
|
, height: 300
|
||
|
}}
|
||
|
>
|
||
|
<View style={[{ paddingVertical: 20, paddingBottom: 30, width: "100%" }]}>
|
||
|
<Text style={{
|
||
|
textAlign: "center"
|
||
|
, fontSize: 24
|
||
|
, fontWeight: 'bold'
|
||
|
, color: "white"
|
||
|
, marginBottom: 5
|
||
|
}}>{(`buat pelunasan`).toUpperCase()}</Text>
|
||
|
</View>
|
||
|
</ImageBackground>
|
||
|
</View>
|
||
|
<View style={{marginTop:40, paddingHorizontal :20}}>
|
||
|
<Text style={{fontSize:20, fontWeight:'600'}}>{dataPaan?.name}</Text>
|
||
|
<View style={{
|
||
|
display:"flex",
|
||
|
flexDirection:"row",
|
||
|
borderBottomWidth: 1,
|
||
|
paddingBottom:10
|
||
|
}}>
|
||
|
<Text style={{ fontSize:20,fontWeight:'600'}}>Total :</Text>
|
||
|
<Text style={{ flex: 1, fontSize: 20, fontWeight: '600' }}> Rp {formatNumber(Number(dataPaan?.amount_total))}</Text>
|
||
|
</View>
|
||
|
<View style={{
|
||
|
marginVertical:10
|
||
|
}}>
|
||
|
<Text style={{marginBottom:5, marginTop:10}}>Tanggal :</Text>
|
||
|
<TextInput style={{
|
||
|
height:20
|
||
|
, borderRadius:10
|
||
|
, marginBottom:10
|
||
|
, fontWeight:'600'
|
||
|
, color:"#000"
|
||
|
}} editable={false} value={formatDate(new Date(dataPaan.date_order)).date} />
|
||
|
|
||
|
<Text style={{ marginBottom: 5 }}>Total Pembayaran :</Text>
|
||
|
<TextInput style={{
|
||
|
height:40,
|
||
|
borderWidth:1,
|
||
|
paddingHorizontal: 10
|
||
|
, borderRadius:10
|
||
|
}} value={pembayaran} onChangeText={setPembayaran} keyboardType="decimal-pad" placeholder='500.000' />
|
||
|
<TouchableOpacity onPress={()=>{
|
||
|
if(pembayaran == ''){
|
||
|
Alert.alert('Info', 'Isi nilai pembayaran terlebih dahulu.')
|
||
|
}else{
|
||
|
Alert.alert('Info', 'Pembayaran telah berhasil dilakukan')
|
||
|
console.log(dataPaan)
|
||
|
dataPaan.payment = Number(pembayaran);
|
||
|
let query = `
|
||
|
INSERT INTO sort_payment (name, data)
|
||
|
SELECT '${dataPaan.name}', '${JSON.stringify(dataPaan)}'
|
||
|
WHERE NOT EXISTS (
|
||
|
SELECT 1 FROM sort_payment WHERE name = '${dataPaan.name}'
|
||
|
);
|
||
|
`;
|
||
|
// console.log(query);
|
||
|
DB(query).then(function(){
|
||
|
setDataForm(false);
|
||
|
});
|
||
|
}
|
||
|
}}>
|
||
|
<View>
|
||
|
<Text style={{
|
||
|
padding:10,
|
||
|
backgroundColor:'orange',
|
||
|
fontSize: 18,
|
||
|
textAlign:'center'
|
||
|
, borderRadius: 10
|
||
|
, marginTop: 20
|
||
|
, fontWeight: '600'
|
||
|
}}>Simpan Pembayaran</Text>
|
||
|
</View>
|
||
|
</TouchableOpacity>
|
||
|
</View>
|
||
|
</View>
|
||
|
</View>
|
||
|
</NativeViewGestureHandler>
|
||
|
</GestureHandlerRootView>
|
||
|
</>:<>
|
||
|
<GestureHandlerRootView>
|
||
|
<View style={[{
|
||
|
position:'absolute',
|
||
|
top: 0,
|
||
|
left: 0,
|
||
|
backgroundColor: bgHead != '' ? bgHead : 'none',
|
||
|
padding: 10,
|
||
|
zIndex: 3, // Make sure it stays on top of other content
|
||
|
}, styles.flexStartBottom, { width: '100%', height: 80, justifyContent: 'flex-start', position: 'absolute', top: 0 }]}>
|
||
|
<TouchableOpacity onPress={customerBack}>
|
||
|
<Ionicons style={{ padding: 8, marginHorizontal: 8, borderRadius: 30, backgroundColor: "rgba(0,0,0,.2)" }} name='arrow-back-outline' size={20} color={'white'}></Ionicons>
|
||
|
</TouchableOpacity>
|
||
|
</View>
|
||
|
<ScrollView onScroll={onScroll}>
|
||
|
<View style={styles.container}>
|
||
|
<View style={{
|
||
|
overflow: "hidden",
|
||
|
height: 120,
|
||
|
flexDirection: "row",
|
||
|
alignItems: "flex-end"
|
||
|
}}>
|
||
|
<ImageBackground
|
||
|
source={require('../../assets/images/bg/SORT_bg_Order.png')}
|
||
|
style={{
|
||
|
flexDirection: "row"
|
||
|
, alignItems: 'flex-end'
|
||
|
, top: 0
|
||
|
, height: 300
|
||
|
}}
|
||
|
>
|
||
|
<View style={[{ paddingVertical: 20, paddingBottom: 30, width: "100%" }]}>
|
||
|
<Text style={{
|
||
|
textAlign: "center"
|
||
|
, fontSize: 24
|
||
|
, fontWeight: 'bold'
|
||
|
, color: "white"
|
||
|
, marginBottom: 5
|
||
|
}}>{(`pelunasan`).toUpperCase()}</Text>
|
||
|
</View>
|
||
|
</ImageBackground>
|
||
|
</View>
|
||
|
<View style={{ position: "static"}}>
|
||
|
<View style={{ marginVertical: 10, flexDirection: "row", paddingHorizontal: 20 }}>
|
||
|
<TextInput style={{
|
||
|
flex: 1,
|
||
|
backgroundColor: "white",
|
||
|
height: 40,
|
||
|
paddingHorizontal: 10,
|
||
|
borderColor: "#333",
|
||
|
borderWidth: 1,
|
||
|
borderRadius: 4
|
||
|
}} placeholder={`search`}></TextInput>
|
||
|
<View style={{
|
||
|
width: 50
|
||
|
, height: 40
|
||
|
, marginLeft: 10
|
||
|
, flexDirection: "row"
|
||
|
, justifyContent: "center"
|
||
|
, alignItems: "center"
|
||
|
, backgroundColor: "gray"
|
||
|
}}>
|
||
|
<Image
|
||
|
source={require('../../assets/images/icons/filter.png')}
|
||
|
style={{ width: 20, height: 20 }}
|
||
|
/>
|
||
|
</View>
|
||
|
</View>
|
||
|
<View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}>
|
||
|
</View>
|
||
|
<View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}>
|
||
|
<Contact setData={setDataPaan} setForm={setDataForm} setShowDetail={setShowDetail} setDataOrderList={setDataOrderList} setDataOrder={setDataOrder} data={contact}></Contact>
|
||
|
</View>
|
||
|
</View>
|
||
|
</View>
|
||
|
</ScrollView>
|
||
|
</GestureHandlerRootView>
|
||
|
</>}
|
||
|
</>
|
||
|
}
|
||
|
</>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
|
||
|
export default PelunasanSreen;
|