apply restaurant decimails formating & fix tax calcualtions

This commit is contained in:
2026-01-17 11:44:04 +03:00
parent 69425580d6
commit f97b83062c
8 changed files with 33 additions and 22 deletions

View File

@@ -27,7 +27,7 @@ const ArabicPrice: React.FC<ArabicPriceProps> = ({
// Format the price to ensure it has 2 decimal places
const formattedPrice =
typeof price === "number" ? formatPriceUi(price, 3) : price;
typeof price === "number" ? formatPriceUi(price, restaurant?.currency_decimals ?? 3) : price;
const { textDecoration, ...restStyle } = style;
const decorationStyle = textDecoration
? ({ textDecoration } as React.CSSProperties)

View File

@@ -21,6 +21,7 @@ const PaymentMethods = () => {
const { paymentMethod, orderType } = useAppSelector(selectCart);
const dispatch = useAppDispatch();
const grandTotal = useAppSelector(selectGrandTotal);
const { restaurant } = useAppSelector((state) => state.order);
// const { isRTL } = useAppSelector((state) => state.locale);
const options: {
@@ -50,7 +51,7 @@ const PaymentMethods = () => {
</>
),
value: "cash",
price: formatPriceUi(grandTotal, 3),
price: formatPriceUi(grandTotal, restaurant.currency_decimals ?? 3),
style: {
color: colors.primary,
},

View File

@@ -771,23 +771,21 @@ export const {
// Tax calculation helper functions
const calculateTaxAmount = (
state: RootState,
amount: number,
tax: Tax,
): number => {
const percentage = parseFloat(tax.percentage);
return (((state.order.restaurant?.vat || 0) + percentage) * amount) / 100;
return (percentage * amount) / 100;
};
const calculateTotalTax = (
state: RootState,
subtotal: number,
taxes: Tax[],
): number => {
return taxes
.filter((tax) => tax.is_active === 1)
.reduce(
(total, tax) => total + calculateTaxAmount(state, subtotal, tax),
(total, tax) => total + calculateTaxAmount(subtotal, tax),
0,
);
};
@@ -838,7 +836,7 @@ export const selectHighestPricedLoyaltyItem = (state: RootState) => {
export const selectDiscountTotal = (state: RootState) =>
(state.order.discount.value / 100) * selectCartTotal(state) +
(state.order.useLoyaltyPoints &&
state.order.restaurant?.is_loyalty_enabled === 1
state.order.restaurant?.is_loyalty_enabled === 1
? selectHighestPricedLoyaltyItem(state)?.price || 0
: 0);
@@ -861,25 +859,29 @@ export const selectTaxes = (state: RootState) => state.order.restaurant.taxes;
export const selectTaxAmount = (state: RootState) => {
const subtotal = selectCartTotal(state) - selectDiscountTotal(state);
const taxes = selectTaxes(state);
return calculateTotalTax(state, subtotal, taxes || []);
return calculateTotalTax(subtotal, taxes || []);
};
export const selectGrandTotal = (state: RootState) => {
const totalDiscount = selectDiscountTotal(state);
const taxAmount = selectTaxAmount(state);
const vatAmount = ((state.order.restaurant?.vat || 0) / 100) * (selectCartTotal(state) - selectDiscountTotal(state));
const subtotal = selectCartTotal(state);
const deliveryFee =
state.order.orderType === OrderType.Delivery
? Number(state.order.restaurant?.delivery_fees) || 0
: 0;
console.log(subtotal, totalDiscount, taxAmount, deliveryFee);
return (
subtotal +
taxAmount -
subtotal -
totalDiscount +
deliveryFee -
state.order.splitBillAmount +
Number(state.order.tip)
taxAmount +
vatAmount -
deliveryFee
// state.order.splitBillAmount +
// Number(state.order.tip)
);
};

View File

@@ -13,13 +13,14 @@ import "react-phone-input-2/lib/style.css";
import { useNavigate, useParams } from "react-router-dom";
import { useSendOtpMutation } from "redux/api/auth";
import { useGetRestaurantDetailsQuery } from "redux/api/others";
import { useAppSelector } from "redux/hooks";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import { colors, DisabledColor, ProGray1 } from "ThemeConstants";
import { default_image } from "utils/constants";
import styles from "./login.module.css";
import { Layout } from "antd";
import ProHeader from "components/ProHeader/ProHeader";
import useBreakPoint from "hooks/useBreakPoint";
import { updateCustomerName } from "features/order/orderSlice";
export default function LoginPage() {
const { t } = useTranslation();
@@ -32,7 +33,7 @@ export default function LoginPage() {
skip: !subdomain,
});
const { isTablet } = useBreakPoint();
const dispatch = useAppDispatch();
// const [phone, setPhone] = useState<string>("");
const [selectedDate, setSelectedDate] = useState<string>("");
const [isOpen, setIsOpen] = useState(false);
@@ -113,6 +114,10 @@ export default function LoginPage() {
height: 50,
fontSize: 14,
}}
onBlur={(e) => {
dispatch(updateCustomerName(e.target.value));
}}
disabled={isLoading}
/>
</Form.Item>

View File

@@ -37,13 +37,14 @@ import NewRateIcon from "components/Icons/order/NewRateIcon";
import NoteIcon from "components/Icons/NoteIcon";
import SuccessIcon from "components/Icons/SuccessIcon";
import { SplitBillParticipantsBottomSheet } from "./components/SplitBillParticipantsBottomSheet";
import { OrderType } from "pages/checkout/hooks/types";
export default function OrderPage() {
const { t } = useTranslation();
const { orderId } = useParams();
const navigate = useNavigate();
const { isRTL } = useAppSelector((state) => state.locale);
const { restaurant } = useAppSelector((state) => state.order);
const { restaurant, orderType } = useAppSelector((state) => state.order);
const hasRefetchedRef = useRef(false);
const [isOpen, setIsOpen] = useState(false);
const [isRateOrderOpen, setIsRateOrderOpen] = useState(false);
@@ -429,7 +430,7 @@ export default function OrderPage() {
<Stepper statuses={orderDetails?.status} />
</div>
{!hasClosedStatus && (
{!hasClosedStatus && orderType === OrderType.DineIn && (
<div className={styles.orderNotes}>
<NoteIcon className={styles.noteIcon} />
<div
@@ -464,7 +465,7 @@ export default function OrderPage() {
</div>
</div>
)}
{hasClosedStatus && (
{hasClosedStatus && orderType === OrderType.DineIn && (
<div className={styles.orderNotesClosed}>
<SuccessIcon className={styles.noteIcon} />
<ProText

View File

@@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
import { Extra as ExtraType } from "utils/types/appTypes";
import styles from "../product.module.css";
import { formatPriceUi } from "utils/helpers";
import { useAppSelector } from "redux/hooks";
export default function Extra({
extrasList,
@@ -17,7 +18,7 @@ export default function Extra({
setSelectedExtras: Dispatch<SetStateAction<ExtraType[]>>;
}) {
const { t } = useTranslation();
const { restaurant } = useAppSelector((state) => state.order);
return (
<>
{extrasList.length > 0 && (
@@ -46,7 +47,7 @@ export default function Extra({
return {
value: value.id.toString(),
label: value.name,
price: `+${formatPriceUi(value.price, 3)}`,
price: `+${formatPriceUi(value.price, restaurant.currency_decimals ?? 3)}`,
};
})}
value={selectedExtras.map((ex) => ex.id.toString())}

View File

@@ -21,7 +21,7 @@ export default function Variants({
const { isRTL } = useAppSelector((state) => state.locale);
const { t } = useTranslation();
const { isDesktop } = useBreakPoint();
const { restaurant } = useAppSelector((state) => state.order);
// Determine variant levels based on options array length
const variantLevels = useMemo(() => {
if (!variantsList || variantsList.length === 0) return [];
@@ -170,7 +170,7 @@ export default function Variants({
value: value,
label: value,
price: variant
? `+${formatPriceUi(variant.price, 3)}`
? `+${formatPriceUi(variant.price, restaurant.currency_decimals ?? 3)}`
: "",
};
})}

View File

@@ -534,6 +534,7 @@ export interface RestaurantDetails {
closingTime: string;
isOpened: boolean;
isFav: boolean;
currency_decimals: number;
}
export interface Banner {