From 8d83205747a89ed895a7147bd961e14305dfad68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arwid=20Thornstr=C3=B6m?= Date: Fri, 3 Sep 2021 15:11:06 +0200 Subject: [PATCH] 20: printproduct group mutation (#21) * Finished the mutation for productGroups * Fixes after CR * added enums for typeid --- .gitignore | 1 + src/datasources/product-api.ts | 122 ++++++++++++++++++++++++++++- src/resolvers/products-resolver.ts | 8 ++ src/schema.graphql | 1 + src/types/product-types.ts | 15 ++++ 5 files changed, 146 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 603ad8c..a5b6960 100644 --- a/.gitignore +++ b/.gitignore @@ -90,5 +90,6 @@ jspm_packages *.sublime-project *.sublime-workspace +.vscode/ .env src/__test__/export diff --git a/src/datasources/product-api.ts b/src/datasources/product-api.ts index a4aa50b..00290ea 100644 --- a/src/datasources/product-api.ts +++ b/src/datasources/product-api.ts @@ -14,10 +14,11 @@ import { ProductInfoInput, ProductBlacklistInput, ProductBlacklistMarketInput, + ProductMaterials, + ProductSizeTypes, } from '../types/product-types'; import { Maybe } from '../types/types'; import { convertToPossibleType } from './utils'; -import { isNode } from 'graphql/language/ast'; const MINUTE = 60; @@ -229,4 +230,123 @@ export class ProductAPI extends BaseSQLDataSource { }); return Promise.all(insertsPromises); } + + async updateGroups(productId: number, groupIds: number[]): Promise { + // Fetch the current state + const allPrintProducts = await this.knex.raw( + `SELECT printid, groupid FROM "product-printproducts" WHERE productid = ?`, + [productId], + ); + + const currentGroups = allPrintProducts.rows.map((item) => item.groupid); + // What we should add + const shouldAdd = groupIds.filter((group) => { + return !currentGroups.includes(group); + }); + // What we should delete + const shouldDelete = allPrintProducts.rows.filter((item) => { + return !groupIds.includes(item.groupid); + }); + + // DELETE + if (shouldDelete.length > 0) { + // Delete from product-printproducts_materials + const printProductIds = shouldDelete + .map((item) => item.printid) + .join(','); + + // Delete from materials first, must be in sequence since we have constraint in materials to printproducts + await this.knex.raw( + `DELETE FROM "product-printproducts_materials" WHERE printid IN (${printProductIds})`, + ); + + // Delete from product-printproducts + await this.knex.raw( + `DELETE FROM "product-printproducts" WHERE printid IN (${printProductIds})`, + ); + } + + // INSERT + if (shouldAdd.length > 0) { + const insertionProducts = []; + // Insert in product-printproducts + // TODO: Depracate typeid, its not used to check repeating + const insertQuery = `INSERT INTO "product-printproducts" (productid, groupid, typeid) VALUES (?, ?, ?)`; + shouldAdd.forEach((groupId) => { + insertionProducts.push( + this.knex.raw(insertQuery, [ + productId, + groupId, + groupId === ProductGroup.WALLPAPER + ? ProductSizeTypes.TILING + : ProductSizeTypes.SCALING, + ]), + ); + }); + + // Run parallell + await Promise.all(insertionProducts); + + // Fetch the new printids to be able to insert new materials + const newPrintIds = await this.knex.raw( + `SELECT printid, groupid FROM "product-printproducts" WHERE productid = ${productId} AND groupid IN (${shouldAdd.join( + ',', + )})`, + ); + + // Insert printIds into product-printproducts_materials + const insertMaterials = []; + const insertMaterialQuery = `INSERT INTO "product-printproducts_materials" (printid, materialid) VALUES (?, ?)`; + newPrintIds.rows.forEach(({ printid, groupid }) => { + switch (groupid) { + case ProductGroup.PHOTO_WALLPAPER: + case ProductGroup.WALLPAPER: + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.STANDARD_WALLPAPER, + ]), + ); + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.SELF_ADHESIVE_WALLPAPER, + ]), + ); + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.PREMIUM_WALLPAPER, + ]), + ); + break; + case ProductGroup.CANVAS: + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.STANDARD_CANVAS, + ]), + ); + break; + case ProductGroup.POSTER: + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.PREMIUM_POSTER, + ]), + ); + break; + case ProductGroup.FRAMED_PRINT: + insertMaterials.push( + this.knex.raw(insertMaterialQuery, [ + printid, + ProductMaterials.PREMIUM_FRAMED_PRINT, + ]), + ); + break; + } + }); + return Promise.all(insertMaterials); + } + } } diff --git a/src/resolvers/products-resolver.ts b/src/resolvers/products-resolver.ts index a61c40b..61c73cd 100644 --- a/src/resolvers/products-resolver.ts +++ b/src/resolvers/products-resolver.ts @@ -1,6 +1,7 @@ import { ProductAPI } from '../datasources/product-api'; import { Product, + ProductGroup, ProductListResult, ProductsFilterInput, } from '../types/product-types'; @@ -94,6 +95,13 @@ export const productMutationTypeDefs = { ); return (dataSources.productApi).getProduct(productId); }, + async productGroup(_, { productId, groupIds }, { dataSources }) { + await (dataSources.productApi).updateGroups( + productId, + groupIds, + ); + return (dataSources.productApi).getProduct(productId); + }, async productKeywords(_, { productId, keywordIds }, { dataSources }) { await (dataSources.keywordApi).setProductKeywords( productId, diff --git a/src/schema.graphql b/src/schema.graphql index 9c40982..f529a8c 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -402,5 +402,6 @@ type Mutation { productId: Int! markets: [ProductBlacklistingInput] ): Product + productGroup(productId: Int!, groupIds: [Int]): Product productKeywords(productId: Int!, keywordIds: [Int]): Product } diff --git a/src/types/product-types.ts b/src/types/product-types.ts index 4a61c6f..0060919 100644 --- a/src/types/product-types.ts +++ b/src/types/product-types.ts @@ -51,6 +51,21 @@ export enum ProductGroup { UNKNOWN = 9, } +export enum ProductMaterials { + STANDARD_WALLPAPER = 1, + SELF_ADHESIVE_WALLPAPER = 2, + STANDARD_CANVAS = 3, + PREMIUM_WALLPAPER = 4, + PREMIUM_POSTER = 5, + PREMIUM_FRAMED_PRINT = 6, +} + +export enum ProductSizeTypes { + SCALING = 1, + FIXED = 2, + TILING = 3, +} + export enum ProductType { UNKNOWN = 0, PHOTO = 1,