/** * iDoklad: zapsani uhrady k vydane fakture. * * Sluzba: https://services.csbot.cz/apps/idoklad * Endpointy: GET /issued-payments/default/{invoiceId}, POST /issued-payments * * Vzor akce, ktera **neco meni**. U te zalezi na idempotenci: kdyz runtime krok * zopakuje po timeoutu, nesmi vzniknout druha uhrada. Klic `ctx.idempotencyKey` * je pro tentyz krok stejny pres vsechny pokusy a runtime ho posila v hlavicce * `Idempotency-Key` automaticky, takze skript nemusi delat nic navic. * * Castka se necha prazdna pro plnou uhradu - vzor z iDokladu uz nese zbytek * k zaplaceni, takze se nemusi pocitat tady. */ export const manifest = { id: 'idoklad.register-payment', name: 'Zapsat úhradu faktury', description: 'Zapíše k vydané faktuře úhradu. Bez zadané částky se použije zbytek ' + 'k zaplacení podle iDokladu.', inputs: [ { id: 'invoiceId', label: 'ID faktury v iDokladu', type: 'number', required: true }, { id: 'amount', label: 'Uhrazená částka', type: 'number', required: false, hint: 'Nevyplněno = celý zbytek k zaplacení.', }, { id: 'dateOfPayment', label: 'Datum úhrady', type: 'date', required: false, hint: 'Nevyplněno = dnes.', }, { id: 'sendConfirmation', label: 'Poslat potvrzení odběrateli', type: 'boolean', required: false, default: false, }, ], outputs: [ { id: 'paymentId', label: 'ID úhrady', type: 'number', required: true }, { id: 'amount', label: 'Zapsaná částka', type: 'number', required: true }, { id: 'dateOfPayment', label: 'Datum úhrady', type: 'date', required: true }, ], }; export async function run(inputs, ctx) { const { unwrap, pick, num, date, need, day } = ctx.util; if (inputs.amount !== null && inputs.amount <= 0) { ctx.fail('Uhrazená částka musí být větší než nula.'); } // Vzor nese zbytek k zaplaceni i vychozi zpusob platby. const defaults = unwrap((await ctx.http.get(`/issued-payments/default/${inputs.invoiceId}`)).body); if (!defaults || typeof defaults !== 'object') { ctx.fail(`K faktuře ${inputs.invoiceId} nejde zapsat úhradu, iDoklad ji nezná.`); } const suggested = num(pick(defaults, 'paymentAmount')); const amount = inputs.amount ?? suggested; if (amount === null) { ctx.fail('iDoklad nevrátil zbytek k zaplacení, zadejte částku ručně.'); } const paidAt = inputs.dateOfPayment ? new Date(inputs.dateOfPayment) : new Date(); const payload = { ...defaults, invoiceId: inputs.invoiceId, paymentAmount: amount, dateOfPayment: day(paidAt), sendPaymentConfirmation: inputs.sendConfirmation ?? false, }; const { body } = await ctx.http.post('/issued-payments', payload); const payment = unwrap(body); ctx.log(`K faktuře ${inputs.invoiceId} zapsána úhrada ${amount}.`); return { paymentId: need(num(pick(payment, 'id')), 'ID úhrady'), amount: need(num(pick(payment, 'paymentAmount')) ?? amount, 'zapsanou částku'), dateOfPayment: need(date(pick(payment, 'dateOfPayment')) ?? date(paidAt), 'datum úhrady'), }; }