import { string } from 'alga-js' import refreshTokenHelper from "../../../../utils/refreshTokenHelper" import forceLogoutHelper from "../../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../../utils/errorHandlingHelper" const idempiereFilterName = (key: string) => { const map: Record = { name: 'Name', value: 'Value', sku: 'SKU', mpn: 'mpn', upc: 'UPC', weight: 'Weight', width: 'Width', length: 'Length', height: 'Height', volume: 'Volume', isBOM: 'IsBOM', organization: 'AD_Org_ID', qtyonhand: 'QtyOnHand' } return map[key] || '' } const filterHandler = (filterModel: any) => { let newFilter = '' for (const key of Object.keys(filterModel)) { const filterName = idempiereFilterName(key) if (!filterName) continue if (newFilter !== '') { newFilter += ' AND ' } const item = filterModel[key] if (item.filterType == 'text') { newFilter += textFilterHandler(filterName, item) } else if (item.filterType == 'number') { newFilter += numberFilterHandler(filterName, item) } } if (newFilter !== '') { newFilter = ` AND (${newFilter})` } return newFilter } const numberFilterHandler = (key: string, item: any) => { let newNumberFilter = '' if (item.type == 'equals') { newNumberFilter = `${key} eq ${item.filter}` } else if (item.type == 'notEqual') { newNumberFilter = `${key} neq ${item.filter}` } else if (item.type == 'greaterThan') { newNumberFilter = `${key} gt ${item.filter}` } else if (item.type == 'greaterThanOrEqual') { newNumberFilter = `${key} ge ${item.filter}` } else if (item.type == 'lessThan') { newNumberFilter = `${key} lt ${item.filter}` } else if (item.type == 'lessThanOrEqual') { newNumberFilter = `${key} le ${item.filter}` } else if (item.type == 'inRange') { newNumberFilter = `${key} ge ${item.filter} AND ${key} le ${item.filterTo}` } return newNumberFilter } const textFilterHandler = (key: string, item: any) => { let newTextFilter = '' if (item.type == 'equals') { newTextFilter = `${key} eq ${item.filter}` } else if (item.type == 'notEqual') { newTextFilter = `${key} neq ${item.filter}` } else if (item.type == 'contains') { newTextFilter = `contains(${key},${item.filter.replaceAll('%', '')})` } else if (item.type == 'notContains') { newTextFilter = `not contains(${key},${item.filter.replaceAll('%', '')})` } else if (item.type == 'startsWith') { newTextFilter = `startswith(${key},'${item.filter}')` } else if (item.type == 'endsWith') { newTextFilter = `endswith(${key},'${item.filter}')` } return newTextFilter } const sortHandler = (sortModel: any[]) => { if (!sortModel || sortModel.length === 0) { return 'M_Product_ID desc' } const parts = sortModel.map((s: any) => { const col = idempiereFilterName(s.colId) if (!col) return '' return `${col} ${s.sort}` }).filter(Boolean) return parts.length > 0 ? parts.join(',') : 'M_Product_ID desc' } const storageCount = (storages: any[], key: string) => { return storages.map(i => i[key]).reduce((acc: number, prev: any) => Number(acc) + Number(prev), 0) } const handleFunc = async (event: any, authToken: any = null) => { let data: any = { rows: [], lastRow: 0 } const config = useRuntimeConfig() const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const startRow = body.startRow const endRow = body.endRow const pageSize = (endRow - startRow) + 1 const orderBy = sortHandler(body.sortModel) const select = string.urlEncode('M_Product_ID,M_Product_UU,Name,Value,SKU,mpn,UPC,Weight,Width,Length,Height,Volume,IsBOM,AD_Org_ID,Strapi_Product_documentId,CompletedAllMarketplaceData') const res: any = await event.context.fetch(`models/m_product?$select=${select}&$expand=M_Storage&$filter=${string.urlEncode('(isActive eq true OR isActive eq false)' + filterHandler(body.filterModel))}&$orderby=${string.urlEncode(orderBy)}&$top=${pageSize}&$skip=${startRow}`, 'GET', token, null) if (res) { const allRecords = res['records']?.map((item: any) => { return { id: item.id, uid: item.uid, name: item.Name, value: item.Value, sku: item.SKU, mpn: item.mpn, upc: item.UPC, weight: item.Weight, width: item.width || item.Width || 0, length: item.length || item.Length || 0, height: item.height || item.Height || 0, volume: item.volume || item.Volume || 0, isBOM: item.IsBOM, organization: item.AD_Org_ID?.identifier || '', organizationId: item.AD_Org_ID?.id || '', strapiProductId: item.Strapi_Product_documentId, completedAllMarketplaceData: item.CompletedAllMarketplaceData, qtyonhand: storageCount(item?.M_Storage ?? [], 'QtyOnHand') } }) || [] data.rows = allRecords data.lastRow = res['row-count'] || 0 } return data } export default defineEventHandler(async (event) => { let data: any = {} try { console.log('[Products AG Grid] handleFunc attempt 1') data = await handleFunc(event) console.log('[Products AG Grid] Success - rows:', data?.rows?.length, 'lastRow:', data?.lastRow) } catch (err: any) { console.log('[Products AG Grid] First attempt failed:', err?.statusCode || err?.message || err) try { let authToken: any = await refreshTokenHelper(event) console.log('[Products AG Grid] Got refresh token, retrying handleFunc') data = await handleFunc(event, authToken) console.log('[Products AG Grid] Retry success - rows:', data?.rows?.length, 'lastRow:', data?.lastRow) } catch (error: any) { console.log('[Products AG Grid] Retry also failed:', error?.statusCode || error?.message || error) data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) } } return data })