"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "AdministeredVaccine", {
    enumerable: true,
    get: function() {
        return AdministeredVaccine;
    }
});
const _sequelize = require("sequelize");
const _constants = require("@tamanu/constants");
const _errors = require("@tamanu/errors");
const _Model = require("./Model");
const _Encounter = require("./Encounter");
const _ScheduledVaccine = require("./ScheduledVaccine");
const _model = require("../types/model");
const _buildEncounterLinkedLookupFilter = require("../sync/buildEncounterLinkedLookupFilter");
let AdministeredVaccine = class AdministeredVaccine extends _Model.Model {
    static initModel({ primaryKey, ...options }) {
        super.init({
            id: primaryKey,
            batch: _sequelize.DataTypes.STRING,
            consent: _sequelize.DataTypes.BOOLEAN,
            consentGivenBy: _sequelize.DataTypes.TEXT,
            status: {
                type: _sequelize.DataTypes.STRING,
                allowNull: false
            },
            reason: _sequelize.DataTypes.STRING,
            injectionSite: _sequelize.DataTypes.STRING,
            givenBy: _sequelize.DataTypes.TEXT,
            givenElsewhere: _sequelize.DataTypes.BOOLEAN,
            vaccineBrand: _sequelize.DataTypes.TEXT,
            vaccineName: _sequelize.DataTypes.TEXT,
            disease: _sequelize.DataTypes.TEXT,
            circumstanceIds: _sequelize.DataTypes.ARRAY(_sequelize.DataTypes.STRING),
            date: (0, _model.dateTimeType)('date')
        }, {
            ...options,
            syncDirection: _constants.SYNC_DIRECTIONS.BIDIRECTIONAL,
            validate: {
                mustHaveScheduledVaccine () {
                    if (!this.deletedAt && !this.scheduledVaccineId) {
                        throw new _errors.InvalidOperationError('An administered vaccine must have a scheduled vaccine.');
                    }
                },
                mustHaveEncounter () {
                    if (!this.deletedAt && !this.encounterId) {
                        throw new _errors.InvalidOperationError('An administered vaccine must have an encounter.');
                    }
                }
            }
        });
    }
    static getListReferenceAssociations() {
        return [
            'encounter',
            'scheduledVaccine'
        ];
    }
    static initRelations(models) {
        this.belongsTo(models.Encounter, {
            foreignKey: 'encounterId',
            as: 'encounter'
        });
        this.belongsTo(models.ScheduledVaccine, {
            foreignKey: 'scheduledVaccineId',
            as: 'scheduledVaccine'
        });
        this.belongsTo(models.User, {
            foreignKey: 'recorderId',
            as: 'recorder'
        });
        this.belongsTo(models.Location, {
            foreignKey: 'locationId',
            as: 'location'
        });
        this.belongsTo(models.Department, {
            foreignKey: 'departmentId',
            as: 'department'
        });
        this.belongsTo(models.ReferenceData, {
            foreignKey: 'notGivenReasonId',
            as: 'notGivenReason'
        });
    }
    static buildPatientSyncFilter(patientCount, markedForSyncPatientsTable) {
        const joins = [];
        const wheres = [];
        if (patientCount > 0) {
            joins.push(`
        LEFT JOIN encounters
        ON administered_vaccines.encounter_id = encounters.id
        AND encounters.patient_id IN (SELECT patient_id FROM ${markedForSyncPatientsTable})
      `);
            wheres.push(`
        encounters.id IS NOT NULL
      `);
        }
        if (wheres.length === 0) {
            return null;
        }
        return `
      ${joins.join('\n')}
      WHERE (
        ${wheres.join('\nOR')}
      )
      AND ${this.tableName}.updated_at_sync_tick > :since
    `;
    }
    static async buildSyncLookupQueryDetails() {
        return (0, _buildEncounterLinkedLookupFilter.buildEncounterLinkedLookupFilter)(this);
    }
    static async lastVaccinationForPatient(patientId, vaccineIds = []) {
        const query = {
            where: {
                '$encounter.patient_id$': patientId,
                status: 'GIVEN'
            },
            order: [
                [
                    'date',
                    'DESC'
                ]
            ],
            include: [
                {
                    model: _Encounter.Encounter,
                    as: 'encounter'
                }
            ]
        };
        if (vaccineIds.length) {
            query.where['$scheduledVaccine.vaccine_id$'] = {
                [_sequelize.Op.in]: vaccineIds
            };
            query.include.push({
                model: _ScheduledVaccine.ScheduledVaccine,
                as: 'scheduledVaccine'
            });
        }
        return AdministeredVaccine.findOne(query);
    }
};

//# sourceMappingURL=AdministeredVaccine.js.map