import React, { useState, useEffect } from 'react'; import { StyleSheet, View, TouchableOpacity, ActivityIndicator } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; import { StarPRNT } from 'react-native-star-prnt'; import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder'; import { useTheme } from 'styled-components/native'; import { ToastType, useToast, useLanguage, OrderDetails as OrderDetailsController, useUtils, useConfig, useSession, } from 'ordering-components/native'; import { OrderDetailsContainer, Pickup, AssignDriver, DriverItem, } from './styles'; import { AcceptOrRejectOrder } from '../AcceptOrRejectOrder'; import { Chat } from '../Chat'; import { FloatingButton } from '../FloatingButton'; import { GoogleMap } from '../GoogleMap'; import { OButton, OModal, OText, OIcon } from '../shared'; import { OrderDetailsParams } from '../../types'; import { verifyDecimals, getProductPrice, getOrderStatus, getCurrenySymbol } from '../../utils'; import { USER_TYPE } from '../../config/constants'; import CountryPicker from 'react-native-country-picker-modal'; import { NotFoundSource } from '../NotFoundSource'; import { OrderHeaderComponent } from './OrderHeaderComponent'; import { OrderContentComponent } from './OrderContentComponent'; import { _retrieveStoreData } from '../../providers/StoreUtil' import { usePrinterCommands } from './usePrinterCommands' export const OrderDetailsUI = (props: OrderDetailsParams) => { const { navigation, messages, setMessages, readMessages, messagesReadList, handleAssignDriver, isFromCheckout, driverLocation, actions, orderTitle, appTitle, loadMessages, notificationApp } = props; const theme = useTheme(); const [, t] = useLanguage(); const [{ parsePrice, parseNumber, parseDate }] = useUtils(); const [{ user, token }] = useSession(); const [{ configs }] = useConfig(); const { generateCommands } = usePrinterCommands() const [, { showToast }] = useToast(); const [unreadAlert, setUnreadAlert] = useState({ business: false, driver: false, }); const { order, businessData, loading, error } = props.order; const { drivers, loadingDriver } = props.drivers; const itemsDrivers: any = []; const [actionOrder, setActionOrder] = useState(''); const [openModalForBusiness, setOpenModalForBusiness] = useState(false); const [openModalForAccept, setOpenModalForAccept] = useState(false); const [openModalForMapView, setOpenModalForMapView] = useState(false); const [isDriverModalVisible, setIsDriverModalVisible] = useState(false); const [printerSettings, setPrinterSettings] = useState('') const [autoPrintEnabled, setAutoPrintEnabled] = useState(false) const orderToComplete = [4, 20, 21] const orderToReady = [7, 14] const deliveryTypes = [1, 7] if (order?.status === 7 || order?.status === 4) { if (drivers?.length > 0 && drivers) { drivers.forEach((driver: any) => { itemsDrivers.push({ available: driver?.available, key: driver?.id, value: driver?.id, label: driver?.name, }); }); if ( !drivers?.some((driver: any) => driver?.id === order?.driver?.id) && order?.driver?.id ) { itemsDrivers.push({ available: order?.driver?.available, key: order?.driver?.id, value: order?.driver?.id, label: order?.driver?.name, }); } } if (order?.driver && (!drivers?.length || drivers?.length === 0)) { itemsDrivers.push({ available: order?.driver?.available, key: order?.driver?.id, value: order?.driver?.id, label: order?.driver?.name, }); } if (order?.driver) { itemsDrivers.push({ available: true, key: null, value: null, label: t('UNASSIGN_DRIVER', 'Unassign Driver'), }); } if (itemsDrivers.length > 0) { itemsDrivers.sort((a: any, b: any) => { if (a.available > b.available) return -1; }); } } const handleChangeOrderStatus = async (status: any, isAcceptOrReject: any = {}) => { if (props.handleChangeOrderStatus) { const order: any = await props.handleChangeOrderStatus(status, isAcceptOrReject) if (order?.status === 7 && autoPrintEnabled && printerSettings) { handleViewSummaryOrder() } return order } } const getFormattedSubOptionName = ({ quantity, name, position, price }: any) => { if (name !== 'No') { const pos = position && position !== 'whole' ? `(${t(position.toUpperCase(), position)})` : ''; return pos ? `${quantity} x ${name} ${pos} +${parsePrice(price, { currency: getCurrenySymbol(order?.currency) })}\n` : `${quantity} x ${name} +${parsePrice(price, { currency: getCurrenySymbol(order?.currency) })}\n`; } else { return 'No\n'; } }; const handleCopyClipboard = () => { const businessName = !!order?.business?.name ? `${order?.business?.name} \n` : ''; const businessEmail = !!order?.business?.email ? `${order?.business?.email} \n` : ''; const businessCellphone = !!order?.business?.cellphone ? `${order?.business?.cellphone} \n` : ''; const businessPhone = !!order?.business?.phone ? `${order?.business?.phone} \n` : ''; const businessAddress = !!order?.business?.address ? `${order?.business?.address} \n` : ''; const businessSpecialAddress = !!order?.business?.address_notes ? `${order?.business?.address_notes} \n \n` : ''; const customerName = !!order?.customer?.name ? `${order?.customer?.name} ${order?.customer?.middle_name || ''} ${order?.customer?.lastname || '' } ${order?.customer?.second_lastname || ''} \n` : ''; const customerEmail = !!order?.customer.email ? `${order?.customer.email} \n` : ''; const customerCellPhone = !!order?.customer?.cellphone ? `${order?.customer?.cellphone} \n` : ''; const customerPhone = !!order?.customer?.phone ? `${order?.customer?.phone} \n` : ''; const customerAddress = !!order?.customer?.address ? `${order?.customer?.address} \n` : ''; const customerSpecialAddress = !!order?.customer?.address_notes ? `${order?.customer?.address_notes} \n` : ''; const payment = order?.paymethod?.name ? `${order?.paymethod?.name} - ${order.delivery_type === 1 ? t('DELIVERY', 'Delivery') : order.delivery_type === 2 ? t('PICKUP', 'Pickup') : order.delivery_type === 3 ? t('EAT_IN', 'Eat in') : order.delivery_type === 4 ? t('CURBSIDE', 'Curbside') : order.delivery_type === 5 ? t('DRIVER_THRU', 'Driver thru') : order.delivery_type === 7 ? t('CATERING_DELIVERY', 'Catering delivery') : order.delivery_type === 8 ? t('CATERING_PICKUP', 'Catering pickup') : t('DELIVERY', 'Delivery') }\n` : ''; const getSuboptions = (suboptions: any) => { const array: any = [] suboptions?.length > 0 && suboptions?.map((suboption: any) => { const string = `${getFormattedSubOptionName(suboption)}` array.push(string) }) return array.join('') } const getOptions = (options: any, productComment: string = '') => { const array: any = []; options?.length && options?.map((option: any) => { const string = ` ${option.name}\n ${getSuboptions(option.suboptions)}`; array.push(string) }) if (productComment) { array.push(` ${t('COMMENT', 'Comment')}\n ${productComment}\n`) } return array.join('') } const productsInArray = order?.products.length && order?.products.map((product: any, i: number) => { const string = `${product?.quantity} X ${product?.name} ${parsePrice(product.total ?? getProductPrice(product), { currency: getCurrenySymbol(order?.currency) })}\n${getOptions(product.options, product.comment)}`; return i === 0 ? ` ${string}` : string }); const productsInString = productsInArray.join(' '); const orderDetails = `${t( 'ORDER_DETAILS', 'Order Details', )}:\n${productsInString}\n`; const subtotal = `${t('SUBTOTAL', 'Subtotal')}: ${parsePrice( order?.subtotal, { currency: getCurrenySymbol(order?.currency) } )}\n`; const drivertip = `${t('DRIVER_TIP', 'Driver tip')} ${parsePrice( order?.summary?.driver_tip || order?.totalDriverTip, { currency: getCurrenySymbol(order?.currency) } )}\n`; const deliveryFee = `${t('DELIVERY_FEE', 'Delivery fee')} ${verifyDecimals( order?.service_fee, parseNumber, )}% ${parsePrice(order?.summary?.service_fee || order?.serviceFee || 0, { currency: getCurrenySymbol(order?.currency) })}\n`; const total = `${t('TOTAL', 'Total')} ${parsePrice( order?.summary?.total || order?.total, { currency: getCurrenySymbol(order?.currency) } )}\n`; const orderStatus = `${t('INVOICE_ORDER_NO', 'Order No.')} ${order.id} ${t( 'IS', 'is', )} ${getOrderStatus(order?.status, t)?.value}\n`; Clipboard.setString( `${orderStatus} ${payment} ${t( 'BUSINESS_DETAILS', 'Business Details', )}\n ${businessName} ${businessEmail} ${businessCellphone} ${businessPhone} ${businessAddress} ${businessSpecialAddress}${t( 'CUSTOMER_DETAILS', 'Customer Details', )}\n ${customerName} ${customerEmail} ${customerCellPhone} ${customerPhone} ${customerAddress} ${customerSpecialAddress}\n${orderDetails} ${subtotal} ${drivertip} ${deliveryFee} ${total}`, ); showToast( ToastType.Info, t('COPY_TO_CLIPBOARD', 'Copy to clipboard.'), 1000, ); }; const handleOpenMessagesForBusiness = () => { setOpenModalForBusiness(true); readMessages && readMessages() loadMessages && loadMessages() setUnreadAlert({ ...unreadAlert, business: false }); }; const handleViewActionOrder = async (action: string, options?: any) => { if (openModalForMapView) { setOpenModalForMapView(false); } if (options?.forceUpdateStatus) { let bodyToSend: any = {}; const orderStatus: any = { acceptByBusiness: { status: 7, }, }; if (actions && action === 'accept') { bodyToSend = orderStatus[actions.accept]; } bodyToSend.id = order?.id; const _order = await handleChangeOrderStatus(bodyToSend?.status, bodyToSend) if (!_order?.id) { showToast(ToastType.Error, t('FAILED_TO_UPDATE_ORDER', 'Failed to update order'), 5000) return } } setActionOrder(action); setOpenModalForAccept(true); }; const printAction = async (printerSettings: any, commands: any, showAlert: boolean = true) => { try { var printResult = await StarPRNT.print(printerSettings?.emulation, commands, printerSettings?.portName); showAlert && showToast(ToastType.Info, t('ORDER_PRINTED_SUCCESS', 'Order printed'), 1000) } catch (e) { showAlert && showToast(ToastType.Error, t('ORDER_PRINTED_FAILED', 'Order not printed, connection failed'), 1000) } } const handleViewSummaryOrder = () => { if (printerSettings) { printerSettings.map((printer: any, idx: number) => { const commands: any = generateCommands({ ...order, orderStatus: getOrderStatus(order?.status, t)?.value }, printer?.printMode) commands.push({ appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed }) printAction(printer, commands, idx === printerSettings.length - 1) }) return } navigation?.navigate && navigation.navigate('OrderSummary', { order, orderStatus: getOrderStatus(order?.status, t)?.value, }); }; const handleCloseModal = () => { readMessages && readMessages() loadMessages && loadMessages() setOpenModalForBusiness(false); }; const handleOpenMapView = () => { setOpenModalForMapView(!openModalForMapView); }; const handleArrowBack: any = () => { navigation?.canGoBack() && navigation.goBack(); }; useEffect(() => { if (messagesReadList?.length) { openModalForBusiness ? setUnreadAlert({ ...unreadAlert, business: false }) : setUnreadAlert({ ...unreadAlert, driver: false }); } }, [messagesReadList]); let locations = [ { ...order?.driver?.location, title: order?.driver?.name ?? t('DRIVER', 'Driver'), icon: order?.driver?.photo || 'https://res.cloudinary.com/demo/image/fetch/c_thumb,g_face,r_max/https://www.freeiconspng.com/thumbs/driver-icon/driver-icon-14.png', level: 4, }, { ...order?.business?.location, title: order?.business?.name, address: { addressName: order?.business?.address, zipcode: order?.business?.zipcode }, icon: order?.business?.logo || 'https://res.cloudinary.com/demo/image/fetch/c_thumb,g_face,r_max/https://res.cloudinary.com/ordering2/image/upload/v1654619525/hzegwosnplvrbtjkpfi6.png', level: 2, }, { ...order?.customer?.location, title: order?.customer?.name ?? t('CUSTOMER', 'Customer'), address: { addressName: order?.customer?.address, zipcode: order?.customer?.zipcode }, icon: order?.customer?.photo || 'https://res.cloudinary.com/demo/image/upload/c_thumb,g_face,r_max/d_avatar.png/non_existing_id.png', level: 3, }, ]; useEffect(() => { if (openModalForAccept && !loading) { setOpenModalForAccept(false); } if (openModalForMapView) { setOpenModalForMapView(false); } }, [loading]); const showFloatButtonsAcceptOrReject: any = { 0: true, }; useEffect(() => { if (driverLocation) { locations[0] = { ...locations[0], driverLocation }; } }, [driverLocation]); useEffect(() => { const getStorageData = async () => { const printers = await _retrieveStoreData('printers') const autoPrint = await _retrieveStoreData('auto_print_after_accept_order') setPrinterSettings(printers?.length && printers) setAutoPrintEnabled(!!autoPrint) } getStorageData() }, []) const styles = StyleSheet.create({ driverOff: { backgroundColor: theme.colors.notAvailable, }, btnPickUp: { borderWidth: 0, backgroundColor: theme.colors.btnBGWhite, borderRadius: 8, }, }); const locationsToSend = locations.filter( (location: any) => location?.lat && location?.lng, ); return ( <> {(!order || Object.keys(order).length === 0) && (error?.length < 1 || !error) && ( {[...Array(6)].map((item, i) => ( ))} )} {(!!error || error?.length > 0) && ( navigation.navigate('Orders')} /> )} {order && Object.keys(order).length > 0 && (error?.length < 1 || !error) && ( <> {(order?.status === 7 || order?.status === 4) && deliveryTypes.includes(order?.delivery_type) && configs?.assign_driver_enabled?.value === '1' && ( {t('ASSIGN_DRIVER', 'Assign driver')} setIsDriverModalVisible(false)} withCountryNameButton renderFlagButton={() => ( <> setIsDriverModalVisible(true)} disabled={ itemsDrivers.length === 0 || loadingDriver }> {loadingDriver ? ( ) : ( {itemsDrivers.length > 0 ? order?.driver?.name || t('SELECT_DRIVER', 'Select Driver') : t('WITHOUT_DRIVERS', 'Without drivers')} )} )} flatListProps={{ keyExtractor: (item: any) => item.value, data: itemsDrivers || [], renderItem: ({ item }: any) => ( { handleAssignDriver && handleAssignDriver(item.value); setIsDriverModalVisible(false); }}> {item.label} {!item.available && ` (${t('NOT_AVAILABLE', 'Not available')})`} {item.value === order?.driver?.id && ` (${t('SELECTED', 'Selected')})`} ), }} /> )} handleCloseModal()}> setOpenModalForAccept(false)} entireModal customClose> handleOpenMapView()} entireModal customClose> {order && Object.keys(order).length > 0 && getOrderStatus(order?.status, t)?.value === t('PENDING', 'Pending') && ( handleViewActionOrder('accept', { forceUpdateStatus: true })} firstButtonClick={() => handleViewActionOrder('reject')} secondBtnText={t('ACCEPT', 'Accept')} secondButton={true} firstColorCustom={theme.colors.red} secondColorCustom={theme.colors.green} widthButton={'45%'} /> )} {orderToReady.includes(order?.status) && ( handleChangeOrderStatus?.(4)} widthButton={'100%'} disabled={loading} /> )} {orderToComplete.includes(order?.status) && !deliveryTypes.includes(order?.delivery_type) && ( handleChangeOrderStatus?.(15)} firstButtonClick={() => handleChangeOrderStatus?.(17)} secondBtnText={t( 'ORDER_PICKUP_COMPLETED_BY_CUSTOMER', 'Pickup completed by customer', )} secondButton={true} firstColorCustom={theme.colors.red} secondColorCustom={theme.colors.green} widthButton={'45%'} disabled={loading} /> )} )} ); }; export const OrderDetailsBusiness = (props: OrderDetailsParams) => { const orderDetailsProps = { ...props, UIComponent: OrderDetailsUI, }; return ; };