All files / src/cronjobs pre-expiry-notification.cronjob.ts

39.02% Statements 16/41
0% Branches 0/14
33.33% Functions 1/3
36.84% Lines 14/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 1091x 1x 1x 1x   1x 1x 1x 1x     1x 1x     1x     1x       1x   1x                                                                                                                                                                        
import { AwsServiceBindings, AwsSesService } from '@logchain/components/aws';
import { Constants } from '@logchain/configs';
import { CompanyRepository } from '@logchain/repositories';
import { NotificationService } from '@logchain/services';
import { AnyObject, RecipientNotification } from '@logchain/types';
import { inject, service } from '@loopback/core';
import { CronJob, cronJob } from '@loopback/cron';
import { PositionalParameters, repository } from '@loopback/repository';
import moment from 'moment';
 
@cronJob()
export class PreExpiryNotificationCronJob extends CronJob {
  private readonly lock_key = '1747627387';
 
  @inject(AwsServiceBindings.SES_SERVICE)
  public ses_service: AwsSesService;
 
  @service()
  public notification_service: NotificationService;
  
  constructor(
    @repository(CompanyRepository)
    public companyRepository: CompanyRepository,
  ) {
    super({
      name: 'Pre Expiry Notification',
      onTick: async () => {
        await this.performCronJob();
      },
      cronTime: '0 0 2 * * *', // Daily at 2:00 AM server time
      // cronTime: '* * * * *', // Every minute
      start: true,
    });
  }
 
  async performCronJob() {
    const isUnLocked = await this.companyRepository.execute(`SELECT pg_try_advisory_lock(${this.lock_key});`);
    if (!isUnLocked[0].pg_try_advisory_lock) {
      return;
    }
 
    await this.companyRepository.execute(`SELECT pg_advisory_unlock(${this.lock_key});`);
    const now = moment();
    const startAt = now.toDate();
    console.log(`*** Cronjob: ${this.name} started at ${startAt}`);
    // Your code start here
    const sql = `
    SELECT DISTINCT ON (u.company_id)
      cl.company_id,
      cl.end_date,
      co."name" as company_name,
      u."name" as admin_name,
      u.contact_email,
      u."language",
      u.settings,
      u.sub
    FROM users_view u
    INNER JOIN company_licences cl ON cl.company_id = u.company_id
    INNER JOIN companies co ON co.id = cl.company_id
    WHERE is_admin = TRUE 
    AND u.status = 2
    AND cl.status = 1
    AND cl.end_date = CURRENT_DATE + INTERVAL '7 days'
    ORDER BY u.company_id, cl.created_date DESC;
    `;
    const params: PositionalParameters = [];
    const records = await this.companyRepository.execute(sql, params) as AnyObject[];
    const recepients = [];
    const identities: RecipientNotification[] = [];
    const p_tasks = [];
    if (records?.length) {
      for(const record of records) {
        identities.push({
          sub: record.sub,
          settings: record.settings,
          language: record.language,
          replacement_data: {
            link: Constants.link2CompanyDetail['companies'],
            company_id: record.company_id,
            company_name: record.company_name,
            end_date: record.end_date,
          },
        });
        recepients.push({
          email: record.contact_email,
          language: record.language,
          replacement_data: {
            admin_name: record.admin_name,
            company_name: record.company_name,
            end_date: record.end_date,
          }
        });
      }
      p_tasks.push(this.ses_service.sendBulkTemplatedEmail(
        Constants.Email.PreExpiryNotification, 
        recepients
      ));
      p_tasks.push(this.notification_service.sendBulkNotifications(
        Constants.Notification.PreExpiryNotification,
        identities,
      ));
    }
    if (p_tasks?.length) await Promise.all(p_tasks);
    const finishedAt = new Date();
    console.log(`*** Cronjob: ${this.name} finished at ${finishedAt}. Total in ${(finishedAt.getTime() - startAt.getTime()) / 1000}ms`);
    await this.companyRepository.execute(`SELECT pg_advisory_unlock(${this.lock_key});`);
  }
}