diff --git a/app/controllers/api/cart_controller.rb b/app/controllers/api/cart_controller.rb index c9de2170d..82cc48615 100644 --- a/app/controllers/api/cart_controller.rb +++ b/app/controllers/api/cart_controller.rb @@ -31,6 +31,12 @@ class API::CartController < API::ApiController render 'api/orders/show' end + def set_offer + authorize @current_order, policy_class: CartPolicy + @order = Cart::SetOfferService.new.call(@current_order, orderable, cart_params[:is_offered]) + render 'api/orders/show' + end + private def orderable diff --git a/app/controllers/concerns/api/order_concern.rb b/app/controllers/concerns/api/order_concern.rb index 9e14854dd..6c0b753c1 100644 --- a/app/controllers/concerns/api/order_concern.rb +++ b/app/controllers/concerns/api/order_concern.rb @@ -17,6 +17,6 @@ module API::OrderConcern end def cart_params - params.permit(:order_token, :orderable_id, :quantity, :user_id) + params.permit(:order_token, :orderable_id, :quantity, :user_id, :is_offered) end end diff --git a/app/frontend/src/javascript/api/cart.ts b/app/frontend/src/javascript/api/cart.ts index 4601de322..f0efea8db 100644 --- a/app/frontend/src/javascript/api/cart.ts +++ b/app/frontend/src/javascript/api/cart.ts @@ -22,4 +22,9 @@ export default class CartAPI { const res: AxiosResponse = await apiClient.put('/api/cart/set_quantity', { order_token: order.token, orderable_id: orderableId, quantity }); return res?.data; } + + static async setOffer (order: Order, orderableId: number, isOffered: boolean): Promise { + const res: AxiosResponse = await apiClient.put('/api/cart/set_offer', { order_token: order.token, orderable_id: orderableId, is_offered: isOffered }); + return res?.data; + } } diff --git a/app/frontend/src/javascript/components/cart/store-cart.tsx b/app/frontend/src/javascript/components/cart/store-cart.tsx index 8e06369fd..f385d3821 100644 --- a/app/frontend/src/javascript/components/cart/store-cart.tsx +++ b/app/frontend/src/javascript/components/cart/store-cart.tsx @@ -115,8 +115,12 @@ const StoreCart: React.FC = ({ onSuccess, onError, currentUser, /** * Toggle product offer */ - const onSwitch = (product, checked: boolean) => { - console.log('Offer ', product.orderable_name, ': ', checked); + const toogleProductOffer = (item) => { + return (checked: boolean) => { + CartAPI.setOffer(cart, item.orderable_id, checked).then(data => { + setCart(data); + }).catch(onError); + }; }; /** @@ -128,14 +132,50 @@ const StoreCart: React.FC = ({ onSuccess, onError, currentUser, } }; + /** + * Get the item total + */ + const itemAmount = (item): number => { + return item.quantity * Math.trunc(item.amount * 100) / 100; + }; + + /** + * return true if cart has offered item + */ + const hasOfferedItem = (): boolean => { + return cart.order_items_attributes + .filter(i => i.is_offered).length > 0; + }; + /** * Get the offered item total */ const offeredAmount = (): number => { return cart.order_items_attributes .filter(i => i.is_offered) - .map(i => i.amount) - .reduce((acc, curr) => acc + curr, 0); + .map(i => Math.trunc(i.amount * 100) * i.quantity) + .reduce((acc, curr) => acc + curr, 0) / 100; + }; + + /** + * Get the total amount before offered amount + */ + const totalBeforeOfferedAmount = (): number => { + return (Math.trunc(cart.total * 100) + Math.trunc(offeredAmount() * 100)) / 100; + }; + + /** + * Get the coupon amount + */ + const couponAmount = (): number => { + return (Math.trunc(cart.total * 100) - Math.trunc(computePriceWithCoupon(cart.total, cart.coupon) * 100)) / 100.00; + }; + + /** + * Get the paid total amount + */ + const paidTotal = (): number => { + return computePriceWithCoupon(cart.total, cart.coupon); }; return ( @@ -163,7 +203,7 @@ const StoreCart: React.FC = ({ onSuccess, onError, currentUser,
{t('app.public.store_cart.total')} -

{FormatLib.price(item.quantity * item.amount)}

+

{FormatLib.price(itemAmount(item))}

@@ -175,7 +215,7 @@ const StoreCart: React.FC = ({ onSuccess, onError, currentUser, Offer the product onSwitch(item, checked)} + onChange={toogleProductOffer(item)} width={40} height={19} uncheckedIcon={false} @@ -203,7 +243,7 @@ const StoreCart: React.FC = ({ onSuccess, onError, currentUser,