diff --git a/src/Controllers/HomeController.cs b/src/Controllers/HomeController.cs new file mode 100644 index 0000000..cdc2140 --- /dev/null +++ b/src/Controllers/HomeController.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.FileProviders; +using QRCoder; + +namespace dontKillBill.Controllers +{ + public class HomeController : Controller + { + + private readonly ApplicationDbContext _context; + private readonly IHostingEnvironment _env; + + + + public HomeController(ApplicationDbContext context, IHostingEnvironment env) + { + _context = context; + _env = env; + } + + + public IActionResult Index() + { + //staci aby to zbehlo raz + // FindFreeIntervals.Find(_context); + + return View(); + + } + public IActionResult SelectInterval(MenuViewModel model) + { + if (!ModelState.IsValid) + { + return Content("Neplatny vstup", "text/html"); + } + + var vouchers = _context.Vouchers.OrderBy(m => m.VoucherId).Skip(model.StartPoint-1).Take(model.EndPoint-model.StartPoint).ToList(); + + return View(vouchers); + } + + public IActionResult NewVoucher(MenuViewModel viewModel) + { + if (!ModelState.IsValid) + { + return Content("Neplatny vstup", "text/html"); + } + + GenerateVouchers(viewModel.Count); + + return View(); + } + + + public IActionResult QrCode(MenuViewModel viewModel) + { + if (!ModelState.IsValid) + { + return Content("Neplatny vstup", "text/html"); + } + + string path=string.Empty; + string exist = Exist(viewModel.ToQr); + + if(exist == viewModel.ToQr.ToString()) + { + path = GenerateQrCode(viewModel.ToQr); + } + + ViewData["exist"] = exist; + ViewData["qrCode"] = path; + return View(); + } + + #region Generate new vouchers + + private void GenerateVouchers(int count) + { + //ak nieje co vytvarat + if (count == 0) + return; + + + var intervals = _context.FreeIntervals.Where(u => u.Used == false); + + //ak uz nepotrebujem generovat podla intervalov + if (!intervals.Any()) + { + GenerateVouchersFromEnd(count); + } + + //generovanie z intervalov + else + { + intervals = intervals.OrderBy(s => s.StartOfInterval).Take(count); + GenerateVouchersFromInterval(intervals, count); + } + + _context.SaveChanges(); + } + + + private void GenerateVouchersFromEnd(int count) + { + var last = _context.Vouchers.OrderByDescending(v => v.VoucherId).FirstOrDefault(); + int start = last.VoucherId+1; + int end = last.VoucherId+count; + + for (int i = start; i < end; i++) + { + var voucher = new Vouchers { VoucherId = i }; + _context.Add(voucher); + } + } + + private void GenerateVouchersFromInterval(IQueryable intervals, int count) + { + int generated = 0; + + foreach (var interval in intervals) + { + + + int start = interval.StartOfInterval; + int end = interval.EndOfInterval; + + for (int i = start; i < end; i++) + { + generated++; + var voucher = new Vouchers { VoucherId = i }; + _context.Add(voucher); + + if (generated == count) + { + interval.StartOfInterval = i + 1; + + return; + } + } + interval.Used = true; + } + + //ak sa to dostane az sem treba dogenerovat vouchre aj za vsetkymi intervalmi + GenerateVouchersFromEnd(count - generated); + } + #endregion + + #region QrCode + + private string Exist(int id) + { + var result = _context.Vouchers.Find(id); + + return result == null ? "Takyto voucher zatial neexistuje" : id.ToString(); + } + + private string GenerateQrCode(int voucherId) + { + string id = voucherId.ToString(); + var webRoot = _env.WebRootPath; + + //ak Qr code este nebol vytvoreny, vytvor ho + if(!FindQrCode(voucherId, webRoot)) + { + var fullPath = Path.Combine(webRoot, "QrCodes", "voucher_" + id + ".png"); + + QRCodeGenerator qrGenerator = new QRCodeGenerator(); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(id, QRCodeGenerator.ECCLevel.Q); + QRCode qrCode = new QRCode(qrCodeData); + Bitmap qrCodeImage = qrCode.GetGraphic(20); + + qrCodeImage.Save(fullPath, ImageFormat.Png); + } + + return Path.Combine("/QrCodes", "voucher_" + id + ".png"); + } + + private bool FindQrCode(int voucherId,string webRoot) + { + var _fileProvider = new PhysicalFileProvider(webRoot); + + var contents = _fileProvider.GetDirectoryContents("/QrCodes"); + + var result = contents.ToList().Find(n => n.Name == "voucher_" + voucherId.ToString() + ".png"); + + if (result == null) + return false; + + return true; + } + #endregion + } + +} diff --git a/src/INFO.txt b/src/INFO.txt new file mode 100644 index 0000000..c1256ac --- /dev/null +++ b/src/INFO.txt @@ -0,0 +1,11 @@ +-mail: martin.trojan.372@gmail.com + +-ked som to chcel len pushnut tak + +$ git push origin Trojan_Martin +Warning: Permanently added the RSA host key for IP address '140.82.118.3' to the list of known hosts. +git@github.com: Permission denied (publickey). +fatal: Could not read from remote repository. + +Please make sure you have the correct access rights +and the repository exists. \ No newline at end of file diff --git a/src/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 0000000..919ee84 --- /dev/null +++ b/src/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,51 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using dontKillBill; + +namespace dontKillBill.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.8-servicing-32085") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("dontKillBill.FreeIntervals", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("EndOfInterval"); + + b.Property("StartOfInterval"); + + b.Property("Used"); + + b.HasKey("Id"); + + b.ToTable("FreeIntervals"); + }); + + modelBuilder.Entity("dontKillBill.Vouchers", b => + { + b.Property("VoucherId") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.HasKey("VoucherId"); + + b.ToTable("Vouchers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Models/ApplicationDbContext.cs b/src/Models/ApplicationDbContext.cs new file mode 100644 index 0000000..e66bcf0 --- /dev/null +++ b/src/Models/ApplicationDbContext.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace dontKillBill +{ + public class ApplicationDbContext : DbContext + { + public ApplicationDbContext(DbContextOptions options) : base(options) + { + + } + + public DbSet Vouchers { get; set; } + + public DbSet FreeIntervals { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + } +} diff --git a/src/Models/FreeIntervals.cs b/src/Models/FreeIntervals.cs new file mode 100644 index 0000000..3c1a262 --- /dev/null +++ b/src/Models/FreeIntervals.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace dontKillBill +{ + public class FreeIntervals + { + + [Key] + public int Id { get; set; } + + public int StartOfInterval { get; set; } + + public int EndOfInterval { get; set; } + + public bool Used { get; set; } + + + + } +} diff --git a/src/Models/ViewModels/MenuViewModel.cs b/src/Models/ViewModels/MenuViewModel.cs new file mode 100644 index 0000000..7febfb0 --- /dev/null +++ b/src/Models/ViewModels/MenuViewModel.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace dontKillBill +{ + public class MenuViewModel + { + /// + /// start of selected interval + /// + [Range(0,int.MaxValue)] + [Display(Name ="Zaciatok intervalu")] + public int StartPoint { get; set; } + + /// + /// end of selected interval + /// + [Range(0, int.MaxValue, ErrorMessage = "Hodnota musi byt kladna")] + [Display(Name = "Koniec intervalu")] + public int EndPoint { get; set; } + + /// + /// Number of vouchers to be generated + /// + [Range(0, int.MaxValue,ErrorMessage ="Hodnota musi byt kladna")] + [Display(Name = "Pocet voucherov ktore maju byt vygenerovane")] + public int Count { get; set; } + + /// + /// voucher id to be generated to qr code + /// + [Range(0, int.MaxValue, ErrorMessage = "Hodnota musi byt kladna")] + [Display(Name = "Pocet voucherov ktore maju byt vygenerovane")] + public int ToQr { get; set; } + + } +} diff --git a/src/Models/Vouchers.cs b/src/Models/Vouchers.cs new file mode 100644 index 0000000..85358ef --- /dev/null +++ b/src/Models/Vouchers.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace dontKillBill +{ + public class Vouchers + { + [Key] + public int VoucherId { get; set; } + } +} diff --git a/src/Program.cs b/src/Program.cs new file mode 100644 index 0000000..ab5909e --- /dev/null +++ b/src/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace dontKillBill +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/src/Startup.cs b/src/Startup.cs new file mode 100644 index 0000000..55abed2 --- /dev/null +++ b/src/Startup.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace dontKillBill +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + + + //add dbContext to Dependency Injection + services.AddDbContext(options => + options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); + + services.Configure(options => + { + // This lambda determines whether user consent for non-essential cookies is needed for a given request. + options.CheckConsentNeeded = context => true; + options.MinimumSameSitePolicy = SameSiteMode.None; + }); + + + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } + + app.UseStaticFiles(); + app.UseCookiePolicy(); + + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); + } + } +} diff --git a/src/Static/FindFreeIntervals.cs b/src/Static/FindFreeIntervals.cs new file mode 100644 index 0000000..e703094 --- /dev/null +++ b/src/Static/FindFreeIntervals.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace dontKillBill +{ + public static class FindFreeIntervals + { + + public static void Find(ApplicationDbContext context) + { + context.Database.EnsureCreated(); + + var vouchers = context.Vouchers.OrderBy(v => v.VoucherId).ToList(); + + List freeIntervals = new List(); + + int start = 1; + + foreach (var record in vouchers) + { + + if (start <= record.VoucherId) + { + var interval = new FreeIntervals { StartOfInterval = start, EndOfInterval = record.VoucherId, Used = false }; + + freeIntervals.Add(interval); + + } + start = record.VoucherId+1; + } + + + foreach(FreeIntervals interval in freeIntervals) + { + context.Add(interval); + } + + context.SaveChanges(); + } + } +} diff --git a/src/Views/Home/Index.cshtml b/src/Views/Home/Index.cshtml new file mode 100644 index 0000000..aebfbf6 --- /dev/null +++ b/src/Views/Home/Index.cshtml @@ -0,0 +1,48 @@ +@model MenuViewModel + +@{ + ViewData["Title"] = "Index"; +} + + +
+ +

Zobrazenie vydanych vouchrov

+ + +

@Html.DisplayNameFor(m => m.StartPoint)

+