Skip to content

Commit

Permalink
fix(core): Prevent duplicate variant price when updating currencyCode
Browse files Browse the repository at this point in the history
Fixes #2391
  • Loading branch information
michaelbromley committed Nov 13, 2023
1 parent f544cf3 commit feecfae
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
19 changes: 19 additions & 0 deletions packages/core/e2e/product-channel.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,5 +506,24 @@ describe('ChannelAware Products and ProductVariants', () => {
{ currencyCode: 'EUR', price: 300 },
]);
});

// https://github.com/vendure-ecommerce/vendure/issues/2391
it('does not duplicate an existing price', async () => {
await adminClient.query(UpdateChannelDocument, {
input: {
id: secondChannelId,
defaultCurrencyCode: CurrencyCode.GBP,
},
});

const { productVariants: after } = await adminClient.query(GetProductVariantListDocument, {});

expect(after.items.map(i => i.currencyCode)).toEqual(['GBP']);
expect(after.items[0]?.prices.sort((a, b) => a.price - b.price)).toEqual([
{ currencyCode: 'GBP', price: 100 },
{ currencyCode: 'AUD', price: 200 },
{ currencyCode: 'EUR', price: 300 },
]);
});
});
});
27 changes: 21 additions & 6 deletions packages/core/src/service/services/channel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { VendureEntity } from '../../entity/base/base.entity';
import { Channel } from '../../entity/channel/channel.entity';
import { Order } from '../../entity/order/order.entity';
import { ProductVariantPrice } from '../../entity/product-variant/product-variant-price.entity';
import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
import { Seller } from '../../entity/seller/seller.entity';
import { Session } from '../../entity/session/session.entity';
import { Zone } from '../../entity/zone/zone.entity';
Expand Down Expand Up @@ -177,6 +178,7 @@ export class ChannelService {
this.eventBus.publish(new ChangeChannelEvent(ctx, entity, channelIds, 'removed', entityType));
return entity;
}

/**
* @description
* Given a channel token, returns the corresponding Channel if it exists, else will throw
Expand Down Expand Up @@ -329,16 +331,29 @@ export class ChannelService {
if (originalDefaultCurrencyCode !== newCurrencyCode) {
// When updating the default currency code for a Channel, we also need to update
// and ProductVariantPrices in that channel which use the old currency code.
const [selectQbQuery, selectQbParams] = this.connection
.getRepository(ctx, ProductVariant)
.createQueryBuilder('variant')
.select('variant.id')
.innerJoin(ProductVariantPrice, 'pvp', 'pvp.variantId = variant.id')
.andWhere('pvp.channelId = :channelId')
.andWhere('pvp.currencyCode = :newCurrencyCode')
.groupBy('variant.id')
.getQueryAndParameters();

const qb = this.connection
.getRepository(ctx, ProductVariantPrice)
.createQueryBuilder('pvp')
.update()
.where('channelId = :channelId', { channelId: channel.id })
.andWhere('currencyCode = :currencyCode', {
currencyCode: originalDefaultCurrencyCode,
})
.set({ currencyCode: newCurrencyCode });

.where('channelId = :channelId')
.andWhere('currencyCode = :oldCurrencyCode')
.andWhere(`variantId NOT IN (${selectQbQuery})`, selectQbParams)
.set({ currencyCode: newCurrencyCode })
.setParameters({
channelId: channel.id,
oldCurrencyCode: originalDefaultCurrencyCode,
newCurrencyCode,
});
await qb.execute();
}
}
Expand Down

0 comments on commit feecfae

Please sign in to comment.