Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document, Schema as MongooseSchema } from 'mongoose'; @Schema({ collection: 'journal_entries', timestamps: true }) export class JournalEntry extends Document { @Prop({ type: MongooseSchema.Types.ObjectId, required: true, index: true }) tenantId!: MongooseSchema.Types.ObjectId; @Prop({ type: MongooseSchema.Types.ObjectId, required: true }) legalEntityId!: MongooseSchema.Types.ObjectId; @Prop({ type: MongooseSchema.Types.ObjectId, required: true }) accountingBookId!: MongooseSchema.Types.ObjectId; @Prop({ required: true }) journalNumber!: string; // e.g. "JV-2026-00001" @Prop({ required: true }) postingDate!: Date; @Prop({ required: true, enum: ['draft', 'submitted', 'approval_pending', 'approved', 'posting', 'posted', 'partially_failed', 'failed', 'reversed', 'cancelled'], default: 'draft' }) status!: string; @Prop({ required: true, enum: [ 'Manual', 'Accounts Receivable', 'Accounts Payable', 'Payroll', 'Procurement', 'Inventory', 'Projects', 'Assets', 'Banking', 'Tax', 'Budget', 'SaaS Billing', 'Adjustment', 'Closing', 'Opening Balance' ], default: 'Manual' }) journalSource!: string; @Prop({ default: 'INR' }) currency!: string; @Prop({ default: 1.0 }) exchangeRate!: number; @Prop({ default: 0 }) baseDebitTotalMinor!: number; @Prop({ default: 0 }) baseCreditTotalMinor!: number; @Prop({ type: MongooseSchema.Types.ObjectId }) approvedBy?: MongooseSchema.Types.ObjectId; @Prop() approvedAt?: Date; @Prop({ type: MongooseSchema.Types.ObjectId }) postedBy?: MongooseSchema.Types.ObjectId; @Prop() postedAt?: Date; @Prop({ type: MongooseSchema.Types.ObjectId }) reversalJournalId?: MongooseSchema.Types.ObjectId; @Prop({ default: false }) isReversal!: boolean; @Prop() reversalReason?: string; @Prop({ type: String, unique: true, sparse: true }) idempotencyKey?: string; } export const JournalEntrySchema = SchemaFactory.createForClass(JournalEntry); JournalEntrySchema.index({ tenantId: 1, journalNumber: 1 }, { unique: true }); @Schema({ collection: 'journal_lines', timestamps: true }) export class JournalLine extends Document { @Prop({ type: MongooseSchema.Types.ObjectId, required: true, index: true }) journalEntryId!: MongooseSchema.Types.ObjectId; @Prop({ type: MongooseSchema.Types.ObjectId, required: true }) ledgerAccountId!: MongooseSchema.Types.ObjectId; @Prop({ default: 0 }) debitAmountMinor!: number; @Prop({ default: 0 }) creditAmountMinor!: number; @Prop({ default: 0 }) baseDebitAmountMinor!: number; @Prop({ default: 0 }) baseCreditAmountMinor!: number; @Prop() description?: string; @Prop({ type: MongooseSchema.Types.Map, of: String, default: {} }) dimensions!: Map<string, string>; // e.g. { "DEPT": "HR", "CC": "CC-01" } } export const JournalLineSchema = SchemaFactory.createForClass(JournalLine); |