export default defineEventHandler(async (event) => { const body = await readBody(event) const filters = body.filters || {} let feeLines = body.records || [] console.log('═══════════════════════════════════════════════════') console.log('FULFILLMENT GROUPING TEST') console.log('═══════════════════════════════════════════════════') console.log(`Total fee lines in file: ${feeLines.length}`) // Apply filters to simulate the API filtering let filterApplied = false if (filters.partnerId) { feeLines = feeLines.filter((line: any) => line.C_BPartner_ID?.id === filters.partnerId) filterApplied = true console.log(`After partner filter: ${feeLines.length} lines`) } if (filters.month && filters.year) { feeLines = feeLines.filter((line: any) => { const shippingDate = new Date(line.shipping_date) return shippingDate.getMonth() + 1 === filters.month && shippingDate.getFullYear() === filters.year }) filterApplied = true console.log(`After month/year filter: ${feeLines.length} lines`) } console.log(`Processing ${feeLines.length} lines (Filter applied: ${filterApplied})`) // Group records by C_BPartner_ID and shipping_date (month/year) const grouped: any = {} const summary: any = { totalLines: feeLines.length, uniquePartners: new Set(), uniqueMonths: new Set(), groups: [], skippedLines: [] } for (const line of feeLines) { // Get C_BPartner_ID directly from the fee line const bpartnerId = line.C_BPartner_ID?.id const bpartnerName = line.C_BPartner_ID?.identifier || `Partner-${bpartnerId}` || 'Unknown' if (!bpartnerId) { console.log('⚠️ Line without partner:', line.id) summary.skippedLines.push({ lineId: line.id, reason: 'No C_BPartner_ID' }) continue } if (!line.shipping_date) { console.log('⚠️ Line without shipping_date:', line.id) summary.skippedLines.push({ lineId: line.id, reason: 'No shipping_date' }) continue } summary.uniquePartners.add(bpartnerId) const shippingDate = new Date(line.shipping_date) const monthYear = `${shippingDate.getFullYear()}-${String(shippingDate.getMonth() + 1).padStart(2, '0')}` const groupKey = `${bpartnerId}_${monthYear}` summary.uniqueMonths.add(monthYear) if (!grouped[groupKey]) { grouped[groupKey] = { bpartnerId, bpartnerName, monthYear, month: shippingDate.getMonth() + 1, year: shippingDate.getFullYear(), lines: [] } } grouped[groupKey].lines.push(line) } // Process each group to show what order would be created for (const groupKey in grouped) { const group = grouped[groupKey] // Group lines by FulfillTypeAccounting and M_Product_ID const fulfillmentLines: any = {} const returnLines: any = {} const spaceRentLines: any = {} const spaceRentFlatLines: any = {} const parcelLines: any = {} for (const line of group.lines) { const productId = line.M_Product_ID?.id const productName = line.M_Product_ID?.identifier || `Product ${productId}` if (!productId) continue if (line.FulfillTypeAccounting === 'fulfillment') { if (!fulfillmentLines[productId]) { fulfillmentLines[productId] = { productId, productName, totalAmt: 0, inoutIds: new Set(), lineCount: 0 } } fulfillmentLines[productId].totalAmt += parseFloat(line.LineTotalAmt) || 0 fulfillmentLines[productId].lineCount++ if (line.M_InOut_ID?.id) { fulfillmentLines[productId].inoutIds.add(line.M_InOut_ID.id) } } else if (line.FulfillTypeAccounting === 'return') { if (!returnLines[productId]) { returnLines[productId] = { productId, productName, totalAmt: 0, inoutIds: new Set(), lineCount: 0 } } returnLines[productId].totalAmt += parseFloat(line.LineTotalAmt) || 0 returnLines[productId].lineCount++ if (line.M_InOut_ID?.id) { returnLines[productId].inoutIds.add(line.M_InOut_ID.id) } } else if (line.FulfillTypeAccounting === 'spacerentqm3') { if (!spaceRentLines[productId]) { spaceRentLines[productId] = { productId, productName, totalAmt: 0, qtyInvoiced: 0, lineCount: 0 } } spaceRentLines[productId].totalAmt += parseFloat(line.LineTotalAmt) || 0 spaceRentLines[productId].qtyInvoiced += parseFloat(line.QtyInvoiced) || 0 spaceRentLines[productId].lineCount++ } else if (line.FulfillTypeAccounting === 'spacerentflat') { if (!spaceRentFlatLines[productId]) { spaceRentFlatLines[productId] = { productId, productName, totalAmt: 0, qtyInvoiced: 0, lineCount: 0 } } spaceRentFlatLines[productId].totalAmt += parseFloat(line.LineTotalAmt) || 0 spaceRentFlatLines[productId].qtyInvoiced += parseFloat(line.QtyInvoiced) || 0 spaceRentFlatLines[productId].lineCount++ } else if (line.FulfillTypeAccounting === 'parcel') { if (!parcelLines[productId]) { parcelLines[productId] = { productId, productName, totalAmt: 0, qtyInvoiced: 0, lineCount: 0 } } parcelLines[productId].totalAmt += parseFloat(line.LineTotalAmt) || 0 parcelLines[productId].qtyInvoiced += parseFloat(line.QtyInvoiced) || 0 parcelLines[productId].lineCount++ } } // Build order lines preview const orderLinesPreview: any[] = [] let totalAmount = 0 // Add fulfillment positions for (const productId in fulfillmentLines) { const lineData = fulfillmentLines[productId] orderLinesPreview.push({ type: 'Fulfillment', productId: parseInt(productId), productName: lineData.productName, description: `Fulfillment: ${lineData.inoutIds.size} shipment${lineData.inoutIds.size > 1 ? 's' : ''}`, qtyOrdered: 1, price: lineData.totalAmt, lineTotal: lineData.totalAmt, sourceLines: lineData.lineCount }) totalAmount += lineData.totalAmt } // Add return positions for (const productId in returnLines) { const lineData = returnLines[productId] orderLinesPreview.push({ type: 'Return', productId: parseInt(productId), productName: lineData.productName, description: `Return: ${lineData.inoutIds.size} return${lineData.inoutIds.size > 1 ? 's' : ''}`, qtyOrdered: 1, price: lineData.totalAmt, lineTotal: lineData.totalAmt, sourceLines: lineData.lineCount }) totalAmount += lineData.totalAmt } // Add space rent positions for (const productId in spaceRentLines) { const lineData = spaceRentLines[productId] orderLinesPreview.push({ type: 'Warehouse Rent', productId: parseInt(productId), productName: lineData.productName, description: `Warehouse Rent: ${lineData.qtyInvoiced.toFixed(2)} qm³`, qtyOrdered: 1, price: lineData.totalAmt, lineTotal: lineData.totalAmt, sourceLines: lineData.lineCount }) totalAmount += lineData.totalAmt } // Add flat space rent positions for (const productId in spaceRentFlatLines) { const lineData = spaceRentFlatLines[productId] orderLinesPreview.push({ type: 'Warehouse Rent (Flat)', productId: parseInt(productId), productName: lineData.productName, description: `Warehouse Rent (Flat): ${lineData.qtyInvoiced.toFixed(2)} units`, qtyOrdered: 1, price: lineData.totalAmt, lineTotal: lineData.totalAmt, sourceLines: lineData.lineCount }) totalAmount += lineData.totalAmt } // Add parcel positions for (const productId in parcelLines) { const lineData = parcelLines[productId] orderLinesPreview.push({ type: 'Parcel', productId: parseInt(productId), productName: lineData.productName, description: `Parcel: ${lineData.qtyInvoiced.toFixed(0)} parcel${lineData.qtyInvoiced !== 1 ? 's' : ''}`, qtyOrdered: 1, price: lineData.totalAmt, lineTotal: lineData.totalAmt, sourceLines: lineData.lineCount }) totalAmount += lineData.totalAmt } summary.groups.push({ groupKey, bpartnerId: group.bpartnerId, bpartnerName: group.bpartnerName, monthYear: group.monthYear, month: group.month, year: group.year, sourceLinesCount: group.lines.length, orderLinesCount: orderLinesPreview.length, totalAmount, breakdown: { fulfillment: Object.keys(fulfillmentLines).length, return: Object.keys(returnLines).length, spaceRent: Object.keys(spaceRentLines).length, spaceRentFlat: Object.keys(spaceRentFlatLines).length, parcel: Object.keys(parcelLines).length }, orderLines: orderLinesPreview }) } // Sort groups for better readability summary.groups.sort((a: any, b: any) => { if (a.year !== b.year) return b.year - a.year if (a.month !== b.month) return b.month - a.month return a.bpartnerName.localeCompare(b.bpartnerName) }) summary.uniquePartners = summary.uniquePartners.size summary.uniqueMonths = summary.uniqueMonths.size summary.totalGroups = summary.groups.length console.log('---------------------------------------------------') console.log('SUMMARY:') console.log(` Total Lines: ${summary.totalLines}`) console.log(` Unique Partners: ${summary.uniquePartners}`) console.log(` Unique Months: ${summary.uniqueMonths}`) console.log(` Total Groups (Orders): ${summary.totalGroups}`) console.log(` Skipped Lines: ${summary.skippedLines.length}`) console.log('---------------------------------------------------') return { success: true, summary: { totalLines: summary.totalLines, uniquePartners: summary.uniquePartners, uniqueMonths: summary.uniqueMonths, totalGroups: summary.totalGroups, skippedLines: summary.skippedLines.length }, groups: summary.groups, skippedLines: summary.skippedLines, filtersApplied: filters } })