File size: 3,704 Bytes
22df730
 
c995cfc
 
22df730
 
 
c995cfc
 
 
22df730
 
c995cfc
 
22df730
 
 
2ff651b
22df730
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916df2b
22df730
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916df2b
22df730
 
 
 
 
 
 
 
 
 
916df2b
22df730
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916df2b
22df730
 
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { Injectable, NotFoundException } from '@nestjs/common';
import { randomUUID } from 'crypto';
import { Book } from '../book/dto/book.dto';
import { bookLinkManager } from '../common/book-link-manager';
import {
  WorkerLinkManager,
  WorkerWithBooks,
} from '../common/worker-link-manager';
import { FileManager } from '../utils/file-manager';
import { parseTxtRow, serializeTxtRow } from '../utils/file.utils';
import { CreateWorkerDto } from './dto/create-worker.dto';
import { Worker } from './dto/worker.dto';
import { DayOfWeek } from '../types/worker.types';
import { Link } from '../common/Link';

@Injectable()
export class WorkerService {
  private file = new FileManager('src/data/workers.txt');
  private workerLinkManager = new WorkerLinkManager();

  async getAll(): Promise<Worker[]> {
    const lines = await this.file.readLines();
    const workers = lines.map(parseTxtRow) as unknown as Worker[];
    return workers;
  }

  async getAllWithIssuedBooks(): Promise<WorkerWithBooks[]> {
    const workers = await this.getAll();
    return Promise.all(
      workers.map((worker) => this.workerLinkManager.enrich(worker)),
    );
  }

  async getByWorkDays(workDays: DayOfWeek[]): Promise<WorkerWithBooks[]> {
    const workers = await this.getAll();
    const enriched = await Promise.all(
      workers.map((w) => this.workerLinkManager.enrich(w)),
    );
    const filtered = enriched.filter((w) =>
      w.workDays.some((day) => workDays.includes(day)),
    );
    return filtered;
  }

  async getById(id: string): Promise<Worker | null> {
    const workers = await this.getAll();
    const worker = workers.find((w) => w.id === id);
    return worker as Worker;
  }

  async getByIdWithIssuedBooks(id: string): Promise<WorkerWithBooks | null> {
    const worker = await this.getById(id);
    if (!worker) return null;
    return this.workerLinkManager.enrich(worker);
  }

  async add(dto: CreateWorkerDto): Promise<Worker> {
    const workers = await this.getAll();

    const newWorker: Worker = {
      id: randomUUID(),
      name: dto.name.trim(),
      surname: dto.surname.trim(),
      experience: dto.experience,
      workDays: dto.workDays,
      issuedBooks: [],
    };

    workers.push(newWorker);
    await this.file.writeLines(workers.map(serializeTxtRow));

    return newWorker;
  }

  async update(
    id: string,
    dto: Partial<CreateWorkerDto>,
  ): Promise<Worker | null> {
    const workers = await this.getAll();
    const index = workers.findIndex((w) => w.id === id);

    if (index === -1) return null;

    workers[index] = {
      ...workers[index],
      ...dto,
    };
    await this.file.writeLines(workers.map(serializeTxtRow));
    return workers[index];
  }

  async delete(id: string): Promise<boolean> {
    const workers = await this.getAll();
    const index = workers.findIndex((w) => w.id === id);

    if (index === -1) return false;

    workers.splice(index, 1);
    await this.file.writeLines(workers.map(serializeTxtRow));

    return true;
  }

  async addIssuedBooks(workerId: string, books: Book[]): Promise<void> {
    const workers = await this.getAll();
    const index = workers.findIndex((worker) => worker.id === workerId);

    if (index === -1) {
      throw new NotFoundException(`Worker with id ${workerId} not found`);
    }

    const target = workers[index];
    const existingBookIds = new Set(
      target.issuedBooks.map((link: Link) => link.id),
    );

    for (const book of books) {
      if (!existingBookIds.has(book.id)) {
        target.issuedBooks.push(bookLinkManager.toLink(book.id));
      }
    }

    workers[index] = target;

    await this.file.writeLines(workers.map(serializeTxtRow));
  }
}