feat(birikim): dönem kapanışındaki birikimi varlıklara ekleme
- Kapatma sonucunda onayla "Birikime ekle" (TL alımı, dönemin son günü) - Birikimler'de "Bekleyen birikimler" listesi - Yeniden kapatmada bağlı kayıt yeni tutara güncellenir (0 → silinir), TL çıkışları aşılırsa reddedilir - Panel "Toplam birikim" artık portföyün güncel değeri Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
//! | POST | `/api/assets/{id}/transactions` | alım / satım ekle |
|
||||
//! | PATCH | `/api/asset-transactions/{id}` | işlemi düzenle |
|
||||
//! | DELETE | `/api/asset-transactions/{id}` | işlemi sil (soft) |
|
||||
//! | GET | `/api/savings/pending` | kapanıp birikime henüz eklenmemiş dönemler |
|
||||
//! | POST | `/api/periods/{id}/to-savings` | dönemin birikimini TL varlığına alım olarak ekle |
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
@@ -292,3 +294,48 @@ pub async fn delete_tx(
|
||||
asset::delete_tx(&s.db, auth.household_id, path_id(&id)?).await?;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
#[derive(Serialize, TS)]
|
||||
#[ts(export, rename = "PendingSavings")]
|
||||
pub struct PendingDto {
|
||||
period_id: String,
|
||||
name: String,
|
||||
/// Dönemin son günü (eklenecek alımın tarihi)
|
||||
last_date: String,
|
||||
/// Kuruş
|
||||
#[ts(type = "number")]
|
||||
to_savings: i64,
|
||||
}
|
||||
|
||||
pub async fn pending(
|
||||
State(s): State<AppState>,
|
||||
auth: AuthUser,
|
||||
) -> AppResult<Json<Vec<PendingDto>>> {
|
||||
let list = asset::pending_period_savings(&s.db, auth.household_id).await?;
|
||||
Ok(Json(
|
||||
list.into_iter()
|
||||
.map(|p| {
|
||||
let end = crate::services::calendar::parse_date(&p.end_date)
|
||||
.expect("geçerli bitiş tarihi");
|
||||
PendingDto {
|
||||
period_id: p.id.to_string(),
|
||||
name: p.name,
|
||||
last_date: crate::services::calendar::format_date(
|
||||
end - time::Duration::days(1),
|
||||
),
|
||||
to_savings: p.to_savings.unwrap_or(0),
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn add_period_savings(
|
||||
State(s): State<AppState>,
|
||||
auth: AuthUser,
|
||||
Path(id): Path<String>,
|
||||
) -> AppResult<(StatusCode, Json<TxDto>)> {
|
||||
let t =
|
||||
asset::add_period_savings(&s.db, auth.household_id, auth.user_id, path_id(&id)?).await?;
|
||||
Ok((StatusCode::CREATED, Json(t.into())))
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ pub fn router(state: AppState) -> Router {
|
||||
.route("/entries/{id}/restore", post(entry::restore))
|
||||
.route("/assets", get(asset::list).post(asset::create))
|
||||
.route("/portfolio", get(rates::portfolio))
|
||||
.route("/savings/pending", get(asset::pending))
|
||||
.route("/periods/{id}/to-savings", post(asset::add_period_savings))
|
||||
.route("/rates", post(rates::create))
|
||||
.route("/rates/{id}", delete(rates::delete))
|
||||
.route("/assets/{id}", patch(asset::update))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
//! | PATCH | `/api/periods/{id}` | ad / tarihler / birikim hedefi / "Nasıl daha iyi…" |
|
||||
//! | POST | `/api/periods/{id}/close` | dönemi kapat: devir + birikime aktarılan (transaction) |
|
||||
//! | POST | `/api/periods/{id}/reopen` | **sahip:** kapalı dönemi düzeltmeye aç (`correcting`) |
|
||||
//! | POST | `/api/periods/{id}/to-savings` | kapanıştaki birikimi TL varlığına ekle (bkz. `routes/asset.rs`) |
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
@@ -223,6 +224,9 @@ pub struct CloseResultDto {
|
||||
to_savings: i64,
|
||||
/// Sonraki döneme devreden; yoksa `null`
|
||||
carryover: Option<CarryoverDto>,
|
||||
/// Birikimlerde bu döneme bağlı kayıt var (yeniden kapatmada yeni tutara güncellendi).
|
||||
/// `false` ve `to_savings > 0` → arayüz "Birikime ekle" önerir.
|
||||
savings_linked: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, TS)]
|
||||
@@ -256,6 +260,7 @@ pub async fn close(
|
||||
period: c.period.into(),
|
||||
realized_savings: c.realized_savings,
|
||||
to_savings: c.to_savings,
|
||||
savings_linked: c.savings_linked,
|
||||
carryover: c.carryover.map(|x| CarryoverDto {
|
||||
kind: x.kind.as_str(),
|
||||
amount: x.amount,
|
||||
|
||||
Reference in New Issue
Block a user