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

View File

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

View File

@@ -771,23 +771,21 @@ export const {
// Tax calculation helper functions // Tax calculation helper functions
const calculateTaxAmount = ( const calculateTaxAmount = (
state: RootState,
amount: number, amount: number,
tax: Tax, tax: Tax,
): number => { ): number => {
const percentage = parseFloat(tax.percentage); const percentage = parseFloat(tax.percentage);
return (((state.order.restaurant?.vat || 0) + percentage) * amount) / 100; return (percentage * amount) / 100;
}; };
const calculateTotalTax = ( const calculateTotalTax = (
state: RootState,
subtotal: number, subtotal: number,
taxes: Tax[], taxes: Tax[],
): number => { ): number => {
return taxes return taxes
.filter((tax) => tax.is_active === 1) .filter((tax) => tax.is_active === 1)
.reduce( .reduce(
(total, tax) => total + calculateTaxAmount(state, subtotal, tax), (total, tax) => total + calculateTaxAmount(subtotal, tax),
0, 0,
); );
}; };
@@ -861,25 +859,29 @@ export const selectTaxes = (state: RootState) => state.order.restaurant.taxes;
export const selectTaxAmount = (state: RootState) => { export const selectTaxAmount = (state: RootState) => {
const subtotal = selectCartTotal(state) - selectDiscountTotal(state); const subtotal = selectCartTotal(state) - selectDiscountTotal(state);
const taxes = selectTaxes(state); const taxes = selectTaxes(state);
return calculateTotalTax(state, subtotal, taxes || []); return calculateTotalTax(subtotal, taxes || []);
}; };
export const selectGrandTotal = (state: RootState) => { export const selectGrandTotal = (state: RootState) => {
const totalDiscount = selectDiscountTotal(state); const totalDiscount = selectDiscountTotal(state);
const taxAmount = selectTaxAmount(state); const taxAmount = selectTaxAmount(state);
const vatAmount = ((state.order.restaurant?.vat || 0) / 100) * (selectCartTotal(state) - selectDiscountTotal(state));
const subtotal = selectCartTotal(state); const subtotal = selectCartTotal(state);
const deliveryFee = const deliveryFee =
state.order.orderType === OrderType.Delivery state.order.orderType === OrderType.Delivery
? Number(state.order.restaurant?.delivery_fees) || 0 ? Number(state.order.restaurant?.delivery_fees) || 0
: 0; : 0;
console.log(subtotal, totalDiscount, taxAmount, deliveryFee);
return ( return (
subtotal + subtotal -
taxAmount -
totalDiscount + totalDiscount +
deliveryFee - taxAmount +
state.order.splitBillAmount + vatAmount -
Number(state.order.tip) 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 { useNavigate, useParams } from "react-router-dom";
import { useSendOtpMutation } from "redux/api/auth"; import { useSendOtpMutation } from "redux/api/auth";
import { useGetRestaurantDetailsQuery } from "redux/api/others"; import { useGetRestaurantDetailsQuery } from "redux/api/others";
import { useAppSelector } from "redux/hooks"; import { useAppDispatch, useAppSelector } from "redux/hooks";
import { colors, DisabledColor, ProGray1 } from "ThemeConstants"; import { colors, DisabledColor, ProGray1 } from "ThemeConstants";
import { default_image } from "utils/constants"; import { default_image } from "utils/constants";
import styles from "./login.module.css"; import styles from "./login.module.css";
import { Layout } from "antd"; import { Layout } from "antd";
import ProHeader from "components/ProHeader/ProHeader"; import ProHeader from "components/ProHeader/ProHeader";
import useBreakPoint from "hooks/useBreakPoint"; import useBreakPoint from "hooks/useBreakPoint";
import { updateCustomerName } from "features/order/orderSlice";
export default function LoginPage() { export default function LoginPage() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -32,7 +33,7 @@ export default function LoginPage() {
skip: !subdomain, skip: !subdomain,
}); });
const { isTablet } = useBreakPoint(); const { isTablet } = useBreakPoint();
const dispatch = useAppDispatch();
// const [phone, setPhone] = useState<string>(""); // const [phone, setPhone] = useState<string>("");
const [selectedDate, setSelectedDate] = useState<string>(""); const [selectedDate, setSelectedDate] = useState<string>("");
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@@ -113,6 +114,10 @@ export default function LoginPage() {
height: 50, height: 50,
fontSize: 14, fontSize: 14,
}} }}
onBlur={(e) => {
dispatch(updateCustomerName(e.target.value));
}}
disabled={isLoading}
/> />
</Form.Item> </Form.Item>

View File

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

View File

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

View File

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

View File

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