import style from '../styles/price-action.module.css'; import Image from 'next/image'; import Link from 'next/link'; import { useEffect, useState } from 'react'; import formatCurrency from '~/libs/formatCurrency'; import { IProductDetail } from '~/types/product'; import { useProductDetail } from '../stores/useProductDetail'; import AddToCart from './AddToCart'; import AddToQuotation from './AddToQuotation'; import { getAuth } from '~/libs/auth'; import useDevice from '@/core/hooks/useDevice'; import odooApi from '~/libs/odooApi'; import { Button, Skeleton } from '@chakra-ui/react'; import DesktopView from '@/core/components/views/DesktopView'; import MobileView from '@/core/components/views/MobileView'; import { TicketIcon } from '@heroicons/react/24/solid'; type Props = { product: IProductDetail; }; const PPN: number = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; const PriceAction = ({ product }: Props) => { const { activePrice, setActive, activeVariantId, quantityInput, setQuantityInput, askAdminUrl, isApproval, setIsApproval, selectedVariant, sla, } = useProductDetail(); const [qtyPickUp, setQtyPickUp] = useState(0); const { isDesktop, isMobile } = useDevice(); useEffect(() => { setActive(selectedVariant); if (product.variants.length > 2 && product.variants[0].price.price === 0) { const variants = product.variants; for (let i = 0; i < variants.length; i++) { if (variants[i].price.price > 0) { setActive(variants[i]); break; } } } }, [product, setActive, selectedVariant]); useEffect(() => { const fetchData = async () => { const qty_available = await odooApi( 'GET', `/api/v1/product_variant/${selectedVariant.id}/qty_available` ); setQtyPickUp(qty_available?.qty); }; fetchData(); }, [selectedVariant]); useEffect(() => { setQuantityInput('1'); }, [selectedVariant]); const price = activePrice?.price_discount || activePrice?.price || 0; const pricedigit = String(Math.floor(price)).length; const fontSize = pricedigit >= 9 ? '20px' : undefined; // voucher hanya diterapkan kalau TIDAK ada discount_percentage (bukan flash/price rule) let voucherCut = 0; // apply voucher only when NOT a flash/price rule if (activePrice && !(activePrice.discount_percentage > 0)) { voucherCut = getVoucherCut(product, activePrice); } const basePriceForDisplay = Number(activePrice?.price_discount ?? 0) || Number(activePrice?.price ?? 0); const finalAfterVoucher = Math.max(basePriceForDisplay - voucherCut, 0); const hasVoucherApplied = voucherCut > 0 && !activePrice?.discount_percentage; // let voucherPastiHemat = 0; // if ( // product?.voucher_pasti_hemat // ? product?.voucher_pasti_hemat.length // : voucherPastiHemat > 0 // ) { // const stringVoucher = product?.voucher_pasti_hemat[0]; // const validJsonString = stringVoucher.replace(/'/g, '"'); // voucherPastiHemat = JSON.parse(validJsonString); // } // --- (1) helper: hitung potongan voucher berdasar product-level voucher + harga variant aktif function getVoucherCut( product: IProductDetail, activePrice?: { price?: number; price_discount?: number } ) { try { const raw = Array.isArray((product as any)?.new_voucher_pasti_hemat) ? (product as any).new_voucher_pasti_hemat[0] : (product as any)?.new_voucher_pasti_hemat; if (!raw) return 0; const discount_type = String( raw.discount_type ?? raw.discountType ?? '' ).toLowerCase(); const discount_amount = Number( raw.discount_amount ?? raw.discountAmount ?? 0 ); const max_discount = Number(raw.max_discount ?? raw.maxDiscount ?? 0); const min_purchase = Number(raw.min_purchase ?? raw.minPurchase ?? 0); // base price ambil price_discount dulu, kalau kosong pakai price const base = Number(activePrice?.price_discount ?? 0) || Number(activePrice?.price ?? 0); if (!base) return 0; if (min_purchase > 0 && base < min_purchase) return 0; let cut = 0; if (discount_type.startsWith('percent')) { // support nilai 0..1 atau 0..100 const pct = discount_amount <= 1 ? discount_amount * 100 : discount_amount; cut = Math.floor(base * (pct / 100)); } else { cut = Math.floor(discount_amount || 0); } if (max_discount > 0) cut = Math.min(cut, max_discount); return Math.max(0, cut); } catch { return 0; } } return (