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) { toID(ean: string) {
if (ean.length === 12) {
// it already is an ID
return ean;
}
if (!this.isValid(ean)) { if (!this.isValid(ean)) {
throw new Error(`Invalid EAN: "${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', description: 'Either the inventored thing or a box containing them',
}) })
export class ItemModel { export class ItemModel {
@Field((type) => ID) @Field((type) => ID, { description: 'Database ID or EAN-13 code' })
id: string; id: string;
@Field() @Field()

View File

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