---
apiVersion: v1
kind: ConfigMap
metadata:
  name: reporting-service
data:
  dfspSettlement.ejs: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <style>
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
                display: block;
                overflow-x: auto;
                white-space: nowrap;
            }
    
            th {
            //            border: 1px solid #efefef;
                text-align: left;
                padding: 0 8px;
            }
    
            td {
    //            border: 1px solid #efefef;
                padding: 8px;
            }
    
            tr:nth-child(even) {
    //            background-color: #efefef;
            }
    
            td > span {
                font-weight: bold;
            }
        </style>
        <title>FSP Settlement Report</title>
    </head>
    <body>
    
    <%
    const formatAmount = (amount) => parseFloat(amount).toLocaleString('en-US', {minimumFractionDigits:4});
    const formatNetPosition = (amount) => {
        const v = parseFloat(amount);
        const vf = Math.abs(v).toLocaleString('en-US', {minimumFractionDigits:4});
        return v >= 0 ? vf : `(${vf})`;
    }
    %>
    
    <table>
        <tr>
            <td><span>Report for:</span></td>
            <td><span>FSP prefix</span></td>
            <td style="text-align: right"><%= dfspInfo[0] && dfspInfo[0].participantId %></td>
            <td><span>FSP ID</span></td>
            <td><%= dfspInfo[0] && dfspInfo[0].name %></td>
            <td><span>Settlement ID</span></td>
            <td style="text-align: right"><%= report[0] && report[0].settlementId %></td>
            <td></td>
            <td><span>Created Date</span></td>
            <td colspan="2" style="text-align: right"><%= report[0] && (d = report[0].createdDate, `${d.toLocaleDateString('en-ZA')} ${d.toLocaleTimeString('en-US')}`)%></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td><span>Last Action Date</span></td>
            <td colspan="2" style="text-align: right"><%=
                report[0] &&
                (d = report
                        .filter(a => a.lastActionDate)
                        .reduce((a,b) => a.lastActionDate.getTime() > b.lastActionDate.getTime() ? a : b).lastActionDate,
                        `${d.toLocaleDateString('en-ZA')} ${d.toLocaleTimeString('en-US')}`)
                %></td>
        </tr>
        <tr>
            <td colspan="100%" style="padding-top: 20px"></td>
        </tr>
        <tr>
            <th>Window ID</th>
            <th>FSP prefix</th>
            <th>FSP ID</th>
            <th>Sent to FSP</th>
            <th></th>
            <th>Received from FSP</th>
            <th></th>
            <th>Total</th>
            <th>Total Value of All Transactions</th>
            <th>Net Position vs. Each DFSP</th>
        </tr>
        <tr>
            <th></th>
            <th></th>
            <th></th>
            <th>Volume</th>
            <th>Value</th>
            <th>Volume</th>
            <th>Value</th>
            <th>Volume</th>
            <th></th>
            <th></th>
        </tr>
        <% for(let entry of report) { %>
            <tr style="text-align: right">
                <td><%= entry.settlementWindowId %></td>
                <td><%= entry.participantId %></td>
                <td style="text-align: left"><%= entry.name %></td>
                <td><%= entry.sentVolume %></td>
                <td><%= formatAmount(entry.sentAmount) %></td>
                <td><%= entry.receivedVolume %></td>
                <td><%= formatAmount(entry.receivedAmount) %></td>
                <td><%= entry.totalVolume %></td>
                <td><%= formatAmount(entry.totalAmount) %></td>
                <td><%= formatNetPosition(entry.netAmount) %></td>
            </tr>
        <% } %>
    
        <tr>
            <td colspan="9" style="padding-top: 30px"><span>Aggregated Net Positions</span></td>
            <td style="text-align: right"><%= report[0] && formatNetPosition(report.reduce((a, b) => a + (parseFloat(b.netAmount) || 0), 0)) %></td>
        </tr>
    </table>
    </body>
    </html>
    
  dfspSettlement.yaml: |
    params:
      settlementId:
        required: true
      dfspId:
        required: true
    
    data:
      dfspInfo: SELECT participantId, name FROM participant WHERE participantId = :dfspId AND name != 'Hub'
      report: |
        SELECT settlementId,
               settlementWindowId,
               p.participantId,
               p.name,
               sentAmount,
               sentVolume,
               receivedAmount,
               receivedVolume,
               (sentAmount + receivedAmount) as totalAmount,
               (sentVolume + receivedVolume) as totalVolume,
               receivedAmount - sentAmount as netAmount,
               s3.createdDate,
                lastActionDate
        FROM participant p INNER JOIN
             (
                 SELECT settlementId,
                        settlementWindowId,
                        participantId,
                        SUM(sentAmount)     as sentAmount,
                        SUM(sentVolume)     as sentVolume,
                        SUM(receivedAmount) as receivedAmount,
                        SUM(receivedVolume) as receivedVolume,
                        MAX(createdDate) as createdDate,
                        MAX(lastActionDate) as lastActionDate
                 FROM (
                          SELECT settlementId,
                                 settlementWindowId,
                                 MAX(createdDate) as createdDate,
                                 MAX(lastActionDate) as lastActionDate,
                                 IF(senderId != :dfspId, senderId, receiverId) as participantId,
                                 SUM(IF(senderId = :dfspId, amount, 0))       as sentAmount,
                                 SUM(IF(senderId = :dfspId, volume, 0))       as sentVolume,
                                 SUM(IF(receiverId = :dfspId, amount, 0))     as receivedAmount,
                                 SUM(IF(receiverId = :dfspId, volume, 0))     as receivedVolume
                          FROM (
                                   SELECT MAX(CASE WHEN tP.amount > 0 THEN p.participantId END) as senderId,
                                          MAX(CASE WHEN tP.amount < 0 THEN p.participantId END) as receiverId,
                                          MAX(tP.amount)                                        as amount,
                                          COUNT(DISTINCT (tF.transferId))                       as volume,
                                          s.settlementId,
                                          sSW.settlementWindowId,
                                          MAX(s.createdDate) as createdDate,
                                          MAX(tF.completedDate)                        as lastActionDate
                                   FROM transferParticipant tP
                                            INNER JOIN transferFulfilment tF on tP.transferId = tF.transferId
                                            INNER JOIN settlementSettlementWindow sSW
                                                       on tF.settlementWindowId = sSW.settlementWindowId
                                            INNER JOIN settlementWindowStateChange sWSC
                                                       on sSW.settlementWindowId = sWSC.settlementWindowId
                                            INNER JOIN settlement s on sSW.settlementId = s.settlementId
                                            INNER JOIN participantCurrency pC
                                                       on tP.participantCurrencyId = pC.participantCurrencyId
                                            INNER JOIN participant p on pC.participantId = p.participantId
                                   WHERE tF.isValid
                                     AND sWSC.settlementWindowStateId = 'CLOSED'
                                     AND s.settlementId = :settlementId
                                   GROUP BY tF.transferId, s.settlementId
                               ) s
                          WHERE s.senderId = :dfspId
                             OR s.receiverId = :dfspId
                          GROUP BY settlementId, settlementWindowId, senderId, receiverId
                      ) s2
    
                 GROUP BY settlementId, settlementWindowId, participantId
             ) s3 ON p.participantId = s3.participantId
        WHERE p.name != 'Hub'
        ORDER BY p.name, settlementWindowId
    
  dfspSettlementDetail.ejs: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <style>
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
                display: block;
                overflow-x: auto;
                white-space: nowrap;
            }
    
            th {
            //            border: 1px solid #efefef;
                text-align: left;
                padding: 0 8px;
            }
    
            td {
    //            border: 1px solid #efefef;
                padding: 8px;
            }
    
            tr:nth-child(even) {
    //            background-color: #efefef;
            }
    
            td > span {
                font-weight: bold;
            }
        </style>
        <title>FSP Settlement Report</title>
    </head>
    <body>
    
    <%
        const formatAmount = (amount) => parseFloat(amount).toLocaleString('en-US');
    %>
    
    <table>
        <tr>
            <td>Participant ID</td>
            <td style="text-align: right"><%= dfspInfo[0].participantId %></td>
            <td>FSP ID</td>
            <td style="text-align: right"><%= dfspInfo[0].name %></td>
            <td>Settlement ID</td>
            <td style="text-align: right"><%= report[0] && report[0].settlementId %></td>
            <td style="width: 20px"></td>
            <td>Created Date</td>
            <td colspan="2" style="text-align: right"><%= report[0] && report[0].settlementCreatedDate.toISOString() %></td>
            <td style="wisth: 20px"></td>
            <td>Currency</td>
            <td><%= report[0] && report[0].currencyId %></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td colspan="14" style="padding-top: 20px"></td>
        </tr>
        <tr>
            <td>Sender Participant ID</td>
            <td>Sender FSP ID</td>
            <td>Receiver Participant ID</td>
            <td>Receiver FSP ID</td>
            <td>Transfer ID</td>
            <td>Tx Type</td>
            <td>Tx Nature</td>
            <td>Last Modified</td>
            <td>Sender ID Type</td>
            <td>Sender ID</td>
            <td>Receiver ID Type</td>
            <td>Receiver ID</td>
            <td>Amount</td>
            <td>Fee</td>
        </tr>
        <% for(let e of report) { %>
            <tr>
                <td><%= e.payerFspid %></td>
                <td><%= e.payerFspName %></td>
                <td><%= e.payeeFspid %></td>
                <td><%= e.payeeFspName %></td>
                <td><%= e.transferId %></td>
                <td><%= e.transactionType %></td>
                <td><%= e.transactionNature %></td>
                <td><%= e.lastModifiedDate.toISOString() %></td>
                <td><%= e.payerIdentifierType %></td>
                <td><%= e.payerIdentifierValue %></td>
                <td><%= e.payeeIdentifierType %></td>
                <td><%= e.payeeIdentifierValue %></td>
                <td><%= formatAmount(e.amount) %></td>
                <td>-</td>
            </tr>
        <% } %>
    </table>
    </body>
    </html>
    
  dfspSettlementDetail.yaml: |
    params:
      settlementId:
        required: true
      fspid:
        required: true
    
    data:
      dfspInfo: SELECT participantId, name FROM participant WHERE name = :fspid AND name != 'Hub'
      report: |
        SELECT
            pCPayer.participantId as payerFspid,
            pPayer.name as payerFspName,
            pCPayee.participantId as payeeFspid,
            pPayee.name as payeeFspName,
            tF.transferId,
            tS.name as transactionType,
            tSS.name as transactionNature,
            tF.completedDate as lastModifiedDate,
            pITPayer.name as payerIdentifierType,
            qpPayer.partyIdentifierValue as payerIdentifierValue,
            pITPayee.name as payeeIdentifierType,
            qpPayee.partyIdentifierValue as payeeIdentifierValue,
            t.amount as amount,
            c.currencyId,
            s.settlementId,
            s.createdDate as settlementCreatedDate,
            sSW.settlementWindowId
        FROM
            transferFulfilment tF
            INNER JOIN transfer t ON t.transferId = tF.transferId
            INNER JOIN transferParticipant tPPayer ON tPPayer.transferId = tF.transferId
                AND tPPayer.transferParticipantRoleTypeId = (SELECT transferParticipantRoleTypeId from transferParticipantRoleType WHERE name = 'PAYER_DFSP')
                INNER JOIN participantCurrency pCPayer ON pCPayer.participantCurrencyId = tPPayer.participantCurrencyId
                INNER JOIN participant pPayer ON pPayer.participantId = pCPayer.participantId
            INNER JOIN transferParticipant tPPayee ON tPPayee.transferId = tF.transferId
                AND tPPayee.transferParticipantRoleTypeId = (SELECT transferParticipantRoleTypeId from transferParticipantRoleType WHERE name = 'PAYEE_DFSP')
                INNER JOIN participantCurrency pCPayee ON pCPayee.participantCurrencyId = tPPayee.participantCurrencyId
                INNER JOIN participant pPayee ON pPayee.participantId = pCPayee.participantId
            INNER JOIN settlementWindow sW on sW.settlementWindowId = tF.settlementWindowId
            INNER JOIN settlementSettlementWindow sSW on tF.settlementWindowId = sSW.settlementWindowId
            INNER JOIN settlementWindowStateChange sWSC on sW.currentStateChangeId = sWSC.settlementWindowStateChangeId
            INNER JOIN settlement s on sSW.settlementId = s.settlementId
            INNER JOIN settlementModel sM ON sM.settlementModelId = s.settlementModelId
            INNER JOIN currency c ON c.currencyId = sM.currencyId
            INNER JOIN quote q on q.transactionReferenceId = tF.transferId
            INNER JOIN quoteParty qpPayer on qpPayer.quoteId = q.quoteId AND qpPayer.partyTypeId = (SELECT partyTypeId FROM partyType WHERE name = 'PAYER')
                INNER JOIN partyIdentifierType pITPayer ON pITPayer.partyIdentifierTypeId = qpPayer.partyIdentifierTypeId
            INNER JOIN quoteParty qpPayee on qpPayee.quoteId = q.quoteId AND qpPayee.partyTypeId = (SELECT partyTypeId FROM partyType WHERE name = 'PAYEE')
                INNER JOIN partyIdentifierType pITPayee ON pITPayee.partyIdentifierTypeId = qpPayee.partyIdentifierTypeId
            INNER JOIN transactionScenario tS on tS.transactionScenarioId = q.transactionScenarioId
            LEFT JOIN transactionSubScenario tSS on tSS.transactionSubScenarioId = q.transactionSubScenarioId
        WHERE
            tF.isValid
            AND s.settlementId = :settlementId
            AND (pPayee.name = :fspid OR pPayer.name = :fspid)
    
  participants.ejs: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <style>
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
            }
    
            td, th {
                border: 1px solid #efefef;
                text-align: left;
                padding: 8px;
            }
    
            tr:nth-child(even) {
                background-color: #efefef;
            }
    
            td > span {
                font-weight: bold;
            }
    
            .amount {
                text-align: right;
            }
        </style>
        <title>Participants Summary</title>
    </head>
    <body>
    
    <%
    const amountFormat = (amount) => parseFloat(amount).toFixed(4).replace(/\d(?=(\d{3})+\.)/g, '$&,');
    %>
    
    <h2>Total Sent</h2>
    <table>
        <tr>
            <th>Name</th>
            <th class="amount">Amount</th>
            <th>Currency</th>
        </tr>
        <% for(let t of totalSent) { %>
            <tr>
                <td><%= t.name %></td>
                <td class="amount"><%= amountFormat(t.total) %></td>
                <td><%= t.currencyId %></td>
            </tr>
        <% } %>
    </table>
    
    <br>
    <h2>Total Received</h2>
    <table>
        <tr>
            <th>Name</th>
            <th class="amount">Amount</th>
            <th>Currency</th>
        </tr>
        <% for(let t of totalReceived) { %>
            <tr>
                <td><%= t.name %></td>
                <td class="amount"><%= amountFormat(t.total) %></td>
                <td><%= t.currencyId %></td>
            </tr>
        <% } %>
    </table>
    
    </body>
    </html>
    
  participants.yaml: |
    params:
      name:
        required: false
        default: null
      currency:
        required: true
      limit:
        required: false
        default: 100
    
    data:
      totalSent: |
        SELECT p.name, SUM(amount) as total, currencyId
        FROM participant p
          INNER JOIN participantCurrency pC on pC.participantId = p.participantId
          INNER JOIN transferParticipant tP ON pC.participantCurrencyId = tP.participantCurrencyId
        WHERE amount > 0 AND currencyId = :currency
          AND CASE WHEN :name IS NOT NULL THEN p.name = :name ELSE TRUE END
        GROUP BY p.name, currencyId
        LIMIT :limit
      totalReceived: |
        SELECT p.name, -SUM(amount) as total, currencyId
        FROM participant p
          INNER JOIN participantCurrency pC on pC.participantId = p.participantId
          INNER JOIN transferParticipant tP ON pC.participantCurrencyId = tP.participantCurrencyId
        WHERE amount < 0 AND currencyId = :currency
          AND CASE WHEN :name IS NOT NULL THEN p.name = :name ELSE TRUE END
        GROUP BY p.name, currencyId
        LIMIT :limit
    
  settlement.ejs: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <style>
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
                display: block;
                overflow-x: auto;
                white-space: nowrap;
            }
    
            td, th {
    //            border: 1px solid #efefef;
                text-align: left;
                padding: 8px;
            }
    
            tr:nth-child(even) {
    //            background-color: #efefef;
            }
    
            td > span {
                font-weight: bold;
            }
        </style>
        <title>Settlement Bank Report</title>
    </head>
    <body>
    
    <%
    const senders = [];
    const receivers = [];
    const amounts = {};
    const totalSent = {};
    const totalReceived = {};
    const participants = {};
    let netTotal = 0;
    const netPositionsPretty = {};
    const defaultCurrency = transfers[0] && transfers[0].currencyId;
    for (let t of transfers) {
        participants[t.senderId] = t.sender;
        if (!senders.includes(t.senderId)) {
            senders.push(t.senderId);
        }
        if (t.receiverId && t.currencyId === defaultCurrency) {
            amounts[`${t.senderId}:${t.receiverId}`] = parseFloat(t.amount);
            totalSent[t.senderId] = (totalSent[t.senderId] || 0) + parseFloat(t.amount);
            totalReceived[t.receiverId] = (totalReceived[t.receiverId] || 0) + parseFloat(t.amount);
            if (!receivers.includes(t.receiverId)) {
                receivers.push(t.receiverId);
            }
        }
    }
    const participantEntries = Object.entries(participants).sort((a, b) => a[1].localeCompare(b[1]));
    
    for(let [id] of participantEntries) {
        let v = ((totalSent[id] || 0) - (totalReceived[id] || 0));
        netTotal += v;
        let vf = Math.abs(v).toLocaleString('en-US');
        netPositionsPretty[id] = v >= 0 ? vf : `(${vf})`;
    }
    
    %>
    
    <table>
        <tr>
            <td><span>Settlement ID</span></td>
            <td style="text-align: right"><%= transfers[0] && transfers[0].settlementId %></td>
            <td></td>
            <td><span>Created Date</span></td>
            <td colspan="2" style="text-align: right"><%= transfers[0] && (d = transfers[0].createdDate, `${d.toLocaleDateString('en-ZA')} ${d.toLocaleTimeString('en-US')}`)%></td>
        </tr>
        <tr>
            <td><span>Currency</span></td>
            <td style="text-align: right"><%= transfers[0] && transfers[0].currencyId %></td>
            <td></td>
            <td><span>Last Action Date</span></td>
            <td colspan="2" style="text-align: right"><%=
                transfers[0] &&
                (d = transfers
                        .filter(a => a.lastActionDate)
                        .reduce((a,b) => a.lastActionDate.getTime() > b.lastActionDate.getTime() ? a : b).lastActionDate,
                        `${d.toLocaleDateString('en-ZA')} ${d.toLocaleTimeString('en-US')}`)
                %></td>
        </tr>
        <tr>
            <td colspan="100%" style="padding-top: 20px"><div style="font-weight: bold">Multilateral Net Positions</div></td>
        </tr>
        <tr>
            <th></th>
            <th></th>
            <% for(let i = 0; i < participantEntries.length; i++) { %>
            <th><span>Received by</span></th>
            <% } %>
            <th>TOTAL SENT</th>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <% for(let [id, name] of participantEntries) { %>
                <td><%= `${id} ${name}` %></td>
            <% } %>
            <td></td>
        </tr>
        <% for(let [senderId, senderName] of participantEntries) { %>
            <tr>
                <td><span>Sent by</span></td>
                <td><%= `${senderId} ${senderName}` %></td>
                <% for(let [receiverId] of participantEntries) { %>
                    <% if (senderId === receiverId) { %>
                        <td style="background-color: #cccccc"></td>
                    <% } else if (amounts[`${senderId}:${receiverId}`]) { %>
                        <td style="text-align: right"><%= amounts[`${senderId}:${receiverId}`].toLocaleString('en-US') %></td>
                    <% } else { %>
                        <td style="text-align: right">-</td>
                    <% } %>
                <% } %>
                <td style="text-align: right"><%= totalSent[senderId] ? totalSent[senderId].toLocaleString('en-US') : '-' %></td>
            </tr>
        <% } %>
        <tr>
            <td colspan="100%" style="padding-top: 10px"></td>
        </tr>
        <tr>
            <td></td>
            <td><span>Total Received</span></td>
            <% for(let [id] of participantEntries) { %>
                <td style="text-align: right"><%= totalReceived[id] ? totalReceived[id].toLocaleString('en-US') : '-' %></td>
            <% } %>
        </tr>
        <tr>
            <td colspan="100%" style="padding-top: 30px"><div style="font-weight: bold">Aggregated Net Positions</div></td>
        </tr>
        <% for(let [id, name] of participantEntries) { %>
            <tr>
                <td><%= `${id} ${name}` %></td>
                <td style="text-align: right"><%= netPositionsPretty[id] %></td>
                <td></td>
            </tr>
        <% } %>
        <tr>
            <td style="padding-top: 30px">Check value</td>
            <td style="text-align: right"><%= netTotal %></td>
            <td>(should be zero)</td>
        </tr>
    </table>
    </body>
    </html>
    
  settlement.yaml: |
    params:
      settlementId:
        required: true
      currency:
        required: false
        default: null
    
    data:
      settlementId: SELECT :settlementId
      transfers: |
        SELECT
                  p2.name as sender,
                  p2.participantId as senderId,
                  receiverId,
                  SUM(amount) as amount,
                  settlementId,
                  ss.createdDate,
                  MAX(lastActionDate) as lastActionDate,
                  currencyId
                FROM
                    participant p2 LEFT JOIN
                    (
                        SELECT settlementId,
                               createdDate,
                               MAX(lastActionDate) as lastActionDate,
                               senderId,
                               receiverId,
                               SUM(amount)         as amount,
                               currencyId
                        FROM (
                                 SELECT MAX(CASE WHEN tP.amount > 0 THEN p.participantId END) as senderId,
                                        MAX(CASE WHEN tP.amount < 0 THEN p.participantId END) as receiverId,
                                        MAX(tP.amount)                               as amount,
                                        MAX(tF.completedDate)                        as lastActionDate,
                                        s.settlementId,
                                        s.createdDate,
                                        currencyId as currencyId
                                 FROM transferParticipant tP
                                          INNER JOIN transferFulfilment tF on tP.transferId = tF.transferId
                                          INNER JOIN settlementSettlementWindow sSW
                                                     on tF.settlementWindowId = sSW.settlementWindowId
                                          INNER JOIN settlementWindowStateChange sWSC
                                                     on sSW.settlementWindowId = sWSC.settlementWindowId
                                          INNER JOIN settlement s on sSW.settlementId = s.settlementId
                                          INNER JOIN participantCurrency pC
                                                     on tP.participantCurrencyId = pC.participantCurrencyId
                                          INNER JOIN participant p on pC.participantId = p.participantId
                                 WHERE tF.isValid
                                   AND sWSC.settlementWindowStateId = 'CLOSED'
                                   AND s.settlementId = :settlementId
                                   AND CASE WHEN :currency IS NOT NULL THEN currencyId = :currency ELSE TRUE END
                                 GROUP BY tF.transferId, s.settlementId, currencyId
                             ) s
                        GROUP BY senderId, receiverId, settlementId, currencyId
                    ) ss ON p2.participantId = ss.senderId
    
                WHERE p2.name != 'Hub'
                GROUP BY settlementId, p2.participantId, receiverId, currencyId
                ORDER BY settlementId DESC, p2.name
    
  settlementInitiation.ejs: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <style>
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
                display: block;
                overflow-x: auto;
                white-space: nowrap;
            }
    
            td, th {
    //            border: 1px solid #efefef;
                text-align: left;
                padding: 8px;
            }
    
            tr:nth-child(even) {
    //            background-color: #efefef;
            }
    
            td > span {
                font-weight: bold;
            }
        </style>
        <title>Settlement Bank Report</title>
    </head>
    <body>
    
    <%
    const cbBankId = {
        ayapay: 'ayapay placeholder\n0000 0000 0000 0000',
        cbpay: 'cbpay placeholder\n0000 0000 0000 0000',
        citizenswallet: 'citizenswallet placeholder\n0000 0000 0000 0000',
        demomfi: 'demomfi placeholder\n0000 0000 0000 0000',
        demowallet: 'demowallet placeholder\n0000 0000 0000 0000',
        easy: 'easy placeholder\n0000 0000 0000 0000',
        hana: 'Hana Microfinance Limited\n0086 1005 0003 5335',
        mmdayapay: 'mmdayapay placeholder\n0000 0000 0000 0000',
        mmdcbpay: 'mmdcbpay placeholder\n0000 0000 0000 0000',
        mmdcitizenswallet: 'mmdcitizenswallet placeholder\n0000 0000 0000 0000',
        mmdokdollar: 'Internet Wallet Myanmar Limited\n0086 1005 0000 7617',
        mmdooredoo: 'mmdooredoo placeholder\n0000 0000 0000 0000',
        noresponsepayeefsp: 'noresponsepayeefsp placeholder\n0000 0000 0000 0000',
        okdollar: 'okdollar placeholder\n0000 0000 0000 0000',
        ooredoo: 'ooredoo placeholder\n0000 0000 0000 0000',
        payeefsp: 'payeefsp placeholder\n0000 0000 0000 0000',
        payerfsp: 'payerfsp placeholder\n0000 0000 0000 0000',
        pm4mlreceiverfsp: 'pm4mlreceiverfsp placeholder\n0000 0000 0000 0000',
        pm4mlsenderfsp: 'pm4mlsenderfsp placeholder\n0000 0000 0000 0000',
        sathapana: 'sathapana placeholder\n0000 0000 0000 0000',
        testfsp1: 'testfsp1 placeholder\n0000 0000 0000 0000',
        testfsp2: 'testfsp2 placeholder\n0000 0000 0000 0000',
        visionfund: 'Vision Fund Myanmar Co., Ltd\n0086 1005 0003 5351'
    };
    // Because no currency has more than four decimal places, we can have quite a large epsilon value
    const EPSILON = 1e-5;
    // We use parseFloat because it returns NaN for parseFloat(null)
    const transfersSum = adjustments.reduce((sum, adj) => sum + parseFloat(adj.amount), 0);
    if (Number.isNaN(transfersSum) || (transfersSum > EPSILON)) {
      throw new Error(`Expected settlement initiation report transfers to sum to zero. Sum: ${transfersSum}. Report data: ${JSON.stringify(adjustments)}.`);
    }
    %>
    
    <table>
        <tr>
            <td><span>Settlement ID</span></td>
            <td style="text-align: right"><%= settlementId[0].settlementId %></td>
        </tr>
        <tr>
            <td><span>Settlement Completed Date</span></td>
            <td style="text-align: right"></td>
        </tr>
        <tr>
            <td><span>Settlement Completed Time</span></td>
            <td style="text-align: right"></td>
        </tr>
        <tr>
            <td><span>Timezone</span></td>
            <td style="text-align: right">MMT</td>
        </tr>
    
        <tr><td></td><td></td></tr>
    
        <tr>
            <td>Participant (WynePay Identifier)</td>
            <td>Participant (CB Bank Identifier)</td>
            <td>Balance</td>
            <td>Settlement Transfer</td>
        </tr>
        <% for (const { name, participantId, accountId, currencyId, amount } of adjustments) { %>
            <tr>
                <td><%= `${participantId} ${accountId} ${name}` %></td>
                <td><%= `${cbBankId[name]}` %></td>
                <td></td>
                <td style="text-align: right"><%= amount %></td>
                <td></td>
            </tr>
        <% } %>
    </table>
    </body>
    </html>
    
  settlementInitiation.yaml: |
    params:
      settlementId:
        required: true
    
    data:
      settlementId: SELECT :settlementId AS settlementId
      adjustments: |
        SELECT
            SUM(tp.amount)            AS  amount,
            p.name                    AS  name,
            p.participantId           AS  participantId,
            pc.participantCurrencyId  AS  accountId,
            pc.currencyId             AS  currencyId
        FROM settlement s
        INNER JOIN settlementSettlementWindow ssw  ON  ssw.settlementId = s.settlementId
        INNER JOIN transferFulfilment tf           ON  tf.settlementWindowId = ssw.settlementWindowId
        INNER JOIN transferParticipant tp          ON  tp.transferId = tf.transferId
        INNER JOIN participantCurrency pc          ON  tp.participantCurrencyId = pc.participantCurrencyId
        INNER JOIN participant p                   ON  p.participantId = pc.participantId
        INNER JOIN ledgerAccountType lat           ON  lat.ledgerAccountTypeId = pc.ledgerAccountTypeId
        WHERE s.settlementId = :settlementId AND lat.name = 'POSITION'
        GROUP BY p.name, pc.participantCurrencyId
