🚀 Initialize Musadaq SaaS: Full Backend + AI + React Dashboard + Docker Setup
This commit is contained in:
122
backend/src/modules/invoices/entities/invoice.entity.ts
Normal file
122
backend/src/modules/invoices/entities/invoice.entity.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* ════════════════════════════════════════════════════════════
|
||||
* مُصادَق (Musadaq) — Invoice Entity
|
||||
* ════════════════════════════════════════════════════════════
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
JoinColumn,
|
||||
Index,
|
||||
} from 'typeorm';
|
||||
import { Tenant } from '../../tenants/entities/tenant.entity';
|
||||
import { Company } from '../../companies/entities/company.entity';
|
||||
import { InvoiceLine } from './invoice-line.entity';
|
||||
|
||||
export enum InvoiceStatus {
|
||||
UPLOADED = 'uploaded',
|
||||
EXTRACTING = 'extracting',
|
||||
EXTRACTED = 'extracted',
|
||||
VALIDATED = 'validated',
|
||||
VALIDATION_FAILED = 'validation_failed',
|
||||
SUBMITTING = 'submitting',
|
||||
APPROVED = 'approved',
|
||||
REJECTED = 'rejected',
|
||||
}
|
||||
|
||||
@Entity('invoices')
|
||||
export class Invoice {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'uuid' })
|
||||
tenant_id!: string;
|
||||
|
||||
@ManyToOne(() => Tenant, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'tenant_id' })
|
||||
tenant!: Tenant;
|
||||
|
||||
@Column({ name: 'company_id', type: 'uuid' })
|
||||
company_id!: string;
|
||||
|
||||
@ManyToOne(() => Company, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'company_id' })
|
||||
company!: Company;
|
||||
|
||||
// ── Invoice Identity ─────────────────────────────────────
|
||||
@Column({ type: 'varchar', length: 100, nullable: true })
|
||||
invoice_number?: string;
|
||||
|
||||
@Column({ type: 'date', nullable: true })
|
||||
invoice_date?: Date;
|
||||
|
||||
@Column({ type: 'enum', enum: ['cash', 'credit'], default: 'cash' })
|
||||
invoice_type!: 'cash' | 'credit';
|
||||
|
||||
@Column({ type: 'varchar', length: 3, default: '388' }) // 388: Sales, 381: Credit Note
|
||||
ubl_type_code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 3, default: '013' }) // 013: Cash, 023: Credit
|
||||
payment_method_code!: string;
|
||||
|
||||
// ── Parties ──────────────────────────────────────────────
|
||||
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||
supplier_tin?: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 255, nullable: true })
|
||||
supplier_name?: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
supplier_address?: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||
buyer_tin?: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||
buyer_national_id?: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 255, nullable: true })
|
||||
buyer_name?: string;
|
||||
|
||||
// ── Totals (decimal 15,3) ────────────────────────────────
|
||||
@Column({ type: 'decimal', precision: 15, scale: 3, default: 0 })
|
||||
subtotal!: number;
|
||||
|
||||
@Column({ type: 'decimal', precision: 15, scale: 3, default: 0 })
|
||||
discount_total!: number;
|
||||
|
||||
@Column({ type: 'decimal', precision: 15, scale: 3, default: 0 })
|
||||
tax_amount!: number;
|
||||
|
||||
@Column({ type: 'decimal', precision: 15, scale: 3, default: 0 })
|
||||
grand_total!: number;
|
||||
|
||||
@Column({ type: 'char', length: 3, default: 'JOD' })
|
||||
currency_code!: string;
|
||||
|
||||
// ── Processing Status ────────────────────────────────────
|
||||
@Column({ type: 'enum', enum: InvoiceStatus, default: InvoiceStatus.UPLOADED })
|
||||
status!: InvoiceStatus;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
original_file_path?: string;
|
||||
|
||||
@Column({ type: 'decimal', precision: 4, scale: 3, nullable: true })
|
||||
ai_confidence_score?: number;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamp' })
|
||||
created_at!: Date;
|
||||
|
||||
@UpdateDateColumn({ type: 'timestamp' })
|
||||
updated_at!: Date;
|
||||
|
||||
// ── One-to-Many Relationship ─────────────────────────────
|
||||
@OneToMany(() => InvoiceLine, (line) => line.invoice, { cascade: true })
|
||||
lines!: InvoiceLine[];
|
||||
}
|
||||
Reference in New Issue
Block a user