import { date } from 'alga-js' import refreshTokenHelper from "../../../../utils/refreshTokenHelper" import getTokenHelper from "../../../../utils/getTokenHelper" import forceLogoutHelper from "../../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../../utils/errorHandlingHelper" import fetchHelper from "../../../../utils/fetchHelper" import dhlHelper from "../../../../utils/dhlHelper" import dhlCustomHelper from "../../../../utils/dhlCustomHelper" import strapiHelper from "../../../../utils/strapiHelper" // Helper function to save CN23 customs document to order attachments via Strapi const saveCustomsDocToOrder = async (event: any, orderId: number, orderUid: string, customsDocBase64: string, shipmentNo: string) => { const config = useRuntimeConfig() try { // First, get or create the attachment record for C_Order (table ID 259) let strapiAttachmentId: number | null = null const existingResponse: any = await strapiHelper(event, `ad-attachments?filters[AD_Table_ID][$eq]=259&filters[Record_ID][$eq]=${orderId}`, 'GET', null) if(existingResponse?.data?.[0]?.id) { strapiAttachmentId = existingResponse.data[0].id } else { // Create new attachment record const newAttachmentResp: any = await strapiHelper(event, `ad-attachments`, 'POST', { data: { AD_Table_ID: 259, Record_ID: orderId, Record_UU: orderUid } }) if(newAttachmentResp?.data?.id) { strapiAttachmentId = newAttachmentResp.data.id } } if(strapiAttachmentId) { // Convert base64 to blob and upload const timestamp = date.now().replace(/[-:]/g, '_').replace(' ', '-') const fileName = `CN23-${shipmentNo}-${timestamp}.pdf` // Create a Buffer from base64 const pdfBuffer = Buffer.from(customsDocBase64, 'base64') // Create FormData for upload const FormData = (await import('form-data')).default const formData = new FormData() formData.append('field', 'attachment') formData.append('ref', 'api::ad-attachment.ad-attachment') formData.append('refId', String(strapiAttachmentId)) formData.append('files', pdfBuffer, { filename: fileName, contentType: 'application/pdf' }) formData.append('fileInfo', JSON.stringify({ caption: `CN23 Customs Document - Shipment ${shipmentNo}`, alternativeText: `CN23-${shipmentNo}`, name: fileName })) // Upload to Strapi (use /api/upload, not /media-api/upload which has custom logic that may fail) const uploadResponse = await $fetch(`${config.api.strapi}/upload`, { method: 'POST', headers: { Authorization: `Bearer ${config.api.strapitoken}`, ...formData.getHeaders() }, body: formData }) return { success: true, strapiAttachmentId, uploadResponse } } return { success: false, error: 'Could not get or create attachment record' } } catch(error: any) { console.error('[CN23] Error saving customs document to Strapi:', error) return { success: false, error: error.message || 'Unknown error' } } } const handleInoutFunc = async (event: any, authToken: any = null, option: any) => { let data: any = {} const token = authToken ?? await getTokenHelper(event) const trackingPayload: any = { TrackingNo: option.tracking_number, DHL_Shipment_Code: option.shipment_code, DHL_Routing_Code: option.routing_code, DHL_Label_Base64: option.label_base64, IsCommissioned: true, shipping_date: date.now('', '', {timeZone: 'UTC'}).replace(' ', 'T')+'Z', shipping_service_name: option.shippingService, tableName: 'M_Inout' } if(option.paket_type) { trackingPayload['M_Paket_Type_ID'] = option.paket_type } if(option.isDHLKleinPaket) { trackingPayload['isDHLKleinPaket'] = true } // Note: CN23 customs document is saved to Strapi attachments, not to M_Inout // (DHL_Customs_Doc_Base64 column does not exist in M_Inout table) const resp: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, trackingPayload) if(resp) { data['shipment'] = resp data['status'] = 200 data['message'] = '' if(resp?.IsCommissionedConfirmed !== true) { const resp2: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id+'?$expand=c_order_id,m_inoutline,c_bpartner_location_id,ad_org_id', 'GET', token, null) // Helper function to format order number with first word of company name const formatOrderNumber = () => { const documentNo = resp2?.C_Order_ID?.DocumentNo ?? '0' const companyName = resp2?.AD_Org_ID?.companyname ?? '' const firstWord = companyName.trim().split(/\s+/)[0] || '' return firstWord ? `${documentNo}-${firstWord}` : documentNo } if(resp2?.C_Order_ID?.C_OrderSource_ID?.id) { const resp3: any = await fetchHelper(event, 'models/c_ordersource/'+resp2.C_Order_ID.C_OrderSource_ID.id, 'GET', token, null) // Debug: Log order source information console.log('[DEBUG] Order Source Info:', { orderSourceId: resp2.C_Order_ID.C_OrderSource_ID.id, orderSourceValue: resp3?.value, marketplaceIdentifier: resp3?.Marketplace?.identifier, marketplaceUrl: resp3?.marketplace_url, hasShopware6: !!resp2?.C_Order_ID?.shopware6_order_id, hasShopify: !!resp2?.C_Order_ID?.shopify_order_id, hasAmazon: !!resp2?.C_Order_ID?.amazon_order_id, hasPlentyone: !!resp2?.C_Order_ID?.plentyone_order_id, hasJTLFFN: !!(resp2?.C_Order_ID?.ExternalOrderId && resp3?.Marketplace?.identifier === 'jtl-ffn'), externalOrderId: resp2?.C_Order_ID?.ExternalOrderId }) // Add order source debug info to data data['orderSourceDebug'] = { orderSourceId: resp2.C_Order_ID.C_OrderSource_ID.id, orderSourceValue: resp3?.value, marketplaceIdentifier: resp3?.Marketplace?.identifier, marketplaceUrl: resp3?.marketplace_url, detectedPlatform: resp2?.C_Order_ID?.shopware6_order_id ? 'shopware6' : resp2?.C_Order_ID?.shopify_order_id ? 'shopify' : resp2?.C_Order_ID?.amazon_order_id ? 'amazon' : resp2?.C_Order_ID?.plentyone_order_id ? 'plentyone' : (resp2?.C_Order_ID?.ExternalOrderId && resp3?.Marketplace?.identifier === 'jtl-ffn') ? 'jtl-ffn' : 'unknown' } if(resp2?.C_Order_ID?.shopware6_order_id) { if(resp3?.marketplace_url) { try { const resp4: any = await laravelHelper(event, 'sales/orders/mark-shopware-order-delivery', 'POST', { marketplace_url: resp3.marketplace_url, marketplace_key: resp3.marketplace_key, marketplace_secret: resp3.marketplace_secret, id: resp2.C_Order_ID.shopware6_order_id, trackingCodes: [option.tracking_number], mail: { email: option.customerEmail, isSentCustomTrackingMail: option.isSentCustomTrackingMail, orderNumber: formatOrderNumber(), name: resp2?.C_Order_ID?.C_BPartner?.identifier ?? 'Mr/Ms', company: 'LogYou GmbH', carrier: option.shippingService ?? 'DHL', lines: resp2?.m_inoutline?.map((i: any) => ({ description: i.M_Product_ID.identifier, quantity: i.QtyEntered })) ?? [], address1: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address1 ?? '', address2: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address2 ?? '', city: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.City ?? '', country: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier ?? '', postal: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Postal ?? '' } }) if(resp4) { const resp5: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, { IsCommissionedConfirmed: true, ack_commissioned_laravel: true, tableName: 'M_Inout' }) } } catch(err: any) { data['shopware'] = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } } } if(resp2?.C_Order_ID?.shopify_order_id) { if(resp3?.marketplace_url) { try { const resp4: any = await laravelHelper(event, 'sales/orders/mark-shopify-order-delivery', 'POST', { orderSource: resp3, id: resp2.C_Order_ID.shopify_order_id, trackingCodes: { number: option.tracking_number, url: option.tracking_url, company: 'DHL Express' }, mail: { email: option.customerEmail, isSentCustomTrackingMail: option.isSentCustomTrackingMail, orderNumber: formatOrderNumber(), name: resp2?.C_Order_ID?.C_BPartner?.identifier ?? 'Mr/Ms', company: 'LogYou GmbH', carrier: option.shippingService ?? 'DHL', lines: resp2?.m_inoutline?.map((i: any) => ({ description: i.M_Product_ID.identifier, quantity: i.QtyEntered })) ?? [], address1: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address1 ?? '', address2: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address2 ?? '', city: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.City ?? '', country: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier ?? '', postal: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Postal ?? '' } }) if(resp4) { const resp5: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, { IsCommissionedConfirmed: true, ack_commissioned_laravel: true, tableName: 'M_Inout' }) } } catch(err: any) { data['shopify'] = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } } } if(resp2?.C_Order_ID?.amazon_order_id) { if(resp3?.marketplace_url) { data['amazon'] = resp3 try { const resp4: any = await laravelHelper(event, 'sales/orders/mark-amazon-order-delivery', 'POST', { orderSource: resp3, id: resp2.C_Order_ID.amazon_order_id, details: { shippingDate: trackingPayload.shipping_date, carrierCode: 'DHL', shippingMethod: 'Paket', referenceId: resp2?.DocumentNo ?? option.inout_id }, trackingCodes: { number: option.tracking_number, url: option.tracking_url, // company: 'DHL Home Delivery', // 'DHL', 'DHL eCommerce', 'DHL Express', 'DHL Freight', 'DHL Global Mail', 'DHL Home Delivery', 'DHL Kargo', 'DHL-Paket', 'DHL Parcel UK', 'DHLPL', }, mail: { email: option.customerEmail, isSentCustomTrackingMail: option.isSentCustomTrackingMail, orderNumber: formatOrderNumber(), name: resp2?.C_Order_ID?.C_BPartner?.identifier ?? 'Mr/Ms', company: 'LogYou GmbH', carrier: option.shippingService ?? 'DHL', lines: resp2?.m_inoutline?.map((i: any) => ({ description: i.M_Product_ID.identifier, quantity: i.QtyEntered })) ?? [], address1: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address1 ?? '', address2: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address2 ?? '', city: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.City ?? '', country: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier ?? '', postal: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Postal ?? '' } }) if(resp4) { const resp5: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, { IsCommissionedConfirmed: true, ack_commissioned_laravel: true, tableName: 'M_Inout' }) } } catch(err: any) { data['amazon'] = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } } } if(resp2?.C_Order_ID?.plentyone_order_id) { if(resp3?.marketplace_url) { try { data['plentyone'] = resp3 const plentyOneWeight = resp2?.m_inoutline?.reduce((acc: any, prev: any) => Number(acc['Weight'] ?? 0) + Number(prev['Weight'] ?? 0), 0) const resp4: any = await laravelHelper(event, 'sales/orders/mark-plentyone-order-delivery', 'POST', { orderSource: resp3, id: resp2.C_Order_ID.plentyone_order_id, details: { shippingDate: trackingPayload.shipping_date, carrierCode: 'DHL', shippingMethod: 'Paket', referenceId: resp2?.DocumentNo ?? option.inout_id, weight: plentyOneWeight ?? 0 }, trackingCodes: { number: option.tracking_number, url: option.tracking_url, // company: 'DHL Home Delivery', // 'DHL', 'DHL eCommerce', 'DHL Express', 'DHL Freight', 'DHL Global Mail', 'DHL Home Delivery', 'DHL Kargo', 'DHL-Paket', 'DHL Parcel UK', 'DHLPL', }, mail: { email: option.customerEmail, isSentCustomTrackingMail: option.isSentCustomTrackingMail, orderNumber: formatOrderNumber(), name: resp2?.C_Order_ID?.C_BPartner?.identifier ?? 'Mr/Ms', company: 'LogYou GmbH', carrier: option.shippingService ?? 'DHL', lines: resp2?.m_inoutline?.map((i: any) => ({ description: i.M_Product_ID.identifier, quantity: i.QtyEntered })) ?? [], address1: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address1 ?? '', address2: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address2 ?? '', city: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.City ?? '', country: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier ?? '', postal: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Postal ?? '' } }) data['plentyone_laravel'] = resp4 if(resp4) { const resp5: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, { IsCommissionedConfirmed: true, ack_commissioned_laravel: true, tableName: 'M_Inout' }) } } catch(err: any) { data['plentyone'] = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } } } if(resp2?.C_Order_ID?.ExternalOrderId && resp3?.Marketplace?.identifier === 'jtl-ffn') { console.log('[DEBUG] JTL-FFN Order Detected:', { externalOrderId: resp2.C_Order_ID.ExternalOrderId, orderSourceValue: resp3?.value, marketplaceIdentifier: resp3?.Marketplace?.identifier, marketplaceUrl: resp3?.marketplace_url, endpoint: 'sales/orders/mark-jtl-order-delivery', hasMarketplaceUrl: !!resp3?.marketplace_url }) if(resp3?.marketplace_url) { console.log('[DEBUG] JTL-FFN: Sending order confirmation to Laravel endpoint:', { endpoint: 'sales/orders/mark-jtl-order-delivery', marketplaceUrl: resp3.marketplace_url, orderId: resp2.C_Order_ID.ExternalOrderId, trackingNumber: option.tracking_number }) try { const resp4: any = await laravelHelper(event, 'sales/orders/mark-jtl-order-delivery', 'POST', { orderSource: resp3, id: resp2.C_Order_ID.ExternalOrderId, details: { shippingDate: trackingPayload.shipping_date, carrierCode: 'DHL', shippingMethod: 'Paket', referenceId: resp2?.DocumentNo ?? option.inout_id, weight: 0 }, trackingCodes: { number: option.tracking_number, url: option.tracking_url, }, mail: { email: option.customerEmail, isSentCustomTrackingMail: option.isSentCustomTrackingMail, orderNumber: formatOrderNumber(), name: resp2?.C_Order_ID?.C_BPartner?.identifier ?? 'Mr/Ms', company: 'LogYou GmbH', carrier: option.shippingService ?? 'DHL', lines: resp2?.m_inoutline?.map((i: any) => ({ description: i.M_Product_ID.identifier, quantity: i.QtyEntered })) ?? [], address1: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address1 ?? '', address2: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Address2 ?? '', city: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.City ?? '', country: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier ?? '', postal: resp2?.C_Order_ID?.C_BPartner_Location_ID?.C_Location_ID?.Postal ?? '' } }) console.log('[DEBUG] JTL-FFN: Laravel response:', { success: !!resp4, response: resp4 }) data['jtl_laravel'] = resp4 if(resp4) { console.log('[DEBUG] JTL-FFN: Marking order as commissioned confirmed') const resp5: any = await fetchHelper(event, 'models/m_inout/'+option.inout_id, 'PUT', token, { IsCommissionedConfirmed: true, ack_commissioned_laravel: true, tableName: 'M_Inout' }) } } catch(err: any) { console.error('[DEBUG] JTL-FFN: Error during order confirmation:', err) data['jtl'] = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } } else { console.warn('[DEBUG] JTL-FFN: No marketplace_url configured for order source') data['jtl_warning'] = 'No marketplace_url configured for JTL-FFN order source' } } } } } return data } const handleFunc = async (event: any) => { let data: any = {} const config = useRuntimeConfig() const body = await readBody(event) let dhlCustomActive = false let dhlCustomData = {} let customerEmail = 'fulfillcustomer@logyou.de' let isSentCustomTrackingMail = false const tokenEmail = await getTokenHelper(event) //@ts-ignore const respInout: any = await fetchHelper(event, 'models/m_inout/'+body.inOutId+'?$expand=c_order_id,ad_org_id', 'GET', tokenEmail, null) if(respInout?.C_Order_ID?.C_OrderSource_ID?.id) { //@ts-ignore const respOrderSource: any = await fetchHelper(event, 'models/c_ordersource/'+respInout.C_Order_ID.C_OrderSource_ID.id, 'GET', tokenEmail, null) isSentCustomTrackingMail = respOrderSource?.isSentCustomTrackingMail ?? false if(body.email) { customerEmail = (respOrderSource?.isExcludetrackingmail ? 'fulfillcustomer@logyou.de' : body.email) } if(respOrderSource?.DHL_USE_CUSTOM == true && respOrderSource?.DHLURL) { dhlCustomActive = true dhlCustomData = { dhlurl: respOrderSource.DHLURL, dhlkey: respOrderSource.DHLKEY, dhlsecret: respOrderSource.DHLSECRET, dhluser: respOrderSource.DHLUSER, dhlpass: respOrderSource.DHLPASS, iscustom: respOrderSource.DHL_USE_CUSTOM, dhl_billing_number_de: respOrderSource.dhl_billing_number_de || '63291441520101', dhl_billing_number_int: respOrderSource.dhl_billing_number_int || '63291441525301' } } } let customerPhone = '+49 987654321' if(body.telephone) { customerPhone = body.telephone } let newObjValue = {} // Build customs object with CN23 support let customsObj: any = { exportType: body.customsExportType || 'OTHER', postalCharges: { currency: body.totalOrderValueCurrency ?? 'EUR', value: 0 }, // Shipper's customs reference (customer reference of sender on CN23 form) shipperCustomsRef: 'EORIDE321993855047810/0000', } // Add export description if exportType is OTHER if(customsObj.exportType === 'OTHER' && body.customsExportDescription) { customsObj.exportDescription = String(body.customsExportDescription).substring(0, 80) } if(body.parcelItems) { customsObj = { ...customsObj, items: body.parcelItems.map((item: any) => { const itemData: any = { itemDescription: String(item.description ?? '').trim().substring(0, 256), packagedQuantity: item.quantity, itemValue: { currency: body.totalOrderValueCurrency ?? 'EUR', value: item.value }, itemWeight: { uom: 'kg', value: item.weight }, } // Add CN23 specific fields if provided if(item.hsCode) { itemData.hsCode = String(item.hsCode).substring(0, 11) } if(item.countryOfOrigin) { itemData.countryOfOrigin = String(item.countryOfOrigin).substring(0, 3).toUpperCase() } return itemData }) } } if(body.orderNumber) { customsObj = {...customsObj, invoiceNo: String(body.orderNumber).substring(0, 35)} } if(customsObj?.items) { newObjValue = { ...newObjValue, customs: customsObj } } let newConsigneeValue = {} if(body.name2) { newConsigneeValue = {...newConsigneeValue, name2: String(body.name2 ?? '').trim()} } if(body.address2) { newConsigneeValue = {...newConsigneeValue, name3: String(body.address2 ?? '').trim()} } /*if(body.shipmentId) { newObjValue = {...newObjValue, shipment: { id: body.shipmentId } } } if(body.companyName) { newObjValue = {...newObjValue, company_name: body.companyName} } if(body.address2) { newObjValue = {...newObjValue, address_2: body.address2} } if(body.countryState) { newObjValue = {...newObjValue, country_state: body.countryState} } if(body.toServicePoint) { newObjValue = {...newObjValue, to_service_point: body.toServicePoint} } if(body.toPostNumber) { newObjValue = {...newObjValue, to_post_number: body.toPostNumber} } if(body.customsInvoiceNR) { newObjValue = {...newObjValue, customs_invoice_nr: body.customsInvoiceNR} } if(body.customsShipmentType) { newObjValue = {...newObjValue, customs_shipment_type: body.customsShipmentType} } if(body.totalOrderValue) { newObjValue = {...newObjValue, total_order_value: body.totalOrderValue} } if(body.totalOrderValueCurrency) { newObjValue = {...newObjValue, total_order_value_currency: body.totalOrderValueCurrency} } if(body.shippingMethodCheckoutName) { newObjValue = {...newObjValue, shipping_method_checkout_name: body.shippingMethodCheckoutName} } if(body.senderAddress) { newObjValue = {...newObjValue, sender_address: body.senderAddress} } if(body.quantity) { newObjValue = {...newObjValue, quantity: body.quantity} } if(body.totalInsuredValue) { newObjValue = {...newObjValue, total_insured_value: body.totalInsuredValue} } { parcel: { name: body.name, address: body.address, city: body.city, country: body.country, postal_code: String(body.postalCode), house_number: String(body.houseNumber || 0), is_return: body.isReturn, request_label: body.requestLabel, apply_shipping_rules: body.applyShippingRules, request_label_async: body.requestLabelAsync, external_reference: body.inOutId, ...newObjValue, } }*/ // Format order number with first word of company name and sanitize special characters const companyName = respInout?.AD_Org_ID?.companyname ?? '' const firstWord = companyName.trim().split(/\s+/)[0]?.replace(/[^a-zA-Z0-9]/g, '') || '' const baseOrderNumber = body.orderNumber ?? body.inOutUId.replaceAll('-', '') const formattedOrderNumber = firstWord ? `${baseOrderNumber}-${firstWord}` : baseOrderNumber let refNo = formattedOrderNumber let refNoDigit = '' if(refNo.length < 9) { refNoDigit = '0' for(let i = 0; i < (9 - Number(refNo.length)); i++) { refNoDigit += '0' refNo = `${refNoDigit}${refNo}` } } // Debug variables for product selection const debugWeight = parseFloat(Number(body.weight ?? 0).toFixed(2)); const debugPaketTypeCode = body.paketType; const debugOrderTotal = respInout?.C_Order_ID?.GrandTotal ?? 0; const debugCountry = body.country; // Fetch Kleinpaket settings from the organization's linked C_BPartner let kleinpaketSettings: any = { KleinPaketPriceLimit: null, isPriceLimitKleinpaketDisabled: false } const orgId = respInout?.AD_Org_ID?.id if (orgId) { try { const orgRes: any = await fetchHelper( event, `models/ad_org/${orgId}?$select=C_BPartner_ID`, 'GET', tokenEmail, null ) const orgBpartnerId = orgRes?.C_BPartner_ID?.id if (orgBpartnerId) { const partnerRes: any = await fetchHelper( event, `models/c_bpartner/${orgBpartnerId}?$select=KleinPaketPriceLimit,isPriceLimitKleinpaketDisabled`, 'GET', tokenEmail, null ) if (partnerRes) { kleinpaketSettings.KleinPaketPriceLimit = partnerRes.KleinPaketPriceLimit ?? null kleinpaketSettings.isPriceLimitKleinpaketDisabled = partnerRes.isPriceLimitKleinpaketDisabled ?? false } console.log(`[DHL Kleinpaket] Fetched settings from Org ${orgId} -> BPartner ${orgBpartnerId}:`, kleinpaketSettings) } else { console.log(`[DHL Kleinpaket] Organization ${orgId} has no linked C_BPartner, using default settings`) } } catch (err: any) { console.error(`[DHL Kleinpaket] Error fetching org business partner settings:`, err?.message || err) } } else { console.log(`[DHL Kleinpaket] No organization ID found on shipment, using default settings`) } // Determine the price limit for Kleinpaket eligibility const defaultPriceLimit = 20 const configuredPriceLimit = kleinpaketSettings.KleinPaketPriceLimit const isPriceLimitDisabled = kleinpaketSettings.isPriceLimitKleinpaketDisabled === true // Use configured limit if it's a valid number > 0, otherwise use default (20) const effectivePriceLimit = (configuredPriceLimit && configuredPriceLimit > 0) ? configuredPriceLimit : defaultPriceLimit // Check price condition: if disabled, always true; otherwise compare to effective limit const meetsPriceCondition = isPriceLimitDisabled || (debugOrderTotal < effectivePriceLimit) console.log(`[DHL Kleinpaket] Price condition check:`) console.log(` - Order GrandTotal: ${debugOrderTotal} EUR`) console.log(` - Configured KleinPaketPriceLimit: ${configuredPriceLimit}`) console.log(` - isPriceLimitKleinpaketDisabled: ${isPriceLimitDisabled}`) console.log(` - Effective price limit: ${isPriceLimitDisabled ? 'DISABLED (no limit)' : effectivePriceLimit + ' EUR'}`) console.log(` - Meets price condition: ${meetsPriceCondition}`) // Check if criteria for V62KP (DHL Kleinpaket) are met const weightCondition = debugWeight < 1 const paketTypeCondition = debugPaketTypeCode === 1000911 const countryCondition = debugCountry === 'DE' const meetsV62KPCriteria = ( weightCondition && paketTypeCondition && meetsPriceCondition && countryCondition ); console.log(`[DHL Kleinpaket] V62KP eligibility check:`) console.log(` - Weight < 1kg: ${weightCondition} (weight: ${debugWeight} kg)`) console.log(` - Paket Type = 1000911: ${paketTypeCondition} (type: ${debugPaketTypeCode})`) console.log(` - Price condition met: ${meetsPriceCondition}`) console.log(` - Country = DE: ${countryCondition} (country: ${debugCountry})`) console.log(` - RESULT: ${meetsV62KPCriteria ? 'ELIGIBLE for V62KP (Kleinpaket)' : 'NOT eligible - using standard product'}`) const payLoad = { product: meetsV62KPCriteria ? 'V62KP' : (body.country === 'DE' ? 'V01PAK' : 'V53WPAK'), billingNumber: meetsV62KPCriteria ? '63807218926201' : (body.country === 'DE' ? '63807218920101' : '63807218925301'), refNo: refNo, shipper: { name1: respInout?.AD_Org_ID?.companyname && respInout?.AD_Org_ID !== 1000000 ? respInout?.AD_Org_ID?.companyname : 'LogYou GmbH', name2: respInout?.AD_Org_ID?.companyname && respInout?.AD_Org_ID !== 1000000 ? 'c/o LogYou GmbH' : '', addressStreet: 'Mühlenweg', addressHouse: '4', postalCode: '35510', city: 'Butzbach', country: 'DEU', email: 'info@logyou.de', phone: '+4960339160570' }, consignee: { name1: String(body.name ?? '').trim(), addressStreet: String(body.address ?? '').trim(), addressHouse: String(body.houseNumber || 0).trim(), postalCode: String(body.postalCode ?? '').trim(), city: String(body.city ?? '').trim(), country: body.countryIso3 || body.countryName?.toUpperCase()?.replaceAll(' ', '')?.slice(0, 3), email: String(customerEmail ?? '').trim(), phone: String(customerPhone ?? '').trim(), ...newConsigneeValue }, details: { dim: { uom: 'cm', height: parseFloat(Number(body.height ?? 0).toFixed(2)), length: parseFloat(Number(body.length ?? 0).toFixed(2)), width: parseFloat(Number(body.width ?? 0).toFixed(2)) }, weight: { uom: 'kg', value: parseFloat((Number(body.weight ?? 0) + 0.25).toFixed(2)) } }, ...newObjValue } let res: any = {} if(dhlCustomActive) { payLoad['billingNumber'] = body.country === 'DE' ? dhlCustomData['dhl_billing_number_de'] : dhlCustomData['dhl_billing_number_int'] res = await dhlCustomHelper(event, dhlCustomData, 'shipping/v2/orders?printFormat=910-300-400', 'POST', { profile: 'STANDARD_GRUPPENPROFIL', shipments: [ payLoad ] }) //data['dhl_custom'] = dhlCustomData } else { res = await dhlHelper(event, 'shipping/v2/orders?printFormat=910-300-400', 'POST', { profile: 'STANDARD_GRUPPENPROFIL', shipments: [ payLoad ] }) } if(res?.items?.[0]) { data['dhl_parcel'] = res.items[0] // Check if CN23 customs document is present in response const customsDocBase64 = res.items[0]?.customsDoc?.b64 || null if(customsDocBase64) { data['hasCustomsDoc'] = true data['customsDoc'] = { b64: customsDocBase64, fileFormat: res.items[0]?.customsDoc?.fileFormat || 'PDF' } } // Save CN23 customs document to order attachments via Strapi (if present and enableCN23 is true) if(customsDocBase64 && body.enableCN23) { try { // Get the order ID and UID from the shipment const token = await getTokenHelper(event) const shipmentData: any = await fetchHelper(event, `models/m_inout/${body.inOutId}?$expand=c_order_id`, 'GET', token, null) if(shipmentData?.C_Order_ID?.id) { const orderId = shipmentData.C_Order_ID.id const orderUid = shipmentData.C_Order_ID.uid || '' const shipmentNo = res.items[0].shipmentNo const strapiResult = await saveCustomsDocToOrder(event, orderId, orderUid, customsDocBase64, shipmentNo) data['strapiCustomsDoc'] = strapiResult if(strapiResult.success) { console.log(`[CN23] Successfully saved customs document to order ${orderId} attachment in Strapi`) } else { console.error(`[CN23] Failed to save customs document to Strapi:`, strapiResult.error) } } else { console.error('[CN23] Could not find order ID from shipment') } } catch(strapiError: any) { console.error('[CN23] Error saving customs document to Strapi:', strapiError) data['strapiCustomsDocError'] = strapiError.message || 'Unknown error' } } try { const res2 = await handleInoutFunc(event, null, { inout_id: body.inOutId, tracking_number: res.items[0].shipmentNo, tracking_url: res.items[0].routingCode, shipment_code: res.items[0].shipmentNo, routing_code: res.items[0].routingCode, label_base64: res.items[0].label.b64, customs_doc_base64: customsDocBase64, paket_type: body.paketType, shippingService: body.shippingService, customerEmail: customerEmail, isSentCustomTrackingMail: isSentCustomTrackingMail, isDHLKleinPaket: meetsV62KPCriteria, }) data = {...data, ...res2} } catch(err: any) { try { let authToken: any = await refreshTokenHelper(event) const res3 = await handleInoutFunc(event, authToken, { inout_id: body.inOutId, tracking_number: res.items[0].shipmentNo, tracking_url: res.items[0].routingCode, shipment_code: res.items[0].shipmentNo, routing_code: res.items[0].routingCode, label_base64: res.items[0].label.b64, customs_doc_base64: customsDocBase64, paket_type: body.paketType, shippingService: body.shippingService, customerEmail: customerEmail, isSentCustomTrackingMail: isSentCustomTrackingMail, isDHLKleinPaket: meetsV62KPCriteria, }) data = {...data, ...res3} } catch(error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) //forceLogoutHelper(event, data) } } } else { data['status'] = 500 data['message'] = res?.status?.detail ?? 'DHL Parcel is not being created!' } // Add debug information to response data['debug'] = { productSelection: { weight: debugWeight, paketTypeCode: debugPaketTypeCode, orderTotal: debugOrderTotal, country: debugCountry, selectedProduct: payLoad.product, selectedBillingNumber: payLoad.billingNumber, conditions: { weightUnder1kg: weightCondition, isPaketTypeCode1000911: paketTypeCondition, isGermany: countryCondition, meetsPriceCondition: meetsPriceCondition, meetsV62KPCriteria: meetsV62KPCriteria }, kleinpaketSettings: { orgId: orgId, KleinPaketPriceLimit: configuredPriceLimit, isPriceLimitKleinpaketDisabled: isPriceLimitDisabled, effectivePriceLimit: isPriceLimitDisabled ? null : effectivePriceLimit, defaultPriceLimit: defaultPriceLimit } }, payload: payLoad } return data } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch(err: any) { data = errorHandlingHelper(err?.data ?? err, err?.data ?? err) } return data })