var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { HttpClient } from 'aurelia-fetch-client';
import { Config } from './../index';
import { DateComputation } from '../resources/filters/date-filter/date-computation';
import { AuthService } from '../security/auth-service';
import { Container } from 'aurelia-framework';
import { Datacontext } from './data-context';
import * as breeze from 'breeze-client';
import { FilterMode } from '../model/common-model';
import { CamelCase } from './../utils/came-case';
import { ValidationController } from 'aurelia-validation';
import { PredicateUtils } from './predicate-utils';
import { Box } from '../modules/box';
var Repository = (function () {
    function Repository(manager, logger, entityTypeName, resourceName, i18n) {
        this.manager = manager;
        this.logger = logger;
        this.entityTypeName = entityTypeName;
        this.resourceName = resourceName;
        this.i18n = i18n;
        this.datacontext = Container.instance.get(Datacontext);
        this.authService = Container.instance.get(AuthService);
        this.dateComputation = Container.instance.get(DateComputation);
        this.config = Container.instance.get(Config);
        this.httpClient = Container.instance.get(HttpClient);
        this.validator = Container.instance.get(ValidationController);
        this.predicateUtils = Container.instance.get(PredicateUtils);
        this.box = Container.instance.get(Box);
    }
    Repository.prototype.fetchForDataGrid = function (resourceNames, params, expands, quickFilter, queryCriteria, queryParameters) {
        var _this = this;
        if (expands === void 0) { expands = null; }
        if (quickFilter === void 0) { quickFilter = null; }
        if (queryParameters === void 0) { queryParameters = null; }
        var orderByClause = "id";
        var results = {};
        var promise = new Promise(function (resolve, reject) {
            var _a;
            if (params != null && params.sortModel != null) {
                var sortArray = params.sortModel;
                orderByClause = '';
                sortArray.forEach(function (c) {
                    if (orderByClause.length > 0)
                        orderByClause += ',';
                    orderByClause += _this.handleTranslations(isArray(c.colId) ? c.colId : [c.colId]);
                    if (orderByClause.indexOf('_') > -1) {
                        orderByClause = orderByClause.replace('_', '.');
                    }
                    orderByClause += " " + c.sort;
                });
            }
            if (orderByClause.trim() == "") {
                orderByClause = null;
            }
            var predicatesFromQueryCriteria = queryCriteria != null ? queryCriteria.predicates : null;
            var predicatesFromParams = (params != null) && _this.getPredicatesFromParams(params, quickFilter);
            var predicates = (predicatesFromQueryCriteria && predicatesFromParams) ? predicatesFromQueryCriteria.and(predicatesFromParams) :
                (predicatesFromQueryCriteria && !predicatesFromParams) ? predicatesFromQueryCriteria :
                    (!predicatesFromQueryCriteria && predicatesFromParams) ? predicatesFromParams : null;
            var entityQuery = breeze.EntityQuery;
            var query;
            if (params != null && params.startRow != null) {
                query = entityQuery.from(resourceNames)
                    .take(params.endRow - params.startRow)
                    .skip(params.startRow)
                    .orderBy(orderByClause)
                    .inlineCount();
            }
            else {
                query = entityQuery.from(resourceNames)
                    .orderBy(orderByClause)
                    .inlineCount();
            }
            if (predicates != null)
                query = query.where(predicates);
            if (expands != null)
                query = query.expand(expands);
            if (queryParameters != null)
                query = query.withParameters(queryParameters);
            if (((_a = queryCriteria.selectPropertyPaths) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                query = query.select(queryCriteria.selectPropertyPaths);
            }
            query = query.using(breeze.FetchStrategy.FromServer);
            _this.manager.executeQuery(query)
                .then(function (data) {
                results.fullCount = data.inlineCount;
                results.results = data.results;
                resolve(results);
            })
                .catch(function (error) {
                _this.queryFailed(error);
                results.error = error;
                reject(results);
            });
        });
        return promise;
    };
    Repository.prototype.getEntityById = function (objectId, expands, fromLocalCache) {
        var _this = this;
        if (fromLocalCache === void 0) { fromLocalCache = false; }
        var entityQuery = breeze.EntityQuery;
        var query = entityQuery.from(this.resourceName).where("id", breeze.FilterQueryOp.Equals, objectId);
        if (expands != null && expands.length > 0)
            query = query.expand(expands);
        query = query.using(fromLocalCache ? breeze.FetchStrategy.FromLocalCache : breeze.FetchStrategy.FromServer);
        return this.manager.executeQuery(query)
            .then(function (data) {
            return data.results[0];
        })
            .catch(function (error) {
            _this.queryFailed(error);
            return null;
        });
    };
    Repository.prototype.getAllEntities = function (expands) {
        var _this = this;
        var entityQuery = breeze.EntityQuery;
        var query = entityQuery.from(this.resourceName);
        if (expands != null && expands.length > 0)
            query = query.expand(expands);
        query = query.using(breeze.FetchStrategy.FromServer);
        return this.manager.executeQuery(query)
            .then(function (data) {
            return data.results;
        })
            .catch(function (error) {
            _this.queryFailed(error);
            return null;
        });
    };
    Repository.prototype.getEntities = function (predicates, expands, parameters, orderBy, paging) {
        if (predicates === void 0) { predicates = null; }
        return this.internalGetEntities(breeze.FetchStrategy.FromServer, predicates, expands, parameters, orderBy, paging);
    };
    Repository.prototype.getEntitiesFromLocalCache = function (predicates, expands, orderBy, paging) {
        if (predicates === void 0) { predicates = null; }
        return this.internalGetEntities(breeze.FetchStrategy.FromLocalCache, predicates, expands, null, orderBy, paging);
    };
    Repository.prototype.getCount = function (predicates, parameters) {
        var _this = this;
        if (predicates === void 0) { predicates = null; }
        var entityQuery = breeze.EntityQuery;
        var query = entityQuery.from(this.resourceName);
        if (predicates != null) {
            query = query.where(predicates);
        }
        if (parameters != null) {
            query = query.withParameters(parameters);
        }
        query = query.take(0).inlineCount(true);
        query = query.using(breeze.FetchStrategy.FromServer);
        return this.manager.executeQuery(query)
            .then(function (data) {
            return data.inlineCount;
        })
            .catch(function (error) {
            _this.queryFailed(error);
            return 0;
        });
    };
    Repository.prototype.firstEntity = function (predicates, expands, parameters, orderBy, skip) {
        var _this = this;
        var _a;
        if (predicates === void 0) { predicates = null; }
        var entityQuery = breeze.EntityQuery;
        var query = entityQuery.from(this.resourceName);
        if (expands != null && expands.length > 0) {
            query = query.expand(expands);
        }
        if (predicates != null) {
            query = query.where(predicates);
        }
        if (parameters != null) {
            query = query.withParameters(parameters);
        }
        if (orderBy != null) {
            query = query.orderBy(orderBy.propertyPaths, (_a = orderBy.isDescending) !== null && _a !== void 0 ? _a : false);
        }
        if (skip != null) {
            query = query.skip(skip);
        }
        query = query.take(1).using(breeze.FetchStrategy.FromServer);
        return this.manager.executeQuery(query)
            .then(function (data) {
            return data.results[0];
        })
            .catch(function (error) {
            _this.queryFailed(error);
            return null;
        });
    };
    Repository.prototype.getEntitiesFromCache = function (entityState) {
        return this.manager.getEntities(this.entityTypeName, entityState);
    };
    Repository.prototype.addEntityInCacheIfNotPresent = function (id, observableEntity, initialValues, entityState) {
        var _this = this;
        var entity = this.manager.getEntityByKey(this.entityTypeName, id);
        var promise = new Promise(function (resolve) {
            if (entity == null) {
                _this.createEntity(initialValues, entityState).then(function (entity) {
                    resolve(entity);
                });
            }
            else {
                resolve(entity);
            }
        });
        return promise;
    };
    Repository.prototype.findAddedEntity = function (initialValues) {
        var addedEntities = this.getEntitiesFromCache(breeze.EntityState.Added);
        var filterPredicate = function (entity) {
            var ret = true;
            for (var p in initialValues) {
                if (initialValues.hasOwnProperty(p)) {
                    ret = ret && initialValues[p] == entity[p];
                }
            }
            return ret;
        };
        var existingAddedEntity = addedEntities.filter(filterPredicate);
        if (existingAddedEntity != null && existingAddedEntity.length === 1) {
            return existingAddedEntity[0];
        }
        return null;
    };
    Repository.prototype.restoreDeletedEntity = function (initialValues) {
        var deletedEntities = this.getEntitiesFromCache(breeze.EntityState.Deleted);
        var filterPredicate = function (entity) {
            var ret = true;
            for (var p in initialValues) {
                if (initialValues.hasOwnProperty(p)) {
                    ret = ret && initialValues[p] == entity[p];
                }
            }
            return ret;
        };
        var existingDeletedEntity = deletedEntities.filter(filterPredicate);
        if (existingDeletedEntity != null && existingDeletedEntity.length == 1) {
            existingDeletedEntity[0].entityAspect.rejectChanges();
            return existingDeletedEntity[0];
        }
        return null;
    };
    Repository.prototype.createEntity = function (initialValues, entityState) {
        var _this = this;
        return new Promise(function (resolve) { return resolve(_this.createEntityHelper(initialValues, entityState)); });
    };
    Repository.prototype.resolveReferences = function (json) {
        if (typeof json === 'string')
            json = JSON.parse(json);
        var byid = {}, refs = [];
        json = (function recurse(obj, prop, parent) {
            if (typeof obj !== 'object' || !obj)
                return obj;
            if (Object.prototype.toString.call(obj) === '[object Array]') {
                for (var i = 0; i < obj.length; i++)
                    if (typeof obj[i] !== 'object' || !obj[i])
                        continue;
                    else if ("$ref" in obj[i])
                        obj[i] = recurse(obj[i], i, obj);
                    else
                        obj[i] = recurse(obj[i], prop, obj);
                return obj;
            }
            if ("$ref" in obj) {
                var ref = obj.$ref;
                if (ref in byid)
                    return byid[ref];
                refs.push([parent, prop, ref]);
                return;
            }
            else if ("$id" in obj) {
                var id = obj.$id;
                delete obj.$id;
                if ("$values" in obj)
                    obj = obj.$values.map(recurse);
                else
                    for (var propObj in obj)
                        obj[propObj] = recurse(obj[propObj], propObj, obj);
                byid[id] = obj;
            }
            return obj;
        })(json);
        for (var i = 0; i < refs.length; i++) {
            var ref = refs[i];
            ref[0][ref[1]] = byid[ref[2]];
        }
        return json;
    };
    Repository.prototype.createEntityFromFactory = function (factoryRequest, overriddenInitialValues) {
        return __awaiter(this, void 0, void 0, function () {
            var factoryResponse, factoryResult, _a, _b, defaultEntityValues, createdEntity;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0: return [4, this.httpClient.post(factoryRequest)];
                    case 1:
                        factoryResponse = _c.sent();
                        if (!factoryResponse.ok) return [3, 4];
                        _b = (_a = JSON).parse;
                        return [4, factoryResponse.text()];
                    case 2:
                        factoryResult = _b.apply(_a, [_c.sent(), function (key, value) { return CamelCase.convertKeysToCamelCase(key, value); }]);
                        defaultEntityValues = this.resolveReferences(factoryResult.entity);
                        if (overriddenInitialValues != null) {
                            defaultEntityValues = Object.assign(defaultEntityValues, overriddenInitialValues);
                        }
                        return [4, this.createEntityHelper(defaultEntityValues)];
                    case 3:
                        createdEntity = _c.sent();
                        this.setFKToUnChanged(createdEntity, 0);
                        return [2, { entity: createdEntity, parameters: factoryResult.parameters }];
                    case 4: throw factoryResponse.text();
                }
            });
        });
    };
    Repository.prototype.setFKToUnChanged = function (entity, level) {
        var _this = this;
        if (level > 5)
            return;
        entity.entityType.navigationProperties.forEach(function (navigationProperty) {
            if (navigationProperty.isScalar) {
                var currentFkObject = entity[navigationProperty.name];
                if (currentFkObject != null && currentFkObject.entityAspect.entityState === breeze.EntityState.Added) {
                    currentFkObject.entityAspect.setUnchanged();
                }
                if (currentFkObject != null) {
                    _this.setFKToUnChanged(currentFkObject, level + 1);
                }
            }
        });
    };
    Repository.prototype.setFKDataPropertyToNullWhenNumericNonNullable = function (entity) {
        entity.entityType.navigationProperties.forEach(function (navigationProperty) {
            if (navigationProperty.isScalar) {
                var currentFkObject = entity[navigationProperty.name];
                if (currentFkObject == null) {
                    navigationProperty.foreignKeyNames.forEach(function (foreignKeyName) {
                        var dataProperty = entity.entityType.dataProperties.find(function (x) { return x.name == foreignKeyName; });
                        if (dataProperty != null && !dataProperty.isComplexProperty && dataProperty.isSettable && !dataProperty.isNullable && dataProperty.dataType.isNumeric && entity[foreignKeyName] != null && entity[foreignKeyName] <= 0) {
                            entity[foreignKeyName] = null;
                        }
                    });
                }
            }
        });
    };
    Repository.prototype.createEntitySync = function (initialValues, entityState) {
        return this.createEntityHelper(initialValues, entityState);
    };
    Repository.prototype.createEntityHelper = function (initialValues, entityState) {
        if (initialValues == null)
            initialValues = {};
        var entityType = this.manager.metadataStore.getEntityType(this.entityTypeName);
        if (entityType.autoGeneratedKeyType != breeze.AutoGeneratedKeyType.Identity && entityType.keyProperties.findIndex(function (val) { return val.name === "id"; }) >= 0)
            if (initialValues.id == undefined)
                initialValues.id = -((new Date()).getTime() & 0xffff);
        var createdEntity = this.manager.createEntity(this.entityTypeName, initialValues, entityState, breeze.MergeStrategy.SkipMerge);
        this.setFKDataPropertyToNullWhenNumericNonNullable(createdEntity);
        return createdEntity;
    };
    Repository.prototype.detachEntity = function (entity) {
        entity.entityAspect.setDetached();
    };
    Repository.prototype.lockRecordForEditing = function (entity) {
        var _this = this;
        var saveOptions = new breeze.SaveOptions();
        saveOptions.resourceName = "lockRecordForEditing";
        return this.manager.saveChanges([entity], saveOptions)
            .then(function (saveSucceeded) {
            _this.logger.Log("Lock the record for editing", saveSucceeded, 'Repository', false);
        })
            .catch(function (errors) {
            _this.logger.LogError("Errors when locking the record", errors, 'Repository', false);
            if (errors.entityErrors) {
                _this.queryFailed(errors);
            }
            return Promise.reject(errors);
        });
    };
    Repository.prototype.saveChanges = function (entities, silentSave, byPassLocking) {
        var _this = this;
        var options = new breeze.SaveOptions();
        if (byPassLocking === true) {
            options.tag = "BY_PASS_LOCKING";
        }
        return this.manager.saveChanges(entities === null || entities === void 0 ? void 0 : entities.filter(function (entity) { return entity.entityAspect.entityState.isDetached() == false; }), options)
            .then(function (saveSucceeded) {
            _this.logger.Log(_this.i18n.tr('general.successfullySaved', { ns: "common" }), saveSucceeded, 'Repository', !silentSave);
        })
            .catch(function (errors) {
            _this.queryFailed(errors);
            return Promise.reject(errors);
        });
    };
    Repository.prototype.cancelChanges = function (silentMode) {
        if (silentMode === void 0) { silentMode = false; }
        this.manager.rejectChanges();
        this.logger.Log(this.i18n.tr('general.cancelModifications', { ns: "common" }), null, 'Repository', !silentMode);
    };
    Repository.prototype.deleteEntities = function (entities, detachInverseFKEntities, beforeSaveAction) {
        var _this = this;
        if (detachInverseFKEntities === void 0) { detachInverseFKEntities = false; }
        if (beforeSaveAction === void 0) { beforeSaveAction = null; }
        var entitiesTemp = __spreadArray([], __read(entities), false);
        var entitiesLength = entities.length;
        var _loop_1 = function () {
            var entity = entities[entitiesLength - 1];
            if (entity.entityAspect.entityState.isAdded()) {
                entity.entityAspect.setDetached();
            }
            else {
                entity.entityAspect.setDeleted();
            }
            if (beforeSaveAction != null) {
                beforeSaveAction(entity);
            }
            if (detachInverseFKEntities) {
                var inverseForeignKeyProperties = entity.entityType.inverseForeignKeyProperties;
                inverseForeignKeyProperties.forEach(function (inverseFK) {
                    if (inverseFK.parentType.name != entity.entityType.name) {
                        var changes = _this.manager.getChanges(inverseFK.parentType.name);
                        var changesLength = changes.length;
                        while (changesLength > 0) {
                            var change = changes[changesLength - 1];
                            change.entityAspect.setDetached();
                            changesLength--;
                        }
                    }
                });
            }
            entitiesLength--;
        };
        while (entitiesLength > 0) {
            _loop_1();
        }
        return this.saveChanges(entitiesTemp, true);
    };
    Repository.prototype.internalGetEntities = function (fetchStrategy, predicates, expands, parameters, orderBy, paging) {
        var _this = this;
        var _a;
        if (predicates === void 0) { predicates = null; }
        var entityQuery = breeze.EntityQuery;
        var query = entityQuery.from(this.resourceName);
        if (expands != null && expands.length > 0)
            query = query.expand(expands);
        if (predicates != null) {
            query = query.where(predicates);
        }
        if (parameters != null) {
            query = query.withParameters(parameters);
        }
        if (orderBy != null) {
            query = query.orderBy(orderBy.propertyPaths, (_a = orderBy.isDescending) !== null && _a !== void 0 ? _a : false);
        }
        if (paging != null) {
            if (paging.pageNumber != null && paging.take != null) {
                query = query.skip((paging.pageNumber - 1) * paging.take);
                query = query.take(paging.take);
            }
            else {
                if (paging.take) {
                    query = query.take(paging.take);
                }
                if (paging.skip) {
                    query = query.skip(paging.skip);
                }
            }
        }
        query = query.using(fetchStrategy);
        return this.manager.executeQuery(query)
            .then(function (data) {
            return data.results;
        })
            .catch(function (error) {
            _this.queryFailed(error);
            return null;
        });
    };
    Repository.prototype.getPredicatesFromParams = function (params, quickFilter) {
        var _this = this;
        var nbOfOrPredicate = 0;
        var predicates = new Array();
        var filterModel = params.filterModel;
        if (filterModel && Object.keys(filterModel).length > 0) {
            Object.keys(filterModel).forEach(function (f) {
                var _a;
                var _b, _c, _d;
                var filter = filterModel[f];
                if (filter != null) {
                    var operator = void 0;
                    if (filter.type != null) {
                        operator = _this.getBreezeOperatorFromFilterType(filter.type);
                    }
                    if (filter.filterType == "text") {
                        var tempPredicate = void 0;
                        if (filter.filter != null) {
                            var textPredicates = _this.predicateUtils.getPredicates(filter.filter, _this.handleTranslation(f), breeze.DataType.String, operator);
                            if (textPredicates.length > 0) {
                                tempPredicate = (_a = breeze.Predicate).and.apply(_a, __spreadArray([], __read(textPredicates), false));
                            }
                        }
                        if (filter.displayEmptyFields) {
                            tempPredicate = _this.addNullabilityToPredicate(tempPredicate, _this.handleTranslation(f), true)
                                .or(new breeze.Predicate(_this.handleTranslation(f), breeze.FilterQueryOp.Equals, ""));
                        }
                        if (tempPredicate != null) {
                            predicates.push(tempPredicate);
                        }
                    }
                    else if (filter.filterType == "number") {
                        var tempPredicate = void 0;
                        if (filter.filter || filter.filterTo) {
                            if (filter.type === "inRange") {
                                tempPredicate = new breeze.Predicate(f, breeze.FilterQueryOp.LessThanOrEqual, filter.filterTo).and(new breeze.Predicate(f, breeze.FilterQueryOp.GreaterThanOrEqual, filter.filter));
                            }
                            else {
                                tempPredicate = new breeze.Predicate(f, operator, (filter.filter ? filter.filter : filter.filterTo));
                            }
                        }
                        if (filter.displayEmptyFields) {
                            tempPredicate = _this.addNullabilityToPredicate(tempPredicate, f, true);
                        }
                        predicates.push(tempPredicate);
                    }
                    else if (filter.filterType == "boolean") {
                        predicates.push(new breeze.Predicate(f, breeze.FilterQueryOp.Equals, filter.filter));
                    }
                    else if (filter.filterType == "date") {
                        var dateInterval = _this.dateComputation.GetDateIntervalFromFilter(filter);
                        var tempPredicate = void 0;
                        if (dateInterval.dateFrom != null) {
                            tempPredicate = new breeze.Predicate(f, breeze.FilterQueryOp.GreaterThanOrEqual, dateInterval.dateFrom.toDate());
                        }
                        if (dateInterval.dateTo != null) {
                            tempPredicate = breeze.Predicate.and(tempPredicate, new breeze.Predicate(f, breeze.FilterQueryOp.LessThanOrEqual, dateInterval.dateTo.toDate()));
                        }
                        if (filter.isDateNullable) {
                            nbOfOrPredicate++;
                            tempPredicate = _this.addNullabilityToPredicate(tempPredicate, f, true);
                        }
                        predicates.push(tempPredicate);
                    }
                    else if (filter.filterType == "set") {
                        var tempPredicates_1 = null;
                        filter.values.forEach(function (value) {
                            if (tempPredicates_1 == null)
                                tempPredicates_1 = new breeze.Predicate(f, breeze.FilterQueryOp.Equals, value);
                            else
                                tempPredicates_1 = tempPredicates_1.or(new breeze.Predicate(f, breeze.FilterQueryOp.Equals, value));
                        });
                        if (tempPredicates_1) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_1);
                        }
                    }
                    else if (filter.filterType == "enumeration") {
                        var enumerationValues = filter.filter;
                        var tempPredicates_2;
                        var property_1 = ((_b = filter.relationIdFieldName) === null || _b === void 0 ? void 0 : _b.length) > 0 ? filter.relationIdFieldName : _this.handleTranslation(f);
                        enumerationValues.forEach(function (enumerationValue) {
                            var _a;
                            if (enumerationValue.selected) {
                                var predicate = void 0;
                                if (((_a = filter.relationIdFieldName) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                                    predicate = new breeze.Predicate(property_1, breeze.FilterQueryOp.Equals, enumerationValue.id);
                                }
                                else {
                                    predicate = new breeze.Predicate(property_1, breeze.FilterQueryOp.Equals, enumerationValue.name);
                                }
                                tempPredicates_2 = tempPredicates_2 != null ? tempPredicates_2.or(predicate) : predicate;
                            }
                        });
                        if (filter.displayEmptyFields) {
                            nbOfOrPredicate++;
                            tempPredicates_2 = _this.addNullabilityToPredicate(tempPredicates_2, property_1, true);
                        }
                        if (tempPredicates_2) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_2);
                        }
                    }
                    else if (filter.filterType == "enum") {
                        var enumValues = filter.filter;
                        var tempPredicates_3;
                        enumValues.forEach(function (enumValue) {
                            if (enumValue.selected) {
                                if (tempPredicates_3 == null)
                                    tempPredicates_3 = new breeze.Predicate(f, breeze.FilterQueryOp.Equals, enumValue.index);
                                else
                                    tempPredicates_3 = tempPredicates_3.or(new breeze.Predicate(f, breeze.FilterQueryOp.Equals, enumValue.index));
                            }
                        });
                        if (tempPredicates_3) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_3);
                        }
                    }
                    else if (filter.filterType == "user") {
                        var fieldKey_1 = f;
                        var byName_1 = true;
                        if (/ByFullName$/.test(fieldKey_1)) {
                            fieldKey_1 = f.replace(/ByFullName$/, 'ById');
                            byName_1 = false;
                        }
                        if (operator != null) {
                            if (filter.userPreFilter != null) {
                                filter.filter = _this.authService.currentUser[byName_1 ? 'fullName' : 'id'];
                            }
                            predicates.push(new breeze.Predicate(fieldKey_1, operator, filter.filter));
                        }
                        else {
                            var userValues = filter.filter;
                            var tempPredicates_4;
                            userValues.forEach(function (userValue) {
                                if (userValue.selected) {
                                    if (tempPredicates_4 == null)
                                        tempPredicates_4 = new breeze.Predicate(fieldKey_1, breeze.FilterQueryOp.Equals, userValue[byName_1 ? 'name' : 'id']);
                                    else
                                        tempPredicates_4 = tempPredicates_4.or(new breeze.Predicate(fieldKey_1, breeze.FilterQueryOp.Equals, userValue[byName_1 ? 'name' : 'id']));
                                }
                            });
                            if (filter.displayEmptyFields) {
                                nbOfOrPredicate++;
                                tempPredicates_4 = _this.addNullabilityToPredicate(tempPredicates_4, fieldKey_1, true);
                            }
                            if (tempPredicates_4) {
                                nbOfOrPredicate++;
                                predicates.push(tempPredicates_4);
                            }
                        }
                    }
                    else if (filter.filterType == "manyToMany" && f.includes('.')) {
                        var values = filter.filter;
                        var allFieldPath = f.split('.');
                        var arrayIndex = (_c = filter.arrayIndex) !== null && _c !== void 0 ? _c : 1;
                        var arrayName_1 = allFieldPath.slice(0, arrayIndex + 1).join(".");
                        var fieldPath_1 = allFieldPath.slice(arrayIndex + 1).join(".");
                        var tempPredicates_5;
                        values.forEach(function (value) {
                            if (value.selected) {
                                if (tempPredicates_5 == null)
                                    tempPredicates_5 = new breeze.Predicate(arrayName_1, breeze.FilterQueryOp.Any, _this.handleTranslation(fieldPath_1), breeze.FilterQueryOp.Equals, value.name);
                                else {
                                    if (filter.filterMode == FilterMode.And) {
                                        tempPredicates_5 = tempPredicates_5.and(new breeze.Predicate(arrayName_1, breeze.FilterQueryOp.Any, _this.handleTranslation(fieldPath_1), breeze.FilterQueryOp.Equals, value.name));
                                    }
                                    else {
                                        tempPredicates_5 = tempPredicates_5.or(new breeze.Predicate(arrayName_1, breeze.FilterQueryOp.Any, _this.handleTranslation(fieldPath_1), breeze.FilterQueryOp.Equals, value.name));
                                    }
                                }
                            }
                        });
                        if (filter.displayEmptyFields) {
                            nbOfOrPredicate++;
                            tempPredicates_5 = _this.addNullabilityToPredicate(tempPredicates_5, arrayName_1, true, fieldPath_1.includes("_translation") ? _this.handleTranslation(fieldPath_1) : fieldPath_1);
                        }
                        if (tempPredicates_5) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_5);
                        }
                    }
                    else if (filter.filterType == "oneToMany") {
                        var values = filter.filter;
                        var tempPredicates_6;
                        var property_2 = ((_d = filter.relationIdFieldName) === null || _d === void 0 ? void 0 : _d.length) > 0 ? filter.relationIdFieldName : _this.handleTranslation(f);
                        values.forEach(function (value) {
                            var _a;
                            if (value.selected) {
                                var predicate = void 0;
                                if (((_a = filter.relationIdFieldName) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                                    predicate = new breeze.Predicate(property_2, breeze.FilterQueryOp.Equals, value.id);
                                }
                                else {
                                    predicate = new breeze.Predicate(property_2, breeze.FilterQueryOp.Equals, value.name);
                                }
                                tempPredicates_6 = tempPredicates_6 != null ? tempPredicates_6.or(predicate) : predicate;
                            }
                        });
                        if (filter.displayEmptyFields) {
                            nbOfOrPredicate++;
                            tempPredicates_6 = _this.addNullabilityToPredicate(tempPredicates_6, property_2, true);
                        }
                        if (tempPredicates_6) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_6);
                        }
                    }
                    else if (filter.type == null && filter.length > 0) {
                        var filterArray = filter;
                        var tempPredicates_7 = null;
                        filterArray.forEach(function (value) {
                            if (tempPredicates_7 == null) {
                                tempPredicates_7 = new breeze.Predicate(_this.handleTranslation(f), breeze.FilterQueryOp.Equals, value);
                            }
                            else {
                                tempPredicates_7 = tempPredicates_7.or(new breeze.Predicate(_this.handleTranslation(f), breeze.FilterQueryOp.Equals, value));
                            }
                        });
                        if (tempPredicates_7) {
                            nbOfOrPredicate++;
                            predicates.push(tempPredicates_7);
                        }
                    }
                }
            });
        }
        var p;
        if (predicates.length > 0) {
            if (predicates.length > 1 && nbOfOrPredicate > 1) {
                var dataProperty = this.manager.metadataStore.getEntityType(this.entityTypeName).keyProperties.find(function (val) { return !val.isNullable && (val.isPartOfKey || !val.isPartOfKey); });
                if (dataProperty != null) {
                    predicates.push(new breeze.Predicate(dataProperty.name, breeze.FilterQueryOp.NotEquals, null));
                }
            }
            p = breeze.Predicate.and(predicates);
        }
        p = this.fillPredicatesWithQuickFilter(p, quickFilter);
        return p;
    };
    Repository.prototype.handleTranslation = function (field) {
        return this.handleTranslations([field])[0];
    };
    Repository.prototype.handleTranslations = function (fields) {
        var _this = this;
        return fields.map(function (field) { return field.replace('_translation', _this.datacontext.translatePropertyName); });
    };
    Repository.prototype.getBreezeOperatorFromFilterType = function (filterType) {
        switch (filterType) {
            case 'contains':
                return breeze.FilterQueryOp.Contains;
            case 'notEqual':
                return breeze.FilterQueryOp.NotEquals;
            case 'inRange':
                return breeze.FilterQueryOp.Equals;
            case 'equals':
                return breeze.FilterQueryOp.Equals;
            case 'startsWith':
                return breeze.FilterQueryOp.StartsWith;
            case 'endsWith':
                return breeze.FilterQueryOp.EndsWith;
            case 'greaterThan':
                return breeze.FilterQueryOp.GreaterThanOrEqual;
            case 'lessThan':
                return breeze.FilterQueryOp.LessThanOrEqual;
            default:
                return null;
        }
    };
    Repository.prototype.addNullabilityToPredicate = function (predicate, property, isNullable, fieldPath) {
        if (fieldPath === void 0) { fieldPath = null; }
        var nullablePredicate;
        if (isNullable) {
            nullablePredicate = fieldPath != null ?
                new breeze.Predicate(property, breeze.FilterQueryOp.Any, fieldPath, breeze.FilterQueryOp.NotEquals, null).not()
                : new breeze.Predicate(property, breeze.FilterQueryOp.Equals, null);
            return predicate ? predicate.or(nullablePredicate) : nullablePredicate;
        }
        return predicate;
    };
    Repository.prototype.fillPredicatesWithQuickFilter = function (predicate, quickFilter) {
        var _this = this;
        var _a;
        if (quickFilter != null && quickFilter.length > 0) {
            var entityTypeName = this.manager.metadataStore.getEntityTypeNameForResourceName(this.resourceName);
            var entityType = this.manager.metadataStore.getEntityType(entityTypeName);
            var languages = Container.instance.get(Config).globalConfig.configuredLanguages || [];
            var columnIndex_1 = (_a = languages.find(function (x) { return x.code == _this.i18n.getLocale(); })) === null || _a === void 0 ? void 0 : _a.columnIndex;
            var currentPredicate_1;
            entityType.dataProperties
                .filter(function (dp) {
                return (dp.dataType == breeze.DataType.String || dp.dataType.name == TranslatedPropertyDataType)
                    && dp.enumType == null
                    && dp.isUnmapped != true;
            })
                .forEach(function (dp) {
                var predicateQuickFilter = _this.quickFilterGetPredicate(dp, quickFilter, columnIndex_1);
                if (predicateQuickFilter.length > 0) {
                    var newPredicates = breeze.Predicate.and(predicateQuickFilter);
                    if (currentPredicate_1 == null) {
                        currentPredicate_1 = newPredicates;
                    }
                    else {
                        currentPredicate_1 = currentPredicate_1.or(newPredicates);
                    }
                }
            });
            if (predicate != null && currentPredicate_1 != null) {
                return predicate.and(currentPredicate_1);
            }
            return predicate !== null && predicate !== void 0 ? predicate : currentPredicate_1;
        }
        return predicate;
    };
    Repository.prototype.quickFilterGetPredicate = function (dp, quickFilter, columnIndex) {
        if (dp.dataType == breeze.DataType.String) {
            return this.predicateUtils.getPredicates(quickFilter, dp.name, breeze.DataType.String, breeze.FilterQueryOp.Contains);
        }
        else if (dp.dataType.name == TranslatedPropertyDataType) {
            if (columnIndex != null) {
                return this.predicateUtils.getPredicates(quickFilter, dp.name + '.lang' + columnIndex, breeze.DataType.String, breeze.FilterQueryOp.Contains);
            }
        }
    };
    Repository.prototype.isKnownServerSideError = function (entityError) {
        var translationKey = 'serverExceptions.' + entityError.errorName;
        if (this.i18n.i18next.exists(translationKey, { ns: "common" })) {
            return {
                isKnown: true,
                translation: this.i18n.tr(translationKey, { ns: "common" })
            };
        }
        if (this.i18n.i18next.exists(translationKey)) {
            return {
                isKnown: true,
                translation: this.i18n.tr(translationKey)
            };
        }
        return {
            isKnown: false
        };
    };
    Repository.prototype.queryFailed = function (errors) {
        var _this = this;
        if (errors.entityErrors) {
            errors.entityErrors.forEach(function (entityError) {
                var responseIsKnown = _this.isKnownServerSideError(entityError);
                if (responseIsKnown.isKnown) {
                    var message = responseIsKnown.translation;
                    if (entityError.errorName == "ELEMENT_COULD_NOT_BE_DELETED") {
                        message += _this.getElementCouldNotBeDeletedMessage(entityError);
                    }
                    _this.box.showError(message, _this.i18n.tr('general.error', { ns: "common" }), null, false);
                }
                else if (entityError.entity) {
                    if (entityError.errorName == "VALIDATION_EXCEPTION") {
                        var message = _this.getValidationException(entityError);
                        _this.validator.addError(message, entityError.entity, entityError.propertyName);
                        if (message != null) {
                            _this.logger.LogError(message, errors, 'Repository', true);
                        }
                        else {
                            _this.getDefaultMessage(entityError, errors);
                        }
                    }
                    else {
                        _this.logger.LogError(entityError.errorMessage, errors, 'Repository', (entityError.propertyName && entityError.propertyName.length > 0));
                    }
                }
                else {
                    _this.getDefaultMessage(entityError, errors, true);
                }
            });
        }
        else {
            if (errors.status == null) {
                this.logger.LogError(this.i18n.tr('serverExceptions.serverNotAvailable', { ns: 'common' }), errors, 'Repository', true);
            }
            else if (errors.status == 414) {
                this.logger.LogError(this.i18n.tr('serverExceptions.uriTooLong', { ns: 'common' }), errors, 'Repository', true);
            }
            else if (errors.status == 500) {
                var message = void 0;
                if (errors.message != null && typeof errors.message == "string" && errors.message.length > 0) {
                    message = errors.message;
                }
                else {
                    message = this.i18n.tr("serverExceptions.unattendedError", { ns: "common" });
                }
                this.logger.LogError(message, errors, 'Repository', true);
            }
            else {
                this.logger.LogError(errors, errors, 'Repository', true);
            }
        }
    };
    Repository.prototype.getElementCouldNotBeDeletedMessage = function (element) {
        var _this = this;
        var message = '<ul class="browser-default">';
        try {
            var entitiesToDel = JSON.parse(element.errorMessage, function (key, value) { return CamelCase.convertKeysToCamelCase(key, value); });
            message += entitiesToDel.map(function (entityToDel) {
                var entityName = entityToDel.entityName.toLowerCase();
                var message = "<li>".concat(entityToDel.count, " ").concat(_this.i18n.tr(entityName + '.' + entityName));
                if (entityToDel.displayValues != null && entityToDel.displayValues.length > 0) {
                    var entityPropertyName = CamelCase.toCamelCase(entityToDel.entityPropertyName);
                    var displayValue = void 0;
                    if (typeof entityToDel.displayValues[0] == "string" || entityToDel.displayValues[0] instanceof String) {
                        displayValue = entityToDel.displayValues.join(", ");
                    }
                    else {
                        displayValue = entityToDel.displayValues.map(function (x) { return x[_this.datacontext.translatePropertyName]; }).join(", ");
                    }
                    var informationMessage = void 0;
                    if (entityToDel.displayValues.length > 1) {
                        informationMessage = 'serverExceptions.ELEMENT_COULD_NOT_BE_DELETED_INFORMATIONS';
                    }
                    else {
                        informationMessage = 'serverExceptions.ELEMENT_COULD_NOT_BE_DELETED_INFORMATION';
                    }
                    message += " ".concat(_this.i18n.tr(informationMessage, { ns: "common", displayName: _this.i18n.tr(entityName + '.' + entityPropertyName) }), " ").concat(displayValue);
                }
                return message + '</li>';
            }).join('');
        }
        catch (error) { }
        finally {
            return message + '</ul>';
        }
    };
    Repository.prototype.getDefaultMessage = function (entityError, errors, showToast) {
        if (showToast === void 0) { showToast = true; }
        var keyTr = 'serverExceptions.' + entityError.errorName;
        var message = this.i18n.tr(keyTr, { ns: "common" });
        if (message == keyTr) {
            message = this.i18n.tr(keyTr);
            if (message == keyTr) {
                message = entityError.errorMessage;
            }
        }
        this.logger.LogError(message, errors, 'Repository', showToast);
    };
    Repository.prototype.getValidationException = function (entityError) {
        if (entityError.errorName == "VALIDATION_EXCEPTION" && entityError.propertyName != null) {
            var errorParameter = JSON.parse(entityError.errorMessage, function (key, value) { return CamelCase.convertKeysToCamelCase(key, value); });
            if (errorParameter != null) {
                if (errorParameter.errorMessageTr != null) {
                    return this.i18n.tr(errorParameter.errorMessageTr, errorParameter.parameters);
                }
                else {
                    if (errorParameter.errorMessage != null) {
                        return errorParameter.errorMessage;
                    }
                }
            }
        }
        return null;
    };
    return Repository;
}());
export { Repository };
var TranslatedPropertyDataType = "TranslatedProperty:#DWFramework.Web.API.Model";

//# sourceMappingURL=repository.js.map
