import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { reassureOwnerIdExists } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
const getInvoicesByIssueDates = sql `
  SELECT *
  FROM accounter_schema.deel_invoices
  WHERE issued_at >= $from
    AND issued_at <= $to;`;
const getInvoicesByIds = sql `
  SELECT *
  FROM accounter_schema.deel_invoices
  WHERE id in $$ids;`;
const getChargeIdsByPaymentIds = sql `
  SELECT d.charge_id, i.payment_id
  FROM accounter_schema.deel_invoices i
  LEFT JOIN accounter_schema.documents d
    ON i.document_id = d.id AND d.charge_id IS NOT NULL
  WHERE i.payment_id in $$paymentIds;`;
const getReceiptToCharge = sql `
SELECT DISTINCT ON (di.payment_id)
    di.payment_id,
    d.charge_id
FROM
    accounter_schema.deel_invoices di
LEFT JOIN accounter_schema.documents d
    ON d.id = di.document_id
ORDER BY
    di.payment_id, di.created_at ASC;`;
const insertDeelInvoiceRecords = sql `
      INSERT INTO accounter_schema.deel_invoices (
        id,
        document_id,
        amount,
        contract_id,
        created_at,
        currency,
        deel_fee,
        due_date,
        is_overdue,
        issued_at,
        label,
        paid_at,
        status,
        total,
        vat_id,
        vat_percentage,
        vat_total,
        adjustment,
        approve_date,
        approvers,
        bonus,
        commissions,
        contract_country,
        contract_start_date,
        contract_type,
        contractor_email,
        contractor_employee_name,
        contractor_unique_identifier,
        deductions,
        expenses,
        frequency,
        general_ledger_account,
        group_id,
        others,
        overtime,
        payment_currency,
        pro_rata,
        processing_fee,
        "work",
        total_payment_currency,
        payment_id,
        recipient_legal_entity_id,
        owner_id)
      VALUES ($id,
        $documentId,
        $amount,
        $contractId,
        $createdAt,
        $currency,
        $deelFee,
        $dueDate,
        $isOverdue,
        $issuedAt,
        $label,
        $paidAt,
        $status,
        $total,
        $vatId,
        $vatPercentage,
        $vatTotal,
        $adjustment,
        $approveDate,
        $approvers,
        $bonus,
        $commissions,
        $contractCountry,
        $contractStartDate,
        $contractType,
        $contractorEmail,
        $contractorEmployeeName,
        $contractorUniqueIdentifier,
        $deductions,
        $expenses,
        $frequency,
        $generalLedgerAccount,
        $groupId,
        $others,
        $overtime,
        $paymentCurrency,
        $proRata,
        $processingFee,
        $work,
        $totalPaymentCurrency,
        $paymentId,
        $recipientLegalEntityId,
        $ownerId)
      RETURNING *;`;
let DeelInvoicesProvider = class DeelInvoicesProvider {
    db;
    adminContextProvider;
    constructor(db, adminContextProvider) {
        this.db = db;
        this.adminContextProvider = adminContextProvider;
    }
    async batchInvoicesByIssueDates(issueDates) {
        const times = issueDates.map(date => date.getTime());
        const from = new Date(Math.min(...times));
        const to = new Date(Math.max(...times));
        const records = await getInvoicesByIssueDates.run({ from, to }, this.db);
        return issueDates.map(date => {
            return records.filter(record => record.issued_at.getTime() === date.getTime());
        });
    }
    async getInvoicesByIssueDates(from, to) {
        try {
            return getInvoicesByIssueDates.run({ from, to }, this.db);
        }
        catch (e) {
            const message = `Error getting Deel invoices by issue dates`;
            console.error(message, e);
            throw new Error(message, { cause: e });
        }
    }
    getInvoicesByIssueDateLoader = new DataLoader((dates) => this.batchInvoicesByIssueDates(dates), { cacheKeyFn: date => date.getTime().toString() });
    async batchInvoicesByIds(ids) {
        const invoices = await getInvoicesByIds.run({ ids }, this.db);
        return ids.map(id => invoices.find(invoice => invoice.id === id));
    }
    getInvoicesByIdLoader = new DataLoader((ids) => this.batchInvoicesByIds(ids));
    async batchChargeIdsByPaymentIds(paymentIds) {
        const matches = await getChargeIdsByPaymentIds.run({ paymentIds }, this.db);
        return paymentIds.map(paymentId => matches.find(match => match.payment_id === paymentId)?.charge_id);
    }
    getChargeIdByPaymentIdLoader = new DataLoader((paymentIds) => this.batchChargeIdsByPaymentIds(paymentIds));
    async getReceiptToCharge() {
        try {
            const records = await getReceiptToCharge.run(undefined, this.db);
            const receiptChargeMap = new Map();
            for (const record of records) {
                if (record.charge_id) {
                    receiptChargeMap.set(record.payment_id, record.charge_id);
                }
            }
            return receiptChargeMap;
        }
        catch (e) {
            const message = `Error getting receipt to charge mapping`;
            console.error(message, e);
            throw new Error(message, { cause: e });
        }
    }
    async insertDeelInvoiceRecords(params) {
        try {
            const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
            // invalidate cache
            return insertDeelInvoiceRecords.run(reassureOwnerIdExists(params, ownerId), this.db);
        }
        catch (e) {
            const message = `Error inserting Deel invoice`;
            console.error(message, e);
            throw new Error(message, { cause: e });
        }
    }
};
DeelInvoicesProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AdminContextProvider])
], DeelInvoicesProvider);
export { DeelInvoicesProvider };
//# sourceMappingURL=deel-invoices.provider.js.map