6228 lines
122 KiB
JavaScript
6228 lines
122 KiB
JavaScript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const db = require('../models');
|
|
const Users = db.users;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Departments = db.departments;
|
|
|
|
const Budgets = db.budgets;
|
|
|
|
const ExpenseCategories = db.expense_categories;
|
|
|
|
const ExpenseReports = db.expense_reports;
|
|
|
|
const ExpenseItems = db.expense_items;
|
|
|
|
const Receipts = db.receipts;
|
|
|
|
const ApprovalSteps = db.approval_steps;
|
|
|
|
const BudgetChecks = db.budget_checks;
|
|
|
|
const Alerts = db.alerts;
|
|
|
|
const PolicyRules = db.policy_rules;
|
|
|
|
const ChatSessions = db.chat_sessions;
|
|
|
|
const ChatMessages = db.chat_messages;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DepartmentsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Engineering",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"cost_center_code": "CC-ENG-10",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Sales",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"cost_center_code": "CC-SAL-20",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Operations",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"cost_center_code": "CC-OPS-30",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Finance",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"cost_center_code": "CC-FIN-40",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Customer Success",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"cost_center_code": "CC-CS-50",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const BudgetsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Engineering 2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period": "yearly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_from": new Date('2026-01-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_to": new Date('2026-12-31T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 250000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"alert_threshold_percent": 80,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Sales Q1 2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period": "yearly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_from": new Date('2026-01-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_to": new Date('2026-03-31T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 90000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"alert_threshold_percent": 75,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Operations 2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period": "quarterly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_from": new Date('2026-01-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_to": new Date('2026-12-31T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 140000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"alert_threshold_percent": 80,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Customer Success H1 2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period": "quarterly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_from": new Date('2026-01-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_to": new Date('2026-06-30T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 60000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"alert_threshold_percent": 80,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Training Monthly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period": "monthly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_from": new Date('2026-02-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"valid_to": new Date('2026-02-28T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 12000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"alert_threshold_percent": 70,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ExpenseCategoriesData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Meals",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code": "MEAL",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"requires_receipt": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Lodging",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code": "HOTEL",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"requires_receipt": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Transport",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code": "TRANS",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"requires_receipt": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Mileage",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code": "KM",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"requires_receipt": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Office Supplies",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code": "SUP",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"requires_receipt": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ExpenseReportsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"report_number": "ER-2026-0001",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_start": new Date('2026-02-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_end": new Date('2026-02-15T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Client visit Lyon",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"purpose": "On-site workshop and meetings with client team",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "paid",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"total_amount": 482.35,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"submitted_at": new Date('2026-02-16T09:15:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"approved_at": new Date('2026-02-18T15:40:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"paid_at": new Date('2026-02-21T10:05:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"report_number": "ER-2026-0002",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_start": new Date('2026-02-05T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_end": new Date('2026-02-07T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Tech conference Paris",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"purpose": "Attending industry conference and networking events",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "in_review",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"total_amount": 1260,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"submitted_at": new Date('2026-02-10T08:20:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"approved_at": new Date('2026-02-12T11:05:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"paid_at": new Date('2026-02-20T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"report_number": "ER-2026-0003",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_start": new Date('2026-01-20T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_end": new Date('2026-01-25T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Regional sales tour",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"purpose": "Prospecting meetings across region",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "cancelled",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"total_amount": 735.9,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"submitted_at": new Date('2026-01-26T10:10:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"approved_at": new Date('2026-01-29T16:30:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"paid_at": new Date('2026-02-05T10:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"report_number": "ER-2026-0004",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_start": new Date('2026-02-01T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_end": new Date('2026-02-01T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Local transport",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"purpose": "Customer success visit",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "approved",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"total_amount": 48.2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"submitted_at": new Date('2026-02-02T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"approved_at": new Date('2026-02-03T10:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"paid_at": new Date('2026-02-10T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"report_number": "ER-2026-0005",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_start": new Date('2026-02-12T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"period_end": new Date('2026-02-14T23:59:59Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Team offsite logistics",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"purpose": "Operational planning offsite",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "in_review",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"total_amount": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"submitted_at": new Date('2026-02-15T08:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"approved_at": new Date('2026-02-19T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"paid_at": new Date('2026-02-22T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ExpenseItemsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"expense_date": new Date('2026-02-06T12:30:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_name": "Brasserie des Brotteaux",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Business lunch with client stakeholders",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount": 86.5,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_amount": 7.86,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_rate": 10,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"payment_method": "cash",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"billable": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"project_code": "PRJ-LYON-2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"distance_km": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"per_km_rate": 0,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"expense_date": new Date('2026-02-06T19:10:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_name": "Hotel Part-Dieu",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "One night lodging",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount": 168,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_amount": 16.8,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_rate": 10,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"payment_method": "company_card",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"billable": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"project_code": "PRJ-LYON-2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"distance_km": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"per_km_rate": 0,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"expense_date": new Date('2026-02-05T07:45:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_name": "SNCF",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Round trip train ticket",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount": 124.9,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_amount": 20.82,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_rate": 20,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"payment_method": "other",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"billable": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"project_code": "PRJ-LYON-2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"distance_km": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"per_km_rate": 0,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"expense_date": new Date('2026-02-07T08:30:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_name": "Taxi Lyon",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Taxi to client office",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount": 32.4,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_amount": 5.4,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_rate": 20,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"payment_method": "other",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"billable": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"project_code": "PRJ-LYON-2026",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"distance_km": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"per_km_rate": 0,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"expense_date": new Date('2026-02-12T18:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_name": "TotalEnergies",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Fuel for client visit",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount": 62.75,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_amount": 10.46,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"tax_rate": 20,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"payment_method": "other",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"billable": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"project_code": "PRJ-INTERNAL",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"distance_km": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"per_km_rate": 0,
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ReceiptsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "files" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "images" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"source": "mobile",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_status": "pending",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_confidence": 0.92,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_merchant": "Brasserie des Brotteaux",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_date": new Date('2026-02-06T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_total": 86.5,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"raw_text": "BRASSERIE DES BROTTEAUX TOTAL 86.50 EUR TVA 10%",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"processed_at": new Date('2026-02-06T12:35:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "files" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "images" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"source": "email",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_status": "processing",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_confidence": 0.95,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_merchant": "Hotel Part-Dieu",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_date": new Date('2026-02-06T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_total": 168,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"raw_text": "HOTEL PART-DIEU TOTAL 168.00 EUR TVA 10%",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"processed_at": new Date('2026-02-06T19:20:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "files" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "images" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"source": "email",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_status": "succeeded",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_confidence": 0.71,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_merchant": "SNCF",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_date": new Date('2026-02-05T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_total": 124.9,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"raw_text": "SNCF BILLET TOTAL 124.90 EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"processed_at": new Date('2026-02-05T07:50:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "files" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "images" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"source": "upload",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_status": "pending",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_confidence": 0.18,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_merchant": "Taxi Lyon",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_date": new Date('2026-02-07T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_total": 32.4,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"raw_text": "Unreadable image, retry suggested",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"processed_at": new Date('2026-02-07T08:40:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "files" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "images" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"source": "upload",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_status": "failed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ocr_confidence": 0.9,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_merchant": "TotalEnergies",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_date": new Date('2026-02-12T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_total": 62.75,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"extracted_currency": "EUR",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"raw_text": "TOTALENERGIES TOTAL 62.75 EUR TVA 20%",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"processed_at": new Date('2026-02-12T18:10:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ApprovalStepsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_order": 1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_type": "finance",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decision": "pending",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decided_at": new Date('2026-02-17T10:30:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"comment": "Approved, client deliverables aligned",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_order": 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_type": "finance",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decision": "returned",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decided_at": new Date('2026-02-18T15:40:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"comment": "Receipt and amounts verified",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_order": 1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_type": "finance",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decision": "rejected",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decided_at": new Date('2026-02-12T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"comment": "Awaiting review",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_order": 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_type": "custom",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decision": "skipped",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decided_at": new Date('2026-02-12T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"comment": "Pending manager approval",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_order": 1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"step_type": "manager",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decision": "returned",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"decided_at": new Date('2026-02-03T10:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"comment": "Please attach missing receipt for taxi",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const BudgetChecksData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"checked_at": new Date('2026-02-16T09:16:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"current_spend": 172500,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"projected_spend": 172982.35,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"remaining_budget": 77017.65,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"over_budget": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"utilization_percent": 69.19,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"notes": "Within budget, below threshold",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"checked_at": new Date('2026-02-10T08:21:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"current_spend": 68800,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"projected_spend": 70060,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"remaining_budget": 19940,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"over_budget": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"utilization_percent": 77.84,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"notes": "Approaching threshold, monitor spend",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"checked_at": new Date('2026-01-26T10:11:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"current_spend": 51200,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"projected_spend": 51935.9,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"remaining_budget": 38064.1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"over_budget": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"utilization_percent": 57.71,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"notes": "Healthy budget status",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"checked_at": new Date('2026-02-02T09:01:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"current_spend": 58800,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"projected_spend": 58848.2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"remaining_budget": 11151.8,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"over_budget": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"utilization_percent": 84.07,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"notes": "Above threshold, trigger warning",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"checked_at": new Date('2026-02-15T08:01:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"current_spend": 11800,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"projected_spend": 11800,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"remaining_budget": 200,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"over_budget": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"utilization_percent": 98.33,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"notes": "Near limit, require justification",
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const AlertsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"alert_type": "ocr_failed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"severity": "warning",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Budget threshold reached",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"message": "Department budget utilization exceeded configured threshold",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"triggered_at": new Date('2026-02-02T09:02:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged_at": new Date('2026-02-02T10:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved_at": new Date('2026-02-10T00:00:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"alert_type": "budget_threshold",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"severity": "critical",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Missing receipt",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"message": "An expense item is missing a required receipt attachment",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"triggered_at": new Date('2026-02-03T10:01:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged_at": new Date('2026-02-10T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved_at": new Date('2026-02-12T00:00:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"alert_type": "ocr_failed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"severity": "critical",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "OCR extraction failed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"message": "Receipt OCR failed, manual review recommended",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"triggered_at": new Date('2026-02-07T08:41:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged_at": new Date('2026-02-07T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved_at": new Date('2026-02-07T09:30:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"alert_type": "ocr_failed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"severity": "warning",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Approval overdue",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"message": "Expense report approval is overdue based on SLA",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"triggered_at": new Date('2026-02-13T08:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged_at": new Date('2026-02-20T00:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved_at": new Date('2026-02-22T00:00:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"alert_type": "policy_violation",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"severity": "info",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"title": "Possible duplicate expense",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"message": "Similar amount and merchant detected within short time window",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"triggered_at": new Date('2026-02-18T14:10:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"acknowledged_at": new Date('2026-02-18T15:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"resolved_at": new Date('2026-02-22T00:00:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const PolicyRulesData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Meals max per day",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"rule_type": "duplicate_detection",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 60,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"max_days_after_expense": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_pattern": "Any",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Meals reimbursed up to 60 EUR per day for standard trips",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Receipt required for lodging",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"rule_type": "merchant_blacklist",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"max_days_after_expense": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_pattern": "Any",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Lodging expenses must include an itemized receipt",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Submit within 30 days",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"rule_type": "merchant_blacklist",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"max_days_after_expense": 30,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_pattern": "Any",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Expenses must be submitted within 30 days of the expense date",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Duplicate detection window",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"rule_type": "merchant_blacklist",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"max_days_after_expense": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_pattern": "Any",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Flags expenses with same merchant and amount within 48 hours",
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
"name": "Blacklisted merchant pattern",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"rule_type": "merchant_blacklist",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"amount_limit": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"max_days_after_expense": 0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"merchant_pattern": "Gift Card",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"active": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"description": "Expenses from disallowed merchant patterns require finance review",
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ChatSessionsData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"channel": "api",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "open",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"topic": "How to submit a report",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"started_at": new Date('2026-02-16T09:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ended_at": new Date('2026-02-16T09:10:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"channel": "mobile",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "closed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"topic": "Receipt OCR issue",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"started_at": new Date('2026-02-07T08:45:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ended_at": new Date('2026-02-07T09:05:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"channel": "mobile",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "open",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"topic": "Policy on meals limit",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"started_at": new Date('2026-02-10T12:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ended_at": new Date('2026-02-10T12:07:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"channel": "mobile",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "open",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"topic": "Track approval status",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"started_at": new Date('2026-02-13T08:10:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ended_at": new Date('2026-02-13T08:25:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"channel": "api",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"status": "closed",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"topic": "Export expenses for audit",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"started_at": new Date('2026-02-18T14:00:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"ended_at": new Date('2026-02-18T14:15:00Z'),
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const ChatMessagesData = [
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sender_type": "system",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"content": "I want to submit an expense report, where do I start",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sent_at": new Date('2026-02-16T09:01:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sender_type": "user",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"content": "Go to Expense Reports, click New, add items and receipts, then submit for approval",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sent_at": new Date('2026-02-16T09:01:15Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sender_type": "assistant",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"content": "My receipt OCR failed, can I fill details manually",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sent_at": new Date('2026-02-07T08:46:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sender_type": "system",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"content": "Yes, open the expense item and enter merchant, date and amount, then reattach a clearer image if possible",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sent_at": new Date('2026-02-07T08:46:20Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sender_type": "system",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"content": "Session closed after inactivity",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"sent_at": new Date('2026-02-07T09:05:00Z'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// type code here for "relation_one" field
|
|
|
|
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Similar logic for "relation_many"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateDepartmentWithBudget() {
|
|
|
|
const relatedBudget0 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Department0 = await Departments.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Department0?.setBudget)
|
|
{
|
|
await
|
|
Department0.
|
|
setBudget(relatedBudget0);
|
|
}
|
|
|
|
const relatedBudget1 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Department1 = await Departments.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Department1?.setBudget)
|
|
{
|
|
await
|
|
Department1.
|
|
setBudget(relatedBudget1);
|
|
}
|
|
|
|
const relatedBudget2 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Department2 = await Departments.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Department2?.setBudget)
|
|
{
|
|
await
|
|
Department2.
|
|
setBudget(relatedBudget2);
|
|
}
|
|
|
|
const relatedBudget3 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Department3 = await Departments.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Department3?.setBudget)
|
|
{
|
|
await
|
|
Department3.
|
|
setBudget(relatedBudget3);
|
|
}
|
|
|
|
const relatedBudget4 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Department4 = await Departments.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Department4?.setBudget)
|
|
{
|
|
await
|
|
Department4.
|
|
setBudget(relatedBudget4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateExpenseReportWithSubmitter() {
|
|
|
|
const relatedSubmitter0 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ExpenseReport0 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ExpenseReport0?.setSubmitter)
|
|
{
|
|
await
|
|
ExpenseReport0.
|
|
setSubmitter(relatedSubmitter0);
|
|
}
|
|
|
|
const relatedSubmitter1 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ExpenseReport1 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ExpenseReport1?.setSubmitter)
|
|
{
|
|
await
|
|
ExpenseReport1.
|
|
setSubmitter(relatedSubmitter1);
|
|
}
|
|
|
|
const relatedSubmitter2 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ExpenseReport2 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ExpenseReport2?.setSubmitter)
|
|
{
|
|
await
|
|
ExpenseReport2.
|
|
setSubmitter(relatedSubmitter2);
|
|
}
|
|
|
|
const relatedSubmitter3 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ExpenseReport3 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ExpenseReport3?.setSubmitter)
|
|
{
|
|
await
|
|
ExpenseReport3.
|
|
setSubmitter(relatedSubmitter3);
|
|
}
|
|
|
|
const relatedSubmitter4 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ExpenseReport4 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ExpenseReport4?.setSubmitter)
|
|
{
|
|
await
|
|
ExpenseReport4.
|
|
setSubmitter(relatedSubmitter4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function associateExpenseReportWithDepartment() {
|
|
|
|
const relatedDepartment0 = await Departments.findOne({
|
|
offset: Math.floor(Math.random() * (await Departments.count())),
|
|
});
|
|
const ExpenseReport0 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ExpenseReport0?.setDepartment)
|
|
{
|
|
await
|
|
ExpenseReport0.
|
|
setDepartment(relatedDepartment0);
|
|
}
|
|
|
|
const relatedDepartment1 = await Departments.findOne({
|
|
offset: Math.floor(Math.random() * (await Departments.count())),
|
|
});
|
|
const ExpenseReport1 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ExpenseReport1?.setDepartment)
|
|
{
|
|
await
|
|
ExpenseReport1.
|
|
setDepartment(relatedDepartment1);
|
|
}
|
|
|
|
const relatedDepartment2 = await Departments.findOne({
|
|
offset: Math.floor(Math.random() * (await Departments.count())),
|
|
});
|
|
const ExpenseReport2 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ExpenseReport2?.setDepartment)
|
|
{
|
|
await
|
|
ExpenseReport2.
|
|
setDepartment(relatedDepartment2);
|
|
}
|
|
|
|
const relatedDepartment3 = await Departments.findOne({
|
|
offset: Math.floor(Math.random() * (await Departments.count())),
|
|
});
|
|
const ExpenseReport3 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ExpenseReport3?.setDepartment)
|
|
{
|
|
await
|
|
ExpenseReport3.
|
|
setDepartment(relatedDepartment3);
|
|
}
|
|
|
|
const relatedDepartment4 = await Departments.findOne({
|
|
offset: Math.floor(Math.random() * (await Departments.count())),
|
|
});
|
|
const ExpenseReport4 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ExpenseReport4?.setDepartment)
|
|
{
|
|
await
|
|
ExpenseReport4.
|
|
setDepartment(relatedDepartment4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateExpenseReportWithBudget() {
|
|
|
|
const relatedBudget0 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const ExpenseReport0 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ExpenseReport0?.setBudget)
|
|
{
|
|
await
|
|
ExpenseReport0.
|
|
setBudget(relatedBudget0);
|
|
}
|
|
|
|
const relatedBudget1 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const ExpenseReport1 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ExpenseReport1?.setBudget)
|
|
{
|
|
await
|
|
ExpenseReport1.
|
|
setBudget(relatedBudget1);
|
|
}
|
|
|
|
const relatedBudget2 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const ExpenseReport2 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ExpenseReport2?.setBudget)
|
|
{
|
|
await
|
|
ExpenseReport2.
|
|
setBudget(relatedBudget2);
|
|
}
|
|
|
|
const relatedBudget3 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const ExpenseReport3 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ExpenseReport3?.setBudget)
|
|
{
|
|
await
|
|
ExpenseReport3.
|
|
setBudget(relatedBudget3);
|
|
}
|
|
|
|
const relatedBudget4 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const ExpenseReport4 = await ExpenseReports.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ExpenseReport4?.setBudget)
|
|
{
|
|
await
|
|
ExpenseReport4.
|
|
setBudget(relatedBudget4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateExpenseItemWithReport() {
|
|
|
|
const relatedReport0 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ExpenseItem0 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ExpenseItem0?.setReport)
|
|
{
|
|
await
|
|
ExpenseItem0.
|
|
setReport(relatedReport0);
|
|
}
|
|
|
|
const relatedReport1 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ExpenseItem1 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ExpenseItem1?.setReport)
|
|
{
|
|
await
|
|
ExpenseItem1.
|
|
setReport(relatedReport1);
|
|
}
|
|
|
|
const relatedReport2 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ExpenseItem2 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ExpenseItem2?.setReport)
|
|
{
|
|
await
|
|
ExpenseItem2.
|
|
setReport(relatedReport2);
|
|
}
|
|
|
|
const relatedReport3 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ExpenseItem3 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ExpenseItem3?.setReport)
|
|
{
|
|
await
|
|
ExpenseItem3.
|
|
setReport(relatedReport3);
|
|
}
|
|
|
|
const relatedReport4 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ExpenseItem4 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ExpenseItem4?.setReport)
|
|
{
|
|
await
|
|
ExpenseItem4.
|
|
setReport(relatedReport4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateExpenseItemWithCategory() {
|
|
|
|
const relatedCategory0 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const ExpenseItem0 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ExpenseItem0?.setCategory)
|
|
{
|
|
await
|
|
ExpenseItem0.
|
|
setCategory(relatedCategory0);
|
|
}
|
|
|
|
const relatedCategory1 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const ExpenseItem1 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ExpenseItem1?.setCategory)
|
|
{
|
|
await
|
|
ExpenseItem1.
|
|
setCategory(relatedCategory1);
|
|
}
|
|
|
|
const relatedCategory2 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const ExpenseItem2 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ExpenseItem2?.setCategory)
|
|
{
|
|
await
|
|
ExpenseItem2.
|
|
setCategory(relatedCategory2);
|
|
}
|
|
|
|
const relatedCategory3 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const ExpenseItem3 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ExpenseItem3?.setCategory)
|
|
{
|
|
await
|
|
ExpenseItem3.
|
|
setCategory(relatedCategory3);
|
|
}
|
|
|
|
const relatedCategory4 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const ExpenseItem4 = await ExpenseItems.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ExpenseItem4?.setCategory)
|
|
{
|
|
await
|
|
ExpenseItem4.
|
|
setCategory(relatedCategory4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateReceiptWithExpense_item() {
|
|
|
|
const relatedExpense_item0 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Receipt0 = await Receipts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Receipt0?.setExpense_item)
|
|
{
|
|
await
|
|
Receipt0.
|
|
setExpense_item(relatedExpense_item0);
|
|
}
|
|
|
|
const relatedExpense_item1 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Receipt1 = await Receipts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Receipt1?.setExpense_item)
|
|
{
|
|
await
|
|
Receipt1.
|
|
setExpense_item(relatedExpense_item1);
|
|
}
|
|
|
|
const relatedExpense_item2 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Receipt2 = await Receipts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Receipt2?.setExpense_item)
|
|
{
|
|
await
|
|
Receipt2.
|
|
setExpense_item(relatedExpense_item2);
|
|
}
|
|
|
|
const relatedExpense_item3 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Receipt3 = await Receipts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Receipt3?.setExpense_item)
|
|
{
|
|
await
|
|
Receipt3.
|
|
setExpense_item(relatedExpense_item3);
|
|
}
|
|
|
|
const relatedExpense_item4 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Receipt4 = await Receipts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Receipt4?.setExpense_item)
|
|
{
|
|
await
|
|
Receipt4.
|
|
setExpense_item(relatedExpense_item4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateApprovalStepWithReport() {
|
|
|
|
const relatedReport0 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ApprovalStep0 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ApprovalStep0?.setReport)
|
|
{
|
|
await
|
|
ApprovalStep0.
|
|
setReport(relatedReport0);
|
|
}
|
|
|
|
const relatedReport1 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ApprovalStep1 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ApprovalStep1?.setReport)
|
|
{
|
|
await
|
|
ApprovalStep1.
|
|
setReport(relatedReport1);
|
|
}
|
|
|
|
const relatedReport2 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ApprovalStep2 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ApprovalStep2?.setReport)
|
|
{
|
|
await
|
|
ApprovalStep2.
|
|
setReport(relatedReport2);
|
|
}
|
|
|
|
const relatedReport3 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ApprovalStep3 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ApprovalStep3?.setReport)
|
|
{
|
|
await
|
|
ApprovalStep3.
|
|
setReport(relatedReport3);
|
|
}
|
|
|
|
const relatedReport4 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ApprovalStep4 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ApprovalStep4?.setReport)
|
|
{
|
|
await
|
|
ApprovalStep4.
|
|
setReport(relatedReport4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateApprovalStepWithApprover() {
|
|
|
|
const relatedApprover0 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ApprovalStep0 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ApprovalStep0?.setApprover)
|
|
{
|
|
await
|
|
ApprovalStep0.
|
|
setApprover(relatedApprover0);
|
|
}
|
|
|
|
const relatedApprover1 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ApprovalStep1 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ApprovalStep1?.setApprover)
|
|
{
|
|
await
|
|
ApprovalStep1.
|
|
setApprover(relatedApprover1);
|
|
}
|
|
|
|
const relatedApprover2 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ApprovalStep2 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ApprovalStep2?.setApprover)
|
|
{
|
|
await
|
|
ApprovalStep2.
|
|
setApprover(relatedApprover2);
|
|
}
|
|
|
|
const relatedApprover3 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ApprovalStep3 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ApprovalStep3?.setApprover)
|
|
{
|
|
await
|
|
ApprovalStep3.
|
|
setApprover(relatedApprover3);
|
|
}
|
|
|
|
const relatedApprover4 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ApprovalStep4 = await ApprovalSteps.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ApprovalStep4?.setApprover)
|
|
{
|
|
await
|
|
ApprovalStep4.
|
|
setApprover(relatedApprover4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateBudgetCheckWithBudget() {
|
|
|
|
const relatedBudget0 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const BudgetCheck0 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (BudgetCheck0?.setBudget)
|
|
{
|
|
await
|
|
BudgetCheck0.
|
|
setBudget(relatedBudget0);
|
|
}
|
|
|
|
const relatedBudget1 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const BudgetCheck1 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (BudgetCheck1?.setBudget)
|
|
{
|
|
await
|
|
BudgetCheck1.
|
|
setBudget(relatedBudget1);
|
|
}
|
|
|
|
const relatedBudget2 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const BudgetCheck2 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (BudgetCheck2?.setBudget)
|
|
{
|
|
await
|
|
BudgetCheck2.
|
|
setBudget(relatedBudget2);
|
|
}
|
|
|
|
const relatedBudget3 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const BudgetCheck3 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (BudgetCheck3?.setBudget)
|
|
{
|
|
await
|
|
BudgetCheck3.
|
|
setBudget(relatedBudget3);
|
|
}
|
|
|
|
const relatedBudget4 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const BudgetCheck4 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (BudgetCheck4?.setBudget)
|
|
{
|
|
await
|
|
BudgetCheck4.
|
|
setBudget(relatedBudget4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function associateBudgetCheckWithReport() {
|
|
|
|
const relatedReport0 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const BudgetCheck0 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (BudgetCheck0?.setReport)
|
|
{
|
|
await
|
|
BudgetCheck0.
|
|
setReport(relatedReport0);
|
|
}
|
|
|
|
const relatedReport1 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const BudgetCheck1 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (BudgetCheck1?.setReport)
|
|
{
|
|
await
|
|
BudgetCheck1.
|
|
setReport(relatedReport1);
|
|
}
|
|
|
|
const relatedReport2 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const BudgetCheck2 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (BudgetCheck2?.setReport)
|
|
{
|
|
await
|
|
BudgetCheck2.
|
|
setReport(relatedReport2);
|
|
}
|
|
|
|
const relatedReport3 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const BudgetCheck3 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (BudgetCheck3?.setReport)
|
|
{
|
|
await
|
|
BudgetCheck3.
|
|
setReport(relatedReport3);
|
|
}
|
|
|
|
const relatedReport4 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const BudgetCheck4 = await BudgetChecks.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (BudgetCheck4?.setReport)
|
|
{
|
|
await
|
|
BudgetCheck4.
|
|
setReport(relatedReport4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateAlertWithReport() {
|
|
|
|
const relatedReport0 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const Alert0 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Alert0?.setReport)
|
|
{
|
|
await
|
|
Alert0.
|
|
setReport(relatedReport0);
|
|
}
|
|
|
|
const relatedReport1 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const Alert1 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Alert1?.setReport)
|
|
{
|
|
await
|
|
Alert1.
|
|
setReport(relatedReport1);
|
|
}
|
|
|
|
const relatedReport2 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const Alert2 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Alert2?.setReport)
|
|
{
|
|
await
|
|
Alert2.
|
|
setReport(relatedReport2);
|
|
}
|
|
|
|
const relatedReport3 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const Alert3 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Alert3?.setReport)
|
|
{
|
|
await
|
|
Alert3.
|
|
setReport(relatedReport3);
|
|
}
|
|
|
|
const relatedReport4 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const Alert4 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Alert4?.setReport)
|
|
{
|
|
await
|
|
Alert4.
|
|
setReport(relatedReport4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function associateAlertWithExpense_item() {
|
|
|
|
const relatedExpense_item0 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Alert0 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Alert0?.setExpense_item)
|
|
{
|
|
await
|
|
Alert0.
|
|
setExpense_item(relatedExpense_item0);
|
|
}
|
|
|
|
const relatedExpense_item1 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Alert1 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Alert1?.setExpense_item)
|
|
{
|
|
await
|
|
Alert1.
|
|
setExpense_item(relatedExpense_item1);
|
|
}
|
|
|
|
const relatedExpense_item2 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Alert2 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Alert2?.setExpense_item)
|
|
{
|
|
await
|
|
Alert2.
|
|
setExpense_item(relatedExpense_item2);
|
|
}
|
|
|
|
const relatedExpense_item3 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Alert3 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Alert3?.setExpense_item)
|
|
{
|
|
await
|
|
Alert3.
|
|
setExpense_item(relatedExpense_item3);
|
|
}
|
|
|
|
const relatedExpense_item4 = await ExpenseItems.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseItems.count())),
|
|
});
|
|
const Alert4 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Alert4?.setExpense_item)
|
|
{
|
|
await
|
|
Alert4.
|
|
setExpense_item(relatedExpense_item4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function associateAlertWithBudget() {
|
|
|
|
const relatedBudget0 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Alert0 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Alert0?.setBudget)
|
|
{
|
|
await
|
|
Alert0.
|
|
setBudget(relatedBudget0);
|
|
}
|
|
|
|
const relatedBudget1 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Alert1 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Alert1?.setBudget)
|
|
{
|
|
await
|
|
Alert1.
|
|
setBudget(relatedBudget1);
|
|
}
|
|
|
|
const relatedBudget2 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Alert2 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Alert2?.setBudget)
|
|
{
|
|
await
|
|
Alert2.
|
|
setBudget(relatedBudget2);
|
|
}
|
|
|
|
const relatedBudget3 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Alert3 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Alert3?.setBudget)
|
|
{
|
|
await
|
|
Alert3.
|
|
setBudget(relatedBudget3);
|
|
}
|
|
|
|
const relatedBudget4 = await Budgets.findOne({
|
|
offset: Math.floor(Math.random() * (await Budgets.count())),
|
|
});
|
|
const Alert4 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Alert4?.setBudget)
|
|
{
|
|
await
|
|
Alert4.
|
|
setBudget(relatedBudget4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function associateAlertWithUser() {
|
|
|
|
const relatedUser0 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const Alert0 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (Alert0?.setUser)
|
|
{
|
|
await
|
|
Alert0.
|
|
setUser(relatedUser0);
|
|
}
|
|
|
|
const relatedUser1 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const Alert1 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (Alert1?.setUser)
|
|
{
|
|
await
|
|
Alert1.
|
|
setUser(relatedUser1);
|
|
}
|
|
|
|
const relatedUser2 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const Alert2 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (Alert2?.setUser)
|
|
{
|
|
await
|
|
Alert2.
|
|
setUser(relatedUser2);
|
|
}
|
|
|
|
const relatedUser3 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const Alert3 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (Alert3?.setUser)
|
|
{
|
|
await
|
|
Alert3.
|
|
setUser(relatedUser3);
|
|
}
|
|
|
|
const relatedUser4 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const Alert4 = await Alerts.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (Alert4?.setUser)
|
|
{
|
|
await
|
|
Alert4.
|
|
setUser(relatedUser4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associatePolicyRuleWithCategory() {
|
|
|
|
const relatedCategory0 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const PolicyRule0 = await PolicyRules.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (PolicyRule0?.setCategory)
|
|
{
|
|
await
|
|
PolicyRule0.
|
|
setCategory(relatedCategory0);
|
|
}
|
|
|
|
const relatedCategory1 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const PolicyRule1 = await PolicyRules.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (PolicyRule1?.setCategory)
|
|
{
|
|
await
|
|
PolicyRule1.
|
|
setCategory(relatedCategory1);
|
|
}
|
|
|
|
const relatedCategory2 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const PolicyRule2 = await PolicyRules.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (PolicyRule2?.setCategory)
|
|
{
|
|
await
|
|
PolicyRule2.
|
|
setCategory(relatedCategory2);
|
|
}
|
|
|
|
const relatedCategory3 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const PolicyRule3 = await PolicyRules.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (PolicyRule3?.setCategory)
|
|
{
|
|
await
|
|
PolicyRule3.
|
|
setCategory(relatedCategory3);
|
|
}
|
|
|
|
const relatedCategory4 = await ExpenseCategories.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseCategories.count())),
|
|
});
|
|
const PolicyRule4 = await PolicyRules.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (PolicyRule4?.setCategory)
|
|
{
|
|
await
|
|
PolicyRule4.
|
|
setCategory(relatedCategory4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateChatSessionWithUser() {
|
|
|
|
const relatedUser0 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ChatSession0 = await ChatSessions.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ChatSession0?.setUser)
|
|
{
|
|
await
|
|
ChatSession0.
|
|
setUser(relatedUser0);
|
|
}
|
|
|
|
const relatedUser1 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ChatSession1 = await ChatSessions.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ChatSession1?.setUser)
|
|
{
|
|
await
|
|
ChatSession1.
|
|
setUser(relatedUser1);
|
|
}
|
|
|
|
const relatedUser2 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ChatSession2 = await ChatSessions.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ChatSession2?.setUser)
|
|
{
|
|
await
|
|
ChatSession2.
|
|
setUser(relatedUser2);
|
|
}
|
|
|
|
const relatedUser3 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ChatSession3 = await ChatSessions.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ChatSession3?.setUser)
|
|
{
|
|
await
|
|
ChatSession3.
|
|
setUser(relatedUser3);
|
|
}
|
|
|
|
const relatedUser4 = await Users.findOne({
|
|
offset: Math.floor(Math.random() * (await Users.count())),
|
|
});
|
|
const ChatSession4 = await ChatSessions.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ChatSession4?.setUser)
|
|
{
|
|
await
|
|
ChatSession4.
|
|
setUser(relatedUser4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateChatMessageWithSession() {
|
|
|
|
const relatedSession0 = await ChatSessions.findOne({
|
|
offset: Math.floor(Math.random() * (await ChatSessions.count())),
|
|
});
|
|
const ChatMessage0 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ChatMessage0?.setSession)
|
|
{
|
|
await
|
|
ChatMessage0.
|
|
setSession(relatedSession0);
|
|
}
|
|
|
|
const relatedSession1 = await ChatSessions.findOne({
|
|
offset: Math.floor(Math.random() * (await ChatSessions.count())),
|
|
});
|
|
const ChatMessage1 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ChatMessage1?.setSession)
|
|
{
|
|
await
|
|
ChatMessage1.
|
|
setSession(relatedSession1);
|
|
}
|
|
|
|
const relatedSession2 = await ChatSessions.findOne({
|
|
offset: Math.floor(Math.random() * (await ChatSessions.count())),
|
|
});
|
|
const ChatMessage2 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ChatMessage2?.setSession)
|
|
{
|
|
await
|
|
ChatMessage2.
|
|
setSession(relatedSession2);
|
|
}
|
|
|
|
const relatedSession3 = await ChatSessions.findOne({
|
|
offset: Math.floor(Math.random() * (await ChatSessions.count())),
|
|
});
|
|
const ChatMessage3 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ChatMessage3?.setSession)
|
|
{
|
|
await
|
|
ChatMessage3.
|
|
setSession(relatedSession3);
|
|
}
|
|
|
|
const relatedSession4 = await ChatSessions.findOne({
|
|
offset: Math.floor(Math.random() * (await ChatSessions.count())),
|
|
});
|
|
const ChatMessage4 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ChatMessage4?.setSession)
|
|
{
|
|
await
|
|
ChatMessage4.
|
|
setSession(relatedSession4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function associateChatMessageWithRelated_report() {
|
|
|
|
const relatedRelated_report0 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ChatMessage0 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 0
|
|
});
|
|
if (ChatMessage0?.setRelated_report)
|
|
{
|
|
await
|
|
ChatMessage0.
|
|
setRelated_report(relatedRelated_report0);
|
|
}
|
|
|
|
const relatedRelated_report1 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ChatMessage1 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 1
|
|
});
|
|
if (ChatMessage1?.setRelated_report)
|
|
{
|
|
await
|
|
ChatMessage1.
|
|
setRelated_report(relatedRelated_report1);
|
|
}
|
|
|
|
const relatedRelated_report2 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ChatMessage2 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 2
|
|
});
|
|
if (ChatMessage2?.setRelated_report)
|
|
{
|
|
await
|
|
ChatMessage2.
|
|
setRelated_report(relatedRelated_report2);
|
|
}
|
|
|
|
const relatedRelated_report3 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ChatMessage3 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 3
|
|
});
|
|
if (ChatMessage3?.setRelated_report)
|
|
{
|
|
await
|
|
ChatMessage3.
|
|
setRelated_report(relatedRelated_report3);
|
|
}
|
|
|
|
const relatedRelated_report4 = await ExpenseReports.findOne({
|
|
offset: Math.floor(Math.random() * (await ExpenseReports.count())),
|
|
});
|
|
const ChatMessage4 = await ChatMessages.findOne({
|
|
order: [['id', 'ASC']],
|
|
offset: 4
|
|
});
|
|
if (ChatMessage4?.setRelated_report)
|
|
{
|
|
await
|
|
ChatMessage4.
|
|
setRelated_report(relatedRelated_report4);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
up: async (queryInterface, Sequelize) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Departments.bulkCreate(DepartmentsData);
|
|
|
|
|
|
|
|
|
|
await Budgets.bulkCreate(BudgetsData);
|
|
|
|
|
|
|
|
|
|
await ExpenseCategories.bulkCreate(ExpenseCategoriesData);
|
|
|
|
|
|
|
|
|
|
await ExpenseReports.bulkCreate(ExpenseReportsData);
|
|
|
|
|
|
|
|
|
|
await ExpenseItems.bulkCreate(ExpenseItemsData);
|
|
|
|
|
|
|
|
|
|
await Receipts.bulkCreate(ReceiptsData);
|
|
|
|
|
|
|
|
|
|
await ApprovalSteps.bulkCreate(ApprovalStepsData);
|
|
|
|
|
|
|
|
|
|
await BudgetChecks.bulkCreate(BudgetChecksData);
|
|
|
|
|
|
|
|
|
|
await Alerts.bulkCreate(AlertsData);
|
|
|
|
|
|
|
|
|
|
await PolicyRules.bulkCreate(PolicyRulesData);
|
|
|
|
|
|
|
|
|
|
await ChatSessions.bulkCreate(ChatSessionsData);
|
|
|
|
|
|
|
|
|
|
await ChatMessages.bulkCreate(ChatMessagesData);
|
|
|
|
|
|
await Promise.all([
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Similar logic for "relation_many"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateDepartmentWithBudget(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateExpenseReportWithSubmitter(),
|
|
|
|
|
|
|
|
|
|
await associateExpenseReportWithDepartment(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateExpenseReportWithBudget(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateExpenseItemWithReport(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateExpenseItemWithCategory(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateReceiptWithExpense_item(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateApprovalStepWithReport(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateApprovalStepWithApprover(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateBudgetCheckWithBudget(),
|
|
|
|
|
|
|
|
|
|
await associateBudgetCheckWithReport(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateAlertWithReport(),
|
|
|
|
|
|
|
|
|
|
await associateAlertWithExpense_item(),
|
|
|
|
|
|
|
|
|
|
await associateAlertWithBudget(),
|
|
|
|
|
|
|
|
|
|
await associateAlertWithUser(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associatePolicyRuleWithCategory(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateChatSessionWithUser(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateChatMessageWithSession(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await associateChatMessageWithRelated_report(),
|
|
|
|
|
|
|
|
]);
|
|
|
|
},
|
|
|
|
down: async (queryInterface, Sequelize) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await queryInterface.bulkDelete('departments', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('budgets', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('expense_categories', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('expense_reports', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('expense_items', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('receipts', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('approval_steps', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('budget_checks', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('alerts', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('policy_rules', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('chat_sessions', null, {});
|
|
|
|
|
|
await queryInterface.bulkDelete('chat_messages', null, {});
|
|
|
|
|
|
},
|
|
}; |