import { string } from 'alga-js' import refreshTokenHelper from "../../utils/refreshTokenHelper" import forceLogoutHelper from "../../utils/forceLogoutHelper" import errorHandlingHelper from "../../utils/errorHandlingHelper" import getTokenHelper from "../../utils/getTokenHelper" import fetchHelper from "../../utils/fetchHelper" const handleFunc = async (event: any, authToken: any = null) => { let data: any = {} const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const searchTerm = body?.search || '' const organizationId = body?.organizationId || null if (!searchTerm) { throw createError({ statusCode: 400, statusMessage: 'Search term is required' }) } // Collect all matching BPartner IDs from multiple searches const bpartnerIdSet = new Set() // Convert search term to lowercase for case-insensitive search const searchTermLower = searchTerm.toLowerCase() // Build organization filter if provided const orgFilter = organizationId ? ` AND AD_Org_ID eq ${organizationId}` : '' // 1. Search for BPartners by name (case-insensitive contains search) const bpartnerFilter = string.urlEncode( `(contains(tolower(Name),'${searchTermLower}') OR contains(tolower(Name2),'${searchTermLower}')) AND isActive eq true${orgFilter}` ) const bpartnerRes: any = await fetchHelper( event, `models/c_bpartner?$filter=${bpartnerFilter}&$top=30`, 'GET', token, null ) if (bpartnerRes?.records) { bpartnerRes.records.forEach((bp: any) => bpartnerIdSet.add(bp.id)) } // 2. Search for BPartner Locations by Name and Name2 (case-insensitive) const locationFilter = string.urlEncode( `(contains(tolower(Name),'${searchTermLower}') OR contains(tolower(Name2),'${searchTermLower}')) AND isActive eq true${orgFilter}` ) const locationRes: any = await fetchHelper( event, `models/c_bpartner_location?$filter=${locationFilter}&$expand=C_BPartner_ID&$top=30`, 'GET', token, null ) if (locationRes?.records) { locationRes.records.forEach((loc: any) => { if (loc.C_BPartner_ID?.id) { bpartnerIdSet.add(loc.C_BPartner_ID.id) } }) } // If no BPartners found, return empty if (bpartnerIdSet.size === 0) { return { bpartners: [], shipments: [] } } const bpartnerIds = Array.from(bpartnerIdSet) // Search for shipments (outbound - C-) that are completed for these BPartners // Note: Organization filter is NOT applied to shipments, only to BPartner/Location name search const shipmentFilters = bpartnerIds.map((id: number) => `C_BPartner_ID eq ${id}`).join(' OR ') const shipmentFilter = string.urlEncode( `MovementType eq 'C-' AND isActive eq true AND DocStatus eq 'CO' AND (${shipmentFilters})` ) const shipmentsRes: any = await fetchHelper( event, `models/m_inout?$filter=${shipmentFilter}&$expand=${string.urlEncode('m_inoutline($expand=m_product_id,c_uom_id,m_locator_id),C_Order_ID,C_BPartner_ID,C_BPartner_Location_ID,AD_User_ID,M_Warehouse_ID,AD_Org_ID')}&$orderby=${string.urlEncode('MovementDate desc')}&$top=50`, 'GET', token, null ) // Build bpartners list from the found records const bpartnersMap = new Map() if (bpartnerRes?.records) { bpartnerRes.records.forEach((bp: any) => { bpartnersMap.set(bp.id, { id: bp.id, name: bp.Name, value: bp.Value }) }) } // Also add BPartners found via location search if (locationRes?.records) { locationRes.records.forEach((loc: any) => { if (loc.C_BPartner_ID?.id && !bpartnersMap.has(loc.C_BPartner_ID.id)) { bpartnersMap.set(loc.C_BPartner_ID.id, { id: loc.C_BPartner_ID.id, name: loc.C_BPartner_ID.Name || loc.C_BPartner_ID.identifier, value: loc.C_BPartner_ID.Value }) } }) } data = { bpartners: Array.from(bpartnersMap.values()), shipments: shipmentsRes?.records || [] } return data } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch(err: any) { try { let authToken: any = await refreshTokenHelper(event) data = await handleFunc(event, authToken) } catch(error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) throw createError({ statusCode: err?.statusCode || 500, statusMessage: err?.statusMessage || 'Error searching BPartner shipments', data: data }) } } return data })