feat(ekstre): banka/kart ekstresi içe aktarma altyapısı (arşiv dönemleri, iade, öğrenen kurallar)
- Arşiv dönemi durumu: geçmiş aylar için; kapatılmaz, devir zincirinde atlanır, bütçe önerilerini besler - POST /bank-import/preview ve /commit: harcama / iade (eksi) / gelir (plan) / yoksay - Tekrar tespiti (import_key), açıklamadan öğrenen kategori kuralları, ödeme/virman ipuçları - Kapalı dönem ve gelecek tarih satır hatası; iade düzenlemede eksi kalır Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ export function PeriodHeading({ period, actions }: { period: Period; actions?: R
|
||||
<span
|
||||
className={cn(
|
||||
'rounded-full px-2.5 py-0.5 text-xs font-medium',
|
||||
period.status === 'closed' ? 'bg-muted text-muted-foreground' : 'bg-warning/15',
|
||||
period.status === 'correcting' ? 'bg-warning/15' : 'bg-muted text-muted-foreground',
|
||||
)}
|
||||
>
|
||||
{t.periods.status[period.status]}
|
||||
|
||||
@@ -52,8 +52,10 @@ export function ClosePeriodPage() {
|
||||
// Açık dönem ya da `?donem=` ile düzeltmedeki dönem (yeniden kapatma)
|
||||
<SelectedPeriod empty={empty}>
|
||||
{(p) =>
|
||||
p.status === 'closed' ? (
|
||||
<p className="text-muted-foreground">{s.alreadyClosed}</p>
|
||||
p.status === 'closed' || p.status === 'archived' ? (
|
||||
<p className="text-muted-foreground">
|
||||
{p.status === 'closed' ? s.alreadyClosed : s.archived}
|
||||
</p>
|
||||
) : (
|
||||
<Wizard key={p.id} period={p} onClosed={setResult} />
|
||||
)
|
||||
|
||||
@@ -20,6 +20,14 @@ const s = t.review
|
||||
*/
|
||||
export function ClosingSection({ period, periods }: { period: Period; periods: Period[] }) {
|
||||
if (period.status === 'closed') return <ClosedInfo period={period} periods={periods} />
|
||||
if (period.status === 'archived') {
|
||||
return (
|
||||
<section className="space-y-1 rounded-2xl border bg-card p-5">
|
||||
<h2 className="font-semibold">{s.archivedTitle}</h2>
|
||||
<p className="text-sm text-muted-foreground">{s.archivedHint}</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
const correcting = period.status === 'correcting'
|
||||
return (
|
||||
<section
|
||||
|
||||
@@ -348,6 +348,9 @@ export const t = {
|
||||
correctingHint:
|
||||
'Kayıtları ve planı düzelt, bitince yeniden kapat; sonraki döneme devir güncellenir.',
|
||||
recloseAction: '🔒 Yeniden Kapat',
|
||||
archivedTitle: 'Arşiv dönemi',
|
||||
archivedHint:
|
||||
'Ekstreden aktarılan geçmiş bir ay. Kayıtları düzeltebilirsin; kapatılmaz, devir üretmez ve bütçe önerilerinde (önceki dönem, son 3 ay) kullanılır.',
|
||||
fixInLedger: 'Defter’de düzelt',
|
||||
fixInPlan: 'Plan’da düzelt',
|
||||
},
|
||||
@@ -611,7 +614,12 @@ export const t = {
|
||||
|
||||
periods: {
|
||||
picker: 'Dönem',
|
||||
status: { open: 'Açık', closed: '🔒 Kapalı', correcting: '✏️ Düzeltmede' },
|
||||
status: {
|
||||
open: 'Açık',
|
||||
closed: '🔒 Kapalı',
|
||||
correcting: '✏️ Düzeltmede',
|
||||
archived: '🗄️ Arşiv',
|
||||
},
|
||||
notFound: 'Dönem bulunamadı. Listeden başka bir dönem seç.',
|
||||
history: 'Geçmiş dönemler',
|
||||
toSavings: (x: string) => `Birikime ${x}`,
|
||||
@@ -655,6 +663,7 @@ export const t = {
|
||||
toDashboard: 'Panele dön',
|
||||
noOpen: 'Kapatılacak açık dönem yok.',
|
||||
alreadyClosed: 'Bu dönem zaten kapalı.',
|
||||
archived: 'Arşiv dönemi kapatılmaz; yalnızca geçmiş kayıtları tutar.',
|
||||
addToSavings: (x: string) => `🐷 Birikime ekle (${x})`,
|
||||
addToSavingsHint:
|
||||
'Onaylarsan bu tutar Birikimler’de, dönemin son günü tarihli Türk Lirası alımı olarak görünür.',
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type BankArchive = { name: string, start_date: string,
|
||||
/**
|
||||
* Son gün, dahil
|
||||
*/
|
||||
last_date: string, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BankRowIn } from "./BankRowIn";
|
||||
|
||||
export type BankCommitRequest = {
|
||||
/**
|
||||
* Kayıtlara yazılacak ödeme türü (ör. Kredi Kartı)
|
||||
*/
|
||||
payment_method_id?: string, rows: Array<BankRowIn>, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BankRowError } from "./BankRowError";
|
||||
|
||||
export type BankImportReport = { entries: number, refunds: number, incomes: number, ignored: number, duplicates: number,
|
||||
/**
|
||||
* Açılan arşiv dönemleri
|
||||
*/
|
||||
archives: Array<string>, errors: Array<BankRowError>, };
|
||||
@@ -0,0 +1,9 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BankArchive } from "./BankArchive";
|
||||
import type { BankPreviewRow } from "./BankPreviewRow";
|
||||
|
||||
export type BankPreview = { rows: Array<BankPreviewRow>,
|
||||
/**
|
||||
* Açılacak arşiv dönemleri
|
||||
*/
|
||||
archives: Array<BankArchive>, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BankRowIn } from "./BankRowIn";
|
||||
|
||||
export type BankPreviewRequest = { source: "card" | "account", rows: Array<BankRowIn>, };
|
||||
@@ -0,0 +1,23 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type BankPreviewRow = { kind: "expense" | "refund" | "income" | "ignore", category_id: string | null,
|
||||
/**
|
||||
* Öneri hanenin öğrendiği kuraldan
|
||||
*/
|
||||
from_rule: boolean,
|
||||
/**
|
||||
* Daha önce aktarılmış (atlanacak)
|
||||
*/
|
||||
duplicate: boolean,
|
||||
/**
|
||||
* `existing` · `archive` · `blocked`
|
||||
*/
|
||||
period: "existing" | "archive" | "blocked",
|
||||
/**
|
||||
* Dönem adı (var olan ya da açılacak arşiv)
|
||||
*/
|
||||
period_name: string | null,
|
||||
/**
|
||||
* Engel nedeni
|
||||
*/
|
||||
message: string | null, };
|
||||
@@ -0,0 +1,7 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type BankRowError = {
|
||||
/**
|
||||
* Satır sırası (0'dan)
|
||||
*/
|
||||
index: number, message: string, };
|
||||
@@ -0,0 +1,15 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type BankRowIn = {
|
||||
/**
|
||||
* `"YYYY-MM-DD"`
|
||||
*/
|
||||
date: string, description: string,
|
||||
/**
|
||||
* Kuruş, > 0
|
||||
*/
|
||||
amount: number, direction: "in" | "out",
|
||||
/**
|
||||
* Yalnızca aktarmada (kullanıcının seçimi)
|
||||
*/
|
||||
kind?: "expense" | "refund" | "income" | "ignore", category_id?: string, };
|
||||
@@ -1,3 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PeriodStatus = "open" | "closed" | "correcting";
|
||||
export type PeriodStatus = "open" | "closed" | "correcting" | "archived";
|
||||
|
||||
Reference in New Issue
Block a user