198 lines
5.6 KiB
TypeScript
198 lines
5.6 KiB
TypeScript
import { QueryInterface, DataTypes } from 'sequelize';
|
|
|
|
export async function up(queryInterface: QueryInterface): Promise<void> {
|
|
// Create claim_budget_tracking table for comprehensive budget management
|
|
await queryInterface.createTable('claim_budget_tracking', {
|
|
budget_id: {
|
|
type: DataTypes.UUID,
|
|
primaryKey: true,
|
|
defaultValue: DataTypes.UUIDV4
|
|
},
|
|
request_id: {
|
|
type: DataTypes.UUID,
|
|
allowNull: false,
|
|
unique: true,
|
|
references: {
|
|
model: 'workflow_requests',
|
|
key: 'request_id'
|
|
},
|
|
onDelete: 'CASCADE',
|
|
onUpdate: 'CASCADE'
|
|
},
|
|
// Initial Budget (from claim creation)
|
|
initial_estimated_budget: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Initial estimated budget when claim was created'
|
|
},
|
|
// Proposal Budget (from Step 1 - Dealer Proposal)
|
|
proposal_estimated_budget: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Total estimated budget from dealer proposal'
|
|
},
|
|
proposal_submitted_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When dealer submitted proposal'
|
|
},
|
|
// Approved Budget (from Step 2 - Requestor Evaluation)
|
|
approved_budget: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Budget approved by requestor in Step 2'
|
|
},
|
|
approved_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When budget was approved by requestor'
|
|
},
|
|
approved_by: {
|
|
type: DataTypes.UUID,
|
|
allowNull: true,
|
|
references: {
|
|
model: 'users',
|
|
key: 'user_id'
|
|
},
|
|
onDelete: 'SET NULL',
|
|
onUpdate: 'CASCADE',
|
|
comment: 'User who approved the budget'
|
|
},
|
|
// IO Blocked Budget (from Step 3 - Department Lead)
|
|
io_blocked_amount: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Amount blocked in IO (from internal_orders table)'
|
|
},
|
|
io_blocked_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When budget was blocked in IO'
|
|
},
|
|
// Closed Expenses (from Step 5 - Dealer Completion)
|
|
closed_expenses: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Total closed expenses from completion documents'
|
|
},
|
|
closed_expenses_submitted_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When completion expenses were submitted'
|
|
},
|
|
// Final Claim Amount (from Step 6 - Requestor Claim Approval)
|
|
final_claim_amount: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Final claim amount approved/modified by requestor in Step 6'
|
|
},
|
|
final_claim_amount_approved_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When final claim amount was approved'
|
|
},
|
|
final_claim_amount_approved_by: {
|
|
type: DataTypes.UUID,
|
|
allowNull: true,
|
|
references: {
|
|
model: 'users',
|
|
key: 'user_id'
|
|
},
|
|
onDelete: 'SET NULL',
|
|
onUpdate: 'CASCADE',
|
|
comment: 'User who approved final claim amount'
|
|
},
|
|
// Credit Note (from Step 8 - Finance)
|
|
credit_note_amount: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Credit note amount issued by finance'
|
|
},
|
|
credit_note_issued_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When credit note was issued'
|
|
},
|
|
// Budget Status
|
|
budget_status: {
|
|
type: DataTypes.ENUM('DRAFT', 'PROPOSED', 'APPROVED', 'BLOCKED', 'CLOSED', 'SETTLED'),
|
|
defaultValue: 'DRAFT',
|
|
allowNull: false,
|
|
comment: 'Current status of budget lifecycle'
|
|
},
|
|
// Currency
|
|
currency: {
|
|
type: DataTypes.STRING(3),
|
|
defaultValue: 'INR',
|
|
allowNull: false,
|
|
comment: 'Currency code (INR, USD, etc.)'
|
|
},
|
|
// Budget Variance
|
|
variance_amount: {
|
|
type: DataTypes.DECIMAL(15, 2),
|
|
allowNull: true,
|
|
comment: 'Difference between approved and closed expenses (closed - approved)'
|
|
},
|
|
variance_percentage: {
|
|
type: DataTypes.DECIMAL(5, 2),
|
|
allowNull: true,
|
|
comment: 'Variance as percentage of approved budget'
|
|
},
|
|
// Audit fields
|
|
last_modified_by: {
|
|
type: DataTypes.UUID,
|
|
allowNull: true,
|
|
references: {
|
|
model: 'users',
|
|
key: 'user_id'
|
|
},
|
|
onDelete: 'SET NULL',
|
|
onUpdate: 'CASCADE',
|
|
comment: 'Last user who modified budget'
|
|
},
|
|
last_modified_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: 'When budget was last modified'
|
|
},
|
|
modification_reason: {
|
|
type: DataTypes.TEXT,
|
|
allowNull: true,
|
|
comment: 'Reason for budget modification'
|
|
},
|
|
created_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: false,
|
|
defaultValue: DataTypes.NOW
|
|
},
|
|
updated_at: {
|
|
type: DataTypes.DATE,
|
|
allowNull: false,
|
|
defaultValue: DataTypes.NOW
|
|
}
|
|
});
|
|
|
|
// Create indexes
|
|
await queryInterface.addIndex('claim_budget_tracking', ['request_id'], {
|
|
name: 'idx_claim_budget_tracking_request_id',
|
|
unique: true
|
|
});
|
|
|
|
await queryInterface.addIndex('claim_budget_tracking', ['budget_status'], {
|
|
name: 'idx_claim_budget_tracking_status'
|
|
});
|
|
|
|
await queryInterface.addIndex('claim_budget_tracking', ['approved_by'], {
|
|
name: 'idx_claim_budget_tracking_approved_by'
|
|
});
|
|
|
|
await queryInterface.addIndex('claim_budget_tracking', ['final_claim_amount_approved_by'], {
|
|
name: 'idx_claim_budget_tracking_final_approved_by'
|
|
});
|
|
}
|
|
|
|
export async function down(queryInterface: QueryInterface): Promise<void> {
|
|
await queryInterface.dropTable('claim_budget_tracking');
|
|
}
|
|
|