Web API for the bulk printing desktop application.

BatchesController.cs 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using BulkPrintingAPI.Configuration;
  2. using BulkPrintingAPI.Pagination;
  3. using MAX.Models;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.EntityFrameworkCore;
  6. using Microsoft.Extensions.Caching.Memory;
  7. using Microsoft.Extensions.Logging;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.ComponentModel.DataAnnotations;
  11. using System.Linq;
  12. using System.Threading.Tasks;
  13. namespace BulkPrintingAPI.Controllers
  14. {
  15. [Produces("application/json")]
  16. [Route("api/[controller]")]
  17. public class BatchesController : Controller
  18. {
  19. public class OrderRequest
  20. {
  21. [Required]
  22. public int? ProductId { get; set; }
  23. [Required]
  24. [Range(1, int.MaxValue)]
  25. public int Quantity { get; set; }
  26. [Required]
  27. public string CustomerReference { get; set; }
  28. [Required]
  29. public string InternalReference { get; set; }
  30. public Guid? OrderGuid { get; set; }
  31. };
  32. private readonly ILogger _logger;
  33. private readonly IMemoryCache _cache;
  34. private readonly DataEncryptionOptions _dataEncryptionOptions;
  35. private readonly SFTPOptions _sftpOptions;
  36. private readonly MAX.ClientFactory _clientFactory;
  37. private readonly MAXContext _context;
  38. public BatchesController(ILoggerFactory loggerFactory, IMemoryCache cache,
  39. DataEncryptionOptions dataEncryptionOptions, SFTPOptions sftpOptions,
  40. MAX.ClientFactory clientFactory, MAXContext context)
  41. {
  42. _logger = loggerFactory.CreateLogger(GetType().FullName);
  43. _cache = cache;
  44. _dataEncryptionOptions = dataEncryptionOptions;
  45. _sftpOptions = sftpOptions;
  46. _clientFactory = clientFactory;
  47. _context = context;
  48. }
  49. private IQueryable<Batch> BatchesForVendor(int vendorId)
  50. {
  51. return _context.Batches.Where(b => b.VendorId == vendorId);
  52. }
  53. [HttpGet]
  54. public async Task<Page<Batch>> GetBatchesAsync([FromQuery] int page = 1,
  55. [FromQuery] int pageSize = 100)
  56. {
  57. var credentials = await Utils.GetLoginCredentialsFromRequestAsync(HttpContext, _context);
  58. return await Page<Batch>.GetPageAsync(
  59. BatchesForVendor(credentials.Vendor.Id).OrderByDescending(b => b.OrderDate),
  60. page, pageSize);
  61. }
  62. [HttpGet("{id}")]
  63. public async Task<IActionResult> GetBatchAsync([FromRoute] int id)
  64. {
  65. if (!ModelState.IsValid)
  66. {
  67. return BadRequest(ModelState);
  68. }
  69. var credentials = await Utils.GetLoginCredentialsFromRequestAsync(HttpContext, _context);
  70. var batch = await BatchesForVendor(credentials.Vendor.Id)
  71. .Include(b => b.Account)
  72. .SingleOrDefaultAsync(m => m.Id == id);
  73. if (batch == null)
  74. {
  75. return NotFound();
  76. }
  77. if (!batch.ReadyForDownload)
  78. {
  79. try
  80. {
  81. await Utils.DownloadVouchersAsync(_sftpOptions, _context, _logger, batch);
  82. }
  83. catch (Exception e)
  84. {
  85. _logger.LogError(string.Format(
  86. "Failed to download vouchers for {0} batchId={1}: {2}",
  87. credentials.ToString(), batch.Id, e.Message));
  88. }
  89. }
  90. return Ok(batch);
  91. }
  92. [HttpPost]
  93. public async Task<IActionResult> PlaceOrderAsync([FromBody] OrderRequest order)
  94. {
  95. if (!ModelState.IsValid)
  96. {
  97. return BadRequest(ModelState);
  98. }
  99. if (order.OrderGuid.HasValue)
  100. {
  101. var batch = await _context.Batches.SingleOrDefaultAsync(b => b.OrderGuid == order.OrderGuid.Value);
  102. if (batch != null)
  103. {
  104. return BadRequest(new { error = "Duplicate OrderGuid" });
  105. }
  106. }
  107. var credentials = await Utils.GetLoginCredentialsFromRequestAsync(HttpContext, _context);
  108. var catalogue = await Utils.GetProductCatalogueAsync(_clientFactory, _logger, _cache,
  109. credentials, false);
  110. Product product;
  111. if (!catalogue.ProductMap.TryGetValue(order.ProductId.Value, out product))
  112. {
  113. return BadRequest(new { error = "Invalid product ID" });
  114. }
  115. var orderResponse = await MAX.Utils.PlaceOrderAsync(_clientFactory, _logger,
  116. credentials, product, order.Quantity, order.CustomerReference, order.InternalReference, order.OrderGuid,
  117. Utils.AesDecryptBytes(credentials.Vendor.EncryptedVoucherKey,
  118. _dataEncryptionOptions.DefaultKey));
  119. _context.Batches.Add(orderResponse.Batch);
  120. credentials.User.Account.Balance = orderResponse.RemainingBalance;
  121. await _context.SaveChangesAsync();
  122. _logger.LogDebug("Saved batchId={0} for {1}", orderResponse.Batch.Id, credentials.ToString());
  123. try
  124. {
  125. await Utils.DownloadVouchersAsync(_sftpOptions, _context, _logger, orderResponse.Batch);
  126. }
  127. catch (Exception e)
  128. {
  129. _logger.LogError(string.Format(
  130. "Failed to download vouchers for {0} batchId={1}: {2}",
  131. credentials.ToString(), orderResponse.Batch.Id, e.Message));
  132. }
  133. return Ok(orderResponse);
  134. }
  135. }
  136. }