"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transaction = exports.PaymentFlat = exports.Payment = exports.TransactionUnitaryCostConfiguration = exports.TransactionUnitaryTagMask = exports.TransactionUnitaryCostPartition = exports.TransactionRelation = exports.TransactionNamespace = exports.TransactionAccountableEntityType = exports.TransactionWeightType = exports.TransactionTarget = void 0;
const jackson_js_1 = require("jackson-js");
const date_1 = require("../jack-x/date");
const tag_1 = require("../tag");
const financial_entry_1 = require("./financial_entry");
const unitary_cost_1 = require("./unitary_cost");
const lodash_1 = __importDefault(require("lodash"));
var TransactionTarget;
(function (TransactionTarget) {
    TransactionTarget["STORE"] = "STORE";
    TransactionTarget["PRODUCTS"] = "PRODUCTS";
    TransactionTarget["LOTS"] = "LOTS";
})(TransactionTarget = exports.TransactionTarget || (exports.TransactionTarget = {}));
var TransactionWeightType;
(function (TransactionWeightType) {
    TransactionWeightType["VOLUMETRIC"] = "VOLUMETRIC";
    TransactionWeightType["UNITARY"] = "UNITARY";
    TransactionWeightType["MONETARY"] = "MONETARY";
})(TransactionWeightType = exports.TransactionWeightType || (exports.TransactionWeightType = {}));
var TransactionAccountableEntityType;
(function (TransactionAccountableEntityType) {
    TransactionAccountableEntityType["TRANSACTION"] = "TRANSACTION";
    TransactionAccountableEntityType["PURCHASE_ORDER"] = "PURCHASE_ORDER";
    TransactionAccountableEntityType["INBOUND_SHIPMENT"] = "INBOUND_SHIPMENT";
    TransactionAccountableEntityType["REMOVAL_ORDER"] = "REMOVAL_ORDER";
    TransactionAccountableEntityType["PRODUCT"] = "PRODUCT";
    TransactionAccountableEntityType["STORE"] = "STORE";
})(TransactionAccountableEntityType = exports.TransactionAccountableEntityType || (exports.TransactionAccountableEntityType = {}));
var TransactionNamespace;
(function (TransactionNamespace) {
    TransactionNamespace["INTERNAL_COSTS"] = "internal/costs";
    TransactionNamespace["INTERNAL_REIMBURSEMENTS"] = "internal/reimbursements";
    TransactionNamespace["USER_COSTS"] = "user/costs";
    TransactionNamespace["USER_REIMBURSEMENTS"] = "user/reimbursements";
    TransactionNamespace["USER_PURCHASE_ORDERS"] = "user/purchase-orders";
})(TransactionNamespace = exports.TransactionNamespace || (exports.TransactionNamespace = {}));
class TransactionRelation {
    constructor(relationObject, weight) {
        this.relationObject = relationObject;
        this.weight = weight;
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionRelation.prototype, "relationObject", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionRelation.prototype, "weight", void 0);
exports.TransactionRelation = TransactionRelation;
class TransactionUnitaryCostPartition {
    constructor(subject, weight, addKeys = []) {
        this.subject = subject;
        this.weight = weight;
        this.additionalKeys = addKeys;
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionUnitaryCostPartition.prototype, "subject", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionUnitaryCostPartition.prototype, "weight", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [String]] })
], TransactionUnitaryCostPartition.prototype, "additionalKeys", void 0);
exports.TransactionUnitaryCostPartition = TransactionUnitaryCostPartition;
class TransactionUnitaryTagMask {
    constructor(source, dest) {
        this.source = source;
        this.dest = dest;
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionUnitaryTagMask.prototype, "source", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], TransactionUnitaryTagMask.prototype, "dest", void 0);
exports.TransactionUnitaryTagMask = TransactionUnitaryTagMask;
class TransactionUnitaryCostConfiguration {
    constructor() {
        this.tagMasksRegex = [];
        this.partitions = [];
    }
    addMaskRegex(source, dest) {
        this.tagMasksRegex.push(new TransactionUnitaryTagMask(source, dest));
    }
    addPartition(subject, weight, addKeys = []) {
        this.partitions.push(new TransactionUnitaryCostPartition(subject, weight, addKeys));
    }
    maskTag(tag, chainable = false) {
        let res = tag.toString();
        for (const mask of this.tagMasksRegex) {
            const regex = new RegExp(mask.source, "gi");
            res = res.replace(regex, mask.dest);
            if (!chainable && tag.toString() != res) {
                return new tag_1.Tag(res);
            }
        }
        return new tag_1.Tag(res);
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [TransactionUnitaryCostPartition]] })
], TransactionUnitaryCostConfiguration.prototype, "partitions", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [TransactionUnitaryTagMask]] })
], TransactionUnitaryCostConfiguration.prototype, "tagMasksRegex", void 0);
exports.TransactionUnitaryCostConfiguration = TransactionUnitaryCostConfiguration;
class Payment {
    // tagTemplate is the tag without discriminator
    constructor(tagTemplate, date, amount) {
        this.tagTemplate = tagTemplate;
        this.date = date;
        this.amount = amount;
        this.vat = undefined;
    }
    // if currency is undefinet, the original exchange will be returned
    flatten(currency) {
        const netExchange = lodash_1.default.find(this.amount, (e) => {
            if (!currency) {
                return e.original == true;
            }
            return e.currency == currency;
        });
        if (!netExchange) {
            return undefined;
        }
        const flat = new PaymentFlat(this.tagTemplate, this.date, netExchange.currency, netExchange.amount);
        const vatExchange = lodash_1.default.find(this.vat || [], (e) => {
            if (!currency) {
                return e.original == true;
            }
            return e.currency == currency;
        });
        if (vatExchange) {
            flat.vat = vatExchange.amount;
        }
        return flat;
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonSerialize)({ using: date_1.DateSerializer.serialize }),
    (0, jackson_js_1.JsonDeserialize)({ using: date_1.DateSerializer.deserialize }),
    (0, jackson_js_1.JsonClassType)({ type: () => [Date] })
], Payment.prototype, "date", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [financial_entry_1.Exchange]] })
], Payment.prototype, "vat", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [financial_entry_1.Exchange]] })
], Payment.prototype, "amount", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [tag_1.Tag] })
], Payment.prototype, "tagTemplate", void 0);
exports.Payment = Payment;
class PaymentFlat {
    // tagTemplate is the tag without discriminator
    constructor(tagTemplate, date, currency, amount) {
        this.tagTemplate = tagTemplate;
        this.date = date;
        this.currency = currency;
        this.amount = amount;
        this.vat = undefined;
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonSerialize)({ using: date_1.DateSerializer.serialize }),
    (0, jackson_js_1.JsonDeserialize)({ using: date_1.DateSerializer.deserialize }),
    (0, jackson_js_1.JsonClassType)({ type: () => [Date] })
], PaymentFlat.prototype, "date", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], PaymentFlat.prototype, "currency", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], PaymentFlat.prototype, "vat", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], PaymentFlat.prototype, "amount", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [tag_1.Tag] })
], PaymentFlat.prototype, "tagTemplate", void 0);
exports.PaymentFlat = PaymentFlat;
class Transaction {
    constructor(id, namespace, accEntityType, accEntity, date, target) {
        this.strip = () => {
            this.notes = "";
            this.profitability = [];
            this.generatedUnitaryCosts = [];
            this.unitaryCostConfiguration = undefined;
            this.generateProfitability = false;
        };
        this.id = id;
        this.accountableEntityType = accEntityType;
        this.accountableEntity = accEntity;
        this.namespace = namespace;
        this.date = date;
        this.title = "";
        this.target = target;
        this.notes = "";
        this.weightType = TransactionWeightType.UNITARY;
        this.label = "";
        this.payments = [];
        this.relations = [];
        this.profitability = [];
        this.generatedUnitaryCosts = [];
        this.isCashflow = false;
        this.generateProfitability = false;
    }
    getRelationObjects() {
        return lodash_1.default.map(this.relations, r => (r.relationObject));
    }
}
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "id", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "accountableEntity", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "accountableEntityType", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonSerialize)({ using: date_1.DateSerializer.serialize }),
    (0, jackson_js_1.JsonDeserialize)({ using: date_1.DateSerializer.deserialize }),
    (0, jackson_js_1.JsonClassType)({ type: () => [Date] })
], Transaction.prototype, "date", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "namespace", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "title", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "notes", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "label", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "target", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "weightType", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [Payment]] })
], Transaction.prototype, "payments", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [financial_entry_1.FinancialEntry]] })
], Transaction.prototype, "profitability", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [unitary_cost_1.UnitaryCost]] })
], Transaction.prototype, "generatedUnitaryCosts", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [Array, [TransactionRelation]] })
], Transaction.prototype, "relations", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)(),
    (0, jackson_js_1.JsonClassType)({ type: () => [TransactionUnitaryCostConfiguration] })
], Transaction.prototype, "unitaryCostConfiguration", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "isCashflow", void 0);
__decorate([
    (0, jackson_js_1.JsonProperty)()
], Transaction.prototype, "generateProfitability", void 0);
exports.Transaction = Transaction;
//# sourceMappingURL=transaction.js.map