import React, { useState } from "react"; import { MovementStatusEnum, MovementTypeEnum } from "../../../types/mm"; import { FaSearch, FaPlus, FaEdit, FaTrash, FaBox, FaDownload, FaUpload, FaEye, FaArrowCircleDown, FaSave, FaTimes, FaInfoCircle, FaWarehouse, FaBarcode, FaCalculator, } from "react-icons/fa"; import { mockWarehouses } from "../../../mocks/mockWarehouses"; import { mockStockMovements } from "../../../mocks/mockStockMovements"; import { mockMaterials } from "../../../mocks/mockMaterials"; import { mockEmployees } from "../../../mocks/mockEmployees"; import Widget from "../../../components/common/Widget"; import { getMovementStatusColor, getMovementStatusText, getMovementStatusIcon, } from "../../../utils/erp"; const WarehouseReceipt: React.FC = () => { const [searchTerm, setSearchTerm] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const [selectedMovement, setSelectedMovement] = useState(""); const [showReceiptForm, setShowReceiptForm] = useState(false); const [editingMovement, setEditingMovement] = useState(null); // Form state - Header data for the entire movement const [headerData, setHeaderData] = useState({ movementNumber: "", referenceDocument: "", referenceType: "Purchase Order", reason: "", movementDate: new Date().toISOString().split("T")[0], performedBy: "", approvedBy: "", description: "", status: MovementStatusEnum.Planned, }); // Materials list for the movement const [materialsList, setMaterialsList] = useState([ { id: Date.now().toString(), materialId: "", warehouseId: "", zoneId: "", locationId: "", quantity: "", lotNumber: "", unitPrice: "", }, ]); const resetForm = () => { setHeaderData({ movementNumber: "", referenceDocument: "", referenceType: "Purchase Order", reason: "", movementDate: new Date().toISOString().split("T")[0], performedBy: "", approvedBy: "", description: "", status: MovementStatusEnum.Planned, }); setMaterialsList([ { id: Date.now().toString(), materialId: "", warehouseId: "", zoneId: "", locationId: "", quantity: "", lotNumber: "", unitPrice: "", }, ]); setEditingMovement(null); }; const handleHeaderInputChange = (field: string, value: string) => { setHeaderData((prev) => ({ ...prev, [field]: value, })); }; const handleMaterialInputChange = ( materialId: string, field: string, value: string ) => { setMaterialsList((prev) => prev.map((material) => material.id === materialId ? { ...material, [field]: value } : material ) ); }; const addMaterial = () => { const newMaterial = { id: Date.now().toString(), materialId: "", warehouseId: "", zoneId: "", locationId: "", quantity: "", lotNumber: "", unitPrice: "", }; setMaterialsList((prev) => [...prev, newMaterial]); }; const removeMaterial = (materialId: string) => { setMaterialsList((prev) => prev.filter((material) => material.id !== materialId) ); }; const handleSubmit = () => { // In a real application, this would submit to an API console.log("Submitting receipt form:", { headerData, materialsList }); setShowReceiptForm(false); resetForm(); // Here you would typically update the mock data or call an API }; const handleEdit = (movementId: string) => { // Find all movements with the same movement number const movement = mockStockMovements.find((m) => m.id === movementId); if (movement) { const movementsWithSameNumber = mockStockMovements.filter( (m) => m.movementNumber === movement.movementNumber ); // Set header data from the first movement setHeaderData({ movementNumber: movement.movementNumber, referenceDocument: movement.referenceDocument || "", referenceType: movement.referenceType || "Purchase Order", reason: movement.reason || "", movementDate: movement.movementDate.toISOString().split("T")[0], performedBy: movement.performedBy || "", approvedBy: movement.approvedBy || "", description: movement.description || "", status: movement.status || MovementStatusEnum.Planned, }); // Set materials list from all movements with the same number const materialsData = movementsWithSameNumber.map((m, index) => ({ id: (Date.now() + index).toString(), materialId: m.materialId, warehouseId: m.toWarehouseId || "", zoneId: m.toZoneId || "", locationId: m.toLocationId || "", quantity: m.quantity.toString(), lotNumber: m.lotNumber || "", unitPrice: (m.material?.costPrice || 0).toString(), })); setMaterialsList(materialsData); setEditingMovement(movementId); setShowReceiptForm(true); } }; const filteredMovements = mockStockMovements.filter((movement) => { const material = movement.material; const matchesSearch = movement.movementNumber .toLowerCase() .includes(searchTerm.toLowerCase()) || material?.name?.toLowerCase().includes(searchTerm.toLowerCase()) || material?.code?.toLowerCase().includes(searchTerm.toLowerCase()); const matchesStatus = statusFilter === "" || movement.status === statusFilter; const matchesType = movement.movementType === MovementTypeEnum.GoodsReceipt; return matchesSearch && matchesStatus && matchesType; }); const MovementDetailModal = () => { const movement = mockStockMovements.find((m) => m.id === selectedMovement); if (!selectedMovement || !movement) return null; // Aynı hareket numarasına sahip tüm malzemeleri bul const relatedMovements = mockStockMovements.filter( (m) => m.movementNumber === movement.movementNumber ); const StatusIcon = getMovementStatusIcon(movement.status!); return (
setSelectedMovement("")} />
{/* Modal Header */}

{movement.movementNumber} - Giriş Detayları

{relatedMovements.length} malzeme •{" "} {movement.movementDate.toLocaleDateString("tr-TR")}

{/* Modal Content */}
{/* Movement Summary */}

Hareket Özeti

{getMovementStatusText(movement.status!)}
Hareket No
{movement.movementNumber}
Tarih
{movement.movementDate.toLocaleDateString("tr-TR")}
Referans
{movement.referenceDocument || "-"}
İşlem Yapan
{movement.performedBy || "-"}
{movement.description && (
Açıklama
{movement.description}
)}
{/* Materials List */}

Giriş Yapılan Malzemeler ({relatedMovements.length})

{relatedMovements.map((mov, index) => { const warehouse = mockWarehouses.find( (w) => w.id === mov.toWarehouseId ); const zone = mockWarehouses .flatMap((w) => w.zones || []) .find((z) => z.id === mov.toZoneId); const location = mockWarehouses .flatMap((w) => w.locations || []) .find((l) => l.id === mov.toLocationId); return (
{/* Material Header */}
{index + 1}
{mov.material?.code} - {mov.material?.name}

{mov.material?.materialType?.name}

{mov.quantity} Adet
Birim Fiyat: ₺ {mov.material?.costPrice?.toFixed(2)}
{/* Material Details */}
{/* Warehouse Info */}
Depo Bilgileri
Depo:{" "} {warehouse?.name}
Bölge:{" "} {zone?.name || "-"}
Lokasyon: {" "} {location?.name || "-"}
{/* Stock Info */}
Stok Bilgileri
Lot No:{" "} {mov.lotNumber || "-"}
Miktar:{" "} {mov.quantity} Adet
Toplam Değer: {" "} ₺ {( (mov.material?.costPrice || 0) * mov.quantity ).toFixed(2)}
{/* Additional Info */}
Ek Bilgiler
Malzeme Grubu: {" "} {mov.material?.materialGroup?.name || "-"}
Referans Tipi: {" "} {mov.referenceType || "-"}
Sebep:{" "} {mov.reason || "-"}
); })}
{/* Modal Footer */}
{relatedMovements.length} malzeme
Toplam: ₺ {relatedMovements .reduce( (sum, mov) => sum + (mov.material?.costPrice || 0) * mov.quantity, 0 ) .toFixed(2)}
); }; return (

Stok Giriş

Depoya malzeme giriş hareketlerini yönetin

{/* Stats Cards */}
m.movementDate.toDateString() === new Date().toDateString() && m.status === MovementStatusEnum.Completed && m.movementType === MovementTypeEnum.GoodsReceipt ).length } color="blue" icon="FaArrowCircleDown" /> m.status === MovementStatusEnum.Planned && m.movementType === MovementTypeEnum.GoodsReceipt ).length } color="yellow" icon="FaClock" /> m.status === MovementStatusEnum.InProgress && m.movementType === MovementTypeEnum.GoodsReceipt ).length } color="blue" icon="FaBox" /> m.status === MovementStatusEnum.Completed && m.movementType === MovementTypeEnum.GoodsReceipt ).length } color="green" icon="FaCheckCircle" />
{/* Filters */}
setSearchTerm(e.target.value)} className="pl-10 pr-4 py-1.5 text-sm w-full border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Movements Table */}
{filteredMovements.map((movement) => { const StatusIcon = getMovementStatusIcon(movement.status!); return ( ); })}
Hareket No Malzeme Depo / Bölge / Lokasyon Miktar / Lot No Referans Tarih Durum İşlemler
{movement.movementNumber}
{movement.performedBy}
{movement.material?.name}
{movement.material?.code}
{movement.toWarehouse?.name || movement.toWarehouse?.code}
{movement.toZone?.name && `${movement.toZone.name}`} {movement.toLocation?.name && ` / ${movement.toLocation.name}`}
{movement.toLocation?.locationCode && (
Kod: {movement.toLocation.locationCode}
)}
{movement.quantity} {movement.unit?.code}
{movement.lotNumber && (
Lot: {movement.lotNumber}
)}
{movement.referenceDocument}
{movement.referenceType}
{movement.movementDate.toLocaleDateString("tr-TR")} {getMovementStatusText(movement.status!)}
{/* Movement Detail Modal */} {/* Receipt Form Modal */} {showReceiptForm && (
{ setShowReceiptForm(false); resetForm(); }} />

{editingMovement ? "Stok Giriş Düzenle" : "Yeni Stok Giriş"}

{/* Header Section - Compact and Responsive */}

Genel Bilgiler

{/* Movement Number */}
handleHeaderInputChange( "movementNumber", e.target.value ) } className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded focus:ring-1 focus:ring-blue-500 focus:border-transparent" placeholder="Otomatik" disabled={!!editingMovement} />
{/* Movement Date */}
handleHeaderInputChange( "movementDate", e.target.value ) } className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded focus:ring-1 focus:ring-blue-500 focus:border-transparent" required />
{/* Reference Document */}
handleHeaderInputChange( "referenceDocument", e.target.value ) } className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded focus:ring-1 focus:ring-blue-500 focus:border-transparent" placeholder="Belge no" />
{/* Reference Type */}
{/* Performed By */}
{/* Status */}
{/* Description - Full width */}