Skip to content

Commit

Permalink
Jl/multipack (#258)
Browse files Browse the repository at this point in the history
* Calculate orig price and savings

* Display multipack individual price and calculated savings

* Add price calculation to offer modal

* Update clear translation
  • Loading branch information
jrlarano authored Oct 24, 2024
1 parent 63379ab commit 6779ab0
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 37 deletions.
67 changes: 64 additions & 3 deletions lib/kits/core-ui/components/common/offer-overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
parseDateStr,
updateShoppingList,
displayOfferMessage,
getLocaleCode
getLocaleCode,
calculateProductPrice,
getTotalQuantityByOffer
} from '../helpers/component';
import {request, V2Offer} from '../../../core';
import * as clientLocalStorage from '../../../../storage/client-local';
Expand Down Expand Up @@ -121,6 +123,7 @@ const OfferOverview = ({
}) => {
template = template?.innerHTML || defaultTemplate;
let container: HTMLDivElement | null = null;
let transformedOffer;

const translations = {
localeCode: scriptEls.localeCode
Expand All @@ -135,7 +138,7 @@ const OfferOverview = ({

const render = async () => {
try {
const transformedOffer =
transformedOffer =
type === 'paged'
? await fetchOffer(offer.id)
: await transformIncitoOffer(offer);
Expand Down Expand Up @@ -188,10 +191,14 @@ const OfferOverview = ({
(offer) => offer.id === product.id
);

const price = useOfferPrice
let price = useOfferPrice
? offer.price || offer.pricing.price
: product?.price;

if (offer.piece_count?.from > 1) {
price = (price + (offer.savings || 0)) / offer.piece_count.from;
}

const priceCurrency =
offer.currency_code || offer.pricing?.currency || currency;

Expand Down Expand Up @@ -493,13 +500,67 @@ const OfferOverview = ({
});
};

const addLocalStorageListener = () => {
window.addEventListener('tjek_shopping_list_update', () => {
const {localeCode, currency} = translations;
const productEls = container?.querySelectorAll(
'.sgn-product-details'
);
let priceCurrency = currency;
const storedPublicationOffers = clientLocalStorage.get(
'publication-saved-offers'
);

productEls?.forEach((productEl: HTMLElement) => {
const priceEl =
productEl.querySelector<HTMLElement>('.sgn-product-price');
const productId = productEl.dataset.offerProductId;
const product = storedPublicationOffers.find(
(product) => product.id === productId
);
priceCurrency = product?.pricing?.currency || currency;

if (priceEl && !product) {
const offerProduct = transformedOffer.products.find(
(product) => product.id === productId
);

priceEl.innerHTML = formatPrice(
offerProduct.price,
localeCode,
priceCurrency
);
return;
}

if (priceEl && product?.pricing?.price) {
const totalQuantityByOffer = getTotalQuantityByOffer(
storedPublicationOffers,
product.offerId
);
const priceNum = calculateProductPrice(
product,
totalQuantityByOffer
);

priceEl.innerHTML = formatPrice(
priceNum,
localeCode,
priceCurrency
);
}
});
});
};

const addEventListeners = () => {
document.querySelector<HTMLDivElement>('.sgn-modal-container')?.focus();

addOpenWebshopListener();
addShoppingListListener();
addProductListener();
closeModalListener();
addLocalStorageListener();
};

return {render};
Expand Down
135 changes: 102 additions & 33 deletions lib/kits/core-ui/components/common/shopping-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
formatPrice,
translate,
updateShoppingList,
getLocaleCode
getLocaleCode,
calculateProductPrice,
getTotalQuantityByOffer
} from '../helpers/component';
import './shopping-list.styl';

Expand Down Expand Up @@ -185,17 +187,29 @@ const ShoppingList = ({
const transformSavedOffers = (savedOffers) => {
const {localeCode, currency} = translations;

return (savedOffers || []).map((offer, index) => ({
index,
...offer,
price: offer?.pricing?.price
? formatPrice(
offer?.pricing?.price * (offer?.quantity || 1),
localeCode,
offer?.pricing?.currency || currency
)
: null
}));
return (savedOffers || []).map((offer, index) => {
const totalQuantityByOffer = getTotalQuantityByOffer(
savedOffers,
offer.offerId
);
const productPrice = calculateProductPrice(
offer,
totalQuantityByOffer
);

return {
index,
...offer,
totalQuantityByOffer,
price: productPrice
? formatPrice(
productPrice,
localeCode,
offer?.pricing?.currency || currency
)
: null
};
});
};

const addTickerListener = () => {
Expand Down Expand Up @@ -350,10 +364,20 @@ const ShoppingList = ({
);
const priceCurrency =
storedPublicationOffers?.[0]?.pricing?.currency || currency;
let totalPrice = 0;

storedPublicationOffers?.forEach((product) => {
const totalQuantityByOffer = getTotalQuantityByOffer(
storedPublicationOffers,
product.offerId
);
const priceNum = calculateProductPrice(
product,
totalQuantityByOffer
);

const totalPrice = storedPublicationOffers?.reduce((acc, product) => {
return acc + product.pricing.price * product.quantity;
}, 0);
totalPrice += priceNum;
});

return totalPrice
? formatPrice(totalPrice, localeCode, priceCurrency)
Expand Down Expand Up @@ -389,8 +413,6 @@ const ShoppingList = ({
(product) => product.id === productId
);

const priceCurrency = product?.pricing?.currency || currency;

if (quantityTxt) {
quantityTxt.value =
action === 'plus' ? `${++quantity}` : `${--quantity}`;
Expand All @@ -399,16 +421,6 @@ const ShoppingList = ({
productEl.remove();
}

if (priceEl && product?.pricing?.price && quantity) {
const priceNum = product?.pricing?.price * (quantity || 1);

priceEl.innerHTML = formatPrice(
priceNum,
localeCode,
priceCurrency
);
}

updateShoppingList(
{
...product,
Expand All @@ -419,12 +431,6 @@ const ShoppingList = ({
},
action
);

if (totalPriceEL && getTotalPrice()) {
totalPriceEL.innerHTML = getTotalPrice();
} else {
totalPriceContainer?.remove();
}
}
};

Expand All @@ -450,6 +456,68 @@ const ShoppingList = ({
});
};

const addLocalStorageListener = () => {
window.addEventListener('tjek_shopping_list_update', () => {
const {localeCode, currency} = translations;
const productEls = document.querySelectorAll(
'.sgn-shopping-list-item-container'
);
let priceCurrency = currency;
let totalPrice = 0;

const totalPriceEL = container?.querySelector<HTMLInputElement>(
'.sgn-shopping-list-content-price-total'
);
const totalPriceContainer =
container?.querySelector<HTMLDivElement>(
'.sgn-shopping-list-content-container-total'
);
const storedPublicationOffers = clientLocalStorage.get(
'publication-saved-offers'
);

productEls.forEach((productEl: HTMLElement) => {
const priceEl = productEl.querySelector<HTMLElement>(
'.sgn-shopping-list-content-price'
);
const productId = productEl.dataset.offerProductId;
const product = storedPublicationOffers.find(
(product) => product.id === productId
);
priceCurrency = product?.pricing?.currency || currency;

if (priceEl && product?.pricing?.price) {
const totalQuantityByOffer = getTotalQuantityByOffer(
storedPublicationOffers,
product.offerId
);
const priceNum = calculateProductPrice(
product,
totalQuantityByOffer
);

totalPrice += priceNum;

priceEl.innerHTML = formatPrice(
priceNum,
localeCode,
priceCurrency
);
}
});

if (totalPriceEL && totalPrice) {
totalPriceEL.innerHTML = formatPrice(
totalPrice,
localeCode,
priceCurrency
);
} else {
totalPriceContainer?.remove();
}
});
};

const formatListToShare = (data, newLineDelimiter = `\n`) => {
let offerStr = '';

Expand All @@ -474,6 +542,7 @@ const ShoppingList = ({
addPrintListener();
addShareListener();
addQuantityListener();
addLocalStorageListener();
};

return {render};
Expand Down
38 changes: 38 additions & 0 deletions lib/kits/core-ui/components/helpers/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,11 @@ export const updateShoppingList = (offer, action: 'plus' | 'minus') => {
const currency = offer.currency_code || offer.pricing.currency;

let shopListOffer = {
offerId: offer.id,
id: offer.id,
name: offer.name,
pieceCount: offer.piece_count,
savings: offer.savings,
pricing: {
price: offer.price,
currency
Expand All @@ -345,8 +348,11 @@ export const updateShoppingList = (offer, action: 'plus' | 'minus') => {
);
if (product) {
shopListOffer = {
offerId: offer.id,
id: product.id,
name: product.title,
pieceCount: offer.piece_count,
savings: offer.savings,
pricing: {
price: useOfferPrice
? offer.price || offer.pricing.price
Expand Down Expand Up @@ -453,3 +459,35 @@ export const getLocaleCode = (countryId: string): string => {

return countryLocaleMap[countryId] || '';
};

export const calculateProductPrice = (offer, totalQuantityByOffer = 1) => {
let productPrice = 0;
const offerPrice = offer.pricing.price; // Individual price per piece

for (let i = offer?.quantity || 1; i >= 1; i--) {
if (offer.pieceCount?.from > 1) {
if (i % offer.pieceCount?.from === 0) {
productPrice += offerPrice;
i -= offer.pieceCount.from - 1;
} else if (totalQuantityByOffer % offer.pieceCount?.from === 0) {
productPrice += offerPrice / offer.pieceCount.from;
} else {
productPrice +=
(offerPrice + offer.savings) / offer.pieceCount.from;
}
} else {
productPrice += offerPrice;
}
}

return productPrice;
};

export const getTotalQuantityByOffer = (savedOffers, offerId) => {
return (savedOffers || []).reduce((totalQuantity, offer) => {
if (offer.offerId === offerId) {
totalQuantity += offer.quantity || 1;
}
return totalQuantity;
}, 0);
};
2 changes: 1 addition & 1 deletion locales/sv_SE.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default {
locale_code: 'sv_SE',
publication_viewer_shopping_list_label: 'Inköpslista',
publication_viewer_shopping_list_clear_button: 'Tydlig lista',
publication_viewer_shopping_list_clear_button: 'Rensa lista',
publication_viewer_delete_crossed_out_button: 'Ta bort överstrukna objekt',
publication_viewer_print_button: 'Skriva ut',
publication_viewer_download_button: 'Ladda ner',
Expand Down

0 comments on commit 6779ab0

Please sign in to comment.