import React, { FC, useEffect, useState } from 'react' import { __experimentalHeading as Heading, Button, ButtonGroup, Notice, Snackbar, Spinner, } from '@wordpress/components' import bringLogo from '../../assets/img/Bring_logo.svg' import './styles.scss' import { BookingRequest, MybringCustomerAndServices, Order, Parcel, ServiceDetails, } from './model/models' import apiFetch from '@wordpress/api-fetch' import CustomerSelector from './components/CustomerSelector' import ShippingOptionSelector from './components/ShippingOptionSelector' import PackageDetails from './components/PackageDetails' import { redo, pages, search, undo } from '@wordpress/icons' import { useI18n } from '@wordpress/react-i18n' import FeedbackForm from './components/FeedbackForm' // @ts-expect-error 7016 import { getAdminLink } from '@woocommerce/settings' import CustomsInformation from './CustomsInformation' import { useEnableWpCompatOverlaySlot } from '@wordpress/ui' const OrderDetails: FC = () => { const { __ } = useI18n() useEnableWpCompatOverlaySlot() const [selectedShippingOption, setSelectedShippingOption] = useState() const [order, setOrder] = useState() const [numberOfItemsMissingHsCode, setNumberOfItemsMissingHsCode] = useState(0) const [loading, setLoading] = useState(false) const [selectedCustomer, setSelectedCustomer] = useState() const [inProgress, setInProgress] = useState(false) const [parcels, setParcels] = useState>([]) const [labelsInProgress, setLabelsInProgress] = useState(false) const [waybillsInProgress, setWaybillsInProgress] = useState(false) const [returnLabelsInProgress, setReturnLabelsInProgress] = useState(false) const [labelFailure, setLabelFailure] = useState(false) const [waybillFailure, setWaybillFailure] = useState(false) const [bringNotSelected, setBringNotSelected] = useState(false) const [updateAvailable, setUpdateAvailable] = useState(false) const [availableServices, setAvailableServices] = useState< Array >([]) const [error, setError] = useState(false) const [bookingError, setBookingError] = useState(false) const [customersAndServices, setCustomersAndServices] = useState< Array >([]) const [validationFailed, setValidationFailed] = useState(false) const urlParams = new URLSearchParams(window.location.search) const orderId = urlParams.get('post') || urlParams.get('id') const fetchOrder = (id: string) => { return apiFetch({ path: `/posten-bring-checkout/orders/${id}`, }).then((response: Order) => { if (response) { setOrder(response) setNumberOfItemsMissingHsCode( (response.nvit && response.items.filter(item => !item.hs_code || item.hs_code === '') .length) || 0 ) setBringNotSelected( (!response.order_shipping_option || response.order_shipping_option === '') && response.mybring_bookings?.length === 0 ) setValidationFailed( response.order_validation_errors.length > 0 && response.order_validation_errors.filter(it => it.bookingDisabled) .length === response.order_validation_errors.length ) } return response }) } const fetchCustomers = (from: string, to: string) => { return apiFetch>({ path: `/posten-bring-checkout/customers?from=${from}&to=${to}`, }).then(response => { if (response) { setCustomersAndServices(response) if (response.length > 0) { const defaultCustomer = response.find(it => it.defaultCustomer) setSelectedCustomer( defaultCustomer?.customerNumber || response[0].customerNumber ) } } }) } const getAvailableServices = ( from: string, to: string, totalWeight?: number ) => { return apiFetch>({ path: `/posten-bring-checkout/services?from=${from}&to=${to}&weight=${ totalWeight || 0 / 1000 }`, }).then(response => { if (response) { setAvailableServices(response) } }) } useEffect(() => { // @ts-expect-error 2339 if (window.prefetchedOrder && window.prefetchedOrder[orderId]) { // @ts-expect-error 2339 setUpdateAvailable(window.prefetchedOrder?.updateAvailable) // @ts-expect-error 2339 const prefetchedData = window.prefetchedOrder[orderId] const prefetchedOrder = prefetchedData.order as Order setOrder(prefetchedOrder) setNumberOfItemsMissingHsCode( (prefetchedOrder.nvit && prefetchedOrder.items.filter( item => !item.hs_code || item.hs_code === '' ).length) || 0 ) setBringNotSelected( (!prefetchedOrder.order_shipping_option || prefetchedOrder.order_shipping_option === '') && prefetchedOrder.mybring_bookings?.length === 0 ) setValidationFailed( prefetchedOrder.order_validation_errors.length > 0 && prefetchedOrder.order_validation_errors.filter( it => it.bookingDisabled ).length === prefetchedOrder.order_validation_errors.length ) setCustomersAndServices( prefetchedData.customers as Array ) if (prefetchedData.customers.length > 0) { const defaultCustomer = ( prefetchedData.customers as Array ).find(it => it.defaultCustomer) setSelectedCustomer( defaultCustomer?.customerNumber || prefetchedData.customers[0].customerNumber ) } setAvailableServices( prefetchedData.shippingOptions as Array ) } else { const fetchOrderCustomersAndServices = async (id: string) => { await fetchOrder(id) .then(orderResult => { return Promise.all([ fetchCustomers(orderResult.from_country, orderResult.to_country), getAvailableServices( orderResult.from_country, orderResult.to_country, orderResult.total_weight ), ]) }) .then(() => setLoading(false)) .catch(() => { setLoading(false) setError(true) }) } if (orderId) { setError(false) setLoading(true) fetchOrderCustomersAndServices(orderId) } } }, [orderId]) useEffect(() => { if ( selectedCustomer && selectedShippingOption === undefined && order?.order_shipping_option ) { setSelectedShippingOption(order.order_shipping_option) } }, [selectedShippingOption, selectedCustomer, order?.order_shipping_option]) function getServiceCode(bookingServiceCode: string): string { switch (bookingServiceCode) { case 'PICKUP_PARCEL': return '0340' case 'PICKUP_PARCEL_BULK': return '0342' case 'HOME_DELIVERY_PARCEL': return '0349' default: return bookingServiceCode } } const placeOrder = async () => { setInProgress(true) setBookingError(false) const data = { orderRef: orderId, testIndicator: false, selectedShippingOption, customerNumber: selectedCustomer, packages: parcels.map(parcel => ({ weightInKg: parcel.weightInGrams / 1000, })), } as BookingRequest apiFetch({ path: `/posten-bring-checkout/bookings?orderId=${order?.order_id}`, method: 'POST', headers: { 'Content-Type': 'application/json', }, data, }) .then(() => { setInProgress(false) setLoading(true) return fetchOrder(order!.order_id) }) .then(updatedOrder => { setOrder(updatedOrder) setLoading(false) }) .catch(() => { setLoading(false) setInProgress(false) setBookingError(true) }) } const getLabels = async (labelType: string) => { setLabelFailure(false) const newTab = window.open('', '_blank') const response = await apiFetch({ path: `/posten-bring-checkout/labels?orderIds=${orderId}&labelType=${labelType}`, method: 'GET', headers: { Accept: 'application/pdf', }, parse: false, }).catch(_ => { setLabelFailure(true) }) setLabelsInProgress(false) setReturnLabelsInProgress(false) if (response?.ok) { const blob = await response.blob() const url = window.URL.createObjectURL( new Blob([blob], { type: 'application/pdf' }) ) if (newTab) { newTab.location.href = url } } } const getWaybills = async () => { setWaybillFailure(false) const newTab = window.open('', '_blank') const response = await apiFetch({ path: `/posten-bring-checkout/waybills?orderIds=${orderId}`, method: 'GET', headers: { Accept: 'application/pdf', }, parse: false, }).catch(_ => { setWaybillFailure(true) }) setWaybillsInProgress(false) if (response?.ok) { const blob = await response.blob() const url = window.URL.createObjectURL( new Blob([blob], { type: 'application/pdf' }) ) if (newTab) { newTab.location.href = url } } } return ( <>
{loading ? (
) : ( <> {bringNotSelected ? (
{__( 'Bring has not been selected for this order', 'posten-bring-checkout' )}
) : ( <> {order && (order.mybring_bookings?.length || 0) > 0 && (
{__( 'Shipment has been ordered', 'posten-bring-checkout' )}
{order.mybring_bookings[0].waybillUrl && ( )} {order.mybring_bookings[0].returnLabelUrl && ( )} {labelFailure && ( setLabelFailure(false)} > {__( 'An error occurred while generating label. Please try again', 'posten-bring-checkout' )} )} {waybillFailure && ( setWaybillFailure(false)} > {__( 'An error occurred while generating waybill. Please try again', 'posten-bring-checkout' )} )}
{__('Shipment ', 'posten-bring-checkout') + order.mybring_bookings[0].consignmentNumber}
{ availableServices?.find( service => service.service_id === getServiceCode( order.mybring_bookings[0].serviceId ) )?.name }
{order.mybring_bookings[0].waybillUrl && (
{__( 'Do you want to order ', 'posten-bring-checkout' )}{' '} {__('pickup', 'posten-bring-checkout')} ?
)}
{order.from_country !== order.to_country && !( order.mybring_bookings[0].serviceId === '0340' && order.from_country === 'NO' ) && (
{__('Download ', 'posten-bring-checkout')} {__( 'commercial invoice', 'posten-bring-checkout' )} {__('Download ', 'posten-bring-checkout')} {__( 'Proforma invoice', 'posten-bring-checkout' )}
)}
)} {order && !error && order.mybring_bookings?.length === 0 && (
{__('Book shipping', 'posten-bring-checkout')}
{bookingError && ( {__( 'An error occurred! We have been notified and are investigating. Please try again later, or contact us via ', 'posten-bring-checkout' )} {__( 'checkout.implementering@posten.no', 'posten-bring-checkout' )} )} {order.nvit && numberOfItemsMissingHsCode > 0 && ( { setLoading(true) fetchOrder(order!.order_id) .then(updatedOrder => { setOrder(updatedOrder) setNumberOfItemsMissingHsCode( (updatedOrder.nvit && updatedOrder.items.filter( item => !item.hs_code || item.hs_code === '' ).length) || 0 ) setLoading(false) }) .finally(() => { setLoading(false) }) }} /> )} {order.order_validation_errors.length > 0 && ( {order.order_validation_errors.map( (validationError, idx) => (
{validationError.message}
) )}
)}

{__( 'By ordering, you accept our ', 'posten-bring-checkout' )} {__( 'terms and conditions.', 'posten-bring-checkout' )}

)} )} )}
{bringNotSelected ? null : (
{updateAvailable && ( {__( 'New version of Posten Bring Checkout available! ', 'posten-bring-checkout' )} {__('Update now.', 'posten-bring-checkout')} )}
)} ) } export default OrderDetails