/** * SAP Business One: dohledani obchodniho partnera. * * Sluzba: https://services.csbot.cz/apps/sap-bo * Endpoint: GET /api/business-partners?$filter=... * * Vzor **predvalidace nad OData**. Service Layer filtruje jazykem OData, kde * se retezce uvozuji apostrofem - a apostrof v nazvu firmy by dotaz rozbil, * takze se zdvojuje. Nenalezeno neni chyba: podle toho se strom vetvi na * zalozeni noveho partnera. */ export const manifest = { id: 'sap-bo.find-business-partner', name: 'Najít obchodního partnera', description: 'Dohledá partnera v SAP Business One podle kódu, IČO nebo názvu. ' + 'Nic nezakládá, výsledek slouží k větvení stromu.', inputs: [ { id: 'cardCode', label: 'Kód partnera', type: 'string', required: false, hint: 'Například C00123. Nejpřesnější, hledá se podle něj první.', }, { id: 'taxId', label: 'IČO', type: 'string', required: false, hint: 'Porovnává se s polem FederalTaxID.', }, { id: 'name', label: 'Název', type: 'string', required: false, hint: 'Stačí část názvu, hledá se podřetězec.', }, ], outputs: [ { id: 'found', label: 'Partner nalezen', type: 'boolean', required: true }, { id: 'cardCode', label: 'Kód partnera', type: 'string', required: false }, { id: 'cardName', label: 'Název partnera', type: 'string', required: false }, { id: 'taxId', label: 'IČO', type: 'string', required: false }, { id: 'currency', label: 'Měna', type: 'string', required: false }, { id: 'matchedBy', label: 'Podle čeho se našel', type: 'string', required: true }, ], timeoutMs: 30000, }; /** Retezec do OData filtru. Apostrof se zdvojuje, jinak dotaz spadne. */ function quote(value) { return `'${String(value).replace(/'/g, "''")}'`; } const notFound = { found: false, cardCode: null, cardName: null, taxId: null, currency: null, matchedBy: 'nenalezeno', }; export async function run(inputs, ctx) { const { pick, text } = ctx.util; if (!inputs.cardCode && !inputs.taxId && !inputs.name) { ctx.fail('Vyplňte kód partnera, IČO nebo název, jinak není podle čeho hledat.'); } // Poradi je zamer: kod je klic, ICO je jednoznacne, nazev se pise pokazde jinak. const attempts = []; if (inputs.cardCode) attempts.push([`CardCode eq ${quote(inputs.cardCode)}`, 'kód']); if (inputs.taxId) attempts.push([`FederalTaxID eq ${quote(inputs.taxId)}`, 'IČO']); if (inputs.name) attempts.push([`contains(CardName,${quote(inputs.name)})`, 'název']); for (const [filter, label] of attempts) { const { body } = await ctx.http.get('/api/business-partners', { query: { $filter: filter, $select: 'CardCode,CardName,FederalTaxID,Currency,CardType', $top: 5, }, }); const raw = pick(body, 'value', 'data', 'items'); const items = Array.isArray(raw) ? raw : Array.isArray(body) ? body : []; if (items.length === 0) { ctx.log(`Podle ${label} se nic nenašlo.`); continue; } if (items.length > 1) ctx.log(`Podle ${label} vyšlo ${items.length} partnerů, bere se první.`); const partner = items[0]; return { found: true, cardCode: text(pick(partner, 'CardCode')), cardName: text(pick(partner, 'CardName')), taxId: text(pick(partner, 'FederalTaxID')), currency: text(pick(partner, 'Currency')), matchedBy: label, }; } return notFound; }