product.resolver.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
  2. import {
  3. AddOptionGroupToProductVariables,
  4. ApplyFacetValuesToProductVariantsVariables,
  5. CreateProductVariables,
  6. GenerateProductVariantsVariables,
  7. GetProductListVariables,
  8. GetProductWithVariantsVariables,
  9. Permission,
  10. RemoveOptionGroupFromProductVariables,
  11. UpdateProductVariables,
  12. UpdateProductVariantsVariables,
  13. } from 'shared/generated-types';
  14. import { ID, PaginatedList } from 'shared/shared-types';
  15. import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
  16. import { Translated } from '../../common/types/locale-types';
  17. import { assertFound } from '../../common/utils';
  18. import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
  19. import { Product } from '../../entity/product/product.entity';
  20. import { I18nError } from '../../i18n/i18n-error';
  21. import { FacetValueService } from '../../service/providers/facet-value.service';
  22. import { ProductVariantService } from '../../service/providers/product-variant.service';
  23. import { ProductService } from '../../service/providers/product.service';
  24. import { Allow } from '../common/auth-guard';
  25. import { Decode } from '../common/id-interceptor';
  26. import { RequestContext } from '../common/request-context';
  27. import { Ctx } from '../common/request-context.decorator';
  28. @Resolver('Product')
  29. export class ProductResolver {
  30. constructor(
  31. private productService: ProductService,
  32. private productVariantService: ProductVariantService,
  33. private facetValueService: FacetValueService,
  34. ) {}
  35. @Query()
  36. @Allow(Permission.ReadCatalog)
  37. async products(
  38. @Ctx() ctx: RequestContext,
  39. @Args() args: GetProductListVariables,
  40. ): Promise<PaginatedList<Translated<Product>>> {
  41. return this.productService.findAll(ctx, args.options || undefined);
  42. }
  43. @Query()
  44. @Allow(Permission.ReadCatalog)
  45. async product(
  46. @Ctx() ctx: RequestContext,
  47. @Args() args: GetProductWithVariantsVariables,
  48. ): Promise<Translated<Product> | undefined> {
  49. return this.productService.findOne(ctx, args.id);
  50. }
  51. @Mutation()
  52. @Allow(Permission.CreateCatalog)
  53. @Decode('assetIds', 'featuredAssetId')
  54. async createProduct(
  55. @Ctx() ctx: RequestContext,
  56. @Args() args: CreateProductVariables,
  57. ): Promise<Translated<Product>> {
  58. const { input } = args;
  59. return this.productService.create(ctx, input);
  60. }
  61. @Mutation()
  62. @Allow(Permission.UpdateCatalog)
  63. @Decode('assetIds', 'featuredAssetId')
  64. async updateProduct(
  65. @Ctx() ctx: RequestContext,
  66. @Args() args: UpdateProductVariables,
  67. ): Promise<Translated<Product>> {
  68. const { input } = args;
  69. return this.productService.update(ctx, input);
  70. }
  71. @Mutation()
  72. @Allow(Permission.UpdateCatalog)
  73. @Decode('productId', 'optionGroupId')
  74. async addOptionGroupToProduct(
  75. @Ctx() ctx: RequestContext,
  76. @Args() args: AddOptionGroupToProductVariables,
  77. ): Promise<Translated<Product>> {
  78. const { productId, optionGroupId } = args;
  79. return this.productService.addOptionGroupToProduct(ctx, productId, optionGroupId);
  80. }
  81. @Mutation()
  82. @Allow(Permission.UpdateCatalog)
  83. @Decode('productId', 'optionGroupId')
  84. async removeOptionGroupFromProduct(
  85. @Ctx() ctx: RequestContext,
  86. @Args() args: RemoveOptionGroupFromProductVariables,
  87. ): Promise<Translated<Product>> {
  88. const { productId, optionGroupId } = args;
  89. return this.productService.removeOptionGroupFromProduct(ctx, productId, optionGroupId);
  90. }
  91. @Mutation()
  92. @Allow(Permission.CreateCatalog)
  93. @Decode('productId')
  94. async generateVariantsForProduct(
  95. @Ctx() ctx: RequestContext,
  96. @Args() args: GenerateProductVariantsVariables,
  97. ): Promise<Translated<Product>> {
  98. const { productId, defaultPrice, defaultSku } = args;
  99. await this.productVariantService.generateVariantsForProduct(ctx, productId, defaultPrice, defaultSku);
  100. return assertFound(this.productService.findOne(ctx, productId));
  101. }
  102. @Mutation()
  103. @Allow(Permission.UpdateCatalog)
  104. async updateProductVariants(
  105. @Ctx() ctx: RequestContext,
  106. @Args() args: UpdateProductVariantsVariables,
  107. ): Promise<Array<Translated<ProductVariant>>> {
  108. const { input } = args;
  109. return Promise.all(input.map(variant => this.productVariantService.update(variant)));
  110. }
  111. @Mutation()
  112. @Allow(Permission.UpdateCatalog)
  113. @Decode('facetValueIds', 'productVariantIds')
  114. async applyFacetValuesToProductVariants(
  115. @Ctx() ctx: RequestContext,
  116. @Args() args: ApplyFacetValuesToProductVariantsVariables,
  117. ): Promise<Array<Translated<ProductVariant>>> {
  118. const { facetValueIds, productVariantIds } = args;
  119. const facetValues = await Promise.all(
  120. (facetValueIds as ID[]).map(async facetValueId => {
  121. const facetValue = await this.facetValueService.findOne(facetValueId, DEFAULT_LANGUAGE_CODE);
  122. if (!facetValue) {
  123. throw new I18nError('error.entity-with-id-not-found', {
  124. entityName: 'FacetValue',
  125. id: facetValueId,
  126. });
  127. }
  128. return facetValue;
  129. }),
  130. );
  131. return this.productVariantService.addFacetValues(productVariantIds, facetValues);
  132. }
  133. }