using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Queries; using InternshipSystem.Api.Queries.SearchQuery; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using static System.String; namespace InternshipSystem.Api.Controllers { [ApiController] [Route("companies")] public class CompaniesController : ControllerBase { public CompaniesController(InternshipDbContext context) { Context = context; } private InternshipDbContext Context { get; } /// /// Get companies matching provided paginated query /// /// Paginated query description /// Successfully retrieved Companies /// Search query was malformed /// Part of companies collection [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task>> SearchByNameAsync([FromQuery] CompanySearchQuery searchQuery, CancellationToken cancellationToken) => await Context.Companies .Where(c => c.Name.ToLower().Contains(searchQuery.Name.ToLower())) .OrderBy(o => o.Name) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) .ToListAsync(cancellationToken); /// /// Get company branches matching provided paginated query /// /// Paginated query description /// /// Successfully retrieved matching offices /// Search query was malformed /// Part of companies collection [HttpGet("{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task>> SearchBranchesByAddress([FromQuery] BranchOfficeSearchQuery searchQuery, long companyId, CancellationToken token) { var company = await Context.Companies.Where(c => c.Id == companyId).FirstAsync(token); return await Context.Entry(company) .Collection(c => c.Branches) .Query() .Where(office => office.Address.City.ToLower().Contains(searchQuery.City.ToLower())) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) .ToListAsync(token); } /// /// Updates or add new company (if not new than contains id) /// /// /// Successfully updated company /// Company form was malformed /// Company not found /// [HttpPut] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task UpdateCompany([FromBody] CompanyForm companyForm, CancellationToken cancellationToken) { var validator = new CompanyForm.Validator(); var validationResult = await validator.ValidateAsync(companyForm, cancellationToken); if (!validationResult.IsValid) { return BadRequest(validationResult.ToString()); } if (companyForm.Id.HasValue) { var companyToUpdate = await Context.Companies.FindAsync(companyForm.Id); if (companyToUpdate != null) { companyToUpdate.Name = IsNullOrEmpty(companyForm.Name) ? companyToUpdate.Name : companyForm.Name; companyToUpdate.Nip = IsNullOrEmpty(companyForm.Nip) ? companyToUpdate.Nip : companyForm.Nip; } else { return NotFound($"Company with id: {companyForm.Id} does not exist"); } } else { var newCompany = new Company { Name = companyForm.Name, Nip = companyForm.Nip, }; await Context.Companies.AddAsync(newCompany, cancellationToken); } await Context.SaveChangesAsync(cancellationToken); return Ok($"Company updated successfully"); } /// /// Deletes existing company by id /// /// /// Successfully deleted company /// Company id is empty /// Company not found /// [HttpDelete("{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task DeleteCompany(long companyId, CancellationToken cancellationToken) { var companyToDelete = await Context.Companies .Include(c => c.Branches) .FirstOrDefaultAsync(c => c.Id.Equals(companyId), cancellationToken: cancellationToken); if (companyToDelete == null) { return NotFound($"Company with id: {companyId} does not exist"); } Context.Companies.Attach(companyToDelete); Context.Companies.Remove(companyToDelete); await Context.SaveChangesAsync(cancellationToken); return Ok($"Company with id: {companyId} deleted successfully"); } /// /// Updates or add new branchOffice (if not new than contains id) /// /// /// /// Successfully updated company branch office /// Branch office was malformed/response> /// Company or branch office not found /// [HttpPut("branchOffice/{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task UpdateBranch([FromBody] BranchOfficeForm branchOfficeForm, long companyId, CancellationToken cancellationToken) { var validator = new BranchOfficeForm.Validator(); var validationResult = await validator.ValidateAsync(branchOfficeForm, cancellationToken); if (!validationResult.IsValid) { return BadRequest(validationResult.ToString()); } var company = await Context.Companies .Include(c => c.Branches) .FirstOrDefaultAsync(c => c.Id.Equals(companyId), cancellationToken: cancellationToken); if (company == null) { return NotFound($"Company with id: {companyId} does not exist"); } if (branchOfficeForm.Id.HasValue) { var branchOffice = company.Branches.Find(b => b.Id.Equals(branchOfficeForm.Id.Value)); if (branchOffice == null) { return NotFound($"Branch office with id: {branchOfficeForm.Id} does not exist"); } branchOffice.Address.Country = IsNullOrEmpty(branchOfficeForm.Country) ? branchOffice.Address.Country : branchOfficeForm.Country; branchOffice.Address.City = IsNullOrEmpty(branchOfficeForm.City) ? branchOffice.Address.City : branchOfficeForm.City; branchOffice.Address.PostalCode = IsNullOrEmpty(branchOfficeForm.PostalCode) ? branchOffice.Address.PostalCode : branchOfficeForm.PostalCode; branchOffice.Address.Street = IsNullOrEmpty(branchOfficeForm.Street) ? branchOffice.Address.Street : branchOfficeForm.Street; branchOffice.Address.Building = IsNullOrEmpty(branchOfficeForm.Building) ? branchOffice.Address.Building : branchOfficeForm.Building; } else { var newBranchOffice = new BranchOffice { Address = new BranchAddress { Country = branchOfficeForm.Country, City = branchOfficeForm.City, PostalCode = branchOfficeForm.PostalCode, Street = branchOfficeForm.Street, Building = branchOfficeForm.Building, } }; company.Branches.Add(newBranchOffice); } await Context.SaveChangesAsync(cancellationToken); return Ok($"Branch office updated successfully"); } /// /// Deletes existing branchOffice /// /// /// Successfully deleted company branch office /// Branch office id is empty /// Company or branch office not found /// [HttpDelete("branchOffice/{branchOfficeId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task DeleteBranch(long branchOfficeId, CancellationToken cancellationToken) { var company = await Context.Companies .Include(c => c.Branches) .Where(c => c.Branches.Any(b => b.Id.Equals(branchOfficeId))) .FirstOrDefaultAsync(cancellationToken: cancellationToken); if (company == null) { return NotFound($"Branch office with id: {branchOfficeId} does not exist"); } var branchOffice = company.Branches.Find(b => b.Id.Equals(branchOfficeId)); company.Branches.Remove(branchOffice); await Context.SaveChangesAsync(cancellationToken); return Ok($"Branch office with id: {branchOfficeId} deleted successfully"); } } }