206 lines
5.8 KiB
TypeScript
206 lines
5.8 KiB
TypeScript
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
OneToMany,
|
|
Index,
|
|
} from 'typeorm';
|
|
import { CashCount } from './cash-count.entity';
|
|
|
|
export enum ClosingStatus {
|
|
IN_PROGRESS = 'in_progress',
|
|
PENDING_REVIEW = 'pending_review',
|
|
APPROVED = 'approved',
|
|
REJECTED = 'rejected',
|
|
RECONCILED = 'reconciled',
|
|
}
|
|
|
|
export enum ClosingType {
|
|
SHIFT = 'shift',
|
|
DAILY = 'daily',
|
|
WEEKLY = 'weekly',
|
|
MONTHLY = 'monthly',
|
|
}
|
|
|
|
@Entity('cash_closings', { schema: 'retail' })
|
|
@Index(['tenantId', 'branchId', 'closingDate'])
|
|
@Index(['tenantId', 'status'])
|
|
@Index(['tenantId', 'sessionId'])
|
|
export class CashClosing {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
@Index()
|
|
tenantId: string;
|
|
|
|
@Column({ name: 'branch_id', type: 'uuid' })
|
|
branchId: string;
|
|
|
|
@Column({ name: 'register_id', type: 'uuid', nullable: true })
|
|
registerId: string;
|
|
|
|
@Column({ name: 'session_id', type: 'uuid', nullable: true })
|
|
sessionId: string;
|
|
|
|
@Column({ length: 30, unique: true })
|
|
number: string;
|
|
|
|
@Column({
|
|
type: 'enum',
|
|
enum: ClosingType,
|
|
default: ClosingType.SHIFT,
|
|
})
|
|
type: ClosingType;
|
|
|
|
@Column({
|
|
type: 'enum',
|
|
enum: ClosingStatus,
|
|
default: ClosingStatus.IN_PROGRESS,
|
|
})
|
|
status: ClosingStatus;
|
|
|
|
@Column({ name: 'closing_date', type: 'date' })
|
|
closingDate: Date;
|
|
|
|
@Column({ name: 'period_start', type: 'timestamp with time zone' })
|
|
periodStart: Date;
|
|
|
|
@Column({ name: 'period_end', type: 'timestamp with time zone' })
|
|
periodEnd: Date;
|
|
|
|
// Opening balance
|
|
@Column({ name: 'opening_balance', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
openingBalance: number;
|
|
|
|
// Expected amounts by payment method
|
|
@Column({ name: 'expected_cash', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
expectedCash: number;
|
|
|
|
@Column({ name: 'expected_card', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
expectedCard: number;
|
|
|
|
@Column({ name: 'expected_transfer', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
expectedTransfer: number;
|
|
|
|
@Column({ name: 'expected_other', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
expectedOther: number;
|
|
|
|
@Column({ name: 'expected_total', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
expectedTotal: number;
|
|
|
|
// Counted amounts
|
|
@Column({ name: 'counted_cash', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
countedCash: number;
|
|
|
|
@Column({ name: 'counted_card', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
countedCard: number;
|
|
|
|
@Column({ name: 'counted_transfer', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
countedTransfer: number;
|
|
|
|
@Column({ name: 'counted_other', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
countedOther: number;
|
|
|
|
@Column({ name: 'counted_total', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
countedTotal: number;
|
|
|
|
// Differences
|
|
@Column({ name: 'cash_difference', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
cashDifference: number;
|
|
|
|
@Column({ name: 'card_difference', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
cardDifference: number;
|
|
|
|
@Column({ name: 'total_difference', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
totalDifference: number;
|
|
|
|
// Transaction summary
|
|
@Column({ name: 'total_sales', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
totalSales: number;
|
|
|
|
@Column({ name: 'total_refunds', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
totalRefunds: number;
|
|
|
|
@Column({ name: 'total_discounts', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
totalDiscounts: number;
|
|
|
|
@Column({ name: 'net_sales', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
netSales: number;
|
|
|
|
@Column({ name: 'orders_count', type: 'int', default: 0 })
|
|
ordersCount: number;
|
|
|
|
@Column({ name: 'refunds_count', type: 'int', default: 0 })
|
|
refundsCount: number;
|
|
|
|
@Column({ name: 'voided_count', type: 'int', default: 0 })
|
|
voidedCount: number;
|
|
|
|
// Cash movements
|
|
@Column({ name: 'cash_in_total', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
cashInTotal: number;
|
|
|
|
@Column({ name: 'cash_out_total', type: 'decimal', precision: 15, scale: 2, default: 0 })
|
|
cashOutTotal: number;
|
|
|
|
// Deposit info
|
|
@Column({ name: 'deposit_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
depositAmount: number;
|
|
|
|
@Column({ name: 'deposit_reference', length: 100, nullable: true })
|
|
depositReference: string;
|
|
|
|
@Column({ name: 'deposit_date', type: 'date', nullable: true })
|
|
depositDate: Date;
|
|
|
|
// User info
|
|
@Column({ name: 'closed_by', type: 'uuid' })
|
|
closedBy: string;
|
|
|
|
@Column({ name: 'reviewed_by', type: 'uuid', nullable: true })
|
|
reviewedBy: string;
|
|
|
|
@Column({ name: 'reviewed_at', type: 'timestamp with time zone', nullable: true })
|
|
reviewedAt: Date;
|
|
|
|
@Column({ name: 'approved_by', type: 'uuid', nullable: true })
|
|
approvedBy: string;
|
|
|
|
@Column({ name: 'approved_at', type: 'timestamp with time zone', nullable: true })
|
|
approvedAt: Date;
|
|
|
|
// Notes
|
|
@Column({ name: 'closing_notes', type: 'text', nullable: true })
|
|
closingNotes: string;
|
|
|
|
@Column({ name: 'review_notes', type: 'text', nullable: true })
|
|
reviewNotes: string;
|
|
|
|
// Detailed breakdown by payment method
|
|
@Column({ name: 'payment_breakdown', type: 'jsonb', nullable: true })
|
|
paymentBreakdown: {
|
|
method: string;
|
|
expected: number;
|
|
counted: number;
|
|
difference: number;
|
|
transactionCount: number;
|
|
}[];
|
|
|
|
// Metadata
|
|
@Column({ type: 'jsonb', nullable: true })
|
|
metadata: Record<string, any>;
|
|
|
|
@CreateDateColumn({ name: 'created_at' })
|
|
createdAt: Date;
|
|
|
|
@UpdateDateColumn({ name: 'updated_at' })
|
|
updatedAt: Date;
|
|
|
|
// Relations
|
|
@OneToMany(() => CashCount, (count) => count.closing)
|
|
cashCounts: CashCount[];
|
|
}
|