1
0
Эх сурвалжийг харах

feat(server): Implement applyFacetValuesToProductVariants mutation

Relates to #2
Michael Bromley 7 жил өмнө
parent
commit
6371d10e66

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
schema.json


+ 2 - 0
server/src/api/product/product.api.graphql

@@ -16,6 +16,8 @@ type Mutation {
     generateVariantsForProduct(productId: ID!, defaultPrice: Int, defaultSku: String): Product!
     "Update existing ProductVariants"
     updateProductVariants(input: [UpdateProductVariantInput!]!): [ProductVariant]!
+    "Applies a FacetValue to the given ProductVariants"
+    applyFacetValuesToProductVariants(facetValueIds: [ID!]!, productVariantIds: [ID!]!): [ProductVariant!]!
 }
 
 type ProductList implements PaginatedList {

+ 21 - 1
server/src/api/product/product.resolver.ts

@@ -1,12 +1,14 @@
 import { Mutation, Query, Resolver } from '@nestjs/graphql';
 
-import { PaginatedList } from '../../../../shared/shared-types';
+import { ID, PaginatedList } from '../../../../shared/shared-types';
 import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
 import { assertFound } from '../../common/utils';
 import { UpdateProductVariantDto } from '../../entity/product-variant/create-product-variant.dto';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
 import { Product } from '../../entity/product/product.entity';
+import { I18nError } from '../../i18n/i18n-error';
 import { Translated } from '../../locale/locale-types';
+import { FacetValueService } from '../../service/facet-value.service';
 import { ProductVariantService } from '../../service/product-variant.service';
 import { ProductService } from '../../service/product.service';
 import { ApplyIdCodec } from '../common/apply-id-codec-decorator';
@@ -16,6 +18,7 @@ export class ProductResolver {
     constructor(
         private productService: ProductService,
         private productVariantService: ProductVariantService,
+        private facetValueService: FacetValueService,
     ) {}
 
     @Query('products')
@@ -72,4 +75,21 @@ export class ProductResolver {
         const { input } = args as { input: UpdateProductVariantDto[] };
         return Promise.all(input.map(variant => this.productVariantService.update(variant)));
     }
+
+    @Mutation()
+    @ApplyIdCodec()
+    async applyFacetValuesToProductVariants(_, args): Promise<Array<Translated<ProductVariant>>> {
+        const { facetValueIds, productVariantIds } = args;
+        const facetValues = await Promise.all(
+            (facetValueIds as ID[]).map(async facetValueId => {
+                const facetValue = await this.facetValueService.findOne(facetValueId, DEFAULT_LANGUAGE_CODE);
+                if (!facetValue) {
+                    throw new I18nError(`error.facet-value-not-found`, { facetValueId });
+                }
+                return facetValue;
+            }),
+        );
+
+        return this.productVariantService.addFacetValues(productVariantIds, facetValues);
+    }
 }

+ 2 - 1
server/src/i18n/messages/en.json

@@ -1,7 +1,8 @@
 {
   "error": {
-    "customer-with-id-not-found": "No customer with the id { customerId } was found",
+    "customer-with-id-not-found": "No customer with the id '{ customerId }' was found",
     "entity-has-no-translation-in-language": "Translatable entity '{ entityName }' has not been translated into the requested language ({ languageCode })",
+    "facet-value-not-found": "A FacetValue with the id '{ facetValueId }' was not found",
     "invalid-facetId": "The facetId '{ facetId }' was not found",
     "invalid-sort-field": "The sort field '{ fieldName }' is invalid. Valid fields are: { validFields }"
   }

+ 20 - 0
server/src/service/product-variant.service.ts

@@ -8,6 +8,7 @@ import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
 import { createTranslatable } from '../common/create-translatable';
 import { updateTranslatable } from '../common/update-translatable';
 import { assertFound } from '../common/utils';
+import { FacetValue } from '../entity/facet-value/facet-value.entity';
 import { ProductOption } from '../entity/product-option/product-option.entity';
 import {
     CreateProductVariantDto,
@@ -97,6 +98,25 @@ export class ProductVariantService {
         );
     }
 
+    async addFacetValues(
+        productVariantIds: ID[],
+        facetValues: FacetValue[],
+    ): Promise<Array<Translated<ProductVariant>>> {
+        const variants = await this.connection.getRepository(ProductVariant).findByIds(productVariantIds, {
+            relations: ['options', 'facetValues'],
+        });
+        for (const variant of variants) {
+            for (const facetValue of facetValues) {
+                if (!variant.facetValues.map(fv => fv.id).includes(facetValue.id)) {
+                    variant.facetValues.push(facetValue);
+                }
+            }
+            await this.connection.manager.save(variant);
+        }
+
+        return variants.map(v => translateDeep(v, DEFAULT_LANGUAGE_CODE, ['options', 'facetValues']));
+    }
+
     private createVariantName(productName: string, options: ProductOption[]): string {
         const optionsSuffix = options
             .map(option => {

+ 7 - 2
server/src/service/product.service.ts

@@ -51,14 +51,19 @@ export class ProductService {
     }
 
     findOne(productId: ID, lang: LanguageCode): Promise<Translated<Product> | undefined> {
-        const relations = ['variants', 'optionGroups', 'variants.options'];
+        const relations = ['variants', 'optionGroups', 'variants.options', 'variants.facetValues'];
 
         return this.connection.manager
             .findOne(Product, productId, { relations })
             .then(
                 product =>
                     product &&
-                    translateDeep(product, lang, ['optionGroups', 'variants', ['variants', 'options']]),
+                    translateDeep(product, lang, [
+                        'optionGroups',
+                        'variants',
+                        ['variants', 'options'],
+                        ['variants', 'facetValues'],
+                    ]),
             );
     }
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно