using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; namespace Yavsc.Controllers { using Helpers; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Models; using Models.Google.Messaging; using Models.Relationship; using Models.Workflow; using Services; using Yavsc.Interface; using Yavsc.Settings; public class CommandController : Controller { protected UserManager _userManager; protected ApplicationDbContext _context; protected GoogleAuthSettings _googleSettings; protected IYavscMessageSender _MessageSender; protected ITrueEmailSender _emailSender; protected IStringLocalizer _localizer; protected SiteSettings _siteSettings; protected SmtpSettings _smtpSettings; protected ICalendarManager _calendarManager; protected readonly ILogger _logger; public CommandController(ApplicationDbContext context, IOptions googleSettings, IYavscMessageSender messageSender, UserManager userManager, ICalendarManager calendarManager, IStringLocalizer localizer, ITrueEmailSender emailSender, IOptions smtpSettings, IOptions siteSettings, ILoggerFactory loggerFactory) { _context = context; _MessageSender = messageSender; _emailSender = emailSender; _googleSettings = googleSettings.Value; _userManager = userManager; _smtpSettings = smtpSettings.Value; _siteSettings = siteSettings.Value; _calendarManager = calendarManager; _localizer = localizer; _logger = loggerFactory.CreateLogger(); } // GET: Command [Authorize] public virtual async Task Index() { var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); return View(await _context.RdvQueries .Include(x => x.Client) .Include(x => x.PerformerProfile) .Include(x => x.PerformerProfile.Performer) .Include(x => x.Location) .Where(x => x.ClientId == uid || x.PerformerId == uid) .ToListAsync()); } // GET: Command/Details/5 public virtual async Task Details(long id) { RdvQuery command = await _context.RdvQueries .Include(x => x.Location) .Include(x => x.PerformerProfile) .SingleAsync(m => m.Id == id); if (command == null) { return NotFound(); } return View(command); } /// /// Gives a view on /// Creating a command for a specified performer /// /// /// [HttpGet] public IActionResult Create(string proId, string activityCode) { if (string.IsNullOrWhiteSpace(proId)) throw new InvalidOperationException( "This method needs a performer id (from parameter proId)" ); if (string.IsNullOrWhiteSpace(activityCode)) throw new InvalidOperationException( "This method needs an activity code" ); var pro = _context.Performers.Include( x => x.Performer).FirstOrDefault( x => x.PerformerId == proId ); if (pro == null) return NotFound(); ViewBag.Activity = _context.Activities.FirstOrDefault(a => a.Code == activityCode); ViewBag.GoogleSettings = _googleSettings; var userid = User.GetUserId(); var user = _userManager.FindByIdAsync(userid).Result; return View("Create", new RdvQuery(activityCode, new Location(), DateTime.Now.AddHours(4)) { PerformerProfile = pro, PerformerId = pro.PerformerId, ClientId = userid, Client = user, ActivityCode = activityCode }); } // POST: Command/Create [HttpPost] [ValidateAntiForgeryToken] public async Task Create(RdvQuery command) { // TODO validate BillingCode value var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var prid = command.PerformerId; if (string.IsNullOrWhiteSpace(uid) || string.IsNullOrWhiteSpace(prid)) throw new InvalidOperationException( "This method needs a PerformerId" ); var pro = _context.Performers.Include( u => u.Performer ).Include(u => u.Performer.DeviceDeclaration) .FirstOrDefault( x => x.PerformerId == command.PerformerId ); var user = await _userManager.FindByIdAsync(uid); command.Client = user; command.ClientId = uid; command.PerformerProfile = pro; // FIXME Why!! ModelState.MarkFieldSkipped("ClientId"); if (ModelState.IsValid) { var existingLocation = _context.Locations.FirstOrDefault(x => x.Address == command.Location.Address && x.Longitude == command.Location.Longitude && x.Latitude == command.Location.Latitude); if (existingLocation != null) { command.Location = existingLocation; } else _context.Attach(command.Location); _context.RdvQueries.Add(command); _context.SaveChanges(User.GetUserId()); var yaev = command.CreateEvent("NewCommand"); MessageWithPayloadResponse nrep = null; if (pro.AcceptNotifications && pro.AcceptPublicContact) { try { _logger.LogInformation("Notifying query"); var uids = new[] { command.PerformerProfile.PerformerId }; nrep = await _MessageSender.NotifyBookQueryAsync(uids, yaev); // TODO setup a profile choice to allow notifications // both on mailbox and mobile // if (grep==null || grep.success<=0 || grep.failure>0) ViewBag.MessagingResponsePayload = nrep; } catch (Exception ex) { _logger.LogError("Message sending failed with: " + ex.Message); throw; } } else { nrep = new MessageWithPayloadResponse { failure = 1, results = new MessageWithPayloadResponse.Result[] { new MessageWithPayloadResponse.Result { error=NotificationTypes.ContactRefused, registration_id= pro.PerformerId } } }; _logger.LogInformation("Command.Create && ( !pro.AcceptNotifications || |pro.AcceptPublicContact ) "); } ViewBag.MessagingResponsePayload = nrep; ViewBag.Activity = _context.Activities.FirstOrDefault(a => a.Code == command.ActivityCode); ViewBag.GoogleSettings = _googleSettings; return View("CommandConfirmation", command); } ViewBag.Activity = _context.Activities.FirstOrDefault(a => a.Code == command.ActivityCode); ViewBag.GoogleSettings = _googleSettings; return View(command); } // GET: Command/Edit/5 public IActionResult Edit(long? id) { if (id == null) { return NotFound(); } RdvQuery command = _context.RdvQueries.Single(m => m.Id == id); if (command == null) { return NotFound(); } return View(command); } // POST: Command/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public IActionResult Edit(RdvQuery command) { if (ModelState.IsValid) { _context.Update(command); _context.SaveChanges(User.GetUserId()); return RedirectToAction("Index"); } return View(command); } // GET: Command/Delete/5 [ActionName("Delete")] public IActionResult Delete(long? id) { if (id == null) { return NotFound(); } RdvQuery command = _context.RdvQueries.Single(m => m.Id == id); if (command == null) { return NotFound(); } return View(command); } // POST: Command/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public IActionResult DeleteConfirmed(long id) { RdvQuery command = _context.RdvQueries.Single(m => m.Id == id); _context.RdvQueries.Remove(command); _context.SaveChanges(User.GetUserId()); return RedirectToAction("Index"); } public IActionResult CGV() { return View(); } } }