getting items by EAN-13

master
Lauren Liberda 2021-07-21 01:14:20 +02:00
parent d16f474421
commit 35fd9c903d
3 changed files with 35 additions and 14 deletions

View File

@ -21,6 +21,10 @@ export class EANService {
}
toID(ean: string) {
if (ean.length === 12) {
// it already is an ID
return ean;
}
if (!this.isValid(ean)) {
throw new Error(`Invalid EAN: "${ean}"`);
}

View File

@ -4,7 +4,7 @@ import { Field, ID, ObjectType } from '@nestjs/graphql';
description: 'Either the inventored thing or a box containing them',
})
export class ItemModel {
@Field((type) => ID)
@Field((type) => ID, { description: 'Database ID or EAN-13 code' })
id: string;
@Field()

View File

@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { EntityManager, Repository, TreeRepository } from 'typeorm';
import { NewItemInput } from './dto/new-item.input';
import { EANService } from './ean/ean.service';
import { Item } from './items.entity';
import { ItemModel } from './items.model';
@ -12,26 +13,33 @@ export class ItemsService {
private itemRepository: Repository<Item>,
@InjectEntityManager()
private entityManager: EntityManager,
private eans: EANService,
) {
this.treeRepository = this.entityManager.getTreeRepository(Item);
}
treeRepository: TreeRepository<Item>;
async getItem(id: string): Promise<Item | undefined> {
return this.itemRepository.findOne(id);
return this.itemRepository.findOne(this.eans.toID(id));
}
async getItemParent(item: ItemModel): Promise<Item | undefined> {
const childItem = await this.itemRepository.findOneOrFail(item.id, {
relations: ['parent'],
});
const childItem = await this.itemRepository.findOneOrFail(
this.eans.toID(item.id),
{
relations: ['parent'],
},
);
return childItem.parent;
}
async getItemAncestors(item: ItemModel): Promise<Item[]> {
const childItem = await this.itemRepository.findOneOrFail(item.id, {
relations: ['parent'],
});
const childItem = await this.itemRepository.findOneOrFail(
this.eans.toID(item.id),
{
relations: ['parent'],
},
);
// TreeRepository.findAncestors()[0] is always the child item
return (await this.treeRepository.findAncestors(childItem)).slice(1);
}
@ -39,15 +47,18 @@ export class ItemsService {
async getItemChildren(item: ItemModel): Promise<Item[]> {
return this.itemRepository.find({
where: {
parent: item.id,
parent: this.eans.toID(item.id),
},
});
}
async getItemDescendants(item: ItemModel): Promise<Item[]> {
const parentItem = await this.itemRepository.findOneOrFail(item.id, {
relations: ['parent'],
});
const parentItem = await this.itemRepository.findOneOrFail(
this.eans.toID(item.id),
{
relations: ['parent'],
},
);
// TreeRepository.findDescendants()[0] is always the parent item
return (await this.treeRepository.findDescendants(parentItem)).slice(1);
}
@ -55,7 +66,10 @@ export class ItemsService {
async createItem(input: NewItemInput): Promise<Item> {
// must use Repository.save() for the closure table to work,
// so we have to check whether the provided ID exists in the first place
if (input.id && (await this.itemRepository.count({ id: input.id })) !== 0) {
if (
input.id &&
(await this.itemRepository.count({ id: this.eans.toID(input.id) })) !== 0
) {
throw new Error('Item with this ID already exists');
}
@ -72,7 +86,10 @@ export class ItemsService {
const item = this.itemRepository.create({
...input,
// if id not provided, use the highest one in db +1
id: highestId ? (BigInt(highestId) + 1n).toString(10) : input.id,
id: highestId
? (BigInt(highestId) + 1n).toString(10)
: // @ts-ignore input.id must exist here
this.eans.toID(input.id),
parent: input.parent
? await this.itemRepository.findOneOrFail(input.parent)
: undefined,