import React, { useState } from "react"; import { FaCheckCircle, FaClock, FaExclamationTriangle, FaCalendar, } from "react-icons/fa"; import { RecommendationTypeEnum, RecommendationStatusEnum, MrpPurchaseSuggestion, } from "../../../types/mrp"; import DataTable, { Column } from "../../../components/common/DataTable"; import { mockBusinessParties } from "../../../mocks/mockBusinessParties"; import { PriorityEnum } from "../../../types/common"; import { getPriorityColor, getPriorityText, getRecommendationStatusColor, getRecommendationStatusText, } from "../../../utils/erp"; interface PurchaseSuggestionsProps { purchaseSuggestions: MrpPurchaseSuggestion[]; } const PurchaseSuggestions: React.FC = ({ purchaseSuggestions, }) => { const [searchTerm, setSearchTerm] = useState(""); const [selectedStatus, setSelectedStatus] = useState< RecommendationStatusEnum | "all" >("all"); const [selectedPriority, setSelectedPriority] = useState< PriorityEnum | "all" >("all"); const [sortBy, setSortBy] = useState< "date" | "cost" | "priority" | "leadTime" >("date"); // Event handlers const handleCreatePurchaseRequest = (suggestion: MrpPurchaseSuggestion) => { console.log("Create purchase request:", suggestion); }; const handleApprove = (id: string) => { console.log("Approve suggestion:", id); }; const handleReject = (id: string) => { console.log("Reject suggestion:", id); }; const handleViewDetails = (suggestion: MrpPurchaseSuggestion) => { console.log("View suggestion details:", suggestion); }; const filteredSuggestions = purchaseSuggestions .filter((suggestion) => { if ( searchTerm && !suggestion.material?.name ?.toLowerCase() .includes(searchTerm.toLowerCase()) && !suggestion.recommendedAction .toLowerCase() .includes(searchTerm.toLowerCase()) ) { return false; } if (selectedStatus !== "all" && suggestion.status !== selectedStatus) { return false; } if ( selectedPriority !== "all" && suggestion.priority !== selectedPriority ) { return false; } return ( suggestion.recommendationType === RecommendationTypeEnum.PurchaseRequisition ); }) .sort((a, b) => { switch (sortBy) { case "date": return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime(); case "cost": return b.estimatedCost - a.estimatedCost; case "priority": { const priorityOrder = { URGENT: 4, HIGH: 3, NORMAL: 2, LOW: 1 }; return ( (priorityOrder[b.priority as keyof typeof priorityOrder] || 0) - (priorityOrder[a.priority as keyof typeof priorityOrder] || 0) ); } case "leadTime": return a.leadTime - b.leadTime; default: return 0; } }); const getUrgencyLevel = (suggestion: MrpPurchaseSuggestion) => { const today = new Date(); const dueDate = new Date(suggestion.dueDate); const leadTimeDate = new Date( today.getTime() + suggestion.leadTime * 24 * 60 * 60 * 1000 ); if (leadTimeDate > dueDate) { return { level: "critical", color: "bg-red-100 text-red-800", label: "Kritik", icon: FaExclamationTriangle, }; } const daysUntilDue = Math.ceil( (dueDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24) ); if (daysUntilDue <= 7) return { level: "urgent", color: "bg-orange-100 text-orange-800", label: "Acil", icon: FaClock, }; if (daysUntilDue <= 30) return { level: "soon", color: "bg-yellow-100 text-yellow-800", label: "Yakın", icon: FaCalendar, }; return { level: "normal", color: "bg-green-100 text-green-800", label: "Normal", icon: FaCheckCircle, }; }; const columns: Column[] = [ { key: "material", header: "Malzeme", sortable: true, render: (suggestion: MrpPurchaseSuggestion) => (
{suggestion.material?.name || `Material-${suggestion.materialId.substring(0, 8)}`}
{suggestion.material?.code}
), }, { key: "urgency", header: "Aciliyet", render: (suggestion: MrpPurchaseSuggestion) => { const urgency = getUrgencyLevel(suggestion); const IconComponent = urgency.icon; return (
{urgency.label}
); }, }, { key: "quantities", header: "Miktarlar", render: (suggestion: MrpPurchaseSuggestion) => (
İhtiyaç: {suggestion.quantity.toLocaleString()}
Önerilen: {suggestion.suggestedQuantity.toLocaleString()}
EOQ: {suggestion.economicOrderQuantity.toLocaleString()}
{suggestion.minimumOrderQuantity > 0 && (
Min: {suggestion.minimumOrderQuantity.toLocaleString()}
)}
), }, { key: "supplier", header: "Tedarikçi", render: (suggestion: MrpPurchaseSuggestion) => (
{suggestion.supplier ? (
{ mockBusinessParties.find( (a) => a.id === suggestion.supplier?.supplierId )?.name }
) : ( Tedarikçi seçilmedi )}
), }, { key: "cost", header: "Maliyet", render: (suggestion: MrpPurchaseSuggestion) => (
₺{suggestion.estimatedCost.toLocaleString()}
{suggestion.supplier && (
Birim: ₺{suggestion.supplier.price.toLocaleString()}
)}
), }, { key: "dates", header: "Tarihler", render: (suggestion: MrpPurchaseSuggestion) => (
Vade: {new Date(suggestion.dueDate).toLocaleDateString("tr-TR")}
Teslimat: {suggestion.leadTime} gün
), }, { key: "priority", header: "Öncelik", render: (suggestion: MrpPurchaseSuggestion) => ( {getPriorityText(suggestion.priority)} ), }, { key: "status", header: "Durum", render: (suggestion: MrpPurchaseSuggestion) => ( {getRecommendationStatusText(suggestion.status)} ), }, { key: "actions", header: "İşlemler", render: (suggestion: MrpPurchaseSuggestion) => (
{suggestion.status === RecommendationStatusEnum.Open && ( <> )}
), }, ]; // Urgency distribution const urgencyDistribution = [ { level: "critical", count: 0, cost: 0 }, { level: "urgent", count: 0, cost: 0 }, { level: "soon", count: 0, cost: 0 }, { level: "normal", count: 0, cost: 0 }, ]; purchaseSuggestions .filter((s) => s.status === RecommendationStatusEnum.Open) .forEach((s) => { const urgency = getUrgencyLevel(s); const index = urgencyDistribution.findIndex( (u) => u.level === urgency.level ); if (index >= 0) { urgencyDistribution[index].count++; urgencyDistribution[index].cost += s.estimatedCost; } }); return ( <> {/* Filters */}
setSearchTerm(e.target.value)} className="w-full px-2 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
{/* Data Table */}
); }; export default PurchaseSuggestions;