Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

feat(jobs): Job offers endpoint #10

Merged
merged 56 commits into from
Jun 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0e23533
feat(migration): migration was created to create the table offers
AdrianAlzamoraG Jun 10, 2022
bd6dd2c
feat(migration): migration was implemented to create the table offers
AdrianAlzamoraG Jun 10, 2022
6db3dc3
feat(jobs): implemented domain class
AdrianAlzamoraG Jun 10, 2022
d2310e4
feat(jobs): clase de respuesta de dominio implementada
AdrianAlzamoraG Jun 10, 2022
3471c67
feat(jobs): offer service interface implemented
AdrianAlzamoraG Jun 10, 2022
4c32671
feat(jobs): api endpoint offer controller is implemented
AdrianAlzamoraG Jun 10, 2022
b941695
feat(jobs): outgoing object mapping implemented
AdrianAlzamoraG Jun 10, 2022
0a1f3c7
feat(jobs): incoming mapping and constrains implemented
AdrianAlzamoraG Jun 10, 2022
22c7fb5
feat(jobs): implemented offer repository interface
AdrianAlzamoraG Jun 10, 2022
dbeebc9
feat(persistence): implemented dbcontext class for persistence handling
AdrianAlzamoraG Jun 10, 2022
8a65aa4
feat(offer): classes of the persistence layer have been implemented
AdrianAlzamoraG Jun 11, 2022
37fd7b2
feat(offer): the service layer class has been implemented
AdrianAlzamoraG Jun 11, 2022
c8aa284
feat(offer): migration has been updated to create jobs
AdrianAlzamoraG Jun 11, 2022
aaa0794
feat(offer): added and implemented user stories from jobs api
AdrianAlzamoraG Jun 11, 2022
738055f
feat(offer): the get all offers scenario and its step were added and …
AdrianAlzamoraG Jun 11, 2022
e4a2977
feat(offer): added and implemented the offer without data scenario an…
AdrianAlzamoraG Jun 11, 2022
bccd74d
feat(offer): added and implemented the offer with data scenario and i…
AdrianAlzamoraG Jun 11, 2022
dfaf22e
feat(offer): added and implemented the offer invalid post scenario an…
AdrianAlzamoraG Jun 11, 2022
6ee3d9e
feat(offer): the update existing offer scenario and its step were add…
AdrianAlzamoraG Jun 11, 2022
8247d2f
feat(offer): the delete existing offer scenario and its step were add…
AdrianAlzamoraG Jun 11, 2022
aca57b7
feat(offer): unnecessary files removed
AdrianAlzamoraG Jun 11, 2022
0472de5
feat(offer): offers context was implemented for persistence handling
AdrianAlzamoraG Jun 11, 2022
51f1849
feat(offer): updated offer repository interface
AdrianAlzamoraG Jun 11, 2022
4b7e704
feat(jobs): implemented domain response class
AdrianAlzamoraG Jun 10, 2022
df55972
feat(jobs): offer service interface implemented
AdrianAlzamoraG Jun 10, 2022
fcb33b0
feat(jobs): api endpoint offer controller is implemented
AdrianAlzamoraG Jun 10, 2022
3d0fa2f
feat(jobs): outgoing object mapping implemented
AdrianAlzamoraG Jun 10, 2022
49edd22
feat(jobs): incoming mapping and constrains implemented
AdrianAlzamoraG Jun 10, 2022
8fd6e6e
feat(jobs): implemented offer repository interface
AdrianAlzamoraG Jun 10, 2022
b2b1006
feat(persistence): implemented dbcontext class for persistence handling
AdrianAlzamoraG Jun 10, 2022
bf5f1c6
feat(offer): classes of the persistence layer have been implemented
AdrianAlzamoraG Jun 11, 2022
85b0177
feat(offer): the service layer class has been implemented
AdrianAlzamoraG Jun 11, 2022
5b97139
feat(offer): migration has been updated to create jobs
AdrianAlzamoraG Jun 11, 2022
37544ff
feat(offer): added and implemented user stories from jobs api
AdrianAlzamoraG Jun 11, 2022
799af8b
feat(offer): the get all offers scenario and its step were added and …
AdrianAlzamoraG Jun 11, 2022
d3c1c1d
feat(offer): added and implemented the offer without data scenario an…
AdrianAlzamoraG Jun 11, 2022
1a6be1e
feat(offer): added and implemented the offer with data scenario and i…
AdrianAlzamoraG Jun 11, 2022
b1d8b17
feat(offer): added and implemented the offer invalid post scenario an…
AdrianAlzamoraG Jun 11, 2022
cd22e4e
feat(offer): the update existing offer scenario and its step were add…
AdrianAlzamoraG Jun 11, 2022
149c3d4
feat(offer): the delete existing offer scenario and its step were add…
AdrianAlzamoraG Jun 11, 2022
3015e31
feat(offer): unnecessary files removed
AdrianAlzamoraG Jun 11, 2022
c083ca2
feat(offer): offers context was implemented for persistence handling
AdrianAlzamoraG Jun 11, 2022
21aa11c
feat(offer): updated offer repository interface
AdrianAlzamoraG Jun 11, 2022
c880571
feat(jobs): updated domain class
AdrianAlzamoraG Jun 11, 2022
f61ee02
feat(jobs): implemented offer repository for persistence
AdrianAlzamoraG Jun 11, 2022
a2ec864
feat(jobs): outgoing and incoming mapping were updated
AdrianAlzamoraG Jun 11, 2022
7e1330a
feat(jobs): offer service implemented
AdrianAlzamoraG Jun 11, 2022
61daf8d
feat(offer): added offer scoped in dependency Injection configuration
AdrianAlzamoraG Jun 11, 2022
4c79824
Merge branch 'develop' into feat/jobs
dalbitresb12 Jun 11, 2022
14edee7
test: remove Job feature files
dalbitresb12 Jun 11, 2022
7d45d0f
style: code formatting
dalbitresb12 Jun 11, 2022
37116d2
refactor: applied requested changes
amenes12 Jun 11, 2022
1e34284
Merge branch 'develop' into feat/jobs
dalbitresb12 Jun 11, 2022
4ae5cae
Merge remote-tracking branch 'origin/feat/jobs' into feat/jobs
amenes12 Jun 11, 2022
f75c9f4
Merge remote-tracking branch 'origin/feat/jobs' into feat/jobs
amenes12 Jun 11, 2022
a259e01
refactor: initialized not nullable properties with empty string
amenes12 Jun 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions WAW.API/Job/Controllers/OffersController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Domain.Services;
using WAW.API.Job.Resources;
using WAW.API.Shared.Extensions;

namespace WAW.API.Job.Controllers;

[ApiController]
[Route("[controller]")]
public class OffersController : ControllerBase {
private readonly IOfferService service;
private readonly IMapper mapper;

public OffersController(IOfferService service, IMapper mapper) {
this.service = service;
this.mapper = mapper;
}

[HttpGet]
public async Task<IEnumerable<OfferResource>> GetAll() {
var offers = await service.ListAll();
return mapper.Map<IEnumerable<Offer>, IEnumerable<OfferResource>>(offers);
}

[HttpPost]
public async Task<IActionResult> Post([FromBody] OfferRequest resource) {
if (!ModelState.IsValid) return BadRequest(ModelState.GetErrorMessages());

var offer = mapper.Map<OfferRequest, Offer>(resource);
var result = await service.Create(offer);
return result.ToResponse<OfferResource>(this, mapper);
}

[HttpPut("{id:int}")]
public async Task<IActionResult> Put(int id, [FromBody] OfferRequest resource) {
if (!ModelState.IsValid) return BadRequest(ModelState.GetErrorMessages());

var offer = mapper.Map<OfferRequest, Offer>(resource);
var result = await service.Update(id, offer);
return result.ToResponse<OfferResource>(this, mapper);
}

[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteAsync(int id) {
var result = await service.Delete(id);
return result.ToResponse<OfferResource>(this, mapper);
}
}
11 changes: 11 additions & 0 deletions WAW.API/Job/Domain/Models/Offer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using WAW.API.Shared.Domain.Model;

namespace WAW.API.Job.Domain.Models;

public class Offer : BaseModel {
public string Title { get; set; } = string.Empty;
public string? Image { get; set; }
public string? Description { get; set; }
public string SalaryRange { get; set; } = string.Empty;
public bool Status { get; set; }
}
15 changes: 15 additions & 0 deletions WAW.API/Job/Domain/Repositories/IOfferRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using WAW.API.Job.Domain.Models;

namespace WAW.API.Job.Domain.Repositories;

public interface IOfferRepository {
Task<IEnumerable<Offer>> ListAll();

Task Add(Offer offer);

Task<Offer?> FindById(long id);

void Update(Offer offer);

void Remove(Offer offer);
}
9 changes: 9 additions & 0 deletions WAW.API/Job/Domain/Services/Communication/OfferResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using WAW.API.Job.Domain.Models;
using WAW.API.Shared.Domain.Service.Communication;

namespace WAW.API.Job.Domain.Services.Communication;

public class OfferResponse : BaseResponse<Offer> {
public OfferResponse(string message) : base(message) {}
public OfferResponse(Offer resource) : base(resource) {}
}
11 changes: 11 additions & 0 deletions WAW.API/Job/Domain/Services/IOfferService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Domain.Services.Communication;

namespace WAW.API.Job.Domain.Services;

public interface IOfferService {
Task<IEnumerable<Offer>> ListAll();
Task<OfferResponse> Create(Offer offer);
Task<OfferResponse> Update(long id, Offer offer);
Task<OfferResponse> Delete(long id);
}
11 changes: 11 additions & 0 deletions WAW.API/Job/Mapping/ModelToResourceProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AutoMapper;
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Resources;

namespace WAW.API.Job.Mapping;

public class ModelToResourceProfile : Profile {
public ModelToResourceProfile() {
CreateMap<Offer, OfferResource>();
}
}
11 changes: 11 additions & 0 deletions WAW.API/Job/Mapping/ResourceToModelProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AutoMapper;
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Resources;

namespace WAW.API.Job.Mapping;

public class ResourceToModelProfile : Profile {
public ResourceToModelProfile() {
CreateMap<OfferRequest, Offer>();
}
}
31 changes: 31 additions & 0 deletions WAW.API/Job/Persistence/Repositories/OfferRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore;
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Domain.Repositories;
using WAW.API.Weather.Persistence.Contexts;
using WAW.API.Weather.Persistence.Repositories;

namespace WAW.API.Job.Persistence.Repositories;

public class OfferRepository : BaseRepository, IOfferRepository {
public OfferRepository(AppDbContext context) : base(context) {}

public async Task<IEnumerable<Offer>> ListAll() {
return await context.Offers.ToListAsync();
}

public async Task Add(Offer offer) {
await context.Offers.AddAsync(offer);
}

public async Task<Offer?> FindById(long id) {
return await context.Offers.FindAsync(id);
}

public void Update(Offer offer) {
context.Offers.Update(offer);
}

public void Remove(Offer offer) {
context.Offers.Remove(offer);
}
}
19 changes: 19 additions & 0 deletions WAW.API/Job/Resources/OfferRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;

namespace WAW.API.Job.Resources;

public class OfferRequest {
[Required]
public string? Title { get; set; }

[Required]
public string? Image { get; set; }

[Required]
public string? Description { get; set; }

public string? SalaryRange { get; set; }

[Required]
public bool? Status { get; set; }
}
10 changes: 10 additions & 0 deletions WAW.API/Job/Resources/OfferResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace WAW.API.Job.Resources;

public class OfferResource {
public long Id { get; set; }
public string Title { get; set; } = string.Empty;
public string? Image { get; set; }
public string? Description { get; set; }
public string SalaryRange { get; set; } = string.Empty;
public bool Status { get; set; }
}
60 changes: 60 additions & 0 deletions WAW.API/Job/Services/OfferService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using WAW.API.Job.Domain.Models;
using WAW.API.Job.Domain.Repositories;
using WAW.API.Job.Domain.Services;
using WAW.API.Job.Domain.Services.Communication;
using WAW.API.Weather.Domain.Repositories;


namespace WAW.API.Job.Services;

public class OfferService : IOfferService {
private readonly IOfferRepository repository;
private readonly IUnitOfWork unitOfWork;

public OfferService(IOfferRepository repository, IUnitOfWork unitOfWork) {
this.repository = repository;
this.unitOfWork = unitOfWork;
}

public Task<IEnumerable<Offer>> ListAll() {
return repository.ListAll();
}

public async Task<OfferResponse> Create(Offer offer) {
try {
await repository.Add(offer);
await unitOfWork.Complete();
return new OfferResponse(offer);
} catch (Exception e) {
return new OfferResponse($"An error occurred while saving the offer: {e.Message}");
}
}

public async Task<OfferResponse> Update(long id, Offer offer) {
var current = await repository.FindById(id);
if (current == null) return new OfferResponse("Offer not found");

offer.CopyProperties(current);

try {
repository.Update(current);
await unitOfWork.Complete();
return new OfferResponse(current);
} catch (Exception e) {
return new OfferResponse($"An error occurred while updating the offer: {e.Message}");
}
}

public async Task<OfferResponse> Delete(long id) {
var current = await repository.FindById(id);
if (current == null) return new OfferResponse("Offer not found");

try {
repository.Remove(current);
await unitOfWork.Complete();
return new OfferResponse(current);
} catch (Exception e) {
return new OfferResponse($"An error occurred while deleting the offer: {e.Message}");
}
}
}
51 changes: 51 additions & 0 deletions WAW.API/Migrations/20220610184650_CreateJobs.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions WAW.API/Migrations/20220610184650_CreateJobs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace WAW.API.Migrations
{
public partial class CreateJobs : Migration
{
protected override void Up(MigrationBuilder migrationBuilder) {
migrationBuilder.CreateTable(
name: "jobs",
columns: table => new {
id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
title = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false),
image = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
description = table.Column<string>(type: "longtext", nullable: false).Annotation("MySql:CharSet", "utf8mb4"),
salaryRange = table.Column<string>(type: "varchar(400)",maxLength: 400, nullable: true),
status = table.Column<bool>(type: "boolean", nullable: false),

},
constraints: table => { table.PrimaryKey("p_k_jobs", x => x.id); }
)
.Annotation("MySql:Charset", "utf8mb4");

}

protected override void Down(MigrationBuilder migrationBuilder) {
migrationBuilder.DropTable(name: "jobs");
}
}
}
13 changes: 13 additions & 0 deletions WAW.API/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using WAW.API.Job.Domain.Repositories;
using WAW.API.Job.Domain.Services;
using WAW.API.Job.Persistence.Repositories;
using WAW.API.Job.Services;
using WAW.API.Company.Domain.Repositories;
using WAW.API.Company.Domain.Services;
using WAW.API.Company.Persistence.Repositories;
Expand All @@ -12,6 +16,8 @@
using WAW.API.Weather.Persistence.Contexts;
using WAW.API.Weather.Persistence.Repositories;
using WAW.API.Weather.Services;
using IUnitOfWork = WAW.API.Weather.Domain.Repositories.IUnitOfWork;
using UnitOfWork = WAW.API.Weather.Persistence.Repositories.UnitOfWork;

var builder = WebApplication.CreateBuilder(args);

Expand Down Expand Up @@ -60,6 +66,9 @@
builder.Services.AddScoped<IForecastRepository, ForecastRepository>();
builder.Services.AddScoped<IForecastService, ForecastService>();

builder.Services.AddScoped<IOfferRepository, OfferRepository>();
builder.Services.AddScoped<IOfferService, OfferService>();

builder.Services.AddScoped<ICompanyRepository, CompanyRepository>();
builder.Services.AddScoped<ICompanyService, CompanyService>();

Expand All @@ -71,6 +80,10 @@
typeof(WAW.API.Company.Mapping.ModelToResourceProfile),
typeof(WAW.API.Company.Mapping.ResourceToModelProfile)
);
builder.Services.AddAutoMapper(
typeof(WAW.API.Job.Mapping.ModelToResourceProfile),
typeof(WAW.API.Job.Mapping.ResourceToModelProfile)
);

var app = builder.Build();

Expand Down
5 changes: 5 additions & 0 deletions WAW.API/WAW.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<ItemGroup>
<InternalsVisibleTo Include="WAW.API.Tests" />
</ItemGroup>
<ItemGroup>
<Folder Include="Job\Controllers" />
<Folder Include="Job\Domain\Models" />
<Folder Include="Job\Domain\Repositories" />
</ItemGroup>
<ItemGroup>
<Folder Include="Company\Controllers" />
</ItemGroup>
Expand Down
Loading