import * as gracely from "gracely" import * as isoly from "isoly" import * as selectively from "selectively" import * as authly from "authly" import { Fee } from "./Fee" import { Processor } from "./Processor" import { Transaction as SettlementTransaction } from "./Transaction" import { V1 } from "./V1" export interface Settlement { reference: string merchant: authly.Identifier | string period: { start: isoly.Date | isoly.DateTime end: isoly.Date | isoly.DateTime } payout?: isoly.Date | { amount: number; date: isoly.Date } reserve?: { amount: number; payout?: isoly.Date } created: isoly.Date currency: isoly.Currency gross: number fee: number | V1.Fee | Fee net: number transactions: SettlementTransaction[] processor?: Processor } export namespace Settlement { export function is(value: any | Settlement): value is Settlement { return ( typeof value == "object" && typeof value.reference == "string" && typeof value.merchant == "string" && typeof value.period == "object" && (isoly.Date.is(value.period.start) || isoly.DateTime.is(value.period.start)) && (isoly.Date.is(value.period.end) || isoly.DateTime.is(value.period.end)) && (value.payout == undefined || isoly.Date.is(value.payout) || (value.payout && typeof value.payout == "object" && typeof value.payout.amount == "number" && isoly.Date.is(value.payout.date))) && (value.reserve == undefined || (typeof value.reserve == "object" && typeof value.reserve.amount == "number" && (value.reserve.payout == undefined || isoly.Date.is(value.reserve.payout)))) && isoly.Date.is(value.created) && isoly.Currency.is(value.currency) && typeof value.gross == "number" && (typeof value.fee == "number" || V1.Fee.is(value.fee) || Fee.is(value.fee)) && typeof value.net == "number" && Array.isArray(value.transactions) && value.transactions.every(SettlementTransaction.is) && (value.processor == undefined || Processor.is(value.processor)) ) } export function flaw(value: Settlement | any): gracely.Flaw { return { type: "Settlement", flaws: typeof value != "object" ? undefined : ([ typeof value.reference == "string" || { property: "reference", type: "string" }, typeof value.merchant == "string" || { property: "merchant", type: "authly.Identifier | string", condition: `Should be merchant id, but may be processor specific reference if unable to match with the correct merchant.`, }, (typeof value.period == "object" && (isoly.Date.is(value.period.start) || isoly.DateTime.is(value.period.start)) && (isoly.Date.is(value.period.end) || isoly.DateTime.is(value.period.end))) || { property: "period", type: "{start: isoly.Date, end: isoly.Date}", }, value.payout == undefined || isoly.Date.is(value.payout) || (value.payout && typeof value.payout == "object" && typeof value.payout.amount == "number" && isoly.Date.is(value.payout.date)) || { property: "payout", type: "undefined | isoly.Date | { amount: number; date: isoly.Date }", }, value.reserve == undefined || (typeof value.reserve == "object" && typeof value.reserve.amount == "number" && (value.reserve.payout == undefined || isoly.Date.is(value.reserve.payout))) || { property: "reserve", type: "{amount: number, payout?: isoly.Date}", }, isoly.Date.is(value.created) || { property: "created", type: "isoly.Date" }, isoly.Currency.is(value.currency) || { property: "currency", type: "isoly.Currency" }, typeof value.gross == "number" || { property: "gross", type: "number" }, typeof value.fee == "number" || (typeof value.fee == "object" && (V1.Fee.is(value.fee) || Fee.is(value.fee))) || { property: "fee", type: "number | { scheme: number; total: number } | { interchange: number; network?: number; intergiro: number; total: number }", }, typeof value.net == "number" || { property: "net", type: "number" }, value.transactions.every(SettlementTransaction.is) || { property: "transactions", type: "Transaction[]" }, value.processor == undefined || Processor.is(value.processor) || { property: "processor", type: `"omnipay" | "silverflow" | "baboba" | "clearhaus" | undefined`, }, ].filter(gracely.Flaw.is) as gracely.Flaw[]), } } export function toCustomer(value: Settlement): Settlement export function toCustomer(value: Settlement[]): Settlement[] export function toCustomer(value: Settlement | Settlement[]): Settlement | Settlement[] { let result: Settlement | Settlement[] if (Array.isArray(value)) result = value.map(s => toCustomer(s)) else { result = { ...value, transactions: SettlementTransaction.toCustomer(value.transactions), fee: typeof value.fee == "object" ? value.fee.total : value.fee, } delete result.processor } return result } export const template = new selectively.Type.Object({ reference: new selectively.Type.String(), merchant: new selectively.Type.String(), period: new selectively.Type.Object({ start: new selectively.Type.String(), end: new selectively.Type.String() }), payout: new selectively.Type.String(), reserve: new selectively.Type.Object({ amount: new selectively.Type.Number(), payout: new selectively.Type.String(), }), created: new selectively.Type.String(), currency: new selectively.Type.Union(isoly.Currency.types.map(c => new selectively.Type.String(c))), gross: new selectively.Type.Number(), fee: new selectively.Type.Union([ new selectively.Type.Number(), new selectively.Type.Object({ scheme: new selectively.Type.Number(), total: new selectively.Type.Number() }), new selectively.Type.Object({ interchange: new selectively.Type.Number(), network: new selectively.Type.Number(), intergiro: new selectively.Type.Number(), total: new selectively.Type.Number(), }), ]), net: new selectively.Type.Number(), transactions: new selectively.Type.Array([SettlementTransaction.template]), processor: new selectively.Type.Union(Processor.types.map(c => new selectively.Type.String(c))), }) }