Container Modal problemleri
This commit is contained in:
parent
811a575ff7
commit
57796d1177
4 changed files with 635 additions and 710 deletions
|
|
@ -82,7 +82,7 @@ define(['./workbox-a959eb95'], (function (workbox) { 'use strict';
|
|||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "/index.html",
|
||||
"revision": "0.daul0044rt"
|
||||
"revision": "0.hml46tc2c78"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import CheckNoteDetails from './CheckNoteDetails'
|
|||
import CollectionDialog from './CollectionDialog'
|
||||
import EndorsementDialog from './EndorsementDialog'
|
||||
import Widget from '../../../components/common/Widget'
|
||||
import { Container } from '@/components/shared'
|
||||
|
||||
interface CheckNoteManagementProps {
|
||||
checks: FiCheck[]
|
||||
|
|
@ -662,6 +663,7 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
|
|||
})
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div className="space-y-2">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
|
|
@ -749,45 +751,6 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Modal Components */}
|
||||
<CheckForm
|
||||
check={editingCheck || undefined}
|
||||
currentAccounts={currentAccounts}
|
||||
onSave={handleSaveCheck}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showCheckForm}
|
||||
/>
|
||||
|
||||
<PromissoryNoteForm
|
||||
note={editingNote || undefined}
|
||||
currentAccounts={currentAccounts}
|
||||
onSave={handleSaveNote}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showNoteForm}
|
||||
/>
|
||||
|
||||
{selectedItem && (
|
||||
<CheckNoteDetails item={selectedItem} onClose={handleCloseDialogs} isOpen={showDetails} />
|
||||
)}
|
||||
|
||||
{selectedItem && (
|
||||
<CollectionDialog
|
||||
item={selectedItem}
|
||||
onConfirm={handleConfirmCollection}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showCollectionDialog}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedItem && (
|
||||
<EndorsementDialog
|
||||
item={selectedItem}
|
||||
onConfirm={handleConfirmEndorsement}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showEndorsementDialog}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="border-b border-gray-200">
|
||||
<nav className="-mb-px flex space-x-6">
|
||||
|
|
@ -833,7 +796,9 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
|
|||
|
||||
<select
|
||||
value={selectedType}
|
||||
onChange={(e) => setSelectedType(e.target.value as CheckTypeEnum | NoteTypeEnum | 'all')}
|
||||
onChange={(e) =>
|
||||
setSelectedType(e.target.value as CheckTypeEnum | NoteTypeEnum | 'all')
|
||||
}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="all">Tüm Türler</option>
|
||||
|
|
@ -909,6 +874,46 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Modal Components */}
|
||||
<CheckForm
|
||||
check={editingCheck || undefined}
|
||||
currentAccounts={currentAccounts}
|
||||
onSave={handleSaveCheck}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showCheckForm}
|
||||
/>
|
||||
|
||||
<PromissoryNoteForm
|
||||
note={editingNote || undefined}
|
||||
currentAccounts={currentAccounts}
|
||||
onSave={handleSaveNote}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showNoteForm}
|
||||
/>
|
||||
|
||||
{selectedItem && (
|
||||
<CheckNoteDetails item={selectedItem} onClose={handleCloseDialogs} isOpen={showDetails} />
|
||||
)}
|
||||
|
||||
{selectedItem && (
|
||||
<CollectionDialog
|
||||
item={selectedItem}
|
||||
onConfirm={handleConfirmCollection}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showCollectionDialog}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedItem && (
|
||||
<EndorsementDialog
|
||||
item={selectedItem}
|
||||
onConfirm={handleConfirmEndorsement}
|
||||
onCancel={handleCloseDialogs}
|
||||
isOpen={showEndorsementDialog}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,17 @@
|
|||
import React, { useState } from "react";
|
||||
import {
|
||||
FaUsers,
|
||||
FaPlus,
|
||||
FaSearch,
|
||||
FaEdit,
|
||||
FaEye,
|
||||
FaReceipt,
|
||||
} from "react-icons/fa";
|
||||
import React, { useState } from 'react'
|
||||
import { FaUsers, FaPlus, FaSearch, FaEdit, FaEye, FaReceipt } from 'react-icons/fa'
|
||||
import {
|
||||
FiCurrentAccount,
|
||||
AccountTypeEnum,
|
||||
RiskGroupEnum,
|
||||
FiCurrentAccountMovement,
|
||||
FiDocumentTypeEnum,
|
||||
} from "../../../types/fi";
|
||||
import DataTable, { Column } from "../../../components/common/DataTable";
|
||||
import CurrentAccountForm from "./CurrentAccountForm";
|
||||
import CurrentAccountDetails from "./CurrentAccountDetails";
|
||||
import CurrentAccountMovementForm from "./CurrentAccountMovementForm";
|
||||
import Widget from "../../../components/common/Widget";
|
||||
} from '../../../types/fi'
|
||||
import DataTable, { Column } from '../../../components/common/DataTable'
|
||||
import CurrentAccountForm from './CurrentAccountForm'
|
||||
import CurrentAccountDetails from './CurrentAccountDetails'
|
||||
import CurrentAccountMovementForm from './CurrentAccountMovementForm'
|
||||
import Widget from '../../../components/common/Widget'
|
||||
import {
|
||||
getAccountTypeColor,
|
||||
getAccountTypeText,
|
||||
|
|
@ -26,183 +19,155 @@ import {
|
|||
getFiDocumentTypeText,
|
||||
getRiskGroupColor,
|
||||
getRiskGroupText,
|
||||
} from "../../../utils/erp";
|
||||
} from '../../../utils/erp'
|
||||
import { Container } from '@/components/shared'
|
||||
|
||||
interface CurrentAccountManagementProps {
|
||||
accounts: FiCurrentAccount[];
|
||||
accountMovements: FiCurrentAccountMovement[];
|
||||
accounts: FiCurrentAccount[]
|
||||
accountMovements: FiCurrentAccountMovement[]
|
||||
}
|
||||
|
||||
const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
||||
accounts,
|
||||
accountMovements,
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState<"accounts" | "movements">(
|
||||
"accounts"
|
||||
);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [selectedType, setSelectedType] = useState<AccountTypeEnum | "all">(
|
||||
"all"
|
||||
);
|
||||
const [selectedRiskGroup, setSelectedRiskGroup] = useState<
|
||||
RiskGroupEnum | "all"
|
||||
>("all");
|
||||
const [sortBy, setSortBy] = useState<"title" | "balance" | "lastTransaction">(
|
||||
"title"
|
||||
);
|
||||
const [selectedAccount, setSelectedAccount] =
|
||||
useState<FiCurrentAccount | null>(null);
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
const [showDetails, setShowDetails] = useState(false);
|
||||
const [editingAccount, setEditingAccount] = useState<FiCurrentAccount | null>(
|
||||
null
|
||||
);
|
||||
const [activeTab, setActiveTab] = useState<'accounts' | 'movements'>('accounts')
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [selectedType, setSelectedType] = useState<AccountTypeEnum | 'all'>('all')
|
||||
const [selectedRiskGroup, setSelectedRiskGroup] = useState<RiskGroupEnum | 'all'>('all')
|
||||
const [sortBy, setSortBy] = useState<'title' | 'balance' | 'lastTransaction'>('title')
|
||||
const [selectedAccount, setSelectedAccount] = useState<FiCurrentAccount | null>(null)
|
||||
const [showForm, setShowForm] = useState(false)
|
||||
const [showDetails, setShowDetails] = useState(false)
|
||||
const [editingAccount, setEditingAccount] = useState<FiCurrentAccount | null>(null)
|
||||
|
||||
// Movement form states
|
||||
const [showMovementForm, setShowMovementForm] = useState(false);
|
||||
const [editingMovement, setEditingMovement] =
|
||||
useState<FiCurrentAccountMovement | null>(null);
|
||||
const [showMovementForm, setShowMovementForm] = useState(false)
|
||||
const [editingMovement, setEditingMovement] = useState<FiCurrentAccountMovement | null>(null)
|
||||
|
||||
// Movement filters
|
||||
const [movementSearchTerm, setMovementSearchTerm] = useState("");
|
||||
const [selectedDocumentType, setSelectedDocumentType] = useState<
|
||||
FiDocumentTypeEnum | "all"
|
||||
>("all");
|
||||
const [movementSortBy, setMovementSortBy] = useState<"date" | "amount">(
|
||||
"date"
|
||||
);
|
||||
const [movementSearchTerm, setMovementSearchTerm] = useState('')
|
||||
const [selectedDocumentType, setSelectedDocumentType] = useState<FiDocumentTypeEnum | 'all'>(
|
||||
'all',
|
||||
)
|
||||
const [movementSortBy, setMovementSortBy] = useState<'date' | 'amount'>('date')
|
||||
|
||||
// Handler functions
|
||||
const handleAdd = () => {
|
||||
setEditingAccount(null);
|
||||
setShowForm(true);
|
||||
};
|
||||
setEditingAccount(null)
|
||||
setShowForm(true)
|
||||
}
|
||||
|
||||
const handleEdit = (account: FiCurrentAccount) => {
|
||||
setEditingAccount(account);
|
||||
setShowForm(true);
|
||||
};
|
||||
setEditingAccount(account)
|
||||
setShowForm(true)
|
||||
}
|
||||
|
||||
const handleViewDetails = (account: FiCurrentAccount) => {
|
||||
setSelectedAccount(account);
|
||||
setShowDetails(true);
|
||||
};
|
||||
setSelectedAccount(account)
|
||||
setShowDetails(true)
|
||||
}
|
||||
|
||||
const handleViewMovements = (account: FiCurrentAccount) => {
|
||||
setSelectedAccount(account);
|
||||
setActiveTab("movements");
|
||||
};
|
||||
setSelectedAccount(account)
|
||||
setActiveTab('movements')
|
||||
}
|
||||
|
||||
const handleSaveAccount = (accountData: Partial<FiCurrentAccount>) => {
|
||||
// This would normally call the parent's save function
|
||||
console.log("Saving account:", accountData);
|
||||
setShowForm(false);
|
||||
setEditingAccount(null);
|
||||
};
|
||||
console.log('Saving account:', accountData)
|
||||
setShowForm(false)
|
||||
setEditingAccount(null)
|
||||
}
|
||||
|
||||
const handleCloseForm = () => {
|
||||
setShowForm(false);
|
||||
setEditingAccount(null);
|
||||
};
|
||||
setShowForm(false)
|
||||
setEditingAccount(null)
|
||||
}
|
||||
|
||||
const handleCloseDetails = () => {
|
||||
setShowDetails(false);
|
||||
setSelectedAccount(null);
|
||||
};
|
||||
setShowDetails(false)
|
||||
setSelectedAccount(null)
|
||||
}
|
||||
|
||||
const handleEditFromDetails = () => {
|
||||
if (selectedAccount) {
|
||||
setShowDetails(false);
|
||||
setEditingAccount(selectedAccount);
|
||||
setShowForm(true);
|
||||
setShowDetails(false)
|
||||
setEditingAccount(selectedAccount)
|
||||
setShowForm(true)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditMovement = (movement: FiCurrentAccountMovement) => {
|
||||
setEditingMovement(movement);
|
||||
setShowMovementForm(true);
|
||||
};
|
||||
setEditingMovement(movement)
|
||||
setShowMovementForm(true)
|
||||
}
|
||||
|
||||
const handleSaveMovement = (
|
||||
movementData: Partial<FiCurrentAccountMovement>
|
||||
) => {
|
||||
const handleSaveMovement = (movementData: Partial<FiCurrentAccountMovement>) => {
|
||||
// This would normally call the parent's save function
|
||||
console.log("Saving movement:", movementData);
|
||||
setShowMovementForm(false);
|
||||
setEditingMovement(null);
|
||||
};
|
||||
console.log('Saving movement:', movementData)
|
||||
setShowMovementForm(false)
|
||||
setEditingMovement(null)
|
||||
}
|
||||
|
||||
const handleCloseMovementForm = () => {
|
||||
setShowMovementForm(false);
|
||||
setEditingMovement(null);
|
||||
};
|
||||
setShowMovementForm(false)
|
||||
setEditingMovement(null)
|
||||
}
|
||||
|
||||
const handleAddMovement = () => {
|
||||
setEditingMovement(null);
|
||||
setShowMovementForm(true);
|
||||
};
|
||||
setEditingMovement(null)
|
||||
setShowMovementForm(true)
|
||||
}
|
||||
|
||||
// Filter movements
|
||||
const filteredMovements = accountMovements
|
||||
.filter((movement) => {
|
||||
if (selectedAccount && movement.accountId !== selectedAccount.id) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (
|
||||
movementSearchTerm &&
|
||||
!movement.description
|
||||
.toLowerCase()
|
||||
.includes(movementSearchTerm.toLowerCase()) &&
|
||||
!movement.referenceNumber
|
||||
?.toLowerCase()
|
||||
.includes(movementSearchTerm.toLowerCase())
|
||||
!movement.description.toLowerCase().includes(movementSearchTerm.toLowerCase()) &&
|
||||
!movement.referenceNumber?.toLowerCase().includes(movementSearchTerm.toLowerCase())
|
||||
) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (
|
||||
selectedDocumentType !== "all" &&
|
||||
movement.documentType !== selectedDocumentType
|
||||
) {
|
||||
return false;
|
||||
if (selectedDocumentType !== 'all' && movement.documentType !== selectedDocumentType) {
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
})
|
||||
.sort((a, b) => {
|
||||
switch (movementSortBy) {
|
||||
case "date":
|
||||
case 'date':
|
||||
return new Date(b.transactionDate).getTime() - new Date(a.transactionDate).getTime()
|
||||
case 'amount':
|
||||
return (
|
||||
new Date(b.transactionDate).getTime() -
|
||||
new Date(a.transactionDate).getTime()
|
||||
);
|
||||
case "amount":
|
||||
return (
|
||||
Math.abs(b.debitAmount || b.creditAmount) -
|
||||
Math.abs(a.debitAmount || a.creditAmount)
|
||||
);
|
||||
Math.abs(b.debitAmount || b.creditAmount) - Math.abs(a.debitAmount || a.creditAmount)
|
||||
)
|
||||
default:
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Movement columns
|
||||
const movementColumns: Column<FiCurrentAccountMovement>[] = [
|
||||
{
|
||||
key: "transactionDate",
|
||||
header: "Tarih",
|
||||
key: 'transactionDate',
|
||||
header: 'Tarih',
|
||||
sortable: true,
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<span className="text-sm">
|
||||
{movement.transactionDate.toLocaleDateString("tr-TR")}
|
||||
</span>
|
||||
<span className="text-sm">{movement.transactionDate.toLocaleDateString('tr-TR')}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "documentType",
|
||||
header: "Belge Türü",
|
||||
key: 'documentType',
|
||||
header: 'Belge Türü',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<span
|
||||
className={`px-2 py-1 text-xs font-medium rounded-full ${getFiDocumentTypeColor(
|
||||
movement.documentType
|
||||
movement.documentType,
|
||||
)}`}
|
||||
>
|
||||
{getFiDocumentTypeText(movement.documentType)}
|
||||
|
|
@ -210,34 +175,32 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "referenceNumber",
|
||||
header: "Belge No",
|
||||
key: 'referenceNumber',
|
||||
header: 'Belge No',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<span className="font-mono text-sm">
|
||||
{movement.referenceNumber || movement.documentNumber || "-"}
|
||||
{movement.referenceNumber || movement.documentNumber || '-'}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "description",
|
||||
header: "Açıklama",
|
||||
key: 'description',
|
||||
header: 'Açıklama',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<div className="max-w-xs">
|
||||
<div className="font-medium text-gray-900 truncate">
|
||||
{movement.description}
|
||||
</div>
|
||||
<div className="font-medium text-gray-900 truncate">{movement.description}</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "debitAmount",
|
||||
header: "Borç",
|
||||
key: 'debitAmount',
|
||||
header: 'Borç',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<div className="text-right">
|
||||
{movement.debitAmount > 0 ? (
|
||||
<span className="text-red-600 font-medium">
|
||||
{movement.debitAmount.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
{movement.debitAmount.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: movement.currency,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
|
|
@ -249,14 +212,14 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "creditAmount",
|
||||
header: "Alacak",
|
||||
key: 'creditAmount',
|
||||
header: 'Alacak',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<div className="text-right">
|
||||
{movement.creditAmount > 0 ? (
|
||||
<span className="text-green-600 font-medium">
|
||||
{movement.creditAmount.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
{movement.creditAmount.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: movement.currency,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
|
|
@ -268,33 +231,27 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "balance",
|
||||
header: "Bakiye",
|
||||
key: 'balance',
|
||||
header: 'Bakiye',
|
||||
render: (movement: FiCurrentAccountMovement) => {
|
||||
const isDebit = movement.balance > 0;
|
||||
const isDebit = movement.balance > 0
|
||||
return (
|
||||
<div className="text-right">
|
||||
<span
|
||||
className={`font-medium ${
|
||||
isDebit ? "text-red-600" : "text-green-600"
|
||||
}`}
|
||||
>
|
||||
{Math.abs(movement.balance).toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
<span className={`font-medium ${isDebit ? 'text-red-600' : 'text-green-600'}`}>
|
||||
{Math.abs(movement.balance).toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: movement.currency,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
</span>
|
||||
<div className="text-xs text-gray-500">
|
||||
{isDebit ? "Borçlu" : "Alacaklı"}
|
||||
<div className="text-xs text-gray-500">{isDebit ? 'Borçlu' : 'Alacaklı'}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "actions",
|
||||
header: "İşlemler",
|
||||
key: 'actions',
|
||||
header: 'İşlemler',
|
||||
render: (movement: FiCurrentAccountMovement) => (
|
||||
<div className="flex gap-1">
|
||||
<button
|
||||
|
|
@ -307,86 +264,72 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
const filteredAccounts = accounts
|
||||
.filter((account) => {
|
||||
if (
|
||||
searchTerm &&
|
||||
!account.businessParty?.name
|
||||
.toLowerCase()
|
||||
.includes(searchTerm.toLowerCase()) &&
|
||||
!account.businessParty?.name.toLowerCase().includes(searchTerm.toLowerCase()) &&
|
||||
!account.accountCode.toLowerCase().includes(searchTerm.toLowerCase()) &&
|
||||
!account.taxNumber?.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (selectedType !== "all" && account.type !== selectedType) {
|
||||
return false;
|
||||
if (selectedType !== 'all' && account.type !== selectedType) {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
selectedRiskGroup !== "all" &&
|
||||
account.riskGroup !== selectedRiskGroup
|
||||
) {
|
||||
return false;
|
||||
if (selectedRiskGroup !== 'all' && account.riskGroup !== selectedRiskGroup) {
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
})
|
||||
.sort((a, b) => {
|
||||
switch (sortBy) {
|
||||
case "title":
|
||||
return (
|
||||
a.businessParty?.name?.localeCompare(b.businessParty?.name || "") ||
|
||||
0
|
||||
);
|
||||
case "balance":
|
||||
return Math.abs(b.balance) - Math.abs(a.balance);
|
||||
case "lastTransaction": {
|
||||
const aDate = a.lastTransactionDate
|
||||
? new Date(a.lastTransactionDate).getTime()
|
||||
: 0;
|
||||
const bDate = b.lastTransactionDate
|
||||
? new Date(b.lastTransactionDate).getTime()
|
||||
: 0;
|
||||
return bDate - aDate;
|
||||
case 'title':
|
||||
return a.businessParty?.name?.localeCompare(b.businessParty?.name || '') || 0
|
||||
case 'balance':
|
||||
return Math.abs(b.balance) - Math.abs(a.balance)
|
||||
case 'lastTransaction': {
|
||||
const aDate = a.lastTransactionDate ? new Date(a.lastTransactionDate).getTime() : 0
|
||||
const bDate = b.lastTransactionDate ? new Date(b.lastTransactionDate).getTime() : 0
|
||||
return bDate - aDate
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const formatBalance = (balance: number) => {
|
||||
const isDebit = balance > 0;
|
||||
const absBalance = Math.abs(balance);
|
||||
const isDebit = balance > 0
|
||||
const absBalance = Math.abs(balance)
|
||||
return {
|
||||
amount: absBalance.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
currency: "TRY",
|
||||
amount: absBalance.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: 'TRY',
|
||||
minimumFractionDigits: 2,
|
||||
}),
|
||||
type: isDebit ? "Borçlu" : "Alacaklı",
|
||||
type: isDebit ? 'Borçlu' : 'Alacaklı',
|
||||
isDebit,
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const columns: Column<FiCurrentAccount>[] = [
|
||||
{
|
||||
key: "accountCode",
|
||||
header: "Hesap Kodu",
|
||||
key: 'accountCode',
|
||||
header: 'Hesap Kodu',
|
||||
sortable: true,
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<span className="font-mono text-sm">{account.accountCode}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "title",
|
||||
header: "Ünvan",
|
||||
key: 'title',
|
||||
header: 'Ünvan',
|
||||
sortable: true,
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<div>
|
||||
<div className="font-medium text-gray-900">
|
||||
{account.businessParty?.name}
|
||||
</div>
|
||||
<div className="font-medium text-gray-900">{account.businessParty?.name}</div>
|
||||
{account.contactPerson && (
|
||||
<div className="text-sm text-gray-500">{account.contactPerson}</div>
|
||||
)}
|
||||
|
|
@ -394,12 +337,12 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "type",
|
||||
header: "Tür",
|
||||
key: 'type',
|
||||
header: 'Tür',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<span
|
||||
className={`px-2 py-1 text-xs font-medium rounded-full ${getAccountTypeColor(
|
||||
account.type
|
||||
account.type,
|
||||
)}`}
|
||||
>
|
||||
{getAccountTypeText(account.type)}
|
||||
|
|
@ -407,34 +350,32 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "balance",
|
||||
header: "Bakiye",
|
||||
key: 'balance',
|
||||
header: 'Bakiye',
|
||||
sortable: true,
|
||||
render: (account: FiCurrentAccount) => {
|
||||
const balanceInfo = formatBalance(account.balance);
|
||||
const balanceInfo = formatBalance(account.balance)
|
||||
return (
|
||||
<div className="text-right">
|
||||
<div
|
||||
className={`font-medium ${
|
||||
balanceInfo.isDebit ? "text-red-600" : "text-green-600"
|
||||
}`}
|
||||
className={`font-medium ${balanceInfo.isDebit ? 'text-red-600' : 'text-green-600'}`}
|
||||
>
|
||||
{balanceInfo.amount}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">{balanceInfo.type}</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "creditLimit",
|
||||
header: "Kredi Limiti",
|
||||
key: 'creditLimit',
|
||||
header: 'Kredi Limiti',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<div className="text-right">
|
||||
<span className="text-sm text-gray-900">
|
||||
{account.creditLimit.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
currency: "TRY",
|
||||
{account.creditLimit.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: 'TRY',
|
||||
minimumFractionDigits: 0,
|
||||
})}
|
||||
</span>
|
||||
|
|
@ -442,12 +383,12 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "riskGroup",
|
||||
header: "Risk Grubu",
|
||||
key: 'riskGroup',
|
||||
header: 'Risk Grubu',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<span
|
||||
className={`px-2 py-1 text-xs font-medium rounded-full ${getRiskGroupColor(
|
||||
account.riskGroup
|
||||
account.riskGroup,
|
||||
)}`}
|
||||
>
|
||||
{getRiskGroupText(account.riskGroup)}
|
||||
|
|
@ -455,33 +396,29 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
),
|
||||
},
|
||||
{
|
||||
key: "contact",
|
||||
header: "İletişim",
|
||||
key: 'contact',
|
||||
header: 'İletişim',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<div className="text-sm">
|
||||
{account.phone && (
|
||||
<div className="text-gray-900">{account.phone}</div>
|
||||
)}
|
||||
{account.email && (
|
||||
<div className="text-gray-500">{account.email}</div>
|
||||
)}
|
||||
{account.phone && <div className="text-gray-900">{account.phone}</div>}
|
||||
{account.email && <div className="text-gray-500">{account.email}</div>}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "lastTransaction",
|
||||
header: "Son Hareket",
|
||||
key: 'lastTransaction',
|
||||
header: 'Son Hareket',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<div className="text-sm text-gray-500">
|
||||
{account.lastTransactionDate
|
||||
? new Date(account.lastTransactionDate).toLocaleDateString("tr-TR")
|
||||
: "Hareket yok"}
|
||||
? new Date(account.lastTransactionDate).toLocaleDateString('tr-TR')
|
||||
: 'Hareket yok'}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "actions",
|
||||
header: "İşlemler",
|
||||
key: 'actions',
|
||||
header: 'İşlemler',
|
||||
render: (account: FiCurrentAccount) => (
|
||||
<div className="flex gap-1">
|
||||
<button
|
||||
|
|
@ -509,37 +446,34 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
// Calculate statistics
|
||||
const totalAccounts = accounts.length;
|
||||
const activeAccounts = accounts.filter((a) => a.isActive).length;
|
||||
const totalAccounts = accounts.length
|
||||
const activeAccounts = accounts.filter((a) => a.isActive).length
|
||||
const totalDebitBalance = accounts
|
||||
.filter((a) => a.balance > 0)
|
||||
.reduce((sum, a) => sum + a.balance, 0);
|
||||
.reduce((sum, a) => sum + a.balance, 0)
|
||||
const totalCreditBalance = accounts
|
||||
.filter((a) => a.balance < 0)
|
||||
.reduce((sum, a) => sum + Math.abs(a.balance), 0);
|
||||
.reduce((sum, a) => sum + Math.abs(a.balance), 0)
|
||||
|
||||
// High risk accounts
|
||||
const highRiskAccounts = accounts.filter(
|
||||
(a) =>
|
||||
a.riskGroup === RiskGroupEnum.High ||
|
||||
a.riskGroup === RiskGroupEnum.Blocked ||
|
||||
Math.abs(a.balance) > a.creditLimit
|
||||
);
|
||||
Math.abs(a.balance) > a.creditLimit,
|
||||
)
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div className="space-y-2">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-gray-900">
|
||||
Cari Hesap Yönetimi
|
||||
</h2>
|
||||
<p className="text-gray-600">
|
||||
Müşteri ve tedarikçi cari hesaplarının yönetimi
|
||||
</p>
|
||||
<h2 className="text-2xl font-bold text-gray-900">Cari Hesap Yönetimi</h2>
|
||||
<p className="text-gray-600">Müşteri ve tedarikçi cari hesaplarının yönetimi</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleAdd}
|
||||
|
|
@ -561,9 +495,9 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
/>
|
||||
<Widget
|
||||
title="Toplam Borç"
|
||||
value={totalDebitBalance.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
currency: "TRY",
|
||||
value={totalDebitBalance.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: 'TRY',
|
||||
minimumFractionDigits: 0,
|
||||
})}
|
||||
color="red"
|
||||
|
|
@ -571,9 +505,9 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
/>
|
||||
<Widget
|
||||
title="Toplam Alacak"
|
||||
value={totalCreditBalance.toLocaleString("tr-TR", {
|
||||
style: "currency",
|
||||
currency: "TRY",
|
||||
value={totalCreditBalance.toLocaleString('tr-TR', {
|
||||
style: 'currency',
|
||||
currency: 'TRY',
|
||||
minimumFractionDigits: 0,
|
||||
})}
|
||||
color="green"
|
||||
|
|
@ -592,11 +526,11 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
<div className="border-b border-gray-200">
|
||||
<nav className="-mb-px flex space-x-6 px-4">
|
||||
<button
|
||||
onClick={() => setActiveTab("accounts")}
|
||||
onClick={() => setActiveTab('accounts')}
|
||||
className={`py-3 px-1 border-b-2 font-medium text-sm ${
|
||||
activeTab === "accounts"
|
||||
? "border-blue-500 text-blue-600"
|
||||
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||
activeTab === 'accounts'
|
||||
? 'border-blue-500 text-blue-600'
|
||||
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
@ -605,11 +539,11 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("movements")}
|
||||
onClick={() => setActiveTab('movements')}
|
||||
className={`py-3 px-1 border-b-2 font-medium text-sm ${
|
||||
activeTab === "movements"
|
||||
? "border-blue-500 text-blue-600"
|
||||
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||
activeTab === 'movements'
|
||||
? 'border-blue-500 text-blue-600'
|
||||
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
@ -621,7 +555,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
</div>
|
||||
|
||||
<div className="p-4">
|
||||
{activeTab === "accounts" && (
|
||||
{activeTab === 'accounts' && (
|
||||
<div className="space-y-4">
|
||||
{/* Filters */}
|
||||
<div className="flex gap-3 items-center">
|
||||
|
|
@ -638,9 +572,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
|
||||
<select
|
||||
value={selectedType}
|
||||
onChange={(e) =>
|
||||
setSelectedType(e.target.value as AccountTypeEnum | "all")
|
||||
}
|
||||
onChange={(e) => setSelectedType(e.target.value as AccountTypeEnum | 'all')}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="all">Tüm Türler</option>
|
||||
|
|
@ -653,11 +585,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
|
||||
<select
|
||||
value={selectedRiskGroup}
|
||||
onChange={(e) =>
|
||||
setSelectedRiskGroup(
|
||||
e.target.value as RiskGroupEnum | "all"
|
||||
)
|
||||
}
|
||||
onChange={(e) => setSelectedRiskGroup(e.target.value as RiskGroupEnum | 'all')}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="all">Tüm Risk Grupları</option>
|
||||
|
|
@ -671,9 +599,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
<select
|
||||
value={sortBy}
|
||||
onChange={(e) =>
|
||||
setSortBy(
|
||||
e.target.value as "title" | "balance" | "lastTransaction"
|
||||
)
|
||||
setSortBy(e.target.value as 'title' | 'balance' | 'lastTransaction')
|
||||
}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
|
|
@ -695,15 +621,14 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
Cari hesap bulunamadı
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
Yeni bir cari hesap ekleyin veya arama kriterlerinizi
|
||||
değiştirin.
|
||||
Yeni bir cari hesap ekleyin veya arama kriterlerinizi değiştirin.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "movements" && (
|
||||
{activeTab === 'movements' && (
|
||||
<div className="space-y-4">
|
||||
{/* Movement Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
|
|
@ -714,7 +639,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
<p className="text-gray-600 text-sm">
|
||||
{selectedAccount
|
||||
? `${selectedAccount.businessParty?.name} (${selectedAccount.accountCode}) hesabının hareketleri`
|
||||
: "Tüm cari hesap hareketleri"}
|
||||
: 'Tüm cari hesap hareketleri'}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
|
@ -751,9 +676,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
<select
|
||||
value={selectedDocumentType}
|
||||
onChange={(e) =>
|
||||
setSelectedDocumentType(
|
||||
e.target.value as FiDocumentTypeEnum | "all"
|
||||
)
|
||||
setSelectedDocumentType(e.target.value as FiDocumentTypeEnum | 'all')
|
||||
}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
|
|
@ -767,9 +690,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
|
||||
<select
|
||||
value={movementSortBy}
|
||||
onChange={(e) =>
|
||||
setMovementSortBy(e.target.value as "date" | "amount")
|
||||
}
|
||||
onChange={(e) => setMovementSortBy(e.target.value as 'date' | 'amount')}
|
||||
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="date">Tarihe Göre</option>
|
||||
|
|
@ -785,9 +706,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
{filteredMovements.length === 0 && (
|
||||
<div className="text-center py-10">
|
||||
<FaReceipt className="w-12 h-12 text-gray-400 mx-auto mb-4" />
|
||||
<h3 className="text-base font-medium text-gray-900 mb-2">
|
||||
Hareket bulunamadı
|
||||
</h3>
|
||||
<h3 className="text-base font-medium text-gray-900 mb-2">Hareket bulunamadı</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
Seçili kriterlere uygun hareket bulunmamaktadır.
|
||||
</p>
|
||||
|
|
@ -797,6 +716,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Forms and Modals */}
|
||||
{showForm && (
|
||||
|
|
@ -826,8 +746,8 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
|
|||
onSave={handleSaveMovement}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default CurrentAccountManagement;
|
||||
export default CurrentAccountManagement
|
||||
|
|
|
|||
|
|
@ -573,6 +573,7 @@ const ActivityRecords: React.FC = () => {
|
|||
<p className="text-gray-500">Arama kriterlerinizi değiştirmeyi deneyin.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Modals */}
|
||||
<ActivityForm
|
||||
|
|
@ -589,7 +590,6 @@ const ActivityRecords: React.FC = () => {
|
|||
onEdit={handleEditFromDetails}
|
||||
activity={selectedActivity}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue