import { string } from 'alga-js' // Already-returned quantity per shipment line (M_InOutLine_ID → qty), used by // the mobile + desktop return pages to cap what can still be returned. // // Only quantities that were PHYSICALLY received count: a completed M_RMA is // just the return authorization (marketplace-imported Amazon/Shopify RMAs are // created Completed with the expected qty before the parcel ever arrives). // The actual receipt is the customer-return M_InOut (MovementType C+) linked // via M_RMA_ID, with lines linked via M_RMALine_ID — that is what quick-rma // creates, and what it checks before reusing an "orphaned" RMA. Counting bare // RMA lines locked lines at "Remaining 0/1" for returns that had never been // processed. // // `excludeRmaId` skips one RMA entirely (the page was reached through that // RMA's external number, so it's the authorization being fulfilled right now). export const useReturnedQty = () => { const headers = () => ({ headers: useRequestHeaders(['cookie']) }) const getReturnedQtyMap = async (shipmentId: number | string, excludeRmaId: number | null = null): Promise> => { const returnedQtyMap: Record = {} if (!shipmentId) return returnedQtyMap try { const rmaRes: any = await $fetch( '/api/filters/m_rma/' + string.urlEncode(`InOut_ID eq ${shipmentId} AND DocStatus eq 'CO'`) + '&$expand=m_rmaline&$top=50', headers() ) const rmas: any[] = (rmaRes?.records || []).filter((rma: any) => !(excludeRmaId && rma.id === excludeRmaId)) if (rmas.length === 0) return returnedQtyMap // RMA line → shipment line, plus the authorized qty per RMA line as a // fallback for legacy receipts whose lines carry no M_RMALine_ID. const shipLineByRmaLine: Record = {} const rmaLinesByRma: Record = {} for (const rma of rmas) { const lines = rma.m_rmaline || rma.M_RMALine || [] rmaLinesByRma[rma.id] = lines for (const rmaLine of lines) { const inOutLineId = rmaLine.M_InOutLine_ID?.id if (inOutLineId) shipLineByRmaLine[rmaLine.id] = inOutLineId } } const receiptRes: any = await $fetch( '/api/filters/m_inout/' + string.urlEncode(`M_RMA_ID in (${rmas.map(r => r.id).join(',')}) AND (DocStatus eq 'CO' OR DocStatus eq 'CL')`) + '&$select=M_RMA_ID,MovementType&$expand=m_inoutline($select=MovementQty,M_RMALine_ID)&$top=100', headers() ) for (const receipt of (receiptRes?.records || [])) { const rmaId = receipt.M_RMA_ID?.id const lines: any[] = receipt.m_inoutline || receipt.M_InOutLine || [] const linked = lines.filter(l => l.M_RMALine_ID?.id) if (linked.length > 0) { for (const line of linked) { const inOutLineId = shipLineByRmaLine[line.M_RMALine_ID.id] if (inOutLineId) { returnedQtyMap[inOutLineId] = (returnedQtyMap[inOutLineId] || 0) + Math.abs(line.MovementQty || 0) } } } else if (rmaId && rmaLinesByRma[rmaId]) { // Receipt exists but its lines aren't linked — attribute the RMA's // authorized quantities instead (pre-M_RMALine_ID data). for (const rmaLine of rmaLinesByRma[rmaId]) { const inOutLineId = rmaLine.M_InOutLine_ID?.id if (inOutLineId) { returnedQtyMap[inOutLineId] = (returnedQtyMap[inOutLineId] || 0) + Math.abs(rmaLine.Qty || 0) } } } } } catch (e) { console.warn('Could not fetch existing returns for shipment:', e) } return returnedQtyMap } return { getReturnedQtyMap } }