import { Order, OrderItem, ValidationError } from './model/models' export declare interface ProductNeedingCustomsInfo { item: OrderItem nvit: boolean missingHsCode: boolean missingSku: boolean missingGoodsDescription: boolean } const CUSTOMS_VALIDATION_ERRORS = [ 'missingHsCode', 'missingProductIdentifiers', 'missingGoodsDescription', ] export const isCustomsValidationError = (validationError: ValidationError) => CUSTOMS_VALIDATION_ERRORS.includes(validationError.code) const isBlank = (value?: string) => !value || value.trim() === '' export const goodsDescriptionOwner = (item: OrderItem) => item.parent_product_id ?? item.product_id const withDetailsFrom = (item: OrderItem, other: OrderItem): OrderItem => ({ ...other, ...Object.fromEntries( Object.entries(item).filter(([, value]) => value != null) ), }) as OrderItem const needsCustomsInfo = ( product: Omit ) => product.missingHsCode || product.missingSku || product.missingGoodsDescription const missingInfoIn = ( order: Order, item: OrderItem ): ProductNeedingCustomsInfo => { const missing = { missingHsCode: !!order.requires_hs_code && isBlank(item.hs_code), missingSku: !!order.requires_sku && isBlank(item.sku), missingGoodsDescription: !!order.requires_goods_description && isBlank(item.goods_description), } return { item, nvit: !!order.nvit || !needsCustomsInfo(missing), ...missing, } } const missingInfoPerProduct = ( orders: Array ): Array => [ ...orders .flatMap(order => order.items.map(item => missingInfoIn(order, item))) .reduce((products, product) => { const earlier = products.get(product.item.product_id) return products.set( product.item.product_id, earlier ? { item: withDetailsFrom(earlier.item, product.item), nvit: earlier.nvit && product.nvit, missingHsCode: earlier.missingHsCode || product.missingHsCode, missingSku: earlier.missingSku || product.missingSku, missingGoodsDescription: earlier.missingGoodsDescription || product.missingGoodsDescription, } : product ) }, new Map()) .values(), ] const goodsDescriptionOnFirstVariationOnly = ( products: Array ): Array => products.map((product, index) => ({ ...product, missingGoodsDescription: product.missingGoodsDescription && products.findIndex( it => it.missingGoodsDescription && goodsDescriptionOwner(it.item) === goodsDescriptionOwner(product.item) ) === index, })) export const productsNeedingCustomsInfo = ( orders: Array ): Array => goodsDescriptionOnFirstVariationOnly(missingInfoPerProduct(orders)).filter( needsCustomsInfo )