All files / apps/api/src/modules/sampleData/loaders sampleDataCalculation.service.ts

100% Statements 113/113
37.5% Branches 6/16
100% Functions 4/4
100% Lines 113/113

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 109 110 111 112 113 1141x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, type FindOptionsWhere } from 'typeorm';
 
import {
  Calculation,
  CompanyCurrency,
  DataExport,
  Message,
  Payment,
  Period,
  Statement,
  StatementForecast,
  Thread,
} from '@amalia/core/models';
import { CalculationTrigger, type ScheduleCalculationEvent } from '@amalia/core/types';
import { MessageTasks, MessageType, QueueService } from '@amalia/kernel/queue/core';
import { type Company } from '@amalia/tenants/companies/types';
 
import { samplePeriods } from '../../../assets/sampleData/periods';
 
@Injectable()
export class SampleDataCalculationService {
  public constructor(
    private readonly queueService: QueueService,
    @InjectRepository(Period)
    private readonly periodRepository: Repository<Period>,
    @InjectRepository(Statement)
    private readonly statementRepository: Repository<Statement>,
    @InjectRepository(StatementForecast)
    private readonly statementForecastRepository: Repository<StatementForecast>,
    @InjectRepository(Payment)
    private readonly paymentRepository: Repository<Payment>,
    @InjectRepository(CompanyCurrency)
    private readonly companyCurrencyRepository: Repository<CompanyCurrency>,
    @InjectRepository(Thread)
    private readonly threadRepository: Repository<Thread>,
    @InjectRepository(Message)
    private readonly messageRepository: Repository<Message>,
    @InjectRepository(DataExport)
    private readonly dataExportRepository: Repository<DataExport>,
    @InjectRepository(Calculation)
    private readonly calculationRepository: Repository<Calculation>,
  ) {}
 
  /**
   * Load calculation data (periods) then runs calculation on given periods.
   * @param company company to create
   */
  public async load(company: Company): Promise<void> {
    const periods = await this.loadPeriods(company);
 
    // Run calculation
    await Promise.all(
      periods.map(async (period) => {
        const calculationEvent: ScheduleCalculationEvent = {
          companyId: company.id,
          query: {
            // As it's a sample data, we could take any trigger
            trigger: CalculationTrigger.MANUAL,
            periodId: period.id,
          },
          options: {
            withRollingPeriods: false,
          },
        };
 
        await this.queueService.sendToQueue(
          {
            type: MessageType.TASK,
            taskIdentifier: MessageTasks.SCHEDULE_CALCULATION,
          },
          { calculationEvent },
        );
      }),
    );
  }
 
  /**
   * Purge company calculation data (statements, periods)
   * @param company
   */
  public async purge(company: Company): Promise<void> {
    const companyConditions: FindOptionsWhere<{ company: { id: string } }> = {
      company: { id: company.id },
    };
 
    await this.dataExportRepository.delete(companyConditions);
    await this.messageRepository.delete(companyConditions);
    await this.threadRepository.delete(companyConditions);
    await this.paymentRepository.delete(companyConditions);
    await this.statementRepository.delete(companyConditions);
    await this.statementForecastRepository.delete(companyConditions);
    await this.periodRepository.delete(companyConditions);
    await this.calculationRepository.delete(companyConditions);
  }
 
  /**
   * Load periods for company.
   * @param company
   * @private
   */
  private async loadPeriods(company: Company): Promise<Period[]> {
    return Promise.all(
      samplePeriods.map((period) =>
        this.periodRepository.save({
          ...period,
          company,
        }),
      ),
    );
  }
}