using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using rockfishCore.Models; using rockfishCore.Util; using System.Linq; using System; //requried to inject configuration in constructor using Microsoft.Extensions.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.EntityFrameworkCore; namespace rockfishCore.Controllers { [Produces("application/json")] [Route("api/report")] [Authorize] public class ReportController : Controller { private readonly rockfishContext _context; private readonly IConfiguration _configuration; public ReportController(rockfishContext context, IConfiguration configuration)//these two are injected, see startup.cs { _context = context; _configuration = configuration; } /////////////////////////////////////////////////////// //Get expiring subscriptions list // [HttpGet("expires")] public JsonResult Get() { var customerList = _context.Customer.Select(p => new { p.Id, p.Name }); var rawExpiresList = _context.Purchase .Where(p => p.ExpireDate != null && p.CancelDate == null) .OrderBy(p => p.ExpireDate) .Select(p => new expiresResultItem { id = p.Id, expireDate = p.ExpireDate, name = p.Name, site_id = p.SiteId, customerId = p.CustomerId }) .ToList(); foreach (expiresResultItem i in rawExpiresList) { i.Customer = customerList.First(p => p.Id == i.customerId).Name; } return Json(rawExpiresList); } //dto classes for route public class expiresResultItem { public long id; public string name; public string Customer; public long customerId; public long? expireDate; public long site_id; } /////////////////////////////////////////////////////// //Get unique product code / name combinations // [HttpPost("emailsforproductcodes")] public JsonResult GetUniqueEmailsByProductCodes([FromBody] requestEmailsForProductCodes req) { var customerList = _context.Customer.Select(p => new { p.Id, p.DoNotContact }); List rawCustomerIds = new List(); foreach (string pcode in req.products) { //fetch all customer id's from purchase collection that match product codes submitted var l = _context.Purchase.Where(p => p.ProductCode == pcode).Select(p => p.CustomerId).Distinct(); rawCustomerIds.AddRange(l.ToList()); } //uniquify the customer list List uniqueCustomerIds = rawCustomerIds.Distinct().ToList(); //container for the raw email lists built serially List rawEmails = new List(); foreach (long cid in uniqueCustomerIds) { //skip if do not contact and not explicitly including do not contact if (customerList.First(p => p.Id == cid).DoNotContact && req.ckNoContact != true) continue; //get all raw email values for this client from db //there may be dupes or even multiple in one rawEmails.AddRange(getEmailsForClient(cid)); } //Now clean up the list and sort and uniquify it List cleanedEmails = cleanupRawEmailList(rawEmails); return Json(cleanedEmails); } //Given a client id find all unique email address in db for that client private List getEmailsForClient(long id) { List ret = new List(); //New for RF 6 var cust = _context.Customer.Where(p => p.Id == id).FirstOrDefault(); if (cust != null) { if (!string.IsNullOrWhiteSpace(cust.AdminEmail)) ret.Add(cust.AdminEmail); if (!string.IsNullOrWhiteSpace(cust.SupportEmail)) ret.Add(cust.SupportEmail); } //TOASTED for RF 6 //search contact, trial, purchase, incident (optionally) // ret.AddRange(_context.Purchase.Where(p => p.CustomerId == id).Select(p => p.Email).Distinct().ToList()); // ret.AddRange(_context.Contact.Where(p => p.CustomerId == id).Select(p => p.Email).Distinct().ToList()); // ret.AddRange(_context.Trial.Where(p => p.CustomerId == id).Select(p => p.Email).Distinct().ToList()); // if (includeIncidentEmails) // ret.AddRange(_context.Incident.Where(p => p.CustomerId == id).Select(p => p.Email).Distinct().ToList()); return ret; } //break out multiple also trim whitespace and lowercase and uniquify them private List cleanupRawEmailList(List src) { List ret = new List(); foreach (string rawAddress in src) { //count the @'s, if there are more than one then get splittn' int count = rawAddress.Count(f => f == '@'); if (count < 1) continue;//no address, skip this one //a little cleanup based on what I had to do in og rockfish string semiRawAddress = rawAddress.Replace(", ", ",").TrimEnd('>').TrimEnd(',').Trim(); //there's at least one address in there, maybe more if (count == 1) ret.Add(semiRawAddress.ToLowerInvariant()); else { //there are multiple so break it apart //determine break character could be a space or a comma char breakChar; if (semiRawAddress.Contains(',')) { breakChar = ','; } else if (semiRawAddress.Contains(' ')) { breakChar = ' '; } else { //no break character, it's a bad address, highlight it so it can be fixed when seen ret.Add("_BAD_EMAIL_" + semiRawAddress + "_BAD_EMAIL_"); continue; } //Ok if we made it here then we can split out the emails string[] splits = semiRawAddress.Split(breakChar); foreach (string s in splits) { if (!string.IsNullOrWhiteSpace(s) && s.Contains("@")) ret.Add(s.ToLowerInvariant().Trim()); } } } //return distinct values only that are ordered by the email domain return ret.Distinct().OrderBy(email => email.Split('@')[1]).ToList(); } //dto classes for route public class requestEmailsForProductCodes { public string[] products; public bool ckIncidental; public bool ckNoContact; } ///////////////////////////////////////////////////////////////////////////////////// }//eoc }//eons