// A payroll run as an ACH file for the bank, read back and checked before upload; then what a
// changed amount, a wrong routing digit and a bank's return look like.
//
//   quillo run nacha.qwe      then open http://localhost:8080/file, /read, /tampered, /refused and /return
//   nacha_returns.ach is a small synthetic return file, from no bank

use "nacha.qwer"

let PAYROLL = {
    immediate_destination: "091000019",
    immediate_origin: "1234567890",
    destination_name: "Wells Fargo",
    origin_name: "Quillo Tools Inc",
    file_date: "261101",
    file_time: "0930",
    reference: "PAY1101",
    batches: [
        {
            company_name: "Quillo Tools",
            company_id: "1234567890",
            sec_code: "PPD",
            description: "PAYROLL",
            descriptive_date: "NOV 01",
            effective_date: "261103",
            odfi: "09100001",
            entries: [
                { kind: "credit", routing: "021000021", account: "1234567", amount: "2500.00", id: "EMP001", name: "Ada Lovelace", addenda: "NOV PAY PERIOD 1" },
                { kind: "credit", account_type: "savings", routing: "011401533", account: "98-7654", amount_cents: 187550, id: "EMP002", name: "Grace Hopper" },
            ],
        },
        {
            company_name: "Quillo Tools",
            company_id: "1234567890",
            sec_code: "CCD",
            description: "INVOICES",
            effective_date: "261103",
            odfi: "09100001",
            entries: [
                { kind: "debit", routing: "091000019", account: "555000", amount: "410.25", id: "INV-77", name: "Bakery Supply LLC" },
            ],
        },
    ],
}

let FILE = nacha_build(PAYROLL)

route GET /file = respond(200, FILE?, { "content-type": "text/plain" })

route GET /read {
    let f = nacha_parse(FILE?)?
    {
        batches: f.batch_count, entries: f.entry_count, hash: f.entry_hash, debit: f.total_debit_cents, credit: f.total_credit_cents,
        blocks: f.block_count, padding: f.padding_lines,
        first: f.batches[0].entries[0],
        rows: nacha_entries(FILE?)? | map((e) => `${e.trace} ${e.kind} ${e.amount_cents} ${e.name}`),
    }
}

// An amount changed by hand: 2500.00 becomes 2600.00 and the batch control no longer agrees.
route GET /tampered {
    let bad = replace(FILE?, "0000250000", "0000260000")
    { first: nacha_parse(bad).error, all: nacha_check(bad).problems }
}

route GET /refused = {
    routing: nacha_build(merge(PAYROLL, { batches: [merge(PAYROLL.batches[0], { entries: [{ kind: "credit", routing: "021000022", account: "1", amount: "1.00", name: "X" }] })] })).error,
    check_digit: nacha_check_digit("09100001")?,
    hash: nacha_entry_hash(["021000021", "011401533", "091000019"])?,
    trace: nacha_trace("09100001", 42)?,
    padded: nacha_parse(nacha_build(merge(PAYROLL, { batches: [PAYROLL.batches[0]] }))?)?.padding_lines,
}

// A file of returns from the bank: entry code 26, an addenda of type 99 with the reason, and a
// notification of change (code 21, type 98) with the corrected account.
route GET /return {
    let f = nacha_parse(read_file("nacha_returns.ach"))?
    let entries = f.batches[0].entries
    {
        returned: entries[0].addenda[0],
        change: entries[1].addenda[0],
        what: entries[0].what,
        means: nacha_reason("R03"),
    }
}
