homemanager-be/src/objects/storage/storage.service.ts

378 lines
8.8 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ILike, IsNull, LessThanOrEqual, Repository } from 'typeorm';
import { StoredItemTransaction } from './entities/item-transaction.entity';
import { Item } from './entities/item.entity';
import { StorageSet } from './entities/storage-set.entity';
import { Storage } from './entities/storage.entity';
import { StoredItem } from './entities/stored-item.entity';
@Injectable()
export class StorageService {
constructor(
@InjectRepository(Item)
private readonly itemRepository: Repository<Item>,
@InjectRepository(Storage)
private readonly storageRepository: Repository<Storage>,
@InjectRepository(StorageSet)
private readonly storageSetRepository: Repository<StorageSet>,
@InjectRepository(StoredItem)
private readonly storedItemRepository: Repository<StoredItem>,
@InjectRepository(StoredItemTransaction)
private readonly transactionRepository: Repository<StoredItemTransaction>,
) {}
async getStorageById(id: number, relations = []) {
return this.storageRepository.findOne({
where: {
id,
},
relations,
});
}
async getStorageWithItemCount(storageId: number) {
return this.storageRepository
.createQueryBuilder('storage')
.leftJoinAndSelect('storage.addedBy', 'addedBy')
.loadRelationCountAndMap('storage.itemCount', 'storage.items')
.where('storage.id = :storageId', { storageId })
.getOne();
}
async getStorageByIdAndSub(id: number, sub: string, relations = []) {
return this.storageRepository.findOne({
where: {
id,
room: {
building: {
groups: {
members: {
sub,
},
},
},
},
},
relations,
});
}
async getStorageByIdAndBuilding(
id: number,
buildingId: number,
relations = [],
) {
return this.storageRepository.findOne({
where: {
id,
room: {
building: {
id: buildingId,
},
},
},
relations,
});
}
async getStorageByIdAndRoom(id: number, roomId: number, relations = []) {
return this.storageRepository.findOne({
where: {
id,
room: {
id: roomId,
},
},
relations,
});
}
async getStorageSetByIdAndSub(id: number, sub: string, relations = []) {
return this.storageSetRepository.findOne({
where: {
id,
room: {
building: {
groups: {
members: {
sub,
},
},
},
},
},
relations: ['storages', 'storages.addedBy', ...relations],
});
}
async getStorageSetByIdAndBuilding(
id: number,
buildingId: number,
relations = [],
) {
return this.storageSetRepository.findOne({
where: {
id,
room: {
building: {
id: buildingId,
},
},
},
relations: ['storages', 'storages.addedBy', ...relations],
});
}
async getStorageSetByIdAndRoom(id: number, roomId: number, relations = []) {
return this.storageSetRepository.findOne({
where: {
id,
room: {
id: roomId,
},
},
relations: ['storages', 'storages.addedBy', ...relations],
});
}
async getStoragesInRoom(roomId: number, includeWithSets = false) {
const qb = this.storageRepository
.createQueryBuilder('storage')
.leftJoin('storage.room', 'storage.room')
.leftJoin('storage.set', 'storage.set')
.loadRelationCountAndMap('storage.itemCount', 'storage.items')
.where('storage.room.id = :roomId', { roomId });
if (!includeWithSets) {
qb.andWhere({ set: IsNull() });
}
qb.addSelect(
'CASE WHEN storage.set IS NULL THEN FALSE ELSE TRUE END',
'storage.hasSet',
);
return qb.getMany();
}
async getStorageSetsInRoom(roomId: number) {
return this.storageSetRepository
.createQueryBuilder('storageSet')
.leftJoin('storageSet.room', 'storageSet.room')
.leftJoinAndMapMany(
'storageSet.storages',
'storageSet.storages',
'storages',
)
.loadRelationCountAndMap('storages.itemCount', 'storages.items')
.where('storageSet.room.id = :roomId', { roomId })
.getMany();
}
async getItemsInStorage(storageId: number, relations = []) {
return this.storedItemRepository.find({
where: {
storage: {
id: storageId,
},
},
relations: ['item', ...relations],
});
}
async searchForItem(searchTerm: string, sub: string) {
const displayName = ILike(`%${searchTerm}%`);
return this.itemRepository.find({
where: [
{
displayName,
addedBy: {
sub,
},
},
{
displayName,
public: true,
},
{
displayName,
addedBy: {
groups: {
members: {
sub,
},
},
},
},
],
take: 10,
select: ['id', 'displayName', 'type', 'barcode', 'image', 'createdAt'],
});
}
async searchForItemByBarcode(barcode: string, sub: string) {
return this.itemRepository.find({
where: [
{
barcode,
addedBy: {
sub,
},
},
{
barcode,
public: true,
},
{
barcode,
addedBy: {
groups: {
members: {
sub,
},
},
},
},
],
take: 10,
select: ['id', 'displayName', 'type', 'barcode', 'image', 'createdAt'],
});
}
async getItemByIdBySub(id: number, sub: string) {
return this.itemRepository.findOne({
where: [
{
id,
addedBy: {
sub,
},
},
{
id,
public: true,
},
{
id,
addedBy: {
groups: {
members: {
sub,
},
},
},
},
],
});
}
async getItemByIdOwnedBySub(id: number, sub: string, relations = []) {
return this.itemRepository.findOne({
where: {
id,
addedBy: {
sub,
},
},
relations,
});
}
async getExpiredOrExpiringSoonInBuilding(buildingId: number) {
// 8 days
return this.storedItemRepository.find({
where: {
expiresAt: LessThanOrEqual(new Date(Date.now() + 691200000)),
building: {
id: buildingId,
},
},
order: {
expiresAt: 'ASC',
},
take: 16,
relations: ['item', 'storage'],
});
}
async getExpiredOrExpiringSoonForSub(sub: string) {
// 8 days
return this.storedItemRepository.find({
where: {
expiresAt: LessThanOrEqual(new Date(Date.now() + 691200000)),
building: {
groups: {
members: {
sub,
},
},
},
},
order: {
expiresAt: 'ASC',
},
take: 16,
relations: ['item', 'building', 'storage'],
});
}
async getStoredItemByStorageAndId(
storage: Storage,
storedItemId: number,
relations = [],
) {
return this.storedItemRepository.findOne({
where: {
id: storedItemId,
storage: { id: storage.id },
},
relations,
});
}
async getStoredItemTransactionById(
storedItemId: number,
storedItemTransactionId: number,
relations = [],
) {
return this.transactionRepository.findOne({
where: {
id: storedItemTransactionId,
storedItem: { id: storedItemId },
},
relations,
});
}
async saveStorage(data: Partial<Storage>) {
const newStorage = new Storage();
Object.assign(newStorage, data);
return this.storageRepository.save(newStorage);
}
async saveItem(data: Partial<Item>) {
const newItem = new Item();
Object.assign(newItem, data);
return this.itemRepository.save(newItem);
}
async saveStoredItem(data: Partial<StoredItem>) {
const newStoredItem = new StoredItem();
Object.assign(newStoredItem, data);
return this.storedItemRepository.save(newStoredItem);
}
async saveStorageSet(data: Partial<StorageSet>) {
const newStorageSet = new StorageSet();
Object.assign(newStorageSet, data);
return this.storageSetRepository.save(newStorageSet);
}
async saveStoredItemTransaction(data: Partial<StoredItemTransaction>) {
const newStoredItemTransaction = new StoredItemTransaction();
Object.assign(newStoredItemTransaction, data);
return this.transactionRepository.save(newStoredItemTransaction);
}
}