datasynth-core 2.2.0

Core domain models, traits, and distributions for synthetic enterprise data generation
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
//! Centralized GL account constants for consistent account mapping.
//!
//! This module provides standard account numbers used across all generators
//! to ensure consistency between document flow JE generation, subledger
//! generation, and reconciliation.

/// Goodwill and intangible asset accounts (used in business combinations).
pub mod intangible_accounts {
    /// Goodwill arising from business combinations
    pub const GOODWILL: &str = "1900";

    /// Customer relationships intangible asset
    pub const CUSTOMER_RELATIONSHIPS: &str = "1910";

    /// Trade name / brand intangible asset
    pub const TRADE_NAME: &str = "1920";

    /// Technology / developed software intangible asset
    pub const TECHNOLOGY: &str = "1930";

    /// Accumulated amortization – intangible assets
    pub const ACCUMULATED_AMORTIZATION: &str = "1950";

    /// Amortization expense – intangible assets
    pub const AMORTIZATION_EXPENSE: &str = "6010";

    /// Bargain purchase gain (when consideration < net identifiable assets FV)
    pub const BARGAIN_PURCHASE_GAIN: &str = "4850";
}

/// Control accounts for subledger integration.
pub mod control_accounts {
    /// Accounts Receivable control account
    pub const AR_CONTROL: &str = "1100";

    /// Accounts Payable control account
    pub const AP_CONTROL: &str = "2000";

    /// Inventory control account
    pub const INVENTORY: &str = "1200";

    /// Fixed Assets control account
    pub const FIXED_ASSETS: &str = "1500";

    /// Accumulated Depreciation control account
    pub const ACCUMULATED_DEPRECIATION: &str = "1510";

    /// GR/IR Clearing account (Goods Receipt/Invoice Receipt)
    pub const GR_IR_CLEARING: &str = "2900";

    /// Intercompany AR clearing
    pub const IC_AR_CLEARING: &str = "1150";

    /// Intercompany AP clearing
    pub const IC_AP_CLEARING: &str = "2050";
}

/// Cash and bank accounts.
pub mod cash_accounts {
    /// Primary operating cash account
    pub const OPERATING_CASH: &str = "1000";

    /// Primary bank account
    pub const BANK_ACCOUNT: &str = "1010";

    /// Petty cash account
    pub const PETTY_CASH: &str = "1020";

    /// Wire transfer clearing account
    pub const WIRE_CLEARING: &str = "1030";
}

/// Revenue accounts.
pub mod revenue_accounts {
    /// Product revenue account
    pub const PRODUCT_REVENUE: &str = "4000";

    /// Service revenue account
    pub const SERVICE_REVENUE: &str = "4100";

    /// Intercompany revenue account
    pub const IC_REVENUE: &str = "4500";

    /// Purchase discount income account
    pub const PURCHASE_DISCOUNT_INCOME: &str = "4800";

    /// Other revenue account
    pub const OTHER_REVENUE: &str = "4900";

    /// Sales discounts account
    pub const SALES_DISCOUNTS: &str = "4010";

    /// Sales returns and allowances account
    pub const SALES_RETURNS: &str = "4020";
}

/// Expense accounts.
pub mod expense_accounts {
    /// Cost of Goods Sold account
    pub const COGS: &str = "5000";

    /// Raw materials expense account
    pub const RAW_MATERIALS: &str = "5100";

    /// Direct labor expense account
    pub const DIRECT_LABOR: &str = "5200";

    /// Manufacturing overhead account
    pub const MANUFACTURING_OVERHEAD: &str = "5300";

    /// Depreciation expense account
    pub const DEPRECIATION: &str = "6000";

    /// Salaries and wages expense account
    pub const SALARIES_WAGES: &str = "6100";

    /// Benefits expense account
    pub const BENEFITS: &str = "6200";

    /// Rent expense account
    pub const RENT: &str = "6300";

    /// Utilities expense account
    pub const UTILITIES: &str = "6400";

    /// Office supplies expense account
    pub const OFFICE_SUPPLIES: &str = "6500";

    /// Travel and entertainment expense account
    pub const TRAVEL_ENTERTAINMENT: &str = "6600";

    /// Professional fees expense account
    pub const PROFESSIONAL_FEES: &str = "6700";

    /// Insurance expense account
    pub const INSURANCE: &str = "6800";

    /// Bad debt expense account
    pub const BAD_DEBT: &str = "6900";

    /// Interest expense account
    pub const INTEREST_EXPENSE: &str = "7100";

    /// Purchase discounts account
    pub const PURCHASE_DISCOUNTS: &str = "7400";

    /// FX gain/loss account
    pub const FX_GAIN_LOSS: &str = "7500";
}

/// Manufacturing cost flow accounts.
pub mod manufacturing_accounts {
    /// Work-in-Process control account
    pub const WIP: &str = "1420";

    /// Finished Goods inventory account
    pub const FINISHED_GOODS: &str = "1410";

    /// Scrap expense account
    pub const SCRAP_EXPENSE: &str = "5210";

    /// Labor accrual liability account
    pub const LABOR_ACCRUAL: &str = "2150";

    /// Overhead applied clearing account
    pub const OVERHEAD_APPLIED: &str = "5310";

    /// Material price variance account
    pub const MATERIAL_PRICE_VARIANCE: &str = "5110";

    /// Material usage variance account
    pub const MATERIAL_USAGE_VARIANCE: &str = "5120";

    /// Labor rate variance account
    pub const LABOR_RATE_VARIANCE: &str = "5130";

    /// Labor efficiency variance account
    pub const LABOR_EFFICIENCY_VARIANCE: &str = "5140";

    /// Overhead volume variance account
    pub const OVERHEAD_VOLUME_VARIANCE: &str = "5150";

    /// Warranty provision liability account
    pub const WARRANTY_PROVISION: &str = "2410";

    /// Warranty expense account
    pub const WARRANTY_EXPENSE: &str = "5400";
}

/// Treasury accounting accounts for debt, hedging, and derivatives.
pub mod treasury_accounts {
    /// Interest payable (accrued interest on debt)
    pub const INTEREST_PAYABLE: &str = "2160";

    /// Debt premium account (above-par issuance)
    pub const DEBT_PREMIUM: &str = "2610";

    /// Debt discount account (below-par issuance, contra-liability)
    pub const DEBT_DISCOUNT: &str = "2620";

    /// Derivative asset (positive fair value of hedging instruments)
    pub const DERIVATIVE_ASSET: &str = "1450";

    /// Derivative liability (negative fair value of hedging instruments)
    /// Note: "2450" is used as PROVISION_LIABILITY in provision_accounts; using "2460".
    pub const DERIVATIVE_LIABILITY: &str = "2460";

    /// OCI — Cash flow hedge reserve (equity section)
    pub const OCI_CASH_FLOW_HEDGE: &str = "3510";

    /// Hedge ineffectiveness expense (P&L)
    pub const HEDGE_INEFFECTIVENESS: &str = "7510";

    /// IC receivable from cash pool (physical pooling)
    pub const CASH_POOL_IC_RECEIVABLE: &str = "1155";

    /// IC payable from cash pool (physical pooling)
    pub const CASH_POOL_IC_PAYABLE: &str = "2055";
}

/// Provision accounts (IAS 37 / ASC 450).
pub mod provision_accounts {
    /// Provision liability account
    pub const PROVISION_LIABILITY: &str = "2450";
    /// Provision expense account
    pub const PROVISION_EXPENSE: &str = "6850";
}

/// Tax accounts.
pub mod tax_accounts {
    /// Sales tax payable account
    pub const SALES_TAX_PAYABLE: &str = "2100";

    /// VAT payable account
    pub const VAT_PAYABLE: &str = "2110";

    /// Withholding tax payable account
    pub const WITHHOLDING_TAX_PAYABLE: &str = "2120";

    /// Income tax payable account
    pub const INCOME_TAX_PAYABLE: &str = "2130";

    /// Input VAT (VAT receivable) account
    pub const INPUT_VAT: &str = "1160";

    /// Tax receivable account (AP input tax)
    pub const TAX_RECEIVABLE: &str = "1460";

    /// Tax expense account
    pub const TAX_EXPENSE: &str = "8000";

    /// Deferred tax liability account
    pub const DEFERRED_TAX_LIABILITY: &str = "2500";

    /// Deferred tax asset account
    pub const DEFERRED_TAX_ASSET: &str = "1600";
}

/// Liability accounts.
pub mod liability_accounts {
    /// Accrued expenses account
    pub const ACCRUED_EXPENSES: &str = "2200";

    /// Accrued salaries account
    pub const ACCRUED_SALARIES: &str = "2210";

    /// Accrued benefits account
    pub const ACCRUED_BENEFITS: &str = "2220";

    /// Unearned revenue account
    pub const UNEARNED_REVENUE: &str = "2300";

    /// Short-term debt account
    pub const SHORT_TERM_DEBT: &str = "2400";

    /// Long-term debt account
    pub const LONG_TERM_DEBT: &str = "2600";

    /// Intercompany payable account
    pub const IC_PAYABLE: &str = "2700";
}

/// Equity accounts.
pub mod equity_accounts {
    /// Common stock account
    pub const COMMON_STOCK: &str = "3000";

    /// Additional paid-in capital account
    pub const APIC: &str = "3100";

    /// Retained earnings account
    pub const RETAINED_EARNINGS: &str = "3200";

    /// Current year earnings account
    pub const CURRENT_YEAR_EARNINGS: &str = "3300";

    /// Treasury stock account
    pub const TREASURY_STOCK: &str = "3400";

    /// Currency translation adjustment account
    pub const CTA: &str = "3500";

    /// Income summary account (used for year-end close)
    pub const INCOME_SUMMARY: &str = "3600";

    /// Dividends paid account
    pub const DIVIDENDS_PAID: &str = "3700";
}

/// Dividend accounts.
pub mod dividend_accounts {
    /// Dividends payable (liability — declared but not yet paid)
    pub const DIVIDENDS_PAYABLE: &str = "2170";
    /// Dividends declared (contra-equity, reduces retained earnings)
    pub const DIVIDENDS_DECLARED: &str = "3710";
}

/// Suspense and clearing accounts.
pub mod suspense_accounts {
    /// General suspense account
    pub const GENERAL_SUSPENSE: &str = "9000";

    /// Payroll clearing account
    pub const PAYROLL_CLEARING: &str = "9100";

    /// Bank reconciliation suspense account
    pub const BANK_RECONCILIATION_SUSPENSE: &str = "9200";

    /// IC elimination suspense account
    pub const IC_ELIMINATION_SUSPENSE: &str = "9300";
}

/// Account type by prefix.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AccountCategory {
    /// Assets (1xxx)
    Asset,
    /// Liabilities (2xxx)
    Liability,
    /// Equity (3xxx)
    Equity,
    /// Revenue (4xxx)
    Revenue,
    /// Cost of Goods Sold (5xxx)
    Cogs,
    /// Operating Expenses (6xxx)
    OperatingExpense,
    /// Other Income/Expense (7xxx)
    OtherIncomeExpense,
    /// Taxes (8xxx)
    Tax,
    /// Suspense/Clearing (9xxx)
    Suspense,
    /// Unknown
    Unknown,
}

impl AccountCategory {
    /// Determine account category from account number.
    pub fn from_account(account: &str) -> Self {
        if account.is_empty() {
            return Self::Unknown;
        }

        match account.chars().next() {
            Some('1') => Self::Asset,
            Some('2') => Self::Liability,
            Some('3') => Self::Equity,
            Some('4') => Self::Revenue,
            Some('5') => Self::Cogs,
            Some('6') => Self::OperatingExpense,
            Some('7') => Self::OtherIncomeExpense,
            Some('8') => Self::Tax,
            Some('9') => Self::Suspense,
            _ => Self::Unknown,
        }
    }

    /// Check if this category is a debit-normal account.
    pub fn is_debit_normal(&self) -> bool {
        matches!(
            self,
            Self::Asset
                | Self::Cogs
                | Self::OperatingExpense
                | Self::OtherIncomeExpense
                | Self::Tax
        )
    }

    /// Check if this category is a credit-normal account.
    pub fn is_credit_normal(&self) -> bool {
        matches!(self, Self::Liability | Self::Equity | Self::Revenue)
    }

    /// Check if this category is a balance sheet account.
    pub fn is_balance_sheet(&self) -> bool {
        matches!(self, Self::Asset | Self::Liability | Self::Equity)
    }

    /// Check if this category is an income statement account.
    pub fn is_income_statement(&self) -> bool {
        matches!(
            self,
            Self::Revenue
                | Self::Cogs
                | Self::OperatingExpense
                | Self::OtherIncomeExpense
                | Self::Tax
        )
    }
}

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
    use super::*;

    #[test]
    fn test_account_category_from_account() {
        assert_eq!(
            AccountCategory::from_account(control_accounts::AR_CONTROL),
            AccountCategory::Asset
        );
        assert_eq!(
            AccountCategory::from_account(control_accounts::AP_CONTROL),
            AccountCategory::Liability
        );
        assert_eq!(
            AccountCategory::from_account(equity_accounts::RETAINED_EARNINGS),
            AccountCategory::Equity
        );
        assert_eq!(
            AccountCategory::from_account(revenue_accounts::PRODUCT_REVENUE),
            AccountCategory::Revenue
        );
        assert_eq!(
            AccountCategory::from_account(expense_accounts::COGS),
            AccountCategory::Cogs
        );
    }

    #[test]
    fn test_debit_credit_normal() {
        assert!(AccountCategory::Asset.is_debit_normal());
        assert!(AccountCategory::Revenue.is_credit_normal());
        assert!(!AccountCategory::Asset.is_credit_normal());
        assert!(!AccountCategory::Revenue.is_debit_normal());
    }

    #[test]
    fn test_balance_sheet_vs_income_statement() {
        assert!(AccountCategory::Asset.is_balance_sheet());
        assert!(AccountCategory::Liability.is_balance_sheet());
        assert!(AccountCategory::Equity.is_balance_sheet());
        assert!(!AccountCategory::Revenue.is_balance_sheet());

        assert!(AccountCategory::Revenue.is_income_statement());
        assert!(AccountCategory::Cogs.is_income_statement());
        assert!(!AccountCategory::Asset.is_income_statement());
    }
}