feat(finance): implement project finance and rate card management features

- Added new controllers for managing project finance and rate cards, including CRUD operations for rate card roles and project finance tasks.
- Introduced API routes for project finance and rate card functionalities, enhancing the backend structure.
- Developed frontend components for displaying and managing project finance data, including a finance drawer and rate card settings.
- Enhanced localization files to support new UI elements and ensure consistency across multiple languages.
- Implemented utility functions for handling man-days and financial calculations, improving overall functionality.
This commit is contained in:
chamikaJ
2025-07-24 15:23:34 +05:30
parent 4b54f2cc17
commit 4ffc3465e3
51 changed files with 10202 additions and 169 deletions

View File

@@ -0,0 +1,114 @@
{
"financeText": "Finance",
"ratecardSingularText": "Rate Card",
"groupByText": "Group by",
"statusText": "Status",
"phaseText": "Phase",
"priorityText": "Priority",
"exportButton": "Export",
"currencyText": "Currency",
"importButton": "Import",
"filterText": "Filter",
"billableOnlyText": "Billable Only",
"nonBillableOnlyText": "Non-Billable Only",
"allTasksText": "All Tasks",
"projectBudgetOverviewText": "Project Budget Overview",
"taskColumn": "Task",
"membersColumn": "Members",
"hoursColumn": "Estimated Hours",
"manDaysColumn": "Estimated Man Days",
"actualManDaysColumn": "Actual Man Days",
"effortVarianceColumn": "Effort Variance",
"totalTimeLoggedColumn": "Total Time Logged",
"costColumn": "Actual Cost",
"estimatedCostColumn": "Estimated Cost",
"fixedCostColumn": "Fixed Cost",
"totalBudgetedCostColumn": "Total Budgeted Cost",
"totalActualCostColumn": "Total Actual Cost",
"varianceColumn": "Variance",
"totalText": "Total",
"noTasksFound": "No tasks found",
"addRoleButton": "+ Add Role",
"ratecardImportantNotice": "* This rate card is generated based on the company's standard job titles and rates. However, you have the flexibility to modify it according to the project. These changes will not impact the organization's standard job titles and rates.",
"saveButton": "Save",
"jobTitleColumn": "Job Title",
"ratePerHourColumn": "Rate per hour",
"ratePerManDayColumn": "Rate per man day",
"calculationMethodText": "Calculation Method",
"hourlyRatesText": "Hourly Rates",
"manDaysText": "Man Days",
"hoursPerDayText": "Hours per Day",
"ratecardPluralText": "Rate Cards",
"labourHoursColumn": "Labour Hours",
"actions": "Actions",
"selectJobTitle": "Select Job Title",
"ratecardsPluralText": "Rate Card Templates",
"deleteConfirm": "Are you sure ?",
"yes": "Yes",
"no": "No",
"alreadyImportedRateCardMessage": "A rate card has already been imported. Clear all imported rate cards to add a new one.",
"budgetOverviewTooltips": {
"manualBudget": "Manual project budget amount set by project manager",
"totalActualCost": "Total actual cost including fixed costs",
"variance": "Difference between manual budget and actual cost",
"utilization": "Percentage of manual budget utilized",
"estimatedHours": "Total estimated hours from all tasks",
"fixedCosts": "Total fixed costs from all tasks",
"timeBasedCost": "Actual cost from time tracking (excluding fixed costs)",
"remainingBudget": "Remaining budget amount"
},
"budgetModal": {
"title": "Edit Project Budget",
"description": "Set a manual budget for this project. This budget will be used for all financial calculations and should include both time-based costs and fixed costs.",
"placeholder": "Enter budget amount",
"saveButton": "Save",
"cancelButton": "Cancel"
},
"budgetStatistics": {
"manualBudget": "Manual Budget",
"totalActualCost": "Total Actual Cost",
"variance": "Variance",
"budgetUtilization": "Budget Utilization",
"estimatedHours": "Estimated Hours",
"fixedCosts": "Fixed Costs",
"timeBasedCost": "Time-based Cost",
"remainingBudget": "Remaining Budget",
"noManualBudgetSet": "(No Manual Budget Set)"
},
"budgetSettingsDrawer": {
"title": "Project Budget Settings",
"budgetConfiguration": "Budget Configuration",
"projectBudget": "Project Budget",
"projectBudgetTooltip": "Total budget allocated for this project",
"currency": "Currency",
"costCalculationMethod": "Cost Calculation Method",
"calculationMethod": "Calculation Method",
"workingHoursPerDay": "Working Hours per Day",
"workingHoursPerDayTooltip": "Number of working hours in a day for man-day calculations",
"hourlyCalculationInfo": "Costs will be calculated using estimated hours × hourly rates",
"manDaysCalculationInfo": "Costs will be calculated using estimated man days × daily rates",
"importantNotes": "Important Notes",
"calculationMethodChangeNote": "• Changing the calculation method will affect how costs are calculated for all tasks in this project",
"immediateEffectNote": "• Changes take effect immediately and will recalculate all project totals",
"projectWideNote": "• Budget settings apply to the entire project and all its tasks",
"cancel": "Cancel",
"saveChanges": "Save Changes",
"budgetSettingsUpdated": "Budget settings updated successfully",
"budgetSettingsUpdateFailed": "Failed to update budget settings"
},
"columnTooltips": {
"hours": "Total estimated hours for all tasks. Calculated from task time estimates.",
"manDays": "Total estimated man days for all tasks. Based on {{hoursPerDay}} hours per working day.",
"actualManDays": "Actual man days spent based on time logged. Calculated as: Total Time Logged ÷ {{hoursPerDay}} hours per day.",
"effortVariance": "Difference between estimated and actual man days. Positive values indicate over-estimation, negative values indicate under-estimation.",
"totalTimeLogged": "Total time actually logged by team members across all tasks.",
"estimatedCostHourly": "Estimated cost calculated as: Estimated Hours × Hourly Rates for assigned team members.",
"estimatedCostManDays": "Estimated cost calculated as: Estimated Man Days × Daily Rates for assigned team members.",
"actualCost": "Actual cost based on time logged. Calculated as: Time Logged × Hourly Rates for team members.",
"fixedCost": "Fixed costs that don't depend on time spent. Added manually per task.",
"totalBudgetHourly": "Total budgeted cost including estimated cost (Hours × Hourly Rates) + Fixed Costs.",
"totalBudgetManDays": "Total budgeted cost including estimated cost (Man Days × Daily Rates) + Fixed Costs.",
"totalActual": "Total actual cost including time-based cost + Fixed Costs.",
"variance": "Cost variance: Total Budgeted Costs - Total Actual Cost. Positive values indicate under-budget, negative values indicate over-budget."
}
}

View File

@@ -0,0 +1,52 @@
{
"nameColumn": "Nombre",
"createdColumn": "Creado",
"noProjectsAvailable": "No hay proyectos disponibles",
"deleteConfirmationTitle": "¿Está seguro de que desea eliminar esta rate card?",
"deleteConfirmationOk": "Sí, eliminar",
"deleteConfirmationCancel": "Cancelar",
"searchPlaceholder": "Buscar rate cards por nombre",
"createRatecard": "Crear Rate Card",
"editTooltip": "Editar rate card",
"deleteTooltip": "Eliminar rate card",
"fetchError": "No se pudieron obtener las rate cards",
"createError": "No se pudo crear la rate card",
"deleteSuccess": "Rate card eliminada con éxito",
"deleteError": "No se pudo eliminar la rate card",
"jobTitleColumn": "Título del trabajo",
"ratePerHourColumn": "Tarifa por hora",
"ratePerDayColumn": "Tarifa por día",
"ratePerManDayColumn": "Tarifa por día-hombre",
"saveButton": "Guardar",
"addRoleButton": "Agregar rol",
"createRatecardSuccessMessage": "Rate card creada con éxito",
"createRatecardErrorMessage": "No se pudo crear la rate card",
"updateRatecardSuccessMessage": "Rate card actualizada con éxito",
"updateRatecardErrorMessage": "No se pudo actualizar la rate card",
"currency": "Moneda",
"actionsColumn": "Acciones",
"addAllButton": "Agregar todo",
"removeAllButton": "Eliminar todo",
"selectJobTitle": "Seleccionar título del trabajo",
"unsavedChangesTitle": "Tiene cambios sin guardar",
"unsavedChangesMessage": "¿Desea guardar los cambios antes de salir?",
"unsavedChangesSave": "Guardar",
"unsavedChangesDiscard": "Descartar",
"ratecardNameRequired": "El nombre de la rate card es obligatorio",
"ratecardNamePlaceholder": "Ingrese el nombre de la rate card",
"noRatecardsFound": "No se encontraron rate cards",
"loadingRateCards": "Cargando rate cards...",
"noJobTitlesAvailable": "No hay títulos de trabajo disponibles",
"noRolesAdded": "Aún no se han agregado roles",
"createFirstJobTitle": "Crear primer título de trabajo",
"jobRolesTitle": "Roles de trabajo",
"noJobTitlesMessage": "Por favor, cree primero títulos de trabajo en la configuración antes de agregar roles a las rate cards.",
"createNewJobTitle": "Crear nuevo título de trabajo",
"jobTitleNamePlaceholder": "Ingrese el nombre del título de trabajo",
"jobTitleNameRequired": "El nombre del título de trabajo es obligatorio",
"jobTitleCreatedSuccess": "Título de trabajo creado con éxito",
"jobTitleCreateError": "No se pudo crear el título de trabajo",
"createButton": "Crear",
"cancelButton": "Cancelar"
}