Passed
Pull Request — master (#165)
by Mathieu
01:46
created

server/src/Application/Accounting/Command/Invoice/GenerateInvoiceCommandHandler.ts   A

Complexity

Total Complexity 5
Complexity/F 5

Size

Lines of Code 79
Function Count 1

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 62
dl 0
loc 79
rs 10
c 0
b 0
f 0
wmc 5
mnd 4
bc 4
fnc 1
bpm 4
cpm 5
noi 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B GenerateInvoiceCommandHandler.execute 0 47 5
1
import { CommandHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { ICustomerRepository } from 'src/Domain/Customer/Repository/ICustomerRepository';
4
import { GenerateInvoiceCommand } from './GenerateInvoiceCommand';
5
import { CustomerNotFoundException } from 'src/Domain/Customer/Exception/CustomerNotFoundException';
6
import { IEventRepository } from 'src/Domain/FairCalendar/Repository/IEventRepository';
7
import { Invoice } from 'src/Domain/Accounting/Invoice.entity';
8
import { InvoiceItem } from 'src/Domain/Accounting/InvoiceItem.entity';
9
import { IInvoiceRepository } from 'src/Domain/Accounting/Repository/IInvoiceRepository';
10
import { IInvoiceItemRepository } from 'src/Domain/Accounting/Repository/IInvoiceItemRepository';
11
import { InvoiceIdGenerator } from 'src/Domain/Accounting/Generators/InvoiceIdGenerator';
12
import { NoBillableEventsFoundException } from 'src/Domain/Accounting/Exception/NoBillableEventsFoundException';
13
import { IDateUtils } from 'src/Application/IDateUtils';
14
15
@CommandHandler(GenerateInvoiceCommand)
16
export class GenerateInvoiceCommandHandler {
17
  constructor(
18
    @Inject('ICustomerRepository')
19
    private readonly customerRepository: ICustomerRepository,
20
    @Inject('IEventRepository')
21
    private readonly eventRepository: IEventRepository,
22
    @Inject('IInvoiceRepository')
23
    private readonly invoiceRepository: IInvoiceRepository,
24
    @Inject('IInvoiceItemRepository')
25
    private readonly invoiceItemRepository: IInvoiceItemRepository,
26
    @Inject('IDateUtils')
27
    private readonly dateUtils: IDateUtils,
28
    private readonly invoiceIdGenerator: InvoiceIdGenerator
29
  ) {}
30
31
  public async execute(command: GenerateInvoiceCommand): Promise<string> {
32
    const { customerId, status, generatedDate, user, expireInDays } = command;
33
34
    const customer = await this.customerRepository.findOneById(customerId);
35
    if (!customer) {
36
      throw new CustomerNotFoundException();
37
    }
38
39
    const [ invoiceId, events ] = await Promise.all([
40
      this.invoiceIdGenerator.generate(),
41
      this.eventRepository.findBillableEventsByMonthAndCustomer(generatedDate, customer)
42
    ]);
43
44
    if (!events) {
45
      throw new NoBillableEventsFoundException();
46
    }
47
48
    const expiryDate = this.dateUtils.addDaysToDate(generatedDate, expireInDays);
49
    const invoice = new Invoice(invoiceId, status, expiryDate.toISOString(), user, customer);
50
    const invoiceItems: InvoiceItem[] = [];
51
52
    for (const {
53
      time,
54
      billable,
55
      day_duration,
56
      project_name,
57
      task_name,
58
      first_name,
59
      last_name,
60
      amount
61
    } of events) {
62
      invoiceItems.push(
63
        new InvoiceItem(
64
          invoice,
65
          `${project_name} - ${task_name} - ${first_name} ${last_name}`,
66
          Math.ceil(time / day_duration * 100) / 100,
67
          Number(amount),
68
          billable ? 0 : 100
69
        )
70
      );
71
    }
72
73
    await this.invoiceRepository.save(invoice);
74
    await this.invoiceItemRepository.save(invoiceItems);
75
76
    return invoice.getId();
77
  }
78
}
79