Created the get Expense details API

This commit is contained in:
ashutosh.nehete 2025-07-23 10:51:58 +05:30
parent 73cf85a1cc
commit 3083083148
36 changed files with 261 additions and 84 deletions

View File

@ -215,7 +215,7 @@ namespace Marco.Pms.DataAccess.Data
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
Name = "In Review", Name = "In Review",
Description = "These issues are currently under review", Description = "These issues are currently under review",
ColorCode = "#6c757d", ColorCode = "#8592a3",
IsDefault = true, IsDefault = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}, },
@ -395,7 +395,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Draft", Name = "Draft",
DisplayName = "Draft", DisplayName = "Draft",
Description = "Expense has been created but not yet submitted.", Description = "Expense has been created but not yet submitted.",
Color = "#6c757d", Color = "#8592a3",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
@ -406,7 +406,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Review Pending", Name = "Review Pending",
DisplayName = "Review", DisplayName = "Review",
Description = "Reviewer is currently reviewing the expense.", Description = "Reviewer is currently reviewing the expense.",
Color = "#0d6efd", Color = "#696cff",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
@ -417,7 +417,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Approval Pending", Name = "Approval Pending",
DisplayName = "Approve", DisplayName = "Approve",
Description = "Review is completed, waiting for action of approver.", Description = "Review is completed, waiting for action of approver.",
Color = "#0dcaf0", Color = "#03c3ec",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
@ -428,7 +428,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Rejected", Name = "Rejected",
DisplayName = "Reject", DisplayName = "Reject",
Description = "Expense was declined, often with a reason(either review rejected or approval rejected.", Description = "Expense was declined, often with a reason(either review rejected or approval rejected.",
Color = "#dc3545", Color = "#ff3e1d",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
@ -439,7 +439,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Process Pending", Name = "Process Pending",
DisplayName = "Process", DisplayName = "Process",
Description = "Approved expense is awaiting final payment.", Description = "Approved expense is awaiting final payment.",
Color = "#ffc107", Color = "#ffab00",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
@ -450,7 +450,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Processed", Name = "Processed",
DisplayName = "Paid", DisplayName = "Paid",
Description = "Expense has been settled.", Description = "Expense has been settled.",
Color = "#198754", Color = "#71dd37",
IsSystem = true, IsSystem = true,
IsActive = true, IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")

View File

@ -1274,7 +1274,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1295,7 +1295,7 @@ namespace Marco.Pms.DataAccess.Migrations
columns: new[] { "Id", "ColorCode", "Description", "IsDefault", "Name", "TenantId" }, columns: new[] { "Id", "ColorCode", "Description", "IsDefault", "Name", "TenantId" },
values: new object[,] values: new object[,]
{ {
{ new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), "#6c757d", "These issues are currently under review", true, "In Review", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), "#8592a3", "These issues are currently under review", true, "In Review", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"), "#FFCC99", "This is a newly created issue.", true, "New", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"), "#FFCC99", "This is a newly created issue.", true, "New", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"), "#E6FF99", "Assigned to employee or team of employees", true, "Assigned", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"), "#E6FF99", "Assigned to employee or team of employees", true, "Assigned", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"), "#99E6FF", "These issues are currently in progress", true, "In Progress", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"), "#99E6FF", "These issues are currently in progress", true, "In Progress", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },

View File

@ -1216,7 +1216,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1222,7 +1222,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1299,7 +1299,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1299,7 +1299,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1267,7 +1267,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1602,7 +1602,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1626,7 +1626,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1593,7 +1593,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1633,7 +1633,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1358,7 +1358,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1366,7 +1366,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1425,7 +1425,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1425,7 +1425,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1428,7 +1428,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1428,7 +1428,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1811,7 +1811,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1835,7 +1835,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1835,7 +1835,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1817,7 +1817,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1857,7 +1857,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1857,7 +1857,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1857,7 +1857,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1862,7 +1862,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -1934,7 +1934,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"), Id = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"),
Color = "#6c757d", Color = "#8592a3",
Description = "Expense has been created but not yet submitted.", Description = "Expense has been created but not yet submitted.",
DisplayName = "Draft", DisplayName = "Draft",
IsActive = true, IsActive = true,
@ -1945,7 +1945,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"),
Color = "#0d6efd", Color = "#696cff",
Description = "Reviewer is currently reviewing the expense.", Description = "Reviewer is currently reviewing the expense.",
DisplayName = "Review", DisplayName = "Review",
IsActive = true, IsActive = true,
@ -1956,7 +1956,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), Id = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"),
Color = "#0dcaf0", Color = "#03c3ec",
Description = "Review is completed, waiting for action of approver.", Description = "Review is completed, waiting for action of approver.",
DisplayName = "Approve", DisplayName = "Approve",
IsActive = true, IsActive = true,
@ -1967,7 +1967,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), Id = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"),
Color = "#dc3545", Color = "#ff3e1d",
Description = "Expense was declined, often with a reason(either review rejected or approval rejected.", Description = "Expense was declined, often with a reason(either review rejected or approval rejected.",
DisplayName = "Reject", DisplayName = "Reject",
IsActive = true, IsActive = true,
@ -1978,7 +1978,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), Id = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"),
Color = "#ffc107", Color = "#ffab00",
Description = "Approved expense is awaiting final payment.", Description = "Approved expense is awaiting final payment.",
DisplayName = "Process", DisplayName = "Process",
IsActive = true, IsActive = true,
@ -1989,7 +1989,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), Id = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"),
Color = "#198754", Color = "#71dd37",
Description = "Expense has been settled.", Description = "Expense has been settled.",
DisplayName = "Paid", DisplayName = "Paid",
IsActive = true, IsActive = true,
@ -2535,7 +2535,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -372,12 +372,12 @@ namespace Marco.Pms.DataAccess.Migrations
columns: new[] { "Id", "Color", "Description", "DisplayName", "IsActive", "IsSystem", "Name", "TenantId" }, columns: new[] { "Id", "Color", "Description", "DisplayName", "IsActive", "IsSystem", "Name", "TenantId" },
values: new object[,] values: new object[,]
{ {
{ new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"), "#6c757d", "Expense has been created but not yet submitted.", "Draft", true, true, "Draft", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"), "#8592a3", "Expense has been created but not yet submitted.", "Draft", true, true, "Draft", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), "#0dcaf0", "Review is completed, waiting for action of approver.", "Approve", true, true, "Approval Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), "#03c3ec", "Review is completed, waiting for action of approver.", "Approve", true, true, "Approval Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), "#198754", "Expense has been settled.", "Paid", true, true, "Processed", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), "#71dd37", "Expense has been settled.", "Paid", true, true, "Processed", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), "#0d6efd", "Reviewer is currently reviewing the expense.", "Review", true, true, "Review Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), "#696cff", "Reviewer is currently reviewing the expense.", "Review", true, true, "Review Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), "#dc3545", "Expense was declined, often with a reason(either review rejected or approval rejected.", "Reject", true, true, "Rejected", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, { new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), "#ff3e1d", "Expense was declined, often with a reason(either review rejected or approval rejected.", "Reject", true, true, "Rejected", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), "#ffc107", "Approved expense is awaiting final payment.", "Process", true, true, "Process Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") } { new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), "#ffab00", "Approved expense is awaiting final payment.", "Process", true, true, "Process Pending", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }
}); });
migrationBuilder.InsertData( migrationBuilder.InsertData(

View File

@ -20,7 +20,7 @@ namespace Marco.Pms.DataAccess.Migrations
.HasAnnotation("ProductVersion", "8.0.12") .HasAnnotation("ProductVersion", "8.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
//MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b =>
{ {
@ -1931,7 +1931,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"), Id = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"),
Color = "#6c757d", Color = "#8592a3",
Description = "Expense has been created but not yet submitted.", Description = "Expense has been created but not yet submitted.",
DisplayName = "Draft", DisplayName = "Draft",
IsActive = true, IsActive = true,
@ -1942,7 +1942,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"),
Color = "#0d6efd", Color = "#696cff",
Description = "Reviewer is currently reviewing the expense.", Description = "Reviewer is currently reviewing the expense.",
DisplayName = "Review", DisplayName = "Review",
IsActive = true, IsActive = true,
@ -1953,7 +1953,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), Id = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"),
Color = "#0dcaf0", Color = "#03c3ec",
Description = "Review is completed, waiting for action of approver.", Description = "Review is completed, waiting for action of approver.",
DisplayName = "Approve", DisplayName = "Approve",
IsActive = true, IsActive = true,
@ -1964,7 +1964,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), Id = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"),
Color = "#dc3545", Color = "#ff3e1d",
Description = "Expense was declined, often with a reason(either review rejected or approval rejected.", Description = "Expense was declined, often with a reason(either review rejected or approval rejected.",
DisplayName = "Reject", DisplayName = "Reject",
IsActive = true, IsActive = true,
@ -1975,7 +1975,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), Id = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"),
Color = "#ffc107", Color = "#ffab00",
Description = "Approved expense is awaiting final payment.", Description = "Approved expense is awaiting final payment.",
DisplayName = "Process", DisplayName = "Process",
IsActive = true, IsActive = true,
@ -1986,7 +1986,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), Id = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"),
Color = "#198754", Color = "#71dd37",
Description = "Expense has been settled.", Description = "Expense has been settled.",
DisplayName = "Paid", DisplayName = "Paid",
IsActive = true, IsActive = true,
@ -2532,7 +2532,7 @@ namespace Marco.Pms.DataAccess.Migrations
new new
{ {
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
ColorCode = "#6c757d", ColorCode = "#8592a3",
Description = "These issues are currently under review", Description = "These issues are currently under review",
IsDefault = true, IsDefault = true,
Name = "In Review", Name = "In Review",

View File

@ -91,6 +91,17 @@ namespace Marco.Pms.Helpers.CacheHelper
return (totalPages, totalCount, expenses); return (totalPages, totalCount, expenses);
} }
public async Task<ExpenseDetailsMongoDB> GetExpenseDetailsByIdAsync(Guid id, Guid tenantId)
{
var filter = Builders<ExpenseDetailsMongoDB>.Filter.And(
Builders<ExpenseDetailsMongoDB>.Filter.Eq(e => e.Id, id.ToString()),
Builders<ExpenseDetailsMongoDB>.Filter.Eq(e => e.TenantId, tenantId.ToString())
);
var expense = await _collection.Find(filter).FirstOrDefaultAsync();
return expense;
}
private async Task InitializeCollectionAsync() private async Task InitializeCollectionAsync()
{ {
var indexKeys = Builders<ExpenseDetailsMongoDB>.IndexKeys.Ascending(x => x.ExpireAt); var indexKeys = Builders<ExpenseDetailsMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);

View File

@ -0,0 +1,31 @@
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Model.ViewModels.Projects;
namespace Marco.Pms.Model.ViewModels.Expenses
{
public class ExpenseDetailsVM
{
public Guid Id { get; set; }
public ProjectInfoVM? Project { get; set; }
public ExpensesTypeMasterVM? ExpensesType { get; set; }
public PaymentModeMatserVM? PaymentMode { get; set; }
public BasicEmployeeVM? PaidBy { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public DateTime TransactionDate { get; set; }
public DateTime CreatedAt { get; set; }
public string SupplerName { get; set; } = string.Empty;
public double Amount { get; set; }
public ExpensesStatusMasterVM? Status { get; set; }
public List<ExpensesStatusMasterVM>? NextStatus { get; set; }
public bool PreApproved { get; set; } = false;
public string? TransactionId { get; set; }
public string Description { get; set; } = string.Empty;
public string? Location { get; set; }
public List<string> S3Key { get; set; } = new List<string>();
public List<string>? ThumbS3Key { get; set; }
public string? GSTNumber { get; set; }
public int? NoOfPersons { get; set; }
public bool IsActive { get; set; } = true;
}
}

View File

@ -47,9 +47,11 @@ namespace Marco.Pms.Services.Controllers
} }
[HttpGet("details/{id}")] [HttpGet("details/{id}")]
public string Get(int id) public async Task<IActionResult> GetExpenseDetails(Guid id)
{ {
return "value"; var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _expensesService.GetExpenseDetailsAsync(id, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
} }
/// <summary> /// <summary>

View File

@ -900,39 +900,43 @@ namespace Marco.Pms.Services.Helpers
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error occurd while storing expense related table in cahce"); _logger.LogError(ex, "Error occurd while storing expense related table in cahce");
return;
} }
return;
} }
public async Task AddExpenseByIdAsync(Guid Id, Guid tenantId) public async Task<ExpenseDetailsMongoDB?> AddExpenseByIdAsync(Guid Id, Guid tenantId)
{ {
var expense = await _context.Expenses.AsNoTracking().FirstOrDefaultAsync(e => e.Id == Id && e.TenantId == tenantId); var expense = await _context.Expenses.AsNoTracking().FirstOrDefaultAsync(e => e.Id == Id && e.TenantId == tenantId);
var expenseCache = _mapper.Map<ExpenseDetailsMongoDB>(expense); var expenseCache = _mapper.Map<ExpenseDetailsMongoDB>(expense);
if (expense != null) if (expense == null)
{ {
try return null;
}
try
{
var billAttachments = await _context.BillAttachments
.Include(ba => ba.Document)
.AsNoTracking()
.Where(ba => ba.ExpensesId == expense.Id && ba.Document != null)
.GroupBy(ba => ba.ExpensesId)
.Select(g => new
{ {
var billAttachments = await _context.BillAttachments S3Keys = g.Select(ba => ba.Document!.S3Key).ToList(),
.Include(ba => ba.Document) ThumbS3Keys = g.Select(ba => ba.Document!.ThumbS3Key ?? ba.Document.S3Key).ToList()
.AsNoTracking() })
.Where(ba => ba.ExpensesId == expense.Id && ba.Document != null) .FirstOrDefaultAsync();
.GroupBy(ba => ba.ExpensesId) if (billAttachments != null)
.Select(g => new
{
S3Keys = g.Select(ba => ba.Document!.S3Key).ToList(),
ThumbS3Keys = g.Select(ba => ba.Document!.ThumbS3Key ?? ba.Document.S3Key).ToList()
})
.FirstOrDefaultAsync();
if (billAttachments != null)
{
expenseCache.S3Key = billAttachments.S3Keys;
expenseCache.ThumbS3Key = billAttachments.ThumbS3Keys;
}
}
catch (Exception ex)
{ {
_logger.LogError(ex, "Error occurd while fetched expense related tables to save in cahce"); expenseCache.S3Key = billAttachments.S3Keys;
expenseCache.ThumbS3Key = billAttachments.ThumbS3Keys;
} }
} }
catch (Exception ex)
{
_logger.LogError(ex, "Error occurd while fetched expense related tables to save in cahce");
return null;
}
try try
{ {
await _expenseCache.AddExpenseToCacheAsync(expenseCache); await _expenseCache.AddExpenseToCacheAsync(expenseCache);
@ -940,8 +944,12 @@ namespace Marco.Pms.Services.Helpers
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error occurd while storing expense related table in cahce"); _logger.LogError(ex, "Error occurd while storing expense related table in cahce");
return null;
} }
return expenseCache;
} }
public async Task AddExpensesListToCache(List<Expenses> expenses) public async Task AddExpensesListToCache(List<Expenses> expenses)
{ {
@ -1000,6 +1008,16 @@ namespace Marco.Pms.Services.Helpers
return (0, 0, null); return (0, 0, null);
} }
public async Task<ExpenseDetailsMongoDB?> GetExpenseDetailsById(Guid id, Guid tenantId)
{
var response = await _expenseCache.GetExpenseDetailsByIdAsync(id, tenantId);
if (response == null || response.Id == string.Empty)
{
return null;
}
return response;
}
#endregion #endregion
#region ======================================================= Report Cache ======================================================= #region ======================================================= Report Cache =======================================================

View File

@ -13,6 +13,7 @@ using Marco.Pms.Model.Projects;
using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Employee; using Marco.Pms.Model.ViewModels.Employee;
using Marco.Pms.Model.ViewModels.Expanses; using Marco.Pms.Model.ViewModels.Expanses;
using Marco.Pms.Model.ViewModels.Expenses;
using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Model.ViewModels.Projects; using Marco.Pms.Model.ViewModels.Projects;
@ -177,6 +178,11 @@ namespace Marco.Pms.Services.MappingProfiles
dest => dest.Id, dest => dest.Id,
opt => opt.MapFrom(src => Guid.Parse(src.Id))); opt => opt.MapFrom(src => Guid.Parse(src.Id)));
CreateMap<ExpenseDetailsMongoDB, ExpenseDetailsVM>()
.ForMember(
dest => dest.Id,
opt => opt.MapFrom(src => Guid.Parse(src.Id)));
#endregion #endregion
#region ======================================================= Master ======================================================= #region ======================================================= Master =======================================================

View File

@ -5,10 +5,12 @@ using Marco.Pms.Model.Dtos.Expenses;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Expenses;
using Marco.Pms.Model.MongoDBModels.Expenses;
using Marco.Pms.Model.MongoDBModels.Utility; using Marco.Pms.Model.MongoDBModels.Utility;
using Marco.Pms.Model.Utilities; using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Expanses; using Marco.Pms.Model.ViewModels.Expanses;
using Marco.Pms.Model.ViewModels.Expenses;
using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Model.ViewModels.Projects; using Marco.Pms.Model.ViewModels.Projects;
using Marco.Pms.Services.Helpers; using Marco.Pms.Services.Helpers;
@ -210,7 +212,7 @@ namespace Marco.Pms.Services.Service
Message = dbEx.Message, Message = dbEx.Message,
StackTrace = dbEx.StackTrace, StackTrace = dbEx.StackTrace,
Source = dbEx.Source, Source = dbEx.Source,
innerexcption = new InnerException = new
{ {
Message = dbEx.InnerException?.Message, Message = dbEx.InnerException?.Message,
StackTrace = dbEx.InnerException?.StackTrace, StackTrace = dbEx.InnerException?.StackTrace,
@ -226,7 +228,7 @@ namespace Marco.Pms.Services.Service
Message = ex.Message, Message = ex.Message,
StackTrace = ex.StackTrace, StackTrace = ex.StackTrace,
Source = ex.Source, Source = ex.Source,
innerexcption = new InnerException = new
{ {
Message = ex.InnerException?.Message, Message = ex.InnerException?.Message,
StackTrace = ex.InnerException?.StackTrace, StackTrace = ex.InnerException?.StackTrace,
@ -236,9 +238,35 @@ namespace Marco.Pms.Services.Service
} }
} }
public string Get(int id) public async Task<ApiResponse<object>> GetExpenseDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
{ {
return "value"; try
{
var expenseDetails = await _cache.GetExpenseDetailsById(id, tenantId);
if (expenseDetails == null)
{
expenseDetails = await _cache.AddExpenseByIdAsync(id, tenantId);
}
var vm = GetAllExpnesRelatedTablesFromMongoDB([expenseDetails]);
return ApiResponse<object>.SuccessResponse(vm, "Successfully fetched the details of expense", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "An unhandled exception occurred while fetching an expense details {ExpenseId}.", id);
return ApiResponse<object>.ErrorResponse("An internal server error occurred.", new
{
Message = ex.Message,
StackTrace = ex.StackTrace,
Source = ex.Source,
InnerException = new
{
Message = ex.InnerException?.Message,
StackTrace = ex.InnerException?.StackTrace,
Source = ex.InnerException?.Source,
}
}, 500);
}
} }
/// <summary> /// <summary>
@ -391,7 +419,7 @@ namespace Marco.Pms.Services.Service
Message = dbEx.Message, Message = dbEx.Message,
StackTrace = dbEx.StackTrace, StackTrace = dbEx.StackTrace,
Source = dbEx.Source, Source = dbEx.Source,
innerexcption = new InnerException = new
{ {
Message = dbEx.InnerException?.Message, Message = dbEx.InnerException?.Message,
StackTrace = dbEx.InnerException?.StackTrace, StackTrace = dbEx.InnerException?.StackTrace,
@ -407,7 +435,7 @@ namespace Marco.Pms.Services.Service
Message = ex.Message, Message = ex.Message,
StackTrace = ex.StackTrace, StackTrace = ex.StackTrace,
Source = ex.Source, Source = ex.Source,
innerexcption = new InnerException = new
{ {
Message = ex.InnerException?.Message, Message = ex.InnerException?.Message,
StackTrace = ex.InnerException?.StackTrace, StackTrace = ex.InnerException?.StackTrace,
@ -423,7 +451,7 @@ namespace Marco.Pms.Services.Service
Message = ex.Message, Message = ex.Message,
StackTrace = ex.StackTrace, StackTrace = ex.StackTrace,
Source = ex.Source, Source = ex.Source,
innerexcption = new InnerException = new
{ {
Message = ex.InnerException?.Message, Message = ex.InnerException?.Message,
StackTrace = ex.InnerException?.StackTrace, StackTrace = ex.InnerException?.StackTrace,
@ -716,6 +744,7 @@ namespace Marco.Pms.Services.Service
public void Delete(int id) public void Delete(int id)
{ {
} }
#region =================================================================== Helper Functions =================================================================== #region =================================================================== Helper Functions ===================================================================
private async Task<List<ExpenseList>> GetAllExpnesRelatedTables(List<Expenses> model) private async Task<List<ExpenseList>> GetAllExpnesRelatedTables(List<Expenses> model)
@ -797,6 +826,85 @@ namespace Marco.Pms.Services.Service
return expenseList; return expenseList;
} }
private async Task<List<ExpenseDetailsVM>> GetAllExpnesRelatedTablesFromMongoDB(List<ExpenseDetailsMongoDB> model)
{
List<ExpenseDetailsVM> expenseList = new List<ExpenseDetailsVM>();
var projectIds = model.Select(m => Guid.Parse(m.ProjectId)).ToList();
var statusIds = model.Select(m => Guid.Parse(m.StatusId)).ToList();
var expensesTypeIds = model.Select(m => Guid.Parse(m.ExpensesTypeId)).ToList();
var paymentModeIds = model.Select(m => Guid.Parse(m.PaymentModeId)).ToList();
var createdByIds = model.Select(m => Guid.Parse(m.CreatedById)).ToList();
var paidByIds = model.Select(m => Guid.Parse(m.PaidById)).ToList();
var projectTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.Projects.AsNoTracking().Where(p => projectIds.Contains(p.Id)).ToListAsync();
});
var paidByTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.Employees.AsNoTracking().Where(e => paidByIds.Contains(e.Id)).ToListAsync();
});
var createdByTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.Employees.AsNoTracking().Where(e => createdByIds.Contains(e.Id)).ToListAsync();
});
var expenseTypeTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.ExpensesTypeMaster.AsNoTracking().Where(et => expensesTypeIds.Contains(et.Id)).ToListAsync();
});
var paymentModeTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id)).ToListAsync();
});
var statusMappingTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.ExpensesStatusMapping
.Include(s => s.Status)
.Include(s => s.NextStatus)
.AsNoTracking()
.Where(es => statusIds.Contains(es.StatusId) && es.Status != null)
.GroupBy(s => s.StatusId)
.Select(g => new
{
StatusId = g.Key,
Status = g.Select(s => s.Status).FirstOrDefault(),
NextStatus = g.Select(s => s.NextStatus).ToList()
}).ToListAsync();
});
// Await all prerequisite checks at once.
await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask);
var projects = await projectTask;
var expenseTypes = await expenseTypeTask;
var paymentModes = await paymentModeTask;
var statusMappings = await statusMappingTask;
var paidBys = await paidByTask;
var createdBys = await createdByTask;
expenseList = model.Select(m =>
{
var response = _mapper.Map<ExpenseDetailsVM>(m);
response.Project = projects.Where(p => p.Id == Guid.Parse(m.ProjectId)).Select(p => _mapper.Map<ProjectInfoVM>(p)).FirstOrDefault();
response.PaidBy = paidBys.Where(p => p.Id == Guid.Parse(m.PaidById)).Select(p => _mapper.Map<BasicEmployeeVM>(p)).FirstOrDefault();
response.CreatedBy = createdBys.Where(e => e.Id == Guid.Parse(m.CreatedById)).Select(e => _mapper.Map<BasicEmployeeVM>(e)).FirstOrDefault();
response.Status = statusMappings.Where(s => s.StatusId == Guid.Parse(m.StatusId)).Select(s => _mapper.Map<ExpensesStatusMasterVM>(s.Status)).FirstOrDefault();
response.NextStatus = statusMappings.Where(s => s.StatusId == Guid.Parse(m.StatusId)).Select(s => _mapper.Map<List<ExpensesStatusMasterVM>>(s.NextStatus)).FirstOrDefault();
response.PaymentMode = paymentModes.Where(pm => pm.Id == Guid.Parse(m.PaymentModeId)).Select(pm => _mapper.Map<PaymentModeMatserVM>(pm)).FirstOrDefault();
response.ExpensesType = expenseTypes.Where(et => et.Id == Guid.Parse(m.ExpensesTypeId)).Select(et => _mapper.Map<ExpensesTypeMasterVM>(et)).FirstOrDefault();
return response;
}).ToList();
return expenseList;
}
/// <summary> /// <summary>
/// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string). /// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string).

View File

@ -7,6 +7,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
public interface IExpensesService public interface IExpensesService
{ {
Task<ApiResponse<object>> GetExpensesListAsync(Employee loggedInEmployee, Guid tenantId, string? filter, int pageSize, int pageNumber); Task<ApiResponse<object>> GetExpensesListAsync(Employee loggedInEmployee, Guid tenantId, string? filter, int pageSize, int pageNumber);
Task<ApiResponse<object>> GetExpenseDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateExpenseAsync(CreateExpensesDto dto, Employee loggedInEmployee, Guid tenantId); Task<ApiResponse<object>> CreateExpenseAsync(CreateExpensesDto dto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> ChangeStatusAsync(ExpenseRecordDto model, Employee loggedInEmployee, Guid tenantId); Task<ApiResponse<object>> ChangeStatusAsync(ExpenseRecordDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId); Task<ApiResponse<object>> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId);