diff --git a/Marechai/Marechai.csproj b/Marechai/Marechai.csproj index 212a3e1b..51df85de 100644 --- a/Marechai/Marechai.csproj +++ b/Marechai/Marechai.csproj @@ -2,7 +2,7 @@ netcoreapp3.1 - 4.0.0.1790 + 4.0.0.1792 Canary Islands Computer Museum Copyright © 2003-2020 Natalia Portillo Canary Islands Computer Museum Website diff --git a/Marechai/Pages/Admin/Books.razor b/Marechai/Pages/Admin/Books.razor new file mode 100644 index 00000000..72fc1a4c --- /dev/null +++ b/Marechai/Pages/Admin/Books.razor @@ -0,0 +1,110 @@ +@{ +/****************************************************************************** +// MARECHAI: Master repository of computing history artifacts information +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2003-2020 Natalia Portillo +*******************************************************************************/ +} + +@page "/admin/books" +@using Marechai.Database.Models +@inherits OwningComponentBase +@inject IStringLocalizer L +@inject Microsoft.AspNetCore.Identity.UserManager UserManager +@inject AuthenticationStateProvider AuthenticationStateProvider +@attribute [Authorize(Roles = "UberAdmin, Admin")] +

@L["Books"]

+@if (_books is null) +{ +

@L["Loading..."]

+ + return; +} +

+ @L["Create new"] +

+ + + + + + + + + + + + + @foreach (var item in _books) + { + + + + + + + + + } + +
+ @L["Title"] + + @L["Native title"] + + @L["Published"] + + @L["Country"] + + @L["ISBN"] +
+ @item.Title + + @item.NativeTitle + + @($"{item.Published:d}") + + @item.Country + + @item.Isbn + + @L["Details"] + @L["Edit"] + +
+ + + + + + @L["Delete book"] + + + + @string.Format(@L["Are you sure you want to delete the book {0}?"], _currentBook?.Title) + + + + + + + diff --git a/Marechai/Pages/Admin/Books.razor.cs b/Marechai/Pages/Admin/Books.razor.cs new file mode 100644 index 00000000..d389d8c8 --- /dev/null +++ b/Marechai/Pages/Admin/Books.razor.cs @@ -0,0 +1,88 @@ +/****************************************************************************** +// MARECHAI: Master repository of computing history artifacts information +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2003-2020 Natalia Portillo +*******************************************************************************/ + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Blazorise; +using Marechai.ViewModels; +using Microsoft.AspNetCore.Components.Authorization; + +namespace Marechai.Pages.Admin +{ + public partial class Books + { + List _books; + BookViewModel _currentBook; + bool _deleteInProgress; + Modal _frmDelete; + bool _loaded; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if(_loaded) + return; + + _books = await Service.GetAsync(); + _loaded = true; + StateHasChanged(); + } + + void ShowModal(long itemId) + { + _currentBook = _books.FirstOrDefault(n => n.Id == itemId); + _frmDelete.Show(); + } + + void HideModal() => _frmDelete.Hide(); + + async void ConfirmDelete() + { + if(_currentBook is null) + return; + + _deleteInProgress = true; + _books = null; + AuthenticationState authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + + // Yield thread to let UI to update + await Task.Yield(); + + await Service.DeleteAsync(_currentBook.Id, (await UserManager.GetUserAsync(authState.User)).Id); + _books = await Service.GetAsync(); + + _deleteInProgress = false; + _frmDelete.Hide(); + + // Yield thread to let UI to update + await Task.Yield(); + + // Tell we finished loading + StateHasChanged(); + } + + void ModalClosing(ModalClosingEventArgs obj) => _currentBook = null; + } +} \ No newline at end of file diff --git a/Marechai/Pages/Admin/Details/Book.razor b/Marechai/Pages/Admin/Details/Book.razor new file mode 100644 index 00000000..9d696847 --- /dev/null +++ b/Marechai/Pages/Admin/Details/Book.razor @@ -0,0 +1,211 @@ +@{ +/****************************************************************************** +// MARECHAI: Master repository of computing history artifacts information +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2003-2020 Natalia Portillo +*******************************************************************************/ +} + +@page "/admin/books/details/{Id:long}" +@page "/admin/books/edit/{Id:long}" +@page "/admin/books/create" +@using Marechai.Database +@using Marechai.Database.Models +@inherits OwningComponentBase +@inject IStringLocalizer L +@inject Iso31661NumericService CountriesService +@inject NavigationManager NavigationManager +@inject IWebHostEnvironment Host +@inject IJSRuntime JSRuntime +@inject Microsoft.AspNetCore.Identity.UserManager UserManager +@inject AuthenticationStateProvider AuthenticationStateProvider +@attribute [Authorize(Roles = "UberAdmin, Admin")] + + +

@L["Book details"]

+
+ +@if (!_loaded) +{ +

@L["Loading..."]

+ + return; +} + +
+ + @L["Title using latin script"] + + + + @L["Please enter a valid title."] + + + + + @if (_editing || _model.NativeTitle != null) + { + + @L["Native title, that is, title using native script (cyrillic, chinese, etc)"] + @if (_editing) + { + @L["Unknown (native title)"] + } + @if (!_editing || + !_unknownNativeTitle) + { + + + + @L["Please enter a valid native title."] + + + + } + + } + @if (_editing || _model.Published != null) + { + + @L["Published"] + @if (_editing) + { + @L["Unknown (publication date)"] + } + @if (!_editing || !_unknownPublished) + { + + + + @L["Please enter a valid publication date."] + + + + } + + } + @if (_editing || _model.CountryId != null) + { + + @L["Country of publication"] + @if (_editing) + { + @L["Unknown (country of publication)"] + } + @if (!_editing || + !_unknownCountry) + { + + } + + } + @if (_editing || _model.Isbn != null) + { + + @L["ISBN"] + @if (_editing) + { + @L["Unknown (ISBN)"] + } + @if (!_editing || + !_unknownIsbn) + { + + + + @L["Please enter a valid ISBN."] + + + + } + + } + @if (_editing || _model.Pages.HasValue) + { + + @L["Pages"] + @if (_editing) + { + @L["Unknown (pages)"] + } + @if (!_editing || + !_unknownPages) + { + + + + @L["Please enter a valid number of pages."] + + + + } + + } + @if (_editing || _model.Edition.HasValue) + { + + @L["Edition"] + @if (_editing) + { + @L["Unknown (edition)"] + } + @if (!_editing || + !_unknownEdition) + { + + + + @L["Please enter a valid edition number."] + + + + } + + } +@{ + // TODO: Source book +} +@{ + // TODO: Link to previous edition +} +
+
+ @if (!_editing) + { + + } + else + { + + + } + @L["Back to list"] +
+ +@{ + // TODO: Book synopsis +} diff --git a/Marechai/Pages/Admin/Details/Book.razor.cs b/Marechai/Pages/Admin/Details/Book.razor.cs new file mode 100644 index 00000000..d3be0611 --- /dev/null +++ b/Marechai/Pages/Admin/Details/Book.razor.cs @@ -0,0 +1,202 @@ +/****************************************************************************** +// MARECHAI: Master repository of computing history artifacts information +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2003-2020 Natalia Portillo +*******************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Blazorise; +using Marechai.Database.Models; +using Marechai.Shared; +using Marechai.ViewModels; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; + +namespace Marechai.Pages.Admin.Details +{ + public partial class Book + { + AuthenticationState _authState; + List _countries; + bool _creating; + bool _editing; + bool _loaded; + BookViewModel _model; + bool _unknownCountry; + bool _unknownEdition; + bool _unknownIsbn; + bool _unknownNativeTitle; + bool _unknownPages; + bool _unknownPublished; + + [Parameter] + public long Id { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if(_loaded) + return; + + _loaded = true; + + _creating = NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant(). + StartsWith("admin/books/create", StringComparison.InvariantCulture); + + if(Id <= 0 && + !_creating) + return; + + _countries = await CountriesService.GetAsync(); + _model = _creating ? new BookViewModel() : await Service.GetAsync(Id); + _authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + + _editing = _creating || NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant(). + StartsWith("admin/books/edit/", + StringComparison.InvariantCulture); + + if(_editing) + SetCheckboxes(); + + StateHasChanged(); + } + + void SetCheckboxes() + { + _unknownCountry = !_model.CountryId.HasValue; + _unknownNativeTitle = string.IsNullOrWhiteSpace(_model.NativeTitle); + _unknownPublished = !_model.Published.HasValue; + _unknownIsbn = string.IsNullOrWhiteSpace(_model.Isbn); + _unknownPages = !_model.Pages.HasValue; + _unknownEdition = !_model.Edition.HasValue; + } + + void OnEditClicked() + { + _editing = true; + SetCheckboxes(); + StateHasChanged(); + } + + async void OnCancelClicked() + { + _editing = false; + + if(_creating) + { + NavigationManager.ToBaseRelativePath("admin/books"); + + return; + } + + _model = await Service.GetAsync(Id); + SetCheckboxes(); + StateHasChanged(); + } + + async void OnSaveClicked() + { + if(_unknownNativeTitle) + _model.NativeTitle = null; + else if(string.IsNullOrWhiteSpace(_model.NativeTitle)) + return; + + if(_unknownCountry) + _model.CountryId = null; + else if(_model.CountryId < 0) + return; + + if(_unknownPages) + _model.Pages = null; + else if(_model.Pages < 1) + return; + + if(_unknownEdition) + _model.Edition = null; + else if(_model.Edition < 1) + return; + + if(_unknownPublished) + _model.Published = null; + else if(_model.Published?.Date >= DateTime.UtcNow.Date) + return; + + if(_unknownIsbn) + _model.Isbn = null; + else if(string.IsNullOrWhiteSpace(_model.Isbn)) + return; + + // Convert ISBN-10 to ISBN-13 + if(_model.Isbn?.Length == 10) + { + char[] newIsbn = new char[13]; + Array.Copy(_model.Isbn.ToCharArray(), 0, newIsbn, 3, 9); + newIsbn[0] = '9'; + newIsbn[1] = '7'; + newIsbn[2] = '8'; + + int sum = (newIsbn[0] - 0x30) + ((newIsbn[1] - 0x30) * 3) + (newIsbn[2] - 0x30) + + ((newIsbn[3] - 0x30) * 3) + (newIsbn[4] - 0x30) + ((newIsbn[5] - 0x30) * 3) + + (newIsbn[6] - 0x30) + ((newIsbn[7] - 0x30) * 3) + (newIsbn[8] - 0x30) + + ((newIsbn[9] - 0x30) * 3) + (newIsbn[10] - 0x30) + ((newIsbn[11] - 0x30) * 3); + + int modulo = sum % 10; + + if(modulo != 0) + modulo = 10 - modulo; + + newIsbn[12] = (char)(modulo + 0x30); + + _model.Isbn = new string(newIsbn); + } + + if(string.IsNullOrWhiteSpace(_model.Title)) + return; + + if(_creating) + Id = await Service.CreateAsync(_model, (await UserManager.GetUserAsync(_authState.User)).Id); + else + await Service.UpdateAsync(_model, (await UserManager.GetUserAsync(_authState.User)).Id); + + _editing = false; + _creating = false; + _model = await Service.GetAsync(Id); + SetCheckboxes(); + StateHasChanged(); + } + + void ValidateTitle(ValidatorEventArgs e) => + Validators.ValidateString(e, L["Title must be smaller than 256 characters."], 256); + + void ValidatePublished(ValidatorEventArgs e) => Validators.ValidateDate(e); + + void ValidateNativeTitle(ValidatorEventArgs e) => + Validators.ValidateString(e, L["Native title must be smaller than 256 characters."], 256); + + void ValidatePages(ValidatorEventArgs e) => Validators.ValidateShort(e, 1); + + void ValidateEdition(ValidatorEventArgs e) => Validators.ValidateInteger(e, 1); + + void ValidateIsbn(ValidatorEventArgs e) => Validators.ValidateIsbn(e); + } +} \ No newline at end of file diff --git a/Marechai/Pages/Admin/Index.razor b/Marechai/Pages/Admin/Index.razor index 82a304f8..98e0599b 100644 --- a/Marechai/Pages/Admin/Index.razor +++ b/Marechai/Pages/Admin/Index.razor @@ -89,6 +89,9 @@
  • @L["Document people"]
  • +
  • + @L["Books"] +
  • diff --git a/Marechai/Resources/Services/AdminService.en.resx b/Marechai/Resources/Services/AdminService.en.resx new file mode 100644 index 00000000..2ace1d53 --- /dev/null +++ b/Marechai/Resources/Services/AdminService.en.resx @@ -0,0 +1,17 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Books + + \ No newline at end of file diff --git a/Marechai/Resources/Services/AdminService.es.resx b/Marechai/Resources/Services/AdminService.es.resx index 9ff4c208..70163ca6 100644 --- a/Marechai/Resources/Services/AdminService.es.resx +++ b/Marechai/Resources/Services/AdminService.es.resx @@ -210,4 +210,7 @@ Resoluciones Resolutions. + + Libros + \ No newline at end of file diff --git a/Marechai/Resources/Services/BooksService.en.resx b/Marechai/Resources/Services/BooksService.en.resx new file mode 100644 index 00000000..91128741 --- /dev/null +++ b/Marechai/Resources/Services/BooksService.en.resx @@ -0,0 +1,119 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Are you sure you want to delete the book {0}? + + + Books + + + Cancel + + + Country + + + Create new + + + Delete + + + Delete book + + + Details + + + Edit + + + ISBN + + + Loading... + + + Native title + + + Published + + + Title + + + Book details + + + Title using latin script + + + Please enter a valid title. + + + Native title, that is, title using native script (cyrillic, chinese, etc) + + + Unknown + + + Please enter a valid native title. + + + Unknown + + + Please enter a valid publication date. + + + Country of publication + + + Please enter a valid ISBN. + + + Pages + + + Please enter a valid number of pages. + + + Edition + + + Please enter a valid edition number. + + + Back to list + + + Title must be smaller than 256 characters. + + + Native title must be smaller than 256 characters. + + + Unknown + + + Unknown + + + Unknown + + + Unknown + + \ No newline at end of file diff --git a/Marechai/Resources/Services/BooksService.es.resx b/Marechai/Resources/Services/BooksService.es.resx new file mode 100644 index 00000000..32e3be0d --- /dev/null +++ b/Marechai/Resources/Services/BooksService.es.resx @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Libros + Books + + + Cargando... + Message that appears while data is being loaded from database + + + País + Country where the book was published + + + Detalles + Details + + + Editar + Edit + + + Eliminar + Delete + + + Eliminar libro + Delete book + + + ¿Está seguro de que desea borrar el libro {0}? + {0} book name + + + Cancelar + Cancel + + + Crear nuevo + + + Título + + + Título nativo + + + Publicado el + + + ISBN + + + Detalles de libro + + + Título utilizando escritura latina + + + Por favor introduce un título válido. + + + Título nativo, es decir, el título usando el sistema de escritura nativo (cirílico, chino, etc) + + + Desconocido + + + Por favor introduce un título nativo válido. + + + Desconocida + + + Por favor introduce una fecha de publicación válida. + + + País de publicación + + + Desconocido + + + Desconocido + + + Por favor introduce un ISBN válido. + + + Páginas + + + Desconocidas + + + Desconocida + + + Por favor introduce un número de páginas válido. + + + Edición + + + Por favor introduce un número de edición válido. + + + Volver a la lista + + + El título debe contener menos de 256 caracteres. + + + El título nativo debe contener menos de 256 caracteres. + + \ No newline at end of file diff --git a/Marechai/Services/BooksService.cs b/Marechai/Services/BooksService.cs new file mode 100644 index 00000000..749131f6 --- /dev/null +++ b/Marechai/Services/BooksService.cs @@ -0,0 +1,134 @@ +/****************************************************************************** +// MARECHAI: Master repository of computing history artifacts information +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2003-2020 Natalia Portillo +*******************************************************************************/ + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Marechai.Database.Models; +using Marechai.ViewModels; +using Microsoft.EntityFrameworkCore; + +namespace Marechai.Services +{ + public class BooksService + { + readonly MarechaiContext _context; + + public BooksService(MarechaiContext context) => _context = context; + + public async Task> GetAsync() => await _context. + Books.OrderBy(b => b.NativeTitle). + ThenBy(b => b.Published).ThenBy(b => b.Title). + Select(b => new BookViewModel + { + Id = b.Id, + Title = b.Title, + NativeTitle = b.NativeTitle, + Published = b.Published, + Synopsis = b.Synopsis, + Isbn = b.Isbn, + CountryId = b.CountryId, + Pages = b.Pages, + Edition = b.Edition, + PreviousId = b.PreviousId, + SourceId = b.SourceId, + Country = b.Country.Name + }).ToListAsync(); + + public async Task GetAsync(long id) => await _context.Books.Where(b => b.Id == id). + Select(b => new BookViewModel + { + Id = b.Id, + Title = b.Title, + NativeTitle = b.NativeTitle, + Published = b.Published, + Synopsis = b.Synopsis, + Isbn = b.Isbn, + CountryId = b.CountryId, + Pages = b.Pages, + Edition = b.Edition, + PreviousId = b.PreviousId, + SourceId = b.SourceId, + Country = b.Country.Name + }).FirstOrDefaultAsync(); + + public async Task UpdateAsync(BookViewModel viewModel, string userId) + { + Book model = await _context.Books.FindAsync(viewModel.Id); + + if(model is null) + return; + + model.Title = viewModel.Title; + model.NativeTitle = viewModel.NativeTitle; + model.Published = viewModel.Published; + model.Synopsis = viewModel.Synopsis; + model.CountryId = viewModel.CountryId; + model.Isbn = viewModel.Isbn; + model.Pages = viewModel.Pages; + model.Edition = viewModel.Edition; + model.PreviousId = viewModel.PreviousId; + model.SourceId = viewModel.SourceId; + await _context.SaveChangesWithUserAsync(userId); + } + + public async Task CreateAsync(BookViewModel viewModel, string userId) + { + var model = new Book + { + Title = viewModel.Title, + NativeTitle = viewModel.NativeTitle, + Published = viewModel.Published, + Synopsis = viewModel.Synopsis, + CountryId = viewModel.CountryId, + Isbn = viewModel.Isbn, + Pages = viewModel.Pages, + Edition = viewModel.Edition, + PreviousId = viewModel.PreviousId, + SourceId = viewModel.SourceId + }; + + await _context.Books.AddAsync(model); + await _context.SaveChangesWithUserAsync(userId); + + return model.Id; + } + + public async Task GetSynopsisTextAsync(int id) => + (await _context.Books.FirstOrDefaultAsync(d => d.Id == id))?.Synopsis; + + public async Task DeleteAsync(long id, string userId) + { + Book item = await _context.Books.FindAsync(id); + + if(item is null) + return; + + _context.Books.Remove(item); + + await _context.SaveChangesWithUserAsync(userId); + } + } +} \ No newline at end of file diff --git a/Marechai/Services/Register.cs b/Marechai/Services/Register.cs index 7ac1729d..087bf2be 100644 --- a/Marechai/Services/Register.cs +++ b/Marechai/Services/Register.cs @@ -67,6 +67,7 @@ namespace Marechai.Services services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); } } } \ No newline at end of file diff --git a/Marechai/Shared/Validators.cs b/Marechai/Shared/Validators.cs index 99be0802..a2aa6ef7 100644 --- a/Marechai/Shared/Validators.cs +++ b/Marechai/Shared/Validators.cs @@ -133,5 +133,81 @@ namespace Marechai.Shared else e.Status = ValidationStatus.Success; } + + public static void ValidateShort(ValidatorEventArgs e, short minValue = 0, short maxValue = short.MaxValue) + { + if(!(e.Value is short item) || + item < minValue || + item > maxValue) + e.Status = ValidationStatus.Error; + else + e.Status = ValidationStatus.Success; + } + + public static void ValidateIsbn(ValidatorEventArgs e) + { + e.Status = ValidationStatus.Error; + + if(!(e.Value is string isbn)) + return; + + if(isbn.Length != 10 && + isbn.Length != 13) + return; + + for(int c = 0; c < (isbn.Length == 13 ? 13 : 9); c++) + { + if(isbn[c] < 0x30 || + isbn[c] > 0x39) + return; + } + + int sum; + int modulo; + + if(isbn.Length == 10) + { + if((isbn[9] < 0x30 || isbn[9] > 0x39) && + isbn[9] != 'x' && + isbn[9] != 'X') + return; + + sum = 0; + modulo = 0; + + for(int i = 0; i < 10; i++) + { + modulo += isbn[i] - 0x30; + sum += modulo; + } + + modulo = sum % 11; + + if((isbn[9] == 'x' || isbn[9] == 'X') && + modulo == 10) + e.Status = ValidationStatus.Success; + else if(modulo == isbn[9] - 0x30) + e.Status = ValidationStatus.Success; + + return; + } + + if(isbn[0] != '9' || + isbn[1] != '7' || + (isbn[1] != '8' && isbn[1] != '9')) + return; + + sum = (isbn[0] - 0x30) + ((isbn[1] - 0x30) * 3) + (isbn[2] - 0x30) + ((isbn[3] - 0x30) * 3) + + (isbn[4] - 0x30) + ((isbn[5] - 0x30) * 3) + (isbn[6] - 0x30) + ((isbn[7] - 0x30) * 3) + + (isbn[8] - 0x30) + ((isbn[9] - 0x30) * 3) + (isbn[10] - 0x30) + ((isbn[11] - 0x30) * 3); + + modulo = sum % 10; + + if(modulo != 0) + modulo = 10 - modulo; + + if(modulo == isbn[12] - 0x30) + e.Status = ValidationStatus.Success; + } } } \ No newline at end of file diff --git a/Marechai/ViewModels/BookViewModel.cs b/Marechai/ViewModels/BookViewModel.cs new file mode 100644 index 00000000..cd444e46 --- /dev/null +++ b/Marechai/ViewModels/BookViewModel.cs @@ -0,0 +1,11 @@ +namespace Marechai.ViewModels +{ + public class BookViewModel : DocumentBaseViewModel + { + public string Isbn { get; set; } + public short? Pages { get; set; } + public int? Edition { get; set; } + public long? PreviousId { get; set; } + public long? SourceId { get; set; } + } +} \ No newline at end of file diff --git a/Marechai/ViewModels/DocumentBaseViewModel.cs b/Marechai/ViewModels/DocumentBaseViewModel.cs new file mode 100644 index 00000000..e1bc8c5c --- /dev/null +++ b/Marechai/ViewModels/DocumentBaseViewModel.cs @@ -0,0 +1,14 @@ +using System; + +namespace Marechai.ViewModels +{ + public abstract class DocumentBaseViewModel : BaseViewModel + { + public string Title { get; set; } + public string NativeTitle { get; set; } + public DateTime? Published { get; set; } + public short? CountryId { get; set; } + public string Country { get; set; } + public string Synopsis { get; set; } + } +} \ No newline at end of file