notrab / react-use-cart

React hook library for managing cart state

Home Page:http://npm.im/react-use-cart

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Handle multiple prices per item

ynnoj opened this issue · comments

I have a use case where I am implementing a localised cart where cart items may have a different prices per currency/locale.

Currently items are require to have a single price: number, which limits the possibility of offering multiple prices on cart items.

We could introduce a conditional type ItemPrice which returns an interface depending on properties provided.

@ynnoj I'd be happy to cut a breaking change if we made price an array (or object) of prices`.

Either:

const item = { id: '...', price: { en: 1000, de: 1200 } }

or

const item = { id: '...', prices: [ { amount: 1000, currency: 'gbp' }, { amount: 1200, currency: 'EUR' } ]

I quite prefer the array of prices since it would allow the price type to be expanded in the future, and generally feels more flexible.

What are your thoughts?

@notrab Happy to add a PR that implements prices: ItemPrice[].

interface ItemPrice {
  amount: number,
  [key: string]: any
}

My concern is then how to we calculate totals on a per currency basis, unless we make currency required.

I guess those total functions need to be updated to also reflect multiple price support.

I have a similar case, but in addition to several prices, I'm fetching data from an API where the price-key is called gross_price. I cannot add to cart without price. Is there any way to rename this key somehow?

@taniaholst what would you like to rename it as?

Well, in order to use addItems(), I need a price, so I need to rename gross_price to price

What's preventing someone from using the field "as is", and using it where/how they need? It sounds like an implementation detail if I'm not mistaken.

I'm not sure if I understand what you mean. I get the error message Error: You must pass a 'price' for new items when I use addItem(), and I've figured it's because my data does not include price, because I am using an API where the price-key is called gross_price. My question is if it is possible to rename the item metadata (not cart metadata) from gross_price to price so addItem() will work?

What I mean is why can't you use price even though it may be gross_price, you could rename gross_price to price when passing it to addItem.

Okey, how?

Here's what the documentation says:

addItem(item, quantity)
The addItem method should be used to add items to the cart.

Args
item (Required): An object that represents your cart item. You must provide an id and price value for new items that you add to cart.
quantity (optional, default: 1): The amount of items you want to add.

I've tried addItem({item.id, item.gross_price}, 1), but that did not work.. Do you know the syntax for this, to send the correct price-value to the cart?

Also, my gross_price is a string, that might be a problem as well..

@taniaholst I don't know the details of the API you're using, or what the payload looks like, but you should use addItem() similar to the following:

addItem({ id: "YOUR_ID", price: 1000 })

price needs to be an integer though, so maybe you can convert it, or set it to 0, and use an additional key/value to store your gross_price, for example:

addItem({ id: "YOUR_ID", price: 1000, gross_price: gross_price })

If you used the 2nd option, you wouldn't be able to take advantage of the line/unit totals, and cart totals, etc.

Yes, the first option worked perfectly! Thank you very much for your patience and help!!

@notrab I'm wondering why we need to save the price from the client side? what happen if the price changes during that checkout? 🤔

@jdnichollsc you should check the prices from the cart match your backend source server-side before creating any kind of checkout link.