Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added ERD-base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions api-cinema-challenge/api-cinema-challenge.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3C371BAA-344D-4C8A-AF08-7829816D726F}"
ProjectSection(SolutionItems) = preProject
..\.gitignore = ..\.gitignore
api-cinema-challenge\ERD-base.png = api-cinema-challenge\ERD-base.png
..\README.md = ..\README.md
EndProjectSection
EndProject
Expand Down
11 changes: 11 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/CustomerDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using api_cinema_challenge.Models;

namespace api_cinema_challenge.DTO
{
public class CustomerPost
{
public string name { get; set; }
public string email { get; set; }
public string phone { get; set; }
}
}
28 changes: 28 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/MovieDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using api_cinema_challenge.Models;

namespace api_cinema_challenge.DTO
{
public class MovieDTO : Dateing
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public IEnumerable<ScreeningDTO> Screenings { get; set; }

}
public class MovieSmall : Dateing
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
}
public class MoviePost
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
}
}
28 changes: 28 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTO/ScreeningDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using api_cinema_challenge.Models;

namespace api_cinema_challenge.DTO
{
public class ScreeningDTO : Dateing
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public int MovieId { get; set; }
}
public class ScreeningDTOBig : Dateing
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public int MovieId { get; set; }
public MovieSmall Movie { get; set; }

}
public class ScreeningPost
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public int MovieId { get; set; }
}
}
21 changes: 18 additions & 3 deletions api-cinema-challenge/api-cinema-challenge/Data/CinemaContext.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using Microsoft.EntityFrameworkCore;
using System.Net.Sockets;
using api_cinema_challenge.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;

namespace api_cinema_challenge.Data
{
public class CinemaContext : DbContext
{
private string _connectionString;
public CinemaContext(DbContextOptions<CinemaContext> options) : base(options)
public CinemaContext()
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnectionString")!;
_connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnection")!;
this.Database.SetConnectionString(_connectionString);
this.Database.EnsureCreated();
}

Expand All @@ -20,7 +23,19 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Primary keys
modelBuilder.Entity<Customer>().HasKey(c => c.Id);
modelBuilder.Entity<Movie>().HasKey(m => m.Id);
modelBuilder.Entity<Screening>().HasKey(s => s.Id);

//Relations
modelBuilder.Entity<Movie>()
.HasMany(m => m.Screenings)
.WithOne(m => m.Movie);

}
public DbSet<Customer> Customers { get; set; }
public DbSet<Movie> Movies { get; set; }
public DbSet<Screening> Screenings { get; set; }
}
}
40 changes: 40 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Data/Seeder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using api_cinema_challenge.Models;

namespace api_cinema_challenge.Data
{
public static class Seeder
{
public async static void SeedCinemaApi(this WebApplication app)
{
using (var db = new CinemaContext())
{
if (!db.Customers.Any())
{
db.Add(new Customer() { Name = "Nigel" });
db.Add(new Customer() { Name = "Dave" });
await db.SaveChangesAsync();
}
if (!db.Movies.Any())
{
db.Add(new Movie() { Title = "Cheese & Pineapple" });
db.Add(new Movie() { Title = "Vegan Cheese Tastic" });
await db.SaveChangesAsync();

}
if (!db.Screenings.Any())
{
db.Add(new Screening() { MovieId = 1, StartsAt = DateTime.UtcNow.AddDays(1)});
await db.SaveChangesAsync();
}

//order data
if (1 == 1)
{

await db.SaveChangesAsync();
}
}
}
}
}
189 changes: 189 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/EndPoint/CinemaEndpoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using api_cinema_challenge.DTO;
using api_cinema_challenge.Models;
using api_cinema_challenge.Repository;
using Microsoft.AspNetCore.Mvc;

namespace api_cinema_challenge.EndPoint
{
public static class CinemaEndpoint
{
public static void ConfigureCinemaEndPoint (this WebApplication app)
{
app.MapPost("/customers", AddCustomer);
app.MapGet("/customers", GetCustomers);
app.MapPut("/customers/{id}", UpdateCustomer);
app.MapDelete("/customers/{id}", DeleteCustomer);

app.MapPost("/movies", AddMovie);
app.MapGet("/movies", GetMovies);
app.MapPut("/movies/{id}", UpdateMovie);
app.MapDelete("movies/{id}", DeleteMovie);

app.MapPost("/movies/{id}/screenings", AddScreening);
app.MapGet("movies/{id}/screenings", GetScreenings);


}
public static async Task<IResult> AddCustomer(IRepository repo, CustomerPost customer)
{
Customer result = new Customer
{
Name = customer.name,
Email = customer.email,
Phone = customer.phone,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
await repo.AddCustomer(result);

return TypedResults.Ok(result);
}
public static async Task<IResult> GetCustomers(IRepository repo)
{
var customers = await repo.GetCustomers();

return TypedResults.Ok(customers);
}
public static async Task<IResult> UpdateCustomer(IRepository repo, CustomerPost customer, int id)
{
var customerReturned = await repo.GetCustomer(id);
if (customerReturned == null)
{
return TypedResults.NotFound();
}
if (customer.name != null) customerReturned.Name = customer.name;
if (customer.email != null) customerReturned.Email = customer.email;
if (customer.phone != null) customerReturned.Phone = customer.phone;

var updated = await repo.UpdateCustomer(customerReturned, id);

return TypedResults.Ok(updated);
}
public static async Task<IResult> DeleteCustomer(IRepository repo, int id)
{
var deleted = await repo.DeleteCustomer(id);
return TypedResults.Ok(deleted);
}

public static async Task<IResult> AddMovie(IRepository repo, MoviePost movie)
{
Movie result = new Movie
{
Title = movie.Title,
Rating = movie.Rating,
Description = movie.Description,
RuntimeMins = movie.RuntimeMins,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
await repo.AddMovie(result);

return TypedResults.Ok(result);

}
public static async Task<IResult> GetMovies(IRepository repo)
{
var movies = await repo.GetMovies();

var movieDTO = movies.Select(m => new MovieDTO
{
Title = m.Title,
Rating = m.Rating,
Description = m.Description,
RuntimeMins = m.RuntimeMins,
CreatedAt = m.CreatedAt,
UpdatedAt = m.UpdatedAt,
Screenings = m.Screenings.Select(s => new ScreeningDTO
{
ScreenNumber = s.ScreenNumber,
Capacity = s.Capacity,
StartsAt = s.StartsAt,
MovieId = s.MovieId,
CreatedAt = s.CreatedAt,
UpdatedAt = s.UpdatedAt
}).ToList()
});
return TypedResults.Ok(movies);
}
public static async Task<IResult> UpdateMovie(IRepository repo, MoviePost movie, int id)
{
var movieReturned = await repo.GetMovie(id);
if (movieReturned == null)
{
return TypedResults.NotFound();
}
if (movie.Title != null) movieReturned.Title = movie.Title;
if (movie.Rating != null) movieReturned.Rating = movie.Rating;
if (movie.Description != null) movieReturned.Description = movie.Description;
if (movie.RuntimeMins != null) movieReturned.RuntimeMins = movie.RuntimeMins;

var updated = await repo.UpdateMovie(movieReturned, id);

MovieDTO movieDTO = new MovieDTO
{
Title = movieReturned.Title,
Rating = movieReturned.Rating,
Description = movieReturned.Description,
RuntimeMins = movieReturned.RuntimeMins,
CreatedAt = movieReturned.CreatedAt,
UpdatedAt = movieReturned.UpdatedAt,
Screenings = movieReturned.Screenings.Select(s => new ScreeningDTO
{
ScreenNumber = s.ScreenNumber,
Capacity = s.Capacity,
StartsAt = s.StartsAt,
MovieId = s.MovieId,
CreatedAt = s.CreatedAt,
UpdatedAt = s.UpdatedAt
}).ToList()
};
return TypedResults.Ok(movieDTO);
}
public static async Task<IResult> DeleteMovie(IRepository repo, int id)
{
var deleted = await repo.DeleteMovie(id);
return TypedResults.Ok(deleted);
}

public static async Task<IResult> AddScreening(IRepository repo, ScreeningPost screening, int id)
{
Screening result = new Screening
{
ScreenNumber = screening.ScreenNumber,
Capacity = screening.Capacity,
StartsAt = screening.StartsAt,
MovieId = screening.MovieId,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
await repo.AddScreening(result);

return TypedResults.Ok(result);

}
public static async Task<IResult> GetScreenings(IRepository repo, int movieId)
{
var result = await repo.GetScreenings(movieId);
var screenings = result.Select(s => new ScreeningDTOBig
{
ScreenNumber = s.ScreenNumber,
Capacity = s.Capacity,
StartsAt = s.StartsAt,
MovieId = s.MovieId,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
Movie = new MovieSmall
{
Title = s.Movie.Title,
Rating = s.Movie.Rating,
Description = s.Movie.Description,
RuntimeMins = s.Movie.RuntimeMins,
CreatedAt = s.Movie.CreatedAt,
UpdatedAt = s.Movie.UpdatedAt
}
});

return TypedResults.Ok(screenings);
}
}
}
10 changes: 10 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Models/Customer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace api_cinema_challenge.Models
{
public class Customer : Dateing
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}
8 changes: 8 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Models/Dateing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace api_cinema_challenge.Models
{
public abstract class Dateing
{
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}
12 changes: 12 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Models/Movie.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace api_cinema_challenge.Models
{
public class Movie : Dateing
{
public int Id { get; set; }
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public IEnumerable<Screening> Screenings { get; set; }
}
}
13 changes: 13 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Models/Screening.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace api_cinema_challenge.Models
{
public class Screening : Dateing
{
public int Id { get; set; }
public int ScreenNumber { get; set; }
public int Capacity { get; set; }

public DateTime StartsAt { get; set; }
public int MovieId { get; set; }
public Movie Movie { get; set; }
}
}
Loading