"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 __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var ImportTransactionService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImportTransactionService = exports.ImportTransactionStatus = exports.ImportMimeTypes = exports.ImportFormat = void 0;
const common_1 = require("@nestjs/common");
const core_1 = require("@nestjs/core");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const crud_service_1 = require("./crud.service");
const axios_1 = require("@nestjs/axios");
const error_messages_1 = require("../constants/error-messages");
const create_field_metadata_dto_1 = require("../dtos/create-field-metadata.dto");
const import_transaction_error_log_entity_1 = require("../entities/import-transaction-error-log.entity");
const date_helper_1 = require("../helpers/date.helper");
const import_transaction_repository_1 = require("../repository/import-transaction.repository");
const uuid_1 = require("uuid");
const csv_service_1 = require("./csv.service");
const excel_service_1 = require("./excel.service");
const solid_introspect_service_1 = require("./solid-introspect.service");
const model_metadata_helper_service_1 = require("../helpers/model-metadata-helper.service");
const user_helper_1 = require("../helpers/user-helper");
const lodash_1 = require("lodash");
const string_helper_1 = require("../helpers/string.helper");
var ImportFormat;
(function (ImportFormat) {
    ImportFormat["CSV"] = "csv";
    ImportFormat["EXCEL"] = "excel";
})(ImportFormat || (exports.ImportFormat = ImportFormat = {}));
var ImportMimeTypes;
(function (ImportMimeTypes) {
    ImportMimeTypes["CSV"] = "text/csv";
    ImportMimeTypes["EXCEL"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
})(ImportMimeTypes || (exports.ImportMimeTypes = ImportMimeTypes = {}));
var ImportTransactionStatus;
(function (ImportTransactionStatus) {
    ImportTransactionStatus["draft"] = "draft";
    ImportTransactionStatus["mapping_created"] = "mapping_created";
    ImportTransactionStatus["import_started"] = "import_started";
    ImportTransactionStatus["import_succeeded"] = "import_succeeded";
    ImportTransactionStatus["import_failed"] = "import_failed";
})(ImportTransactionStatus || (exports.ImportTransactionStatus = ImportTransactionStatus = {}));
let ImportTransactionService = ImportTransactionService_1 = class ImportTransactionService extends crud_service_1.CRUDService {
    constructor(entityManager, repo, moduleRef, excelService, csvService, httpService, introspectService, modelMetadataHelperService) {
        super(entityManager, repo, 'importTransaction', 'solid-core', moduleRef);
        this.entityManager = entityManager;
        this.repo = repo;
        this.moduleRef = moduleRef;
        this.excelService = excelService;
        this.csvService = csvService;
        this.httpService = httpService;
        this.introspectService = introspectService;
        this.modelMetadataHelperService = modelMetadataHelperService;
        this.logger = new common_1.Logger(ImportTransactionService_1.name);
    }
    async getImportTemplate(modelMetadataId, format = ImportFormat.CSV) {
        const modelMetadata = await this.modelMetadataService.findOne(modelMetadataId, {
            populate: ['fields'],
        });
        if (!modelMetadata) {
            throw new Error(error_messages_1.ERROR_MESSAGES.MODEL_METADATA_NOT_FOUND(modelMetadataId));
        }
        const allFields = await this.modelMetadataHelperService.loadFieldHierarchy(modelMetadata.singularName);
        const headers = this.fieldsAllowedForImport(allFields)
            .map(field => field.displayName);
        if (format === ImportFormat.CSV) {
            const stream = await this.csvService.createCsvStream(null, 0, headers);
            const fileName = `${modelMetadata.singularName}-import-template.csv`;
            const mimeType = 'text/csv';
            return {
                stream,
                fileName,
                mimeType,
            };
        }
        else if (format === ImportFormat.EXCEL) {
            const stream = await this.excelService.createExcelStream(null, 0, headers);
            const fileName = `${modelMetadata.singularName}-import-template.xlsx`;
            const mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
            return {
                stream,
                fileName,
                mimeType,
            };
        }
        else {
            throw new Error(error_messages_1.ERROR_MESSAGES.INVALID_FORMAT('import' + format));
        }
    }
    async getImportInstructions(modelMetadataId) {
        const modelMetadata = await this.modelMetadataService.findOne(modelMetadataId, {
            populate: ['fields'],
        });
        if (!modelMetadata) {
            throw new Error(error_messages_1.ERROR_MESSAGES.MODEL_METADATA_NOT_FOUND(modelMetadataId));
        }
        const allFields = await this.modelMetadataHelperService.loadFieldHierarchy(modelMetadata.singularName);
        const systemFieldNames = this.modelMetadataHelperService
            .getSystemFieldsMetadata()
            .map(field => field.name);
        const userExcluded = (0, user_helper_1.getUserExcludedFields)();
        const standardInstructions = {
            requiredFields: [],
            dateFields: [],
            dateTimeFields: [],
            numberFields: [],
            emailFields: [],
            regexFields: [],
            jsonFields: [],
            booleanFields: [],
        };
        for (const field of allFields) {
            if (systemFieldNames.includes(field.name)) {
                continue;
            }
            if (userExcluded.includes(field.name)) {
                continue;
            }
            if (field.required) {
                standardInstructions.requiredFields.push(field.displayName);
            }
            if (field.type === create_field_metadata_dto_1.SolidFieldType.date) {
                standardInstructions.dateFields.push(field.displayName);
            }
            if (field.type === create_field_metadata_dto_1.SolidFieldType.datetime) {
                standardInstructions.dateTimeFields.push(field.displayName);
            }
            if ([create_field_metadata_dto_1.SolidFieldType.bigint, create_field_metadata_dto_1.SolidFieldType.int, create_field_metadata_dto_1.SolidFieldType.decimal].includes(field.type)) {
                standardInstructions.numberFields.push(field.displayName);
            }
            if (field.type === create_field_metadata_dto_1.SolidFieldType.email) {
                standardInstructions.emailFields.push(field.displayName);
            }
            if (field.regexPattern) {
                standardInstructions.regexFields.push({
                    fieldName: field.displayName,
                    regexPattern: field.regexPattern,
                });
            }
            if (field.type === create_field_metadata_dto_1.SolidFieldType.json) {
                standardInstructions.jsonFields.push(field.displayName);
            }
            if (field.type === create_field_metadata_dto_1.SolidFieldType.boolean) {
                standardInstructions.booleanFields.push(field.displayName);
            }
        }
        const customInstructions = [];
        return {
            standard: standardInstructions,
            custom: customInstructions,
        };
    }
    async getImportMappingInfo(importTransactionId) {
        const importTransaction = await this.loadImportTransaction(importTransactionId);
        const importableFields = this.fieldsAllowedForImport(importTransaction.modelMetadata.fields).map(field => ({
            name: field.name,
            displayName: field.displayName,
            required: field.required,
        }));
        const importFileMediaObject = this.getImportFileObject(importTransaction);
        const importFileStream = await this.getImportFileStream(importFileMediaObject);
        const sampleRecord = await this.getFileRecordsSample(importFileStream, importFileMediaObject.mimeType);
        const wrappedRecords = sampleRecord.data.map((record) => {
            return Object.entries(record).map(([key, value]) => ({
                cellHeader: key,
                cellValue: value,
                defaultMappedFieldName: importableFields.find(field => field.displayName === key)?.name || '',
            }));
        }).flat();
        return {
            sampleImportedRecordInfo: wrappedRecords,
            importableFields: importableFields,
        };
    }
    async startImportSync(importTransactionId, activeUser) {
        const importTransaction = await this.loadImportTransaction(importTransactionId);
        const modelName = (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(importTransaction.modelMetadata.singularName));
        const permissionKey = `${modelName}Controller.insertMany`;
        const userPermissions = activeUser.permissions ?? [];
        const hasPermission = Array.isArray(userPermissions)
            ? userPermissions.includes(permissionKey)
            : userPermissions[permissionKey] === true;
        if (!hasPermission) {
            const action = permissionKey.split('.').pop();
            const message = error_messages_1.ERROR_MESSAGES.PERMISSION_MESSAGES[action]?.(modelName) ?? 'You are not allowed to perform this action.';
            throw new common_1.ForbiddenException({
                message,
                errorCode: 'permission-denied',
            });
        }
        const importFileMediaObject = this.getImportFileObject(importTransaction);
        const importFileStream = await this.getImportFileStream(importFileMediaObject);
        const { ids, errorLogIds } = await this.importFromFileToDB(importTransaction, importFileStream, importFileMediaObject.mimeType);
        (errorLogIds.length > 0) ? importTransaction.status = ImportTransactionStatus.import_failed : importTransaction.status = ImportTransactionStatus.import_succeeded;
        await this.repo.save(importTransaction);
        return {
            status: importTransaction.status,
            importedIds: ids,
            importedCount: ids.length,
            failedCount: errorLogIds.length,
        };
    }
    startImportAsync(importTransactionId) {
        throw new Error('Method not implemented.');
    }
    async exportFailedImportedImports(importTransactionId) {
        const firstErrorLogEntry = await this.entityManager.getRepository(import_transaction_error_log_entity_1.ImportTransactionErrorLog).findOne({
            where: {
                importTransaction: { id: importTransactionId },
            },
        });
        if (!firstErrorLogEntry) {
            throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.NO_ERROR_LOG_FOR_IMPORT(importTransactionId));
        }
        const headers = [
            ...Object.keys(firstErrorLogEntry.rowData ? JSON.parse(firstErrorLogEntry.rowData) : {}),
            'Error',
        ];
        const importTransaction = await this.loadImportTransaction(importTransactionId);
        const importFileMediaObject = this.getImportFileObject(importTransaction);
        const mimeType = importFileMediaObject.mimeType;
        const templateFormat = mimeType === ImportMimeTypes.CSV ? "csv" : "excel";
        const dataRecordsFunc = async (chunkIndex, chunkSize) => {
            const errorLogEntries = await this.entityManager.getRepository(import_transaction_error_log_entity_1.ImportTransactionErrorLog).find({
                where: {
                    importTransaction: { id: importTransactionId },
                },
                skip: chunkIndex * chunkSize,
                take: chunkSize,
            });
            if (!errorLogEntries || errorLogEntries.length === 0) {
                return [];
            }
            return errorLogEntries.map(entry => {
                const rowData = entry.rowData ? JSON.parse(entry.rowData) : {};
                return {
                    ...rowData,
                    Error: entry.errorMessage,
                };
            });
        };
        const exportStream = await this.getFailedRecordsStream(templateFormat, headers, dataRecordsFunc);
        if (!exportStream) {
            throw new common_1.BadRequestException(`Failed to create export stream for import transaction ID ${importTransactionId}.`);
        }
        const extension = templateFormat === "excel" ? 'xlsx' : 'csv';
        return {
            stream: exportStream,
            fileName: `${importTransaction.modelMetadata.singularName}-failed-imports.${extension}`,
            mimeType: templateFormat === "excel" ? ImportMimeTypes.EXCEL : ImportMimeTypes.CSV,
        };
    }
    async getFailedRecordsStream(templateFormat, headers, dataRecordsFunc) {
        let exportStream = null;
        switch (templateFormat) {
            case "excel":
                exportStream = await this.excelService.createExcelStream(dataRecordsFunc, 100, headers);
                break;
            case "csv":
                exportStream = await this.csvService.createCsvStream(dataRecordsFunc, 100, headers);
                break;
            default:
                throw new Error('Invalid export format');
        }
        return exportStream;
    }
    async loadImportTransaction(importTransactionId) {
        const importTransaction = await this.findOne(importTransactionId, {
            populate: ['modelMetadata'],
            populateMedia: ['fileLocation'],
        });
        const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(importTransaction.modelMetadata.singularName);
        importTransaction.modelMetadata.fields = modelFields;
        return importTransaction;
    }
    fieldsAllowedForImport(fields) {
        const systemFieldNames = this.modelMetadataHelperService
            .getSystemFieldsMetadata()
            .map(field => field.name);
        const userExcluded = (0, user_helper_1.getUserExcludedFields)();
        return fields.filter(field => field.type !== create_field_metadata_dto_1.SolidFieldType.mediaMultiple &&
            field.type !== create_field_metadata_dto_1.SolidFieldType.mediaSingle &&
            field.type !== create_field_metadata_dto_1.SolidFieldType.computed &&
            field.type !== create_field_metadata_dto_1.SolidFieldType.password &&
            field.type !== create_field_metadata_dto_1.SolidFieldType.richText &&
            field.type !== create_field_metadata_dto_1.SolidFieldType.uuid &&
            field.relationType !== create_field_metadata_dto_1.RelationType.oneToMany &&
            !systemFieldNames.includes(field.name) &&
            !userExcluded.includes(field.name));
    }
    async getFileRecordsSample(importFileStream, mimeType) {
        if (mimeType === 'text/csv') {
            const generator = this.csvService.readCsvInPagesFromStream(importFileStream, { pageSize: 1 });
            const firstRecord = await generator.next();
            return firstRecord.value;
        }
        else if (mimeType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
            const generator = this.excelService.readExcelInPagesFromStream(importFileStream, { pageSize: 1 });
            const firstRecord = await generator.next();
            return firstRecord.value;
        }
        else {
            throw new Error(error_messages_1.ERROR_MESSAGES.INVALID_FORMAT(mimeType));
        }
    }
    getImportFileObject(importTransaction) {
        const importFileMediaObject = importTransaction['_media']['fileLocation'][0];
        if (!importFileMediaObject) {
            throw new Error(`Import file for transaction ID ${importTransaction.id} not found.`);
        }
        return importFileMediaObject;
    }
    async getImportFileStream(importFileMediaObject) {
        const fileUrl = importFileMediaObject['_full_url'];
        const mimeType = importFileMediaObject['mimeType'];
        if (!fileUrl) {
            throw new Error(`File URL  ${fileUrl} not found.`);
        }
        const fileUrlResponse = await this.httpService.axiosRef.get(fileUrl, {
            responseType: 'stream',
        });
        if (!fileUrlResponse || !fileUrlResponse.data) {
            throw new Error(error_messages_1.ERROR_MESSAGES.FILE_READ_FAILED_FROM_URL(fileUrl));
        }
        return fileUrlResponse.data;
    }
    async importFromFileToDB(importTransaction, importFileStream, mimeType) {
        if (!importTransaction.modelMetadata) {
            throw new Error(`Model metadata for import transaction ID ${importTransaction.id} not found.`);
        }
        const createdRecordIds = [];
        const createdErrorLogIds = [];
        const modelService = this.getModelService(importTransaction.modelMetadata.singularName);
        if (mimeType === ImportMimeTypes.CSV) {
            for await (const page of this.csvService.readCsvInPagesFromStream(importFileStream)) {
                const { ids, errorLogIds } = await this.importRecords(page, importTransaction, modelService);
                createdRecordIds.push(...ids);
                createdErrorLogIds.push(...errorLogIds);
            }
        }
        else if (mimeType === ImportMimeTypes.EXCEL) {
            for await (const page of this.excelService.readExcelInPagesFromStream(importFileStream)) {
                const { ids, errorLogIds } = await this.importRecords(page, importTransaction, modelService);
                createdRecordIds.push(...ids);
                createdErrorLogIds.push(...errorLogIds);
            }
        }
        else {
            throw new Error(error_messages_1.ERROR_MESSAGES.INVALID_FORMAT(mimeType));
        }
        return {
            ids: createdRecordIds,
            errorLogIds: createdErrorLogIds,
        };
    }
    async importRecords(page, importTransaction, modelService) {
        if (!importTransaction.modelMetadata || !importTransaction.modelMetadata.fields) {
            throw new Error(`Model metadata with fields for import transaction ID ${importTransaction.id} not found.`);
        }
        const ids = [];
        const errorLogIds = [];
        for (const record of page.data) {
            try {
                const createdRecord = await this.insertRecord(record, JSON.parse(importTransaction.mapping), importTransaction.modelMetadata, modelService);
                ids.push(createdRecord.id);
            }
            catch (error) {
                this.logger.debug(`Error inserting record: ${JSON.stringify(record)}. Error: ${error.message}`);
                const errorLog = await this.createErrorLogEntry(importTransaction, record, error);
                errorLogIds.push(errorLog.id);
            }
        }
        return {
            ids: ids,
            errorLogIds: errorLogIds,
        };
    }
    async createErrorLogEntry(importTransaction, record, error) {
        const importTransactionRepo = this.entityManager.getRepository(import_transaction_error_log_entity_1.ImportTransactionErrorLog);
        const rowNumber = (0, uuid_1.v4)();
        const errorLogEntry = {
            importTransactionErrorLogId: `${importTransaction.id}-${rowNumber}`,
            rowNumber: 1,
            rowData: JSON.stringify(record),
            importTransaction: importTransaction,
            errorMessage: error.message,
            errorTrace: error.stack || '',
        };
        const savedEntry = await importTransactionRepo.save(errorLogEntry);
        return savedEntry;
    }
    async insertRecord(record, mapping, modelMetadataWithFields, modelService) {
        const dto = await this.convertImportedRecordToDto(record, mapping, modelMetadataWithFields);
        const createdRecord = await modelService.create(dto, [], {});
        return createdRecord;
    }
    getModelService(modelSingularName) {
        const modelServiceWrapper = this.introspectService.getProvider(`${(0, string_helper_1.classify)(modelSingularName)}Service`);
        const modelService = modelServiceWrapper.instance;
        if (!modelService) {
            throw new Error(error_messages_1.ERROR_MESSAGES.MODEL_SERVICE_NOT_FOUND(modelSingularName));
        }
        return modelService;
    }
    async convertImportedRecordToDto(record, mapping, modelMetadataWithFields) {
        const dtoRecord = {};
        for (const key in record) {
            const mappedField = mapping.find(m => m.header === key);
            if (mappedField) {
                const fieldMetadata = modelMetadataWithFields.fields.find(f => f.name === mappedField.fieldName);
                if (fieldMetadata) {
                    await this.populateDtoForACell(dtoRecord, fieldMetadata, record, key);
                }
                else {
                    this.logger.warn(`Field ${mappedField.fieldName} not found in model metadata ${modelMetadataWithFields.singularName}`);
                }
            }
        }
        return dtoRecord;
    }
    async populateDtoForACell(dtoRecord, fieldMetadata, record, key) {
        const fieldType = fieldMetadata.type;
        switch (fieldType) {
            case create_field_metadata_dto_1.SolidFieldType.relation: {
                return await this.populateDtoForRelations(fieldMetadata, record, key, dtoRecord);
            }
            case create_field_metadata_dto_1.SolidFieldType.date:
            case create_field_metadata_dto_1.SolidFieldType.datetime:
                return this.populateDtoForDate(record, key, fieldMetadata, dtoRecord);
            case create_field_metadata_dto_1.SolidFieldType.int:
            case create_field_metadata_dto_1.SolidFieldType.bigint:
            case create_field_metadata_dto_1.SolidFieldType.decimal:
                return this.populateDtoForNumber(dtoRecord, fieldMetadata, record, key);
            case create_field_metadata_dto_1.SolidFieldType.boolean:
                return this.populateDtoForBoolean(dtoRecord, fieldMetadata, record, key);
            case create_field_metadata_dto_1.SolidFieldType.selectionStatic:
            case create_field_metadata_dto_1.SolidFieldType.selectionDynamic:
                return this.populateDtoForSelectionValues(dtoRecord, fieldMetadata, record, key);
            case create_field_metadata_dto_1.SolidFieldType.email:
            case create_field_metadata_dto_1.SolidFieldType.shortText:
            case create_field_metadata_dto_1.SolidFieldType.longtext:
            case create_field_metadata_dto_1.SolidFieldType.richText: {
                dtoRecord[fieldMetadata.name] = record[key] ? String(record[key]).trim() : null;
                return dtoRecord;
            }
            default: {
                dtoRecord[fieldMetadata.name] = record[key];
                return dtoRecord;
            }
        }
    }
    populateDtoForSelectionValues(dtoRecord, fieldMetadata, record, key) {
        const rawValue = record[key];
        if (rawValue == null || rawValue === '' || (typeof rawValue === 'string' && rawValue.trim() === '')) {
            dtoRecord[fieldMetadata.name] = null;
            return dtoRecord;
        }
        const isMultipleSelection = fieldMetadata.isMultiSelect;
        if (isMultipleSelection) {
            const selectionValues = String(rawValue)
                .split(',')
                .map(value => value.trim())
                .filter(value => value !== '');
            dtoRecord[fieldMetadata.name] = JSON.stringify(selectionValues);
        }
        else {
            dtoRecord[fieldMetadata.name] = rawValue;
        }
        return dtoRecord;
    }
    populateDtoForBoolean(dtoRecord, fieldMetadata, record, key) {
        const cellValue = record[key];
        if (cellValue === null || cellValue === undefined || cellValue === '') {
            dtoRecord[fieldMetadata.name] = null;
            return dtoRecord;
        }
        const booleanValue = (String(cellValue).toLowerCase() === 'true' || String(cellValue) === '1' || String(cellValue).toLowerCase() === 'yes') ? true : (String(cellValue).toLowerCase() === 'false' || String(cellValue) === '0' || String(cellValue).toLowerCase() === 'no') ? false : null;
        if (booleanValue === null) {
            throw new Error(`Invalid boolean value for cell ${key} with value ${cellValue}`);
        }
        dtoRecord[fieldMetadata.name] = booleanValue;
        return dtoRecord;
    }
    populateDtoForNumber(dtoRecord, fieldMetadata, record, key) {
        const cellValue = record[key];
        if (cellValue === null || cellValue === undefined || cellValue === '') {
            dtoRecord[fieldMetadata.name] = null;
            return dtoRecord;
        }
        const numberValue = Number(cellValue);
        if (isNaN(numberValue)) {
            throw new Error(`Invalid number value for cell ${key} with value ${record[key]}`);
        }
        dtoRecord[fieldMetadata.name] = numberValue;
        return dtoRecord;
    }
    populateDtoForDate(record, key, fieldMetadata, dtoRecord) {
        {
            const cellValue = record[key];
            if (!cellValue) {
                dtoRecord[fieldMetadata.name] = null;
                return dtoRecord;
            }
            this.logger.verbose(cellValue, 'cellValue');
            const dateValue = (0, date_helper_1.parseFlexibleDate)(cellValue);
            this.logger.verbose(dateValue, 'dateValue');
            if (!dateValue) {
                throw new Error(`Invalid date value for cell ${key} with value ${cellValue}`);
            }
            dtoRecord[fieldMetadata.name] = dateValue;
            return dtoRecord;
        }
    }
    async populateDtoForRelations(fieldMetadata, record, key, dtoRecord) {
        if (!fieldMetadata.relationCoModelSingularName) {
            throw new Error(error_messages_1.ERROR_MESSAGES.RELATION_CO_MODEL_NOT_DEFINED_FOR_FIELD(fieldMetadata.name));
        }
        const relatedRecordsIds = await this.getRelatedEntityIdsFromUserKeys(fieldMetadata, record, key);
        if (relatedRecordsIds.length === 0) {
            return dtoRecord;
        }
        if (fieldMetadata.relationType === create_field_metadata_dto_1.RelationType.manyTomany || fieldMetadata.relationType === create_field_metadata_dto_1.RelationType.oneToMany) {
            dtoRecord[`${fieldMetadata.name}Ids`] = relatedRecordsIds;
            dtoRecord[`${fieldMetadata.name}Command`] = create_field_metadata_dto_1.RelationFieldsCommand.set;
        }
        else if (fieldMetadata.relationType === create_field_metadata_dto_1.RelationType.manyToOne) {
            dtoRecord[`${fieldMetadata.name}Id`] = relatedRecordsIds.pop();
        }
        return dtoRecord;
    }
    async getRelatedEntityIdsFromUserKeys(fieldMetadata, record, key) {
        const relationUserKeys = record[key] ? String(record[key]).split(',').map((userKey) => userKey.trim()) : [];
        if (relationUserKeys.length === 0)
            return [];
        const coModelService = this.getModelService(fieldMetadata.relationCoModelSingularName);
        const coModelWithUserKeyField = await this.modelMetadataService.findOneBySingularName(fieldMetadata.relationCoModelSingularName, ['userKeyField']);
        const coModelUserKeyFieldName = coModelWithUserKeyField?.userKeyField?.name || 'id';
        const relationFilterDto = {
            filters: {
                [coModelUserKeyFieldName]: {
                    $in: relationUserKeys,
                },
            },
        };
        const relatedRecordsResult = await coModelService.find(relationFilterDto);
        if (!relatedRecordsResult || !relatedRecordsResult.records || relatedRecordsResult.records.length === 0 || relatedRecordsResult.records.length !== relationUserKeys.length) {
            throw new Error(`Invalid related records userKey values found for cell ${key} with value ${record[key]}`);
        }
        const relatedRecordsIds = relatedRecordsResult.records.map(record => record.id);
        return relatedRecordsIds;
    }
};
exports.ImportTransactionService = ImportTransactionService;
exports.ImportTransactionService = ImportTransactionService = ImportTransactionService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectEntityManager)()),
    __metadata("design:paramtypes", [typeorm_2.EntityManager,
        import_transaction_repository_1.ImportTransactionRepository,
        core_1.ModuleRef,
        excel_service_1.ExcelService,
        csv_service_1.CsvService,
        axios_1.HttpService,
        solid_introspect_service_1.SolidIntrospectService,
        model_metadata_helper_service_1.ModelMetadataHelperService])
], ImportTransactionService);
//# sourceMappingURL=import-transaction.service.js.map