Quellcode durchsuchen

fix(core): Throw on no active taxZone when applying taxes to price

Relates to #321
Michael Bromley vor 5 Jahren
Ursprung
Commit
451ae50d23

+ 1 - 1
packages/core/src/config/tax/tax-zone-strategy.ts

@@ -7,5 +7,5 @@ import { Channel, Order, Zone } from '../../entity';
  * @docsCategory tax
  */
 export interface TaxZoneStrategy {
-    determineTaxZone(zones: Zone[], channel: Channel, order?: Order): Zone;
+    determineTaxZone(zones: Zone[], channel: Channel, order?: Order): Zone | undefined;
 }

+ 19 - 20
packages/core/src/service/services/product-variant.service.ts

@@ -61,7 +61,7 @@ export class ProductVariantService {
         return this.connection
             .getRepository(ProductVariant)
             .findOne(productVariantId, { relations })
-            .then((result) => {
+            .then(result => {
                 if (result) {
                     return translateDeep(this.applyChannelPriceAndTax(result, ctx), ctx.languageCode);
                 }
@@ -81,8 +81,8 @@ export class ProductVariantService {
                     'featuredAsset',
                 ],
             })
-            .then((variants) => {
-                return variants.map((variant) =>
+            .then(variants => {
+                return variants.map(variant =>
                     translateDeep(this.applyChannelPriceAndTax(variant, ctx), ctx.languageCode, [
                         'options',
                         'facetValues',
@@ -112,8 +112,8 @@ export class ProductVariantService {
                     id: 'ASC',
                 },
             })
-            .then((variants) =>
-                variants.map((variant) => {
+            .then(variants =>
+                variants.map(variant => {
                     const variantWithPrices = this.applyChannelPriceAndTax(variant, ctx);
                     return translateDeep(variantWithPrices, ctx.languageCode, [
                         'options',
@@ -144,7 +144,7 @@ export class ProductVariantService {
         }
 
         return qb.getManyAndCount().then(async ([variants, totalItems]) => {
-            const items = variants.map((variant) => {
+            const items = variants.map(variant => {
                 const variantWithPrices = this.applyChannelPriceAndTax(variant, ctx);
                 return translateDeep(variantWithPrices, ctx.languageCode);
             });
@@ -159,17 +159,15 @@ export class ProductVariantService {
         return this.connection
             .getRepository(ProductVariant)
             .findOne(variantId, { relations: ['options'] })
-            .then((variant) =>
-                !variant ? [] : variant.options.map((o) => translateDeep(o, ctx.languageCode)),
-            );
+            .then(variant => (!variant ? [] : variant.options.map(o => translateDeep(o, ctx.languageCode))));
     }
 
     getFacetValuesForVariant(ctx: RequestContext, variantId: ID): Promise<Array<Translated<FacetValue>>> {
         return this.connection
             .getRepository(ProductVariant)
             .findOne(variantId, { relations: ['facetValues', 'facetValues.facet'] })
-            .then((variant) =>
-                !variant ? [] : variant.facetValues.map((o) => translateDeep(o, ctx.languageCode, ['facet'])),
+            .then(variant =>
+                !variant ? [] : variant.facetValues.map(o => translateDeep(o, ctx.languageCode, ['facet'])),
             );
     }
 
@@ -196,7 +194,7 @@ export class ProductVariantService {
         }
         const updatedVariants = await this.findByIds(
             ctx,
-            input.map((i) => i.id),
+            input.map(i => i.id),
         );
         this.eventBus.publish(new ProductVariantEvent(ctx, updatedVariants, 'updated'));
         return updatedVariants;
@@ -216,7 +214,7 @@ export class ProductVariantService {
             input,
             entityType: ProductVariant,
             translationType: ProductVariantTranslation,
-            beforeSave: async (variant) => {
+            beforeSave: async variant => {
                 const { optionIds } = input;
                 if (optionIds && optionIds.length) {
                     const selectedOptions = await this.connection
@@ -261,7 +259,7 @@ export class ProductVariantService {
             input,
             entityType: ProductVariant,
             translationType: ProductVariantTranslation,
-            beforeSave: async (updatedVariant) => {
+            beforeSave: async updatedVariant => {
                 if (input.taxCategoryId) {
                     const taxCategory = await this.taxCategoryService.findOne(input.taxCategoryId);
                     if (taxCategory) {
@@ -333,15 +331,16 @@ export class ProductVariantService {
      * Populates the `price` field with the price for the specified channel.
      */
     applyChannelPriceAndTax(variant: ProductVariant, ctx: RequestContext): ProductVariant {
-        const channelPrice = variant.productVariantPrices.find((p) =>
-            idsAreEqual(p.channelId, ctx.channelId),
-        );
+        const channelPrice = variant.productVariantPrices.find(p => idsAreEqual(p.channelId, ctx.channelId));
         if (!channelPrice) {
             throw new InternalServerError(`error.no-price-found-for-channel`);
         }
         const { taxZoneStrategy } = this.configService.taxOptions;
         const zones = this.zoneService.findAll(ctx);
         const activeTaxZone = taxZoneStrategy.determineTaxZone(zones, ctx.channel);
+        if (!activeTaxZone) {
+            throw new InternalServerError(`error.no-active-tax-zone`);
+        }
         const applicableTaxRate = this.taxRateService.getApplicableTaxRate(
             activeTaxZone,
             variant.taxCategory,
@@ -374,12 +373,12 @@ export class ProductVariantService {
         if (
             !samplesEach(
                 optionIds,
-                product.optionGroups.map((g) => g.options.map((o) => o.id)),
+                product.optionGroups.map(g => g.options.map(o => o.id)),
             )
         ) {
             this.throwIncompatibleOptionsError(product.optionGroups);
         }
-        product.variants.forEach((variant) => {
+        product.variants.forEach(variant => {
             const variantOptionIds = this.sortJoin(variant.options, ',', 'id');
             const inputOptionIds = this.sortJoin(input.optionIds || [], ',');
             if (variantOptionIds === inputOptionIds) {
@@ -398,7 +397,7 @@ export class ProductVariantService {
 
     private sortJoin<T>(arr: T[], glue: string, prop?: keyof T): string {
         return arr
-            .map((x) => (prop ? x[prop] : x))
+            .map(x => (prop ? x[prop] : x))
             .sort()
             .join(glue);
     }