diff --git a/BookAPI/BookAPI.csproj b/BookAPI/BookAPI.csproj new file mode 100644 index 0000000..6acfe25 --- /dev/null +++ b/BookAPI/BookAPI.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/BookAPI/BookAPI.sln b/BookAPI/BookAPI.sln new file mode 100644 index 0000000..2dea4e5 --- /dev/null +++ b/BookAPI/BookAPI.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33103.184 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookAPI", "BookAPI.csproj", "{FE52426A-BCF6-48AA-9441-63448C8FD5D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B6210FC6-C5EE-459E-ADC7-0D07807156F6} + EndGlobalSection +EndGlobal diff --git a/BookAPI/Controllers/AuthorController.cs b/BookAPI/Controllers/AuthorController.cs new file mode 100644 index 0000000..2e3664c --- /dev/null +++ b/BookAPI/Controllers/AuthorController.cs @@ -0,0 +1,99 @@ +using AutoMapper; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Implementation; +using BookAPI.Service.Interface; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Net; + +namespace BookAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class AuthorController : ControllerBase + { + private readonly IAuthorRepository _authorRepository; + private readonly IMapper _mapper; + + public AuthorController(IAuthorRepository authorRepository, IMapper mapper) + { + _authorRepository = authorRepository; + _mapper = mapper; + } + + [HttpPost] + public async Task> CreateAuthor(CreateAuthor createAuthor) + { + try + { + var author = _mapper.Map(createAuthor); // map CreateAuthor to Author + await _authorRepository.AddAsync(author); + var result = _mapper.Map(author); + return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = result }; + } + catch (Exception ex) + { + var errors = new List { ex.Message }; + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet("{id}")] + public async Task> GetAuthorById(int id) + { + try + { + var author = await _authorRepository.GetByIdAsync(id); + if (author == null) + { + return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false }; + } + var result = _mapper.Map(author); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result }; + } + catch (Exception ex) + { + var errors = new List { ex.Message }; + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet] + public async Task> GetAllAuthors() + { + try + { + var authors = await _authorRepository.GetAllAsync(); + var result = _mapper.Map>(authors); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result }; + } + catch (Exception ex) + { + var errors = new List { ex.Message }; + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet("{id}/books")] + public async Task> GetBooksAttachedToAnAuthor(int id) + { + try + { + var books = await _authorRepository.GetBooksAttachedToAuthor(id); + if (books == null) + { + return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false }; + } + var result = _mapper.Map>(books); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result }; + } + catch (Exception ex) + { + var errors = new List { ex.Message }; + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + } + +} diff --git a/BookAPI/Controllers/BookController.cs b/BookAPI/Controllers/BookController.cs new file mode 100644 index 0000000..5065fc7 --- /dev/null +++ b/BookAPI/Controllers/BookController.cs @@ -0,0 +1,82 @@ +using AutoMapper; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Interface; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Net; + +namespace BookAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class BookController : ControllerBase + { + private readonly IRepository _bookRepository; + private readonly IMapper _mapper; + + public BookController(IRepository bookRepository, IMapper mapper) + { + _bookRepository = bookRepository; + _mapper = mapper; + } + + [HttpPost("CreateBook")] + public async Task> CreateBook(CreateBook createBook) + { + var errors = new List(); + try + { + var book = _mapper.Map(createBook); + await _bookRepository.AddAsync(book); + var createdBook = _mapper.Map(book); // map Book to CreateBook + return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = createdBook }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet("{id}")] + public async Task> GetBookById(int id) + { + var errors = new List(); + try + { + var book = await _bookRepository.GetByIdAsync(id); + if (book == null) + { + errors.Add($"Book with id {id} not found"); + return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors }; + } + var thebook = _mapper.Map(book); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thebook }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet] + public async Task> GetAllBooks() + { + var errors = new List(); + try + { + var books = await _bookRepository.GetAllAsync(); + var thebooks = _mapper.Map>(books); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thebooks }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + } + + } diff --git a/BookAPI/Controllers/PublisherController.cs b/BookAPI/Controllers/PublisherController.cs new file mode 100644 index 0000000..5a9c9b4 --- /dev/null +++ b/BookAPI/Controllers/PublisherController.cs @@ -0,0 +1,110 @@ +using AutoMapper; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Implementation; +using BookAPI.Service.Interface; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Net; + +namespace BookAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class PublisherController : ControllerBase + { + private readonly IPublisherRepository _publisherRepository; + private readonly IMapper _mapper; + + public PublisherController(IPublisherRepository publisherRepository, IMapper mapper) + { + _publisherRepository = publisherRepository; + _mapper = mapper; + } + + [HttpPost] + public async Task> CreatePublisher(CreatePublisher createPublisher) + { + var errors = new List(); + try + { + var publisher = _mapper.Map(createPublisher); + await _publisherRepository.AddAsync(publisher); + var createdPublisher = _mapper.Map(publisher); + + return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = createdPublisher }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet("{id}")] + public async Task> GetPublisher(int id) + { + var errors = new List(); + try + { + var publisher = await _publisherRepository.GetByIdAsync(id); + if (publisher == null) + { + errors.Add($"Publisher with id {id} not found"); + return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors }; + } + var thePublisher = _mapper.Map(publisher); + + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thePublisher }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet] + public async Task> GetAllPublishers() + { + var errors = new List(); + try + { + var publishers = await _publisherRepository.GetAllAsync(); + var thePublishers = _mapper.Map>(publishers); + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thePublishers }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + [HttpGet("{id}/authors")] + public async Task> GetAuthorsAttachedToAPublisher(int id) + { + var errors = new List(); + try + { + var publisher = await _publisherRepository.GetByIdAsync(id); + if (publisher == null) + { + errors.Add($"Publisher with id {id} not found"); + return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors }; + } + var authors = await _publisherRepository.GetAuthorsAttachedToPublisher(id); + var theAuthors = _mapper.Map>(authors); + + return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = theAuthors }; + } + catch (Exception ex) + { + errors.Add(ex.Message); + return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors }; + } + } + + } + + } diff --git a/BookAPI/Data/ApplicationDbContext.cs b/BookAPI/Data/ApplicationDbContext.cs new file mode 100644 index 0000000..fa7005c --- /dev/null +++ b/BookAPI/Data/ApplicationDbContext.cs @@ -0,0 +1,15 @@ +using BookAPI.Model; +using Microsoft.EntityFrameworkCore; + +namespace BookAPI.Data +{ + public class ApplicationDbContext : DbContext + { + public ApplicationDbContext(DbContextOptions options) : base(options) + { + } + public DbSet Books { get; set; } + public DbSet Publishers { get; set; } + public DbSet Authors { get; set; } + } +} diff --git a/BookAPI/Dto/CreateAuthor.cs b/BookAPI/Dto/CreateAuthor.cs new file mode 100644 index 0000000..45a797d --- /dev/null +++ b/BookAPI/Dto/CreateAuthor.cs @@ -0,0 +1,8 @@ +namespace BookAPI.Dto +{ + public class CreateAuthor + { + public string Name { get; set; } + public int PublisherId { get; set; } + } +} diff --git a/BookAPI/Dto/CreateBook.cs b/BookAPI/Dto/CreateBook.cs new file mode 100644 index 0000000..78e497a --- /dev/null +++ b/BookAPI/Dto/CreateBook.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace BookAPI.Dto +{ + public class CreateBook + { + public string Title { get; set; } + public DateTime PublicationDate { get; set; } + [ForeignKey("Author")] + public int AuthorId { get; set; } + [ForeignKey("Publisher")] + public int PublisherId { get; set; } + } +} diff --git a/BookAPI/Dto/CreatePublisher.cs b/BookAPI/Dto/CreatePublisher.cs new file mode 100644 index 0000000..060442d --- /dev/null +++ b/BookAPI/Dto/CreatePublisher.cs @@ -0,0 +1,8 @@ +namespace BookAPI.Dto +{ + public class CreatePublisher + { + public string Name { get; set; } + public string Address { get; set; } + } +} diff --git a/BookAPI/Helper/Automapper.cs b/BookAPI/Helper/Automapper.cs new file mode 100644 index 0000000..47efa35 --- /dev/null +++ b/BookAPI/Helper/Automapper.cs @@ -0,0 +1,16 @@ +using AutoMapper; +using BookAPI.Dto; +using BookAPI.Model; + +namespace BookAPI.AutoMapper +{ + public class Automapper : Profile + { + public Automapper() + { + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + } + } +} diff --git a/BookAPI/Migrations/20230310094639_initial.Designer.cs b/BookAPI/Migrations/20230310094639_initial.Designer.cs new file mode 100644 index 0000000..232dce7 --- /dev/null +++ b/BookAPI/Migrations/20230310094639_initial.Designer.cs @@ -0,0 +1,140 @@ +// +using System; +using BookAPI.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BookAPI.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20230310094639_initial")] + partial class initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublisherId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PublisherId"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("BookAPI.Model.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("AuthorId") + .HasColumnType("int"); + + b.Property("PublicationDate") + .HasColumnType("datetime2"); + + b.Property("PublisherId") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PublisherId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("BookAPI.Model.Publisher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Publishers"); + }); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.HasOne("BookAPI.Model.Publisher", "Publisher") + .WithMany("Authors") + .HasForeignKey("PublisherId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Publisher"); + }); + + modelBuilder.Entity("BookAPI.Model.Book", b => + { + b.HasOne("BookAPI.Model.Author", "Author") + .WithMany("Books") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookAPI.Model.Publisher", null) + .WithMany("Books") + .HasForeignKey("PublisherId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("BookAPI.Model.Publisher", b => + { + b.Navigation("Authors"); + + b.Navigation("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BookAPI/Migrations/20230310094639_initial.cs b/BookAPI/Migrations/20230310094639_initial.cs new file mode 100644 index 0000000..cc5fed5 --- /dev/null +++ b/BookAPI/Migrations/20230310094639_initial.cs @@ -0,0 +1,101 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BookAPI.Migrations +{ + public partial class initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Publishers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + Address = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Publishers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Authors", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + PublisherId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Authors", x => x.Id); + table.ForeignKey( + name: "FK_Authors_Publishers_PublisherId", + column: x => x.PublisherId, + principalTable: "Publishers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Books", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Title = table.Column(type: "nvarchar(max)", nullable: false), + PublicationDate = table.Column(type: "datetime2", nullable: false), + AuthorId = table.Column(type: "int", nullable: false), + PublisherId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Books", x => x.Id); + table.ForeignKey( + name: "FK_Books_Authors_AuthorId", + column: x => x.AuthorId, + principalTable: "Authors", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Books_Publishers_PublisherId", + column: x => x.PublisherId, + principalTable: "Publishers", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Authors_PublisherId", + table: "Authors", + column: "PublisherId"); + + migrationBuilder.CreateIndex( + name: "IX_Books_AuthorId", + table: "Books", + column: "AuthorId"); + + migrationBuilder.CreateIndex( + name: "IX_Books_PublisherId", + table: "Books", + column: "PublisherId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Books"); + + migrationBuilder.DropTable( + name: "Authors"); + + migrationBuilder.DropTable( + name: "Publishers"); + } + } +} diff --git a/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs b/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 0000000..3ac95f3 --- /dev/null +++ b/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,138 @@ +// +using System; +using BookAPI.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BookAPI.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublisherId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PublisherId"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("BookAPI.Model.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("AuthorId") + .HasColumnType("int"); + + b.Property("PublicationDate") + .HasColumnType("datetime2"); + + b.Property("PublisherId") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PublisherId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("BookAPI.Model.Publisher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Publishers"); + }); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.HasOne("BookAPI.Model.Publisher", "Publisher") + .WithMany("Authors") + .HasForeignKey("PublisherId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Publisher"); + }); + + modelBuilder.Entity("BookAPI.Model.Book", b => + { + b.HasOne("BookAPI.Model.Author", "Author") + .WithMany("Books") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookAPI.Model.Publisher", null) + .WithMany("Books") + .HasForeignKey("PublisherId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("BookAPI.Model.Author", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("BookAPI.Model.Publisher", b => + { + b.Navigation("Authors"); + + b.Navigation("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BookAPI/Model/ApiResponse.cs b/BookAPI/Model/ApiResponse.cs new file mode 100644 index 0000000..7cd1758 --- /dev/null +++ b/BookAPI/Model/ApiResponse.cs @@ -0,0 +1,12 @@ +using System.Net; + +namespace BookAPI.Model +{ + public class ApiResponse + { + public HttpStatusCode StatusCode { get; set; } + public bool IsSuccess { get; set; } + public List ErrorMessages { get; set; } + public object Result { get; set; } + } +} diff --git a/BookAPI/Model/Author.cs b/BookAPI/Model/Author.cs new file mode 100644 index 0000000..228e864 --- /dev/null +++ b/BookAPI/Model/Author.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace BookAPI.Model +{ + public class Author + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public string Name { get; set; } + [ForeignKey("Publisher")] + public int PublisherId { get; set; } + public Publisher Publisher { get; set; } + public ICollection Books { get; set; } + } + +} \ No newline at end of file diff --git a/BookAPI/Model/Book.cs b/BookAPI/Model/Book.cs new file mode 100644 index 0000000..ebb39a7 --- /dev/null +++ b/BookAPI/Model/Book.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace BookAPI.Model +{ + public class Book + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public string Title { get; set; } + public DateTime PublicationDate { get; set; } + [ForeignKey("Author")] + public int AuthorId { get; set; } + //[ForeignKey("Publisher")] + //public int PublisherId { get; set; } + public Author Author { get; set; } + //public Publisher Publisher { get; set; } + } + +} diff --git a/BookAPI/Model/Publisher.cs b/BookAPI/Model/Publisher.cs new file mode 100644 index 0000000..cb868c8 --- /dev/null +++ b/BookAPI/Model/Publisher.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace BookAPI.Model +{ + public class Publisher + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public string Name { get; set; } + public string Address { get; set; } + public ICollection Authors { get; set; } + public ICollection Books { get; set; } + } + +} diff --git a/BookAPI/Program.cs b/BookAPI/Program.cs new file mode 100644 index 0000000..0a83e09 --- /dev/null +++ b/BookAPI/Program.cs @@ -0,0 +1,38 @@ +using BookAPI.Data; +using BookAPI.Model; +using BookAPI.Service.Implementation; +using BookAPI.Service.Interface; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); +builder.Services.AddDbContext(options => +{ options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")); }); +builder.Services.AddScoped(); +builder.Services.AddScoped,BookRepository>(); +builder.Services.AddScoped(); + +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/BookAPI/Properties/launchSettings.json b/BookAPI/Properties/launchSettings.json new file mode 100644 index 0000000..6bc97e5 --- /dev/null +++ b/BookAPI/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:48188", + "sslPort": 44394 + } + }, + "profiles": { + "BookAPI": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7237;http://localhost:5023", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/BookAPI/README.md b/BookAPI/README.md new file mode 100644 index 0000000..406ef50 --- /dev/null +++ b/BookAPI/README.md @@ -0,0 +1 @@ +This a simple BookAPI that has CRUD operations for three models which include Author,Book and Publisher diff --git a/BookAPI/Service/Implementation/AuthorRepository.cs b/BookAPI/Service/Implementation/AuthorRepository.cs new file mode 100644 index 0000000..18f3f04 --- /dev/null +++ b/BookAPI/Service/Implementation/AuthorRepository.cs @@ -0,0 +1,63 @@ +using AutoMapper; +using BookAPI.Data; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Interface; +using Microsoft.EntityFrameworkCore; + +namespace BookAPI.Service.Implementation +{ + public class AuthorRepository : IAuthorRepository + { + private readonly ApplicationDbContext _dbContext; + + public AuthorRepository(ApplicationDbContext dbContext) + { + _dbContext = dbContext; + + } + + public async Task> GetAllAsync() + { + return await _dbContext.Authors.ToListAsync(); + + } + + public async Task GetByIdAsync(int id) + { + var author = await _dbContext.Authors.FindAsync(id); + return author; + } + + public async Task AddAsync(Author entity) + { + + await _dbContext.Authors.AddAsync(entity); + await _dbContext.SaveChangesAsync(); + } + + + public async Task> GetBooksAttachedToAuthor(int authorId) + { + var books = await _dbContext.Books.Where(b => b.AuthorId == authorId).ToListAsync(); + + return books; + } + + //Task> IRepository.GetAllAsync() + //{ + // throw new NotImplementedException(); + //} + + //Task IRepository.GetByIdAsync(int id) + //{ + // throw new NotImplementedException(); + //} + + //Task IRepository.AddAsync(Author entity) + //{ + // throw new NotImplementedException(); + //} + } + +} diff --git a/BookAPI/Service/Implementation/BookRepository.cs b/BookAPI/Service/Implementation/BookRepository.cs new file mode 100644 index 0000000..fbab0a1 --- /dev/null +++ b/BookAPI/Service/Implementation/BookRepository.cs @@ -0,0 +1,39 @@ +using AutoMapper; +using BookAPI.Data; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Interface; +using Microsoft.EntityFrameworkCore; + +namespace BookAPI.Service.Implementation +{ + public class BookRepository : IRepository + { + private readonly ApplicationDbContext _dbContext; + + + public BookRepository(ApplicationDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> GetAllAsync() + { + return await _dbContext.Books.ToListAsync(); + } + + public async Task GetByIdAsync(int id) + { + var book = await _dbContext.Books.FindAsync(id); + return book; + + } + + public async Task AddAsync(Book entity) + { + await _dbContext.AddAsync(entity); + await _dbContext.SaveChangesAsync(); + } + } + +} diff --git a/BookAPI/Service/Implementation/PublisherRepository.cs b/BookAPI/Service/Implementation/PublisherRepository.cs new file mode 100644 index 0000000..e34610e --- /dev/null +++ b/BookAPI/Service/Implementation/PublisherRepository.cs @@ -0,0 +1,45 @@ +using AutoMapper; +using BookAPI.Data; +using BookAPI.Dto; +using BookAPI.Model; +using BookAPI.Service.Interface; +using Microsoft.EntityFrameworkCore; + +namespace BookAPI.Service.Implementation +{ + public class PublisherRepository : IPublisherRepository + { + private readonly ApplicationDbContext _dbContext; + private readonly IMapper _mapper; + + public PublisherRepository(ApplicationDbContext dbContext) + { + _dbContext = dbContext; + + } + + public async Task> GetAllAsync() + { + return await _dbContext.Publishers.ToListAsync(); + + } + + public async Task GetByIdAsync(int id) + { + var publisher = await _dbContext.Publishers.FindAsync(id); + return publisher; + + } + + public async Task AddAsync(Publisher entity) + { + await _dbContext.Publishers.AddAsync(entity); + await _dbContext.SaveChangesAsync(); + } + + public async Task> GetAuthorsAttachedToPublisher(int publisherId) + { + return _dbContext.Authors.Where(a => a.PublisherId == publisherId).ToList(); + } + } +} diff --git a/BookAPI/Service/Interface/IAuthorRepository.cs b/BookAPI/Service/Interface/IAuthorRepository.cs new file mode 100644 index 0000000..6d18f15 --- /dev/null +++ b/BookAPI/Service/Interface/IAuthorRepository.cs @@ -0,0 +1,9 @@ +using BookAPI.Model; + +namespace BookAPI.Service.Interface +{ + public interface IAuthorRepository : IRepository + { + Task> GetBooksAttachedToAuthor(int authorId); + } +} diff --git a/BookAPI/Service/Interface/IPublisherRepository.cs b/BookAPI/Service/Interface/IPublisherRepository.cs new file mode 100644 index 0000000..04bbf5c --- /dev/null +++ b/BookAPI/Service/Interface/IPublisherRepository.cs @@ -0,0 +1,13 @@ +using BookAPI.Dto; +using BookAPI.Model; + +namespace BookAPI.Service.Interface +{ + public interface IPublisherRepository : IRepository + { + // other methods in the interface... + + Task> GetAuthorsAttachedToPublisher(int publisherId); + } + +} diff --git a/BookAPI/Service/Interface/IRepositoryInterface.cs b/BookAPI/Service/Interface/IRepositoryInterface.cs new file mode 100644 index 0000000..cf50f56 --- /dev/null +++ b/BookAPI/Service/Interface/IRepositoryInterface.cs @@ -0,0 +1,10 @@ +namespace BookAPI.Service.Interface +{ + public interface IRepository where T : class + { + Task> GetAllAsync(); + Task GetByIdAsync(int id); + Task AddAsync(T entity); + } + +} diff --git a/BookAPI/appsettings.Development.json b/BookAPI/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/BookAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/BookAPI/appsettings.json b/BookAPI/appsettings.json new file mode 100644 index 0000000..167083b --- /dev/null +++ b/BookAPI/appsettings.json @@ -0,0 +1,10 @@ +{ + "ConnectionStrings": { "DefaultConnection": "server=LAPTOP-C6680A7T\\SQLEXPRESS;database=BookAPI;Integrated Security=true;" }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Console banking/FraudulentBank.Customer/Customer.cs b/Console banking/FraudulentBank.Customer/Customer.cs new file mode 100644 index 0000000..3bfb1bd --- /dev/null +++ b/Console banking/FraudulentBank.Customer/Customer.cs @@ -0,0 +1,496 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Numerics; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Transactions; +using static System.Net.Mime.MediaTypeNames; + +namespace FraudulentBank.Customer +{ + + + public class Transaction + { + public DateTime Date { get; set; } + public string TransactionType { get; set; } + public decimal Amount { get; set; } + public string AccountNumber { get; set; } + public Transaction(string accountNumber, string transactionType, decimal amount, DateTime date) + { + AccountNumber = accountNumber; + TransactionType = transactionType; + Amount = amount; + Date = date; + } + } + + + public class Customer + { + public string Name { get; set; } + public string Email { get; set; } + public string AccountNumber { get; set; } + public decimal Balance { get; set; } + public string Password { get; set; } + public List? Transactions { get; set; } + + public Customer(string name, string accountNumber, string hashedPassword, string email, decimal balance) + { + Name = name; + Email = email; + Password = hashedPassword; + AccountNumber = accountNumber; + Balance = balance; + Transactions = new List(); + } + + + public static void SignUp() + { + Console.Write("Kindly Enter Your Name: "); + string name = Console.ReadLine(); + + + Console.Write("Kindly Enter Your Email: "); + string email = Console.ReadLine(); + + Console.Write("Kindly Enter Your Password: "); + string password = ""; + while (true) + { + ConsoleKeyInfo key = Console.ReadKey(true); + if (key.Key == ConsoleKey.Enter) + { + break; + } + else if (key.Key == ConsoleKey.Backspace && password.Length > 0) + { + password = password.Remove(password.Length - 1); + Console.Write("\b \b"); + } + else if (key.KeyChar != '\u0000' && !char.IsControl(key.KeyChar)) + { + password += key.KeyChar; + Console.Write("*"); + } + } + + string accountNumber = GenerateAccountNumber(); + + decimal balance = 0; + + List transactions = new List(); + + string hashedPassword = HashPassword(password); + + var customer = new Customer(name, hashedPassword, email, accountNumber, balance); + + + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{customer.AccountNumber}.txt"; + using (StreamWriter writer = new StreamWriter(fileName)) + { + writer.WriteLine($"Name: {customer.Name}"); + writer.WriteLine($"Email: {customer.Email}"); + writer.WriteLine($"Account Number: {customer.AccountNumber}"); + writer.WriteLine($"Password: {customer.Password}"); + writer.WriteLine($"Balance: {customer.Balance}"); + writer.WriteLine("Transaction History:"); + } + Console.WriteLine($"Congratulations {name}! Your account has been created with account number {accountNumber}."); + Console.WriteLine("Press 1 to login, or any other key to exit."); + string choice = Console.ReadLine(); + + if (choice == "1") + { + Login(); + } + else + { + Console.WriteLine("Goodbye! Thanks for using our banking application."); + Environment.Exit(0); + + } + } + + + + public static void SaveCustomersToFile(List Customers) + { + string fileName = "Customers.txt"; + string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName; + + using (StreamWriter writer = new StreamWriter(filePath)) + { + foreach (Customer customer in Customers) + { + writer.WriteLine($"{customer.Name},{customer.AccountNumber},{customer.Password},{customer.Email},{customer.Balance}"); + } + } + } + + + static string GenerateAccountNumber() + { + List Customers = new List(); + Random random = new Random(); + string accountNumber; + do + { + accountNumber = "20" + random.Next(10000000, 100000000).ToString(); + } while (Customers.Any(c => c.AccountNumber == accountNumber)); + + return accountNumber; + } + + static string HashPassword(string password) + { + using (var sha256 = SHA256.Create()) + { + var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password)); + var hash = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower(); + return hash; + } + } + + public static void Login() + { + Console.WriteLine("Enter your account number: "); + string accountNumber = Console.ReadLine(); + Console.WriteLine("Enter your password: "); + string password = ""; + while (true) + { + ConsoleKeyInfo key = Console.ReadKey(true); + if (key.Key == ConsoleKey.Enter) + { + break; + } + else if (key.Key == ConsoleKey.Backspace && password.Length > 0) + { + password = password.Remove(password.Length - 1); + Console.Write("\b \b"); + } + else if (key.KeyChar != '\u0000' && !char.IsControl(key.KeyChar)) + { + password += key.KeyChar; + Console.Write("*"); + } + } + + string hashedPassword = Customer.HashPassword(password); + + // Load customer data from file with account number as file name + string fileName = $"{accountNumber}.txt"; + Customer c = Customer.LoadCustomerFromFile(accountNumber); + + if (c != null && c.Password == hashedPassword) + { + Console.WriteLine("Login Successful."); + bool isLoggedIn = true; + + while (isLoggedIn) + { + Console.WriteLine("\nPlease select an option:"); + Console.WriteLine("1. Deposit"); + Console.WriteLine("2. Withdraw"); + Console.WriteLine("3. View Balance"); + Console.WriteLine("4. Transaction History"); + Console.WriteLine("5. Exit"); + + string choice = Console.ReadLine(); + + switch (choice) + { + case "1": + Deposit(accountNumber); + break; + + case "2": + Withdraw(accountNumber); + break; + + case "3": + ViewBalance(); + break; + + case "4": + DisplayTransactionHistory(); + break; + + case "5": + isLoggedIn = false; + Console.WriteLine("Goodbye! Thanks for using our banking application."); + Environment.Exit(5); + break; + + default: + Console.WriteLine("Invalid option, please try again."); + break; + } + + } + } + else + { + Console.WriteLine("Invalid account number or password."); + + } + } + + public static bool AuthenticateCustomer(string accountNumber, string hashedPassword) + { + var Customers = new List(); + foreach (Customer customer in Customers) + { + if (customer.AccountNumber == accountNumber && customer.Password == hashedPassword) + { + return true; + } + } + + return false; + } + + //public static List LoadCustomersFromFile() + //{ + // List customers = new List(); + + // try + // { + // string fileName = "Customers.txt"; + // string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName; + // if (File.Exists(filePath)) + // { + // string[] lines = File.ReadAllLines(filePath); + // foreach (string line in lines) + // { + // string[] fields = line.Split(','); + // string name = fields[0]; + // string hashedPassword = fields[1]; + // string email = fields[2]; + // string accountNumber = fields[3]; + // decimal balance = decimal.Parse(fields[4]); + + // Customer customer = new Customer(name, hashedPassword, email, accountNumber, balance); + // customers.Add(customer); + // } + // } + // } + // catch (Exception ex) + // { + // Console.WriteLine($"An error occurred while loading customers from file: {ex.Message}"); + // } + + // return customers; + //} + + public static Customer LoadCustomerFromFile(string accountNumber) + { + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt"; + + if (!File.Exists(fileName)) + { + throw new FileNotFoundException($"File not found: {fileName}"); + } + + string[] lines = File.ReadAllLines(fileName); + + if (lines.Length < 5) + { + throw new FormatException("File has incorrect format."); + } + + string name = lines[0].Substring(6); + string loadedAccountNumber = lines[2].Substring(16); + string hashedPassword = lines[3].Substring(10); + string email = lines[1].Substring(7); + decimal balance = decimal.Parse(lines[4].Substring(9)); + + Customer customer = new Customer(name, accountNumber, hashedPassword, email, balance); + + return customer; + } + + + + + + + public static void Deposit(string accountNumber) + { + Console.Write("Enter the deposit amount: "); + decimal amount = decimal.Parse(Console.ReadLine()); + + + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt"; + Customer c = Customer.LoadCustomerFromFile(accountNumber); + + if (c.AccountNumber != accountNumber) + { + Console.WriteLine("Invalid account number."); + return; + } + + // Create a new transaction object and add it to the customer's transactions list + var transaction = new Transaction(accountNumber, "Deposit", amount, DateTime.Now); + + + // Update the customer's balance + c.Balance += amount; + + + // Append transaction to transaction history file + string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt"; + using (StreamWriter writer = File.AppendText(transactionFileName)) + { + writer.WriteLine($"{transaction.AccountNumber}|{transaction.TransactionType}|{transaction.Amount}|{transaction.Date}"); + } + + Console.WriteLine($"Transaction successful. Your new balance is {c.Balance:C}"); + } + + + + + public static void SaveTransactionToFile(string accountNumber, Transaction transaction) + { + string fileName = "Transaction.txt"; + string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName; + + // Write the transaction data to the file + using (StreamWriter writer = File.AppendText(filePath)) + { + string transactionData = $"{accountNumber},{transaction.TransactionType},{transaction.Amount},{transaction.Date}"; + writer.WriteLine(transactionData); + } + } + + public static List LoadTransactionHistoryFromFile(string accountNumber) + { + string fileName = $@"C:\Users\Oluwafemi.Dally\Documents\{accountNumber}_transaction.txt"; + + if (!File.Exists(fileName)) + { + throw new FileNotFoundException($"File not found: {fileName}"); + } + + List transactions = new List(); + + using (StreamReader reader = new StreamReader(fileName)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + string[] fields = line.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + DateTime date = DateTime.ParseExact(fields[3], "M/d/yyyy h:mm:ss tt", CultureInfo.InvariantCulture); + string TransactionType = fields[1]; + decimal amount = decimal.Parse(fields[2]); + Transaction transaction = new Transaction(accountNumber, TransactionType, amount, date); + transactions.Add(transaction); + } + } + + return transactions; + } + + + + + public static void Withdraw(string accountNumber) + { + Console.Write("Enter the withdrawal amount: "); + decimal amount = decimal.Parse(Console.ReadLine()); + + List Customers = new List(); + + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt"; + Customer c = Customer.LoadCustomerFromFile(accountNumber); + + if (c.AccountNumber != accountNumber) + { + Console.WriteLine("Invalid account number."); + return; + } + + if (amount > c.Balance) + { + Console.WriteLine("Insufficient funds."); + return; + } + + var transaction = new Transaction(accountNumber, "Withdrawal", amount, DateTime.Now); + + // Update the customer's balance + c.Balance -= amount; + + // Append transaction to transaction history file + string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt"; + using (StreamWriter writer = File.AppendText(transactionFileName)) + { + writer.WriteLine($"{transaction.AccountNumber}|{transaction.TransactionType}|{transaction.Amount}|{transaction.Date}"); + } + + Console.WriteLine($"Transaction successful. Your new balance is {c.Balance:C}"); + } + + + public static void DisplayTransactionHistory() + { + Console.WriteLine("Enter your account number:"); + string accountNumber = Console.ReadLine(); + + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt"; + string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt"; + + Customer c = Customer.LoadCustomerFromFile(accountNumber); + + if (c.AccountNumber != accountNumber) + { + Console.WriteLine("Invalid account number."); + return; + } + + else + { + // Display the customer's transaction history + Console.WriteLine($"Transaction history for {c.Name} ({c.AccountNumber}):"); + List transactions = LoadTransactionHistoryFromFile(accountNumber); + foreach (Transaction transaction in transactions) + { + Console.WriteLine($"Date: {transaction.Date}\tType: {transaction.TransactionType}\tAmount: {transaction.Amount:C}"); + } + } + } + + + public static void ViewBalance() + { + Console.Write("Account number: "); + string accountNumber = Console.ReadLine(); + + string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt"; + Customer c = Customer.LoadCustomerFromFile(accountNumber); + + if (c.AccountNumber != accountNumber) + { + Console.WriteLine("Invalid account number."); + return; + } + else + { + Console.WriteLine($"Balance: NGN{c.Balance:C}"); + } + + + } + + } +} + diff --git a/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj b/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj new file mode 100644 index 0000000..27ac386 --- /dev/null +++ b/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj new file mode 100644 index 0000000..d90fddc --- /dev/null +++ b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj @@ -0,0 +1,13 @@ + + + + Exe + net6.0 + enable + enable + + + + + + diff --git a/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln new file mode 100644 index 0000000..5751492 --- /dev/null +++ b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33103.184 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FraudulentBank.Presentation", "FraudulentBank.Presentation.csproj", "{EF171E09-77E8-497C-941B-7034CFEB0726}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FraudulentBank.Customer", "..\FraudulentBank.Customer\FraudulentBank.Customer.csproj", "{2F204812-D56D-4E5B-8DE2-E43E643DEEE6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EF171E09-77E8-497C-941B-7034CFEB0726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF171E09-77E8-497C-941B-7034CFEB0726}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF171E09-77E8-497C-941B-7034CFEB0726}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF171E09-77E8-497C-941B-7034CFEB0726}.Release|Any CPU.Build.0 = Release|Any CPU + {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {012BDA32-9D27-4202-BAC0-7B347D081F25} + EndGlobalSection +EndGlobal diff --git a/Console banking/FraudulentBank.Presentation/Program.cs b/Console banking/FraudulentBank.Presentation/Program.cs new file mode 100644 index 0000000..7649e52 --- /dev/null +++ b/Console banking/FraudulentBank.Presentation/Program.cs @@ -0,0 +1,39 @@ +using FraudulentBank.Customer; +using System.Transactions; +using System.Xml.Linq; + +//static void Main(string[] args) +{ + // while (true) + { + Console.WriteLine("**********WELCOME TO FRAUDULENT BANK*********"); + Console.WriteLine("1. Sign up"); + Console.WriteLine("2. Log in"); + Console.WriteLine("3. Exit"); + string choice = Console.ReadLine(); + + + switch (choice) + { + case "1": + Customer.SignUp(); + break; + case "2": + Customer.Login(); + break; + case "3": + Environment.Exit(0); + break; + default: + Console.WriteLine("Invalid choice. Please try again."); + break; + } + } +} + + + + + + +