crpt
This commit is contained in:
		
							
								
								
									
										287
									
								
								src/screens/AssemblyScreen/AssemblyControls.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								src/screens/AssemblyScreen/AssemblyControls.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,287 @@
 | 
			
		||||
import {useDispatch, useSelector} from "react-redux";
 | 
			
		||||
import {RootState, useAppDispatch} from "../../redux/store";
 | 
			
		||||
import {ASSEMBLY_STATE} from "../../types/assembly";
 | 
			
		||||
import {StyleSheet, Text, View} from "react-native";
 | 
			
		||||
import BasicButton, {BasicButtonProps} from "../../components/BasicButton/BasicButton";
 | 
			
		||||
import {BaseButton} from "react-native-gesture-handler";
 | 
			
		||||
import {
 | 
			
		||||
    confirmAssembly, endAssembly,
 | 
			
		||||
    openAcceptModal,
 | 
			
		||||
    selectProduct,
 | 
			
		||||
    setAssembled,
 | 
			
		||||
    skipCrpt
 | 
			
		||||
} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import {useScanningContext} from "../../providers/ScanProvider";
 | 
			
		||||
import assemblyApi from "../../api/assemblyApi";
 | 
			
		||||
import {OkMessageResponse} from "../../types/api";
 | 
			
		||||
import Toast from "react-native-toast-message";
 | 
			
		||||
import {useEffect, useState} from "react";
 | 
			
		||||
import {RFPercentage} from "react-native-responsive-fontsize";
 | 
			
		||||
import {responsiveHeight} from "react-native-responsive-dimensions";
 | 
			
		||||
import {closeLoadingModal, openLoadingModal, setLoadingText} from "../../features/loadingModal/loadingModalSlice";
 | 
			
		||||
import printingService from "../../utils/PrintingService";
 | 
			
		||||
import printingApi from "../../api/printingApi";
 | 
			
		||||
import {setPrinterName} from "../../features/printing/printingSlice";
 | 
			
		||||
import {openReprintModal} from "../../features/reprintModal/reprintModalSlice";
 | 
			
		||||
import {showReward} from "../../features/animations/animationsSlice";
 | 
			
		||||
import {fetchBalance, refreshTransactions} from "../../features/balance/balanceSlice";
 | 
			
		||||
import {NavigationProp, useNavigation} from "@react-navigation/native";
 | 
			
		||||
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const AssemblyButton = (props: BasicButtonProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <BasicButton
 | 
			
		||||
            {...props}
 | 
			
		||||
            containerStyle={{flex: 1}}
 | 
			
		||||
        />
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
const NotStartedButtons = () => {
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const onStartAssembly = () => {
 | 
			
		||||
        dispatch(openAcceptModal());
 | 
			
		||||
    }
 | 
			
		||||
    return (
 | 
			
		||||
        <AssemblyButton
 | 
			
		||||
            label={"Начать сборку"}
 | 
			
		||||
            onPress={onStartAssembly}
 | 
			
		||||
        />
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ScanningCrptButtons = () => {
 | 
			
		||||
    const dispatch = useAppDispatch();
 | 
			
		||||
 | 
			
		||||
    const state = useSelector((state: RootState) => state.assembly);
 | 
			
		||||
    const [isInitialized, setIsInitialized] = useState(false);
 | 
			
		||||
    const getNeedState = () => {
 | 
			
		||||
        if (!state.order) return {};
 | 
			
		||||
        return state.order.products.reduce((acc, product) => {
 | 
			
		||||
            acc[product.databaseId] = false;
 | 
			
		||||
            return acc;
 | 
			
		||||
        }, {} as { [key: number]: boolean })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [crptNeedState, setCrptNeedState] = useState<{ [key: number]: boolean }>(getNeedState());
 | 
			
		||||
    const {scan} = useScanningContext();
 | 
			
		||||
    const onAttached = (response: OkMessageResponse) => {
 | 
			
		||||
 | 
			
		||||
        Toast.show({
 | 
			
		||||
            type: response.ok ? "success" : "error",
 | 
			
		||||
            text1: "Сканирование честного знака",
 | 
			
		||||
            text2: response.message,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (!response.ok) return
 | 
			
		||||
 | 
			
		||||
        setCrptNeedState(prevState => {
 | 
			
		||||
            if (!state.selectedProduct) return prevState;
 | 
			
		||||
            return {...prevState, [state.selectedProduct.databaseId]: false}
 | 
			
		||||
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    const onScanned = (data: string) => {
 | 
			
		||||
        if (!state.selectedProduct) return;
 | 
			
		||||
        assemblyApi.attachCrpt(state.selectedProduct.databaseId, data).then(onAttached);
 | 
			
		||||
    }
 | 
			
		||||
    const onScanClick = () => {
 | 
			
		||||
        scan({callback: onScanned});
 | 
			
		||||
    }
 | 
			
		||||
    const initialize = async () => {
 | 
			
		||||
        dispatch(setLoadingText('Проверка необходимости сканирования честного знака...'))
 | 
			
		||||
        dispatch(openLoadingModal());
 | 
			
		||||
        if (!state.order) return;
 | 
			
		||||
        const responses = await Promise.all(state.order.products.map(async (product) => {
 | 
			
		||||
            const response = await assemblyApi.needCrpt(product.databaseId);
 | 
			
		||||
            return {productId: product.databaseId, need: response.needCrpt};
 | 
			
		||||
        }));
 | 
			
		||||
        // update state
 | 
			
		||||
        setCrptNeedState(responses.reduce((acc, {productId, need}) => {
 | 
			
		||||
            acc[productId] = need;
 | 
			
		||||
            return acc;
 | 
			
		||||
        }, {} as { [key: number]: boolean }));
 | 
			
		||||
 | 
			
		||||
        setIsInitialized(true);
 | 
			
		||||
        dispatch(closeLoadingModal());
 | 
			
		||||
        ////
 | 
			
		||||
        ////
 | 
			
		||||
        dispatch(selectProduct(0))
 | 
			
		||||
    }
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!isInitialized) return;
 | 
			
		||||
        if (Object.values(crptNeedState).every(value => !value))
 | 
			
		||||
            dispatch(skipCrpt())
 | 
			
		||||
    }, [crptNeedState]);
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        initialize();
 | 
			
		||||
    }, []);
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
            <AssemblyButton
 | 
			
		||||
                disabled={!state.selectedProduct || !crptNeedState[state.selectedProduct.databaseId]}
 | 
			
		||||
                onPress={onScanClick}
 | 
			
		||||
                label={"Сканировать честный знак"}
 | 
			
		||||
            />
 | 
			
		||||
            <AssemblyButton
 | 
			
		||||
                onPress={() => {
 | 
			
		||||
                    dispatch(skipCrpt())
 | 
			
		||||
                }}
 | 
			
		||||
                label={"Пропустить"}
 | 
			
		||||
            />
 | 
			
		||||
        </>
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const AssemblingButtons = () => {
 | 
			
		||||
    const dispatch = useAppDispatch();
 | 
			
		||||
    const state = useSelector((state: RootState) => state.assembly);
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        dispatch(selectProduct(0));
 | 
			
		||||
    }, []);
 | 
			
		||||
    return (
 | 
			
		||||
        <AssemblyButton
 | 
			
		||||
            disabled={state.selectedProduct?.assembled}
 | 
			
		||||
            onPress={() => {
 | 
			
		||||
                if (!state.selectedProduct) return;
 | 
			
		||||
                dispatch(setAssembled({orderProductId: state.selectedProduct.databaseId}));
 | 
			
		||||
            }}
 | 
			
		||||
            label={"Отметить как собранный"}
 | 
			
		||||
        />
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const AllProductsAssembledButtons = () => {
 | 
			
		||||
    const dispatch = useAppDispatch();
 | 
			
		||||
    const state = useSelector((state: RootState) => state.assembly);
 | 
			
		||||
 | 
			
		||||
    const [skipButtonVisible, setSkipButtonVisible] = useState(false);
 | 
			
		||||
 | 
			
		||||
    const onConfirmClick = () => {
 | 
			
		||||
        if (!state.assembly) return;
 | 
			
		||||
        dispatch(setLoadingText('Подтверждение сборки...'))
 | 
			
		||||
        dispatch(openLoadingModal());
 | 
			
		||||
        assemblyApi.confirm(state.assembly.databaseId).then(({ok, message}) => {
 | 
			
		||||
            dispatch(closeLoadingModal());
 | 
			
		||||
            Toast.show({
 | 
			
		||||
                type: ok ? 'success' : 'error',
 | 
			
		||||
                text1: 'Подтверждение сборки',
 | 
			
		||||
                text2: message
 | 
			
		||||
            })
 | 
			
		||||
            if (ok) {
 | 
			
		||||
                dispatch(confirmAssembly());
 | 
			
		||||
            } else {
 | 
			
		||||
                setSkipButtonVisible(true);
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    const onSkipClick = () => {
 | 
			
		||||
        dispatch(confirmAssembly());
 | 
			
		||||
    }
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
            <AssemblyButton label={"Подтвердить сборку"} onPress={onConfirmClick}/>
 | 
			
		||||
            {skipButtonVisible && <AssemblyButton label={"Пропустить"} onPress={onSkipClick}/>}
 | 
			
		||||
        </>
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ConfirmedButtons = () => {
 | 
			
		||||
    const navigator = useNavigation<NavigationProp<TabNavigatorParamList, 'Barcode'>>();
 | 
			
		||||
 | 
			
		||||
    const dispatch = useAppDispatch();
 | 
			
		||||
    const order = useSelector((state: RootState) => state.assembly.order);
 | 
			
		||||
    const assembly = useSelector((state: RootState) => state.assembly.assembly);
 | 
			
		||||
    const onPrintLabel = () => {
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
        if (!order) return;
 | 
			
		||||
        let printer = printingService.getInstance().getPrinter(order.baseMarketplace);
 | 
			
		||||
        dispatch(setLoadingText('Идет печать этикетки...'))
 | 
			
		||||
        dispatch(openLoadingModal())
 | 
			
		||||
        printingApi.getLabel(order.databaseId).then(pdfData => {
 | 
			
		||||
            printingService.getInstance().printPdf(printer, pdfData).then((response) => {
 | 
			
		||||
                dispatch(closeLoadingModal());
 | 
			
		||||
                if (response) return;
 | 
			
		||||
                dispatch(setPrinterName({printerName: printer}));
 | 
			
		||||
                dispatch(openReprintModal());
 | 
			
		||||
            });
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    const onEndAssembly = () => {
 | 
			
		||||
        if (!assembly) return;
 | 
			
		||||
        assemblyApi.close(assembly.databaseId).then(({ok, message, reward}) => {
 | 
			
		||||
            Toast.show({
 | 
			
		||||
                type: ok ? 'success' : 'error',
 | 
			
		||||
                text1: 'Завершение сборки',
 | 
			
		||||
                text2: message
 | 
			
		||||
            });
 | 
			
		||||
            if (ok) {
 | 
			
		||||
                dispatch(showReward({reward}));
 | 
			
		||||
                dispatch(fetchBalance())
 | 
			
		||||
                dispatch(refreshTransactions())
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dispatch(endAssembly());
 | 
			
		||||
            navigator.navigate('Barcode');
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        onPrintLabel();
 | 
			
		||||
    }, []);
 | 
			
		||||
    return (<>
 | 
			
		||||
        <AssemblyButton
 | 
			
		||||
            onPress={onPrintLabel}
 | 
			
		||||
            label={"Печать этикетки"}/>
 | 
			
		||||
        <AssemblyButton
 | 
			
		||||
            onPress={onEndAssembly}
 | 
			
		||||
            label={"Завершить сборку"}/>
 | 
			
		||||
    </>)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const EndedButtons = () => {
 | 
			
		||||
    return (<></>)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const AssemblyControls = () => {
 | 
			
		||||
    const state = useSelector((state: RootState) => state.assembly);
 | 
			
		||||
    const getButtons = () => {
 | 
			
		||||
        if (state.localState === undefined) return (<BasicButton
 | 
			
		||||
            label={"Ошибка"}
 | 
			
		||||
            disabled={true}
 | 
			
		||||
        />)
 | 
			
		||||
 | 
			
		||||
        switch (state.localState) {
 | 
			
		||||
            case ASSEMBLY_STATE.NOT_STARTED:
 | 
			
		||||
                return <NotStartedButtons/>
 | 
			
		||||
            case ASSEMBLY_STATE.SCANNING_CRPT:
 | 
			
		||||
                return <ScanningCrptButtons/>
 | 
			
		||||
            case ASSEMBLY_STATE.ASSEMBLING_PRODUCTS:
 | 
			
		||||
                return <AssemblingButtons/>
 | 
			
		||||
            case ASSEMBLY_STATE.ALL_PRODUCTS_ASSEMBLED:
 | 
			
		||||
                return <AllProductsAssembledButtons/>
 | 
			
		||||
            case ASSEMBLY_STATE.CONFIRMED:
 | 
			
		||||
                return <ConfirmedButtons/>
 | 
			
		||||
            case ASSEMBLY_STATE.ENDED:
 | 
			
		||||
                return <EndedButtons/>
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return (<>{getButtons()}</>)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
    buttonsContainer: {
 | 
			
		||||
        backgroundColor: "white",
 | 
			
		||||
        padding: RFPercentage(2),
 | 
			
		||||
        flex: 0.5,
 | 
			
		||||
        borderRadius: RFPercentage(3),
 | 
			
		||||
        rowGap: responsiveHeight(2)
 | 
			
		||||
    },
 | 
			
		||||
})
 | 
			
		||||
export default AssemblyControls;
 | 
			
		||||
		Reference in New Issue
	
	Block a user