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