Skip to content

Commit

Permalink
feat(cart): compute cart prices for in-memory driver (#2614)
Browse files Browse the repository at this point in the history
  • Loading branch information
griest024 committed Nov 22, 2023
1 parent 48f4ba0 commit 7a60ddb
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {

import { DaffCartWithStoreCredit } from '@daffodil/cart-store-credit';
import { DaffCartWithStoreCreditFactory } from '@daffodil/cart-store-credit/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffCartStoreCreditInMemoryBackendService } from './store-credit.service';

Expand All @@ -18,6 +19,9 @@ describe('@daffodil/cart-store-credit/driver/in-memory | DaffCartStoreCreditInMe

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
DaffProductTestingModule,
],
providers: [
DaffCartStoreCreditInMemoryBackendService,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
DaffCartFactory,
DaffCartItemFactory,
} from '@daffodil/cart/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffInMemoryBackendCartItemsService } from './cart-items.service';

Expand All @@ -31,6 +32,9 @@ describe('DaffInMemoryBackendCartItemsService', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
DaffProductTestingModule,
],
providers: [
DaffInMemoryBackendCartItemsService,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
} from '@daffodil/cart';
import { DaffCartItemFactory } from '@daffodil/cart/testing';
import { DaffInMemoryDataServiceInterface } from '@daffodil/core/testing';
import { DaffInMemoryBackendProductService } from '@daffodil/product/driver/in-memory';

import { daffCartInMemoryComputeCartItemPrices } from '../../helpers/compute-cart-item-prices';
import { daffCartInMemoryComputeCartTotals } from '../../helpers/compute-cart-totals';
import {
DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK,
DaffCartInMemoryExtraAttributesHook,
Expand All @@ -30,6 +33,7 @@ export class DaffInMemoryBackendCartItemsService implements DaffInMemoryDataServ
constructor(
private cartItemFactory: DaffCartItemFactory,
@Inject(DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK) private extraFieldsHook: DaffCartInMemoryExtraAttributesHook,
private productBackend: DaffInMemoryBackendProductService,
) {}

get(reqInfo: RequestInfo) {
Expand Down Expand Up @@ -105,16 +109,16 @@ export class DaffInMemoryBackendCartItemsService implements DaffInMemoryDataServ
const cartIndex = reqInfo.collection.findIndex(c => c.id === reqInfo.id);
const itemChanges = reqInfo.utils.getJsonBody(reqInfo.req);
const itemIndex = cart.items.findIndex((item) => itemId === item.id);
reqInfo.collection[cartIndex] = {
reqInfo.collection[cartIndex] = daffCartInMemoryComputeCartTotals({
...cart,
items: cart.items.map(
(item, index) => index === itemIndex ? {
(item, index) => index === itemIndex ? daffCartInMemoryComputeCartItemPrices({
...cart.items[itemIndex],
...itemChanges,
} : item,
}, this.productBackend.products) : item,
),
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}, this.productBackend.products);

return reqInfo.collection[cartIndex];
}
Expand All @@ -124,27 +128,27 @@ export class DaffInMemoryBackendCartItemsService implements DaffInMemoryDataServ
const cartIndex = reqInfo.collection.findIndex(c => c.id === reqInfo.id);
const itemInput = reqInfo.utils.getJsonBody(reqInfo.req);
const existingCartItemIndex = cart.items.findIndex(item => item.product_id === itemInput.productId);
if(existingCartItemIndex > -1) {
if (existingCartItemIndex > -1) {
const updatedCartItem = {
...cart.items[existingCartItemIndex],
qty: cart.items[existingCartItemIndex].qty + itemInput.qty,
};
reqInfo.collection[cartIndex] = {
reqInfo.collection[cartIndex] = daffCartInMemoryComputeCartTotals({
...cart,
items: cart.items.map(
(item, index) => index === existingCartItemIndex ? updatedCartItem : item,
(item, index) => index === existingCartItemIndex ? daffCartInMemoryComputeCartItemPrices(updatedCartItem, this.productBackend.products) : item,
),
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}, this.productBackend.products);
} else {
reqInfo.collection[cartIndex] = {
reqInfo.collection[cartIndex] = daffCartInMemoryComputeCartTotals({
...cart,
items: [
...cart.items,
this.transformItemInput(itemInput),
daffCartInMemoryComputeCartItemPrices(this.transformItemInput(itemInput), this.productBackend.products),
],
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}, this.productBackend.products);
}

return reqInfo.collection[cartIndex];
Expand All @@ -154,11 +158,11 @@ export class DaffInMemoryBackendCartItemsService implements DaffInMemoryDataServ
const cart = this.getCart(reqInfo);
const itemIndex = cart.items.findIndex(({ id }) => itemId === id);
const cartIndex = reqInfo.collection.findIndex(c => c.id === reqInfo.id);
reqInfo.collection[cartIndex] = {
reqInfo.collection[cartIndex] = daffCartInMemoryComputeCartTotals({
...cart,
items: cart.items.filter((item, index) => index !== itemIndex),
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}, this.productBackend.products);

return reqInfo.collection[cartIndex];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
DaffCartPaymentFactory,
DaffCartShippingRateFactory,
} from '@daffodil/cart/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffInMemoryBackendCartRootService } from './cart-root.service';

Expand Down Expand Up @@ -51,6 +52,7 @@ describe('DaffInMemoryBackendCartRootService | Integration', () => {
imports: [
HttpClientModule,
HttpClientInMemoryWebApiModule.forRoot(DaffInMemoryBackendCartRootService, { delay: 0 }),
DaffProductTestingModule,
],
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
DaffCartFactory,
DaffCartItemFactory,
} from '@daffodil/cart/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffInMemoryBackendCartRootService } from './cart-root.service';

Expand Down Expand Up @@ -79,6 +80,9 @@ describe('DaffInMemoryBackendCartRootService | Unit', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
DaffProductTestingModule,
],
providers: [
DaffInMemoryBackendCartRootService,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DaffCartFactory,
DaffCartShippingRateFactory,
} from '@daffodil/cart/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffInMemoryBackendCartShippingInformationService } from './cart-shipping-information.service';

Expand All @@ -28,6 +29,9 @@ describe('DaffInMemoryBackendCartShippingInformationService', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
DaffProductTestingModule,
],
providers: [
DaffInMemoryBackendCartShippingInformationService,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
DaffCartShippingInformation,
} from '@daffodil/cart';
import { DaffInMemoryDataServiceInterface } from '@daffodil/core/testing';
import { DaffInMemoryBackendProductService } from '@daffodil/product/driver/in-memory';

import { daffCartInMemoryComputeCartTotals } from '../../helpers/compute-cart-totals';
import {
DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK,
DaffCartInMemoryExtraAttributesHook,
Expand All @@ -27,6 +29,7 @@ import {
export class DaffInMemoryBackendCartShippingInformationService implements DaffInMemoryDataServiceInterface {
constructor(
@Inject(DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK) private extraFieldsHook: DaffCartInMemoryExtraAttributesHook,
private productBackend: DaffInMemoryBackendProductService,
) {}

get(reqInfo: RequestInfo) {
Expand Down Expand Up @@ -65,7 +68,7 @@ export class DaffInMemoryBackendCartShippingInformationService implements DaffIn
cart.shipping_information = shippingInformation;

return {
...cart,
...daffCartInMemoryComputeCartTotals(cart, this.productBackend.products),
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}
Expand All @@ -76,7 +79,7 @@ export class DaffInMemoryBackendCartShippingInformationService implements DaffIn
cart.shipping_information = null;

return {
...cart,
...daffCartInMemoryComputeCartTotals(cart, this.productBackend.products),
extra_attributes: this.extraFieldsHook(reqInfo, cart),
};
}
Expand Down
10 changes: 7 additions & 3 deletions libs/cart/driver/in-memory/src/backend/cart/cart.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
DaffCartFactory,
DaffCartItemFactory,
} from '@daffodil/cart/testing';
import { DaffProductTestingModule } from '@daffodil/product/testing';

import { DaffInMemoryBackendCartService } from './cart.service';

Expand All @@ -32,6 +33,9 @@ describe('DaffInMemoryBackendCartService', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
DaffProductTestingModule,
],
providers: [
DaffInMemoryBackendCartService,
{
Expand Down Expand Up @@ -87,10 +91,10 @@ describe('DaffInMemoryBackendCartService', () => {
});

it('should return the cart', () => {
expect(result.body).toEqual({
...mockCart,
expect(result.body).toEqual(jasmine.objectContaining({
id: mockCart.id,
extra_attributes: extraAttributes,
});
}));
expect(result.status).toEqual(STATUS.OK);
});

Expand Down
6 changes: 5 additions & 1 deletion libs/cart/driver/in-memory/src/backend/cart/cart.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Injectable,
Inject,
} from '@angular/core';
import { faker } from '@faker-js/faker';
import {
STATUS,
RequestInfo,
Expand All @@ -11,7 +12,9 @@ import {
import { DaffCart } from '@daffodil/cart';
import { DaffCartFactory } from '@daffodil/cart/testing';
import { DaffInMemoryDataServiceInterface } from '@daffodil/core/testing';
import { DaffInMemoryBackendProductService } from '@daffodil/product/driver/in-memory';

import { daffCartInMemoryComputeCartTotals } from '../../helpers/compute-cart-totals';
import {
DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK,
DaffCartInMemoryExtraAttributesHook,
Expand All @@ -27,6 +30,7 @@ export class DaffInMemoryBackendCartService implements DaffInMemoryDataServiceIn
constructor(
private cartFactory: DaffCartFactory,
@Inject(DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK) private extraFieldsHook: DaffCartInMemoryExtraAttributesHook,
private productBackend: DaffInMemoryBackendProductService,
) {}

get(reqInfo: RequestInfo) {
Expand Down Expand Up @@ -129,7 +133,7 @@ export class DaffInMemoryBackendCartService implements DaffInMemoryDataServiceIn
return cart
? {
body: {
...cart,
...daffCartInMemoryComputeCartTotals(cart, this.productBackend.products),
extra_attributes: this.extraFieldsHook(reqInfo, <DaffCart>cart),
},
status: STATUS.OK,
Expand Down
12 changes: 12 additions & 0 deletions libs/cart/driver/in-memory/src/helpers/compute-cart-item-prices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { faker } from '@faker-js/faker';

import { DaffCartItem } from '@daffodil/cart';
import { daffMultiply } from '@daffodil/core';
import { DaffProduct } from '@daffodil/product';

export function daffCartInMemoryComputeCartItemPrices(cartItem: DaffCartItem, products: DaffProduct[]): DaffCartItem {
cartItem.price = products.find(({ id }) => id === cartItem.product_id)?.price || 0;
cartItem.row_total = daffMultiply(cartItem.price, cartItem.qty);

return cartItem;
}
55 changes: 55 additions & 0 deletions libs/cart/driver/in-memory/src/helpers/compute-cart-totals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { faker } from '@faker-js/faker';

import {
DaffCart,
DaffCartTotalTypeEnum,
} from '@daffodil/cart';
import { DaffProduct } from '@daffodil/product';

export function daffCartInMemoryComputeCartTotals(cart: DaffCart, products: DaffProduct[]): DaffCart {
const shipping = cart.shipping_information ? faker.datatype.number({ min: 0, max: 99 }) : 0;
const subtotalExcludingTax = cart.items?.reduce((acc, { product_id }) =>
acc + (products.find(({ id }) => id === product_id)?.price || 0),
0,
) || 0;
const discount = faker.datatype.number({ min: 0, max: subtotalExcludingTax });
const subtotalIncludingTax = subtotalExcludingTax + cart.totals[DaffCartTotalTypeEnum.tax].value;
const subtotalWithDiscountExcludingTax = subtotalExcludingTax - discount;
const subtotalWithDiscountIncludingTax = subtotalIncludingTax - discount;
const grandTotal = subtotalWithDiscountIncludingTax + shipping;

return {
...cart,
totals: {
...cart.totals,
[DaffCartTotalTypeEnum.shipping]: {
...cart.totals[DaffCartTotalTypeEnum.shipping],
value: shipping,
},
[DaffCartTotalTypeEnum.subtotalExcludingTax]: {
...cart.totals[DaffCartTotalTypeEnum.subtotalExcludingTax],
value: subtotalExcludingTax,
},
[DaffCartTotalTypeEnum.discount]: {
...cart.totals[DaffCartTotalTypeEnum.discount],
value: discount,
},
[DaffCartTotalTypeEnum.subtotalIncludingTax]: {
...cart.totals[DaffCartTotalTypeEnum.subtotalIncludingTax],
value: subtotalIncludingTax,
},
[DaffCartTotalTypeEnum.subtotalWithDiscountExcludingTax]: {
...cart.totals[DaffCartTotalTypeEnum.subtotalWithDiscountExcludingTax],
value: subtotalWithDiscountExcludingTax,
},
[DaffCartTotalTypeEnum.subtotalWithDiscountIncludingTax]: {
...cart.totals[DaffCartTotalTypeEnum.subtotalWithDiscountIncludingTax],
value: subtotalWithDiscountIncludingTax,
},
[DaffCartTotalTypeEnum.grandTotal]: {
...cart.totals[DaffCartTotalTypeEnum.grandTotal],
value: grandTotal,
},
},
};
}

0 comments on commit 7a60ddb

Please sign in to comment.