cala_server/graphql/
entry.rs

1use async_graphql::{dataloader::*, *};
2
3use cala_ledger::primitives::{AccountId, DebitOrCredit, Layer, TransactionId};
4
5use super::{
6    account::Account, convert::ToGlobalId, loader::LedgerDataLoader, primitives::*,
7    transaction::Transaction,
8};
9
10#[derive(Clone, SimpleObject)]
11#[graphql(complex)]
12pub struct Entry {
13    id: ID,
14    entry_id: UUID,
15    version: u32,
16    transaction_id: UUID,
17    journal_id: UUID,
18    account_id: UUID,
19    entry_type: String,
20    sequence: u32,
21    layer: Layer,
22    units: Decimal,
23    direction: DebitOrCredit,
24    description: Option<String>,
25    created_at: Timestamp,
26}
27
28#[ComplexObject]
29impl Entry {
30    async fn account(&self, ctx: &Context<'_>) -> async_graphql::Result<Account> {
31        let loader = ctx.data_unchecked::<DataLoader<LedgerDataLoader>>();
32        Ok(loader
33            .load_one(AccountId::from(self.account_id))
34            .await?
35            .expect("Account not found"))
36    }
37
38    async fn transaction(&self, ctx: &Context<'_>) -> async_graphql::Result<Transaction> {
39        let loader = ctx.data_unchecked::<DataLoader<LedgerDataLoader>>();
40        Ok(loader
41            .load_one(TransactionId::from(self.transaction_id))
42            .await?
43            .expect("transaction not found"))
44    }
45}
46
47impl ToGlobalId for cala_ledger::EntryId {
48    fn to_global_id(&self) -> async_graphql::types::ID {
49        use base64::{engine::general_purpose, Engine as _};
50        let id = format!(
51            "entry:{}",
52            general_purpose::STANDARD_NO_PAD.encode(self.to_string())
53        );
54        async_graphql::types::ID::from(id)
55    }
56}
57
58impl From<cala_ledger::entry::Entry> for Entry {
59    fn from(entity: cala_ledger::entry::Entry) -> Self {
60        let created_at = entity.created_at();
61        let values = entity.into_values();
62        Self {
63            id: values.id.to_global_id(),
64            entry_id: UUID::from(values.id),
65            version: values.version,
66            transaction_id: UUID::from(values.transaction_id),
67            account_id: UUID::from(values.account_id),
68            journal_id: UUID::from(values.journal_id),
69            entry_type: values.entry_type,
70            sequence: values.sequence,
71            layer: values.layer,
72            units: Decimal::from(values.units),
73            direction: values.direction,
74            description: values.description,
75            created_at: Timestamp::from(created_at),
76        }
77    }
78}