Added the API to get list of jobs
This commit is contained in:
parent
6e945cf6c1
commit
4a0144c23b
8461
Marco.Pms.DataAccess/Migrations/20251113051300_Removed_Assignee_From_JobTicket_Table.Designer.cs
generated
Normal file
8461
Marco.Pms.DataAccess/Migrations/20251113051300_Removed_Assignee_From_JobTicket_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Removed_Assignee_From_JobTicket_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_JobTickets_Employees_AssigneeId",
|
||||||
|
table: "JobTickets");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_JobTickets_AssigneeId",
|
||||||
|
table: "JobTickets");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AssigneeId",
|
||||||
|
table: "JobTickets");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "AssigneeId",
|
||||||
|
table: "JobTickets",
|
||||||
|
type: "char(36)",
|
||||||
|
nullable: true,
|
||||||
|
collation: "ascii_general_ci");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_JobTickets_AssigneeId",
|
||||||
|
table: "JobTickets",
|
||||||
|
column: "AssigneeId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_JobTickets_Employees_AssigneeId",
|
||||||
|
table: "JobTickets",
|
||||||
|
column: "AssigneeId",
|
||||||
|
principalTable: "Employees",
|
||||||
|
principalColumn: "Id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5291,9 +5291,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid?>("AssigneeId")
|
|
||||||
.HasColumnType("char(36)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
b.Property<DateTime>("CreatedAt")
|
||||||
.HasColumnType("datetime(6)");
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
@ -5334,8 +5331,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("AssigneeId");
|
|
||||||
|
|
||||||
b.HasIndex("CreatedById");
|
b.HasIndex("CreatedById");
|
||||||
|
|
||||||
b.HasIndex("ProjectId");
|
b.HasIndex("ProjectId");
|
||||||
@ -8086,10 +8081,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Marco.Pms.Model.ServiceProject.JobTicket", b =>
|
modelBuilder.Entity("Marco.Pms.Model.ServiceProject.JobTicket", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "Assignee")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("AssigneeId");
|
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
|
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("CreatedById")
|
.HasForeignKey("CreatedById")
|
||||||
@ -8118,8 +8109,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("UpdatedById");
|
.HasForeignKey("UpdatedById");
|
||||||
|
|
||||||
b.Navigation("Assignee");
|
|
||||||
|
|
||||||
b.Navigation("CreatedBy");
|
b.Navigation("CreatedBy");
|
||||||
|
|
||||||
b.Navigation("Project");
|
b.Navigation("Project");
|
||||||
|
|||||||
@ -15,11 +15,6 @@ namespace Marco.Pms.Model.ServiceProject
|
|||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
[ForeignKey("ProjectId")]
|
[ForeignKey("ProjectId")]
|
||||||
public ServiceProject? Project { get; set; }
|
public ServiceProject? Project { get; set; }
|
||||||
public Guid? AssigneeId { get; set; }
|
|
||||||
|
|
||||||
[ValidateNever]
|
|
||||||
[ForeignKey("AssigneeId")]
|
|
||||||
public Employee? Assignee { get; set; }
|
|
||||||
public Guid StatusId { get; set; }
|
public Guid StatusId { get; set; }
|
||||||
|
|
||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using Marco.Pms.Model.Dtos.ServiceProject;
|
using Marco.Pms.Model.Dtos.ServiceProject;
|
||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Employees;
|
||||||
using Marco.Pms.Model.Utilities;
|
|
||||||
using Marco.Pms.Model.ViewModels.ServiceProject;
|
using Marco.Pms.Model.ViewModels.ServiceProject;
|
||||||
using Marco.Pms.Services.Service.ServiceInterfaces;
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
@ -35,11 +34,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public async Task<IActionResult> GetServiceProjectList([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
public async Task<IActionResult> GetServiceProjectList([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.GetServiceProjectListAsync(pageNumber, pageSize, loggedInEmploee, tenantId);
|
var response = await _serviceProject.GetServiceProjectListAsync(pageNumber, pageSize, loggedInEmploee, tenantId);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
@ -49,11 +43,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
[HttpGet("details/{id}")]
|
[HttpGet("details/{id}")]
|
||||||
public async Task<IActionResult> GetServiceProjectDetails(Guid id)
|
public async Task<IActionResult> GetServiceProjectDetails(Guid id)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.GetServiceProjectDetailsAsync(id, loggedInEmploee, tenantId);
|
var response = await _serviceProject.GetServiceProjectDetailsAsync(id, loggedInEmploee, tenantId);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
@ -63,11 +52,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
[HttpPost("create")]
|
[HttpPost("create")]
|
||||||
public async Task<IActionResult> CreateProject([FromBody] ServiceProjectDto serviceProject)
|
public async Task<IActionResult> CreateProject([FromBody] ServiceProjectDto serviceProject)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.CreateServiceProjectAsync(serviceProject, loggedInEmploee, tenantId);
|
var response = await _serviceProject.CreateServiceProjectAsync(serviceProject, loggedInEmploee, tenantId);
|
||||||
if (response.Success)
|
if (response.Success)
|
||||||
@ -83,11 +67,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
[HttpPut("edit/{id}")]
|
[HttpPut("edit/{id}")]
|
||||||
public async Task<IActionResult> UpdateServicecProject(Guid id, [FromBody] ServiceProjectDto serviceProject)
|
public async Task<IActionResult> UpdateServicecProject(Guid id, [FromBody] ServiceProjectDto serviceProject)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.UpdateServiceProjectAsync(id, serviceProject, loggedInEmploee, tenantId);
|
var response = await _serviceProject.UpdateServiceProjectAsync(id, serviceProject, loggedInEmploee, tenantId);
|
||||||
if (response.Success)
|
if (response.Success)
|
||||||
@ -102,11 +81,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
[HttpDelete("delete/{id}")]
|
[HttpDelete("delete/{id}")]
|
||||||
public async Task<IActionResult> DeActivateServiceProject(Guid id, bool isActive = false)
|
public async Task<IActionResult> DeActivateServiceProject(Guid id, bool isActive = false)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.DeActivateServiceProjectAsync(id, isActive, loggedInEmploee, tenantId);
|
var response = await _serviceProject.DeActivateServiceProjectAsync(id, isActive, loggedInEmploee, tenantId);
|
||||||
if (response.Success)
|
if (response.Success)
|
||||||
@ -120,14 +94,18 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
|
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
|
|
||||||
|
[HttpGet("job/list")]
|
||||||
|
public async Task<IActionResult> GetJobTicketsList([FromQuery] Guid? projectId, [FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20, [FromQuery] bool isActive = true)
|
||||||
|
{
|
||||||
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.GetJobTicketsListAsync(projectId, pageNumber, pageSize, isActive, tenantId, loggedInEmploee);
|
||||||
|
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("job/create")]
|
[HttpPost("job/create")]
|
||||||
public async Task<IActionResult> CreateJobTicket(CreateJobTicketDto model)
|
public async Task<IActionResult> CreateJobTicket(CreateJobTicketDto model)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
}
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.CreateJobTicketAsync(model, loggedInEmploee, tenantId);
|
var response = await _serviceProject.CreateJobTicketAsync(model, loggedInEmploee, tenantId);
|
||||||
if (response.Success)
|
if (response.Success)
|
||||||
|
|||||||
@ -16,6 +16,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
|
Task<ApiResponse<object>> GetJobTicketsListAsync(Guid? projectId, int pageNumber, int pageSize, bool isActive, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> CreateJobTicketAsync(CreateJobTicketDto model, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> CreateJobTicketAsync(CreateJobTicketDto model, Employee loggedInEmployee, Guid tenantId);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -362,6 +362,139 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a paginated, filtered list of job tickets for a tenant, including related project, status, assignees, and tags.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="projectId">Optional project filter.</param>
|
||||||
|
/// <param name="pageNumber">Page index (1-based).</param>
|
||||||
|
/// <param name="pageSize">Page size.</param>
|
||||||
|
/// <param name="isActive">Active filter.</param>
|
||||||
|
/// <param name="tenantId">Tenant context.</param>
|
||||||
|
/// <param name="loggedInEmployee">Employee requesting data.</param>
|
||||||
|
/// <returns>Paged list of JobTicketVM plus metadata, or error response.</returns>
|
||||||
|
public async Task<ApiResponse<object>> GetJobTicketsListAsync(Guid? projectId, int pageNumber, int pageSize, bool isActive, Guid tenantId, Employee loggedInEmployee)
|
||||||
|
{
|
||||||
|
if (tenantId == Guid.Empty)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("TenantId missing for job ticket fetch by employee {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
return ApiResponse<object>.ErrorResponse(
|
||||||
|
"Access Denied",
|
||||||
|
"Missing or invalid tenant context.",
|
||||||
|
403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageNumber < 1 || pageSize < 1)
|
||||||
|
{
|
||||||
|
_logger.LogInfo("Invalid paging parameters for job ticket fetch. PageNumber: {PageNumber}, PageSize: {PageSize}", pageNumber, pageSize);
|
||||||
|
return ApiResponse<object>.ErrorResponse(
|
||||||
|
"Bad Request",
|
||||||
|
"Page number and size must be greater than zero.",
|
||||||
|
400);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Build filtered query with necessary includes for eager loading
|
||||||
|
var jobTicketQuery = _context.JobTickets
|
||||||
|
.Include(jt => jt.Status)
|
||||||
|
.Include(jt => jt.Project)
|
||||||
|
.Include(jt => jt.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(jt =>
|
||||||
|
jt.TenantId == tenantId &&
|
||||||
|
jt.IsActive == isActive &&
|
||||||
|
jt.Project != null &&
|
||||||
|
jt.Status != null &&
|
||||||
|
jt.CreatedBy != null &&
|
||||||
|
jt.CreatedBy.JobRole != null);
|
||||||
|
|
||||||
|
// Optionally filter by project
|
||||||
|
if (projectId.HasValue)
|
||||||
|
{
|
||||||
|
var projectExists = await _context.ServiceProjects
|
||||||
|
.AnyAsync(sp => sp.Id == projectId && sp.TenantId == tenantId && sp.IsActive);
|
||||||
|
|
||||||
|
if (!projectExists)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Requested service project not found. ProjectId: {ProjectId}, TenantId: {TenantId}", projectId, tenantId);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Service project not found", "Service project not found for this tenant.", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobTicketQuery = jobTicketQuery.Where(jt => jt.ProjectId == projectId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total results and paging
|
||||||
|
var totalEntities = await jobTicketQuery.CountAsync();
|
||||||
|
var totalPages = (int)Math.Ceiling((double)totalEntities / pageSize);
|
||||||
|
|
||||||
|
// Fetch filtered/paged tickets
|
||||||
|
var jobTickets = await jobTicketQuery
|
||||||
|
.OrderByDescending(e => e.CreatedAt)
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var jobTicketIds = jobTickets.Select(jt => jt.Id).ToList();
|
||||||
|
|
||||||
|
// Fetch assignee and tag mappings concurrently using separate DbContexts for parallel IO
|
||||||
|
var assigneeTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.JobEmployeeMappings
|
||||||
|
.Include(jem => jem.Assignee).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(jem => jobTicketIds.Contains(jem.JobTicketId) && jem.Assignee != null && jem.Assignee.JobRole != null && jem.TenantId == tenantId)
|
||||||
|
.ToListAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
var tagTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.JobTagMappings
|
||||||
|
.Include(jtm => jtm.JobTag)
|
||||||
|
.Where(jtm => jobTicketIds.Contains(jtm.JobTicketId) && jtm.JobTag != null && jtm.TenantId == tenantId)
|
||||||
|
.ToListAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(assigneeTask, tagTask);
|
||||||
|
|
||||||
|
var assigneeMappings = assigneeTask.Result;
|
||||||
|
var tagMappings = tagTask.Result;
|
||||||
|
|
||||||
|
// Map tickets to view models and inject assignees/tags per ticket
|
||||||
|
var jobTicketVMs = jobTickets.Select(jt =>
|
||||||
|
{
|
||||||
|
var vm = _mapper.Map<JobTicketVM>(jt);
|
||||||
|
vm.Assignees = assigneeMappings
|
||||||
|
.Where(jem => jem.JobTicketId == jt.Id)
|
||||||
|
.Select(jem => _mapper.Map<BasicEmployeeVM>(jem.Assignee))
|
||||||
|
.ToList();
|
||||||
|
vm.Tags = tagMappings
|
||||||
|
.Where(jtm => jtm.JobTicketId == jt.Id)
|
||||||
|
.Select(jtm => _mapper.Map<TagVM>(jtm.JobTag))
|
||||||
|
.ToList();
|
||||||
|
return vm;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var response = new
|
||||||
|
{
|
||||||
|
CurrentPage = pageNumber,
|
||||||
|
TotalPages = totalPages,
|
||||||
|
TotalEntities = totalEntities,
|
||||||
|
Data = jobTicketVMs,
|
||||||
|
};
|
||||||
|
|
||||||
|
_logger.LogInfo("Job tickets fetched: {Count} tickets for tenant {TenantId}, page {PageNumber}", jobTicketVMs.Count, tenantId, pageNumber);
|
||||||
|
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, $"{jobTicketVMs.Count} job records fetched successfully.", 200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Exception in fetching job tickets list for tenant {TenantId} by employee {EmployeeId}", tenantId, loggedInEmployee.Id);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Internal Server Error", "Unable to fetch job tickets list. Please try again later.", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new job ticket with optional assignees and tags within a transactional scope.
|
/// Creates a new job ticket with optional assignees and tags within a transactional scope.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
"Title": "Dev"
|
"Title": "Dev"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMSOrg"
|
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1"
|
||||||
},
|
},
|
||||||
"SmtpSettings": {
|
"SmtpSettings": {
|
||||||
"SmtpServer": "smtp.gmail.com",
|
"SmtpServer": "smtp.gmail.com",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user