diff --git a/Yavsc.Abstract/Workflow/IEvent.cs b/Yavsc.Abstract/Workflow/IEvent.cs index 460df0b5..4e6cf601 100644 --- a/Yavsc.Abstract/Workflow/IEvent.cs +++ b/Yavsc.Abstract/Workflow/IEvent.cs @@ -5,18 +5,18 @@ namespace Yavsc.Interfaces.Workflow { /// /topic/(bookquery|estimate) /// /// - string Topic { get; set ; } + string Topic { get; } /// /// Should be the user's name /// /// string Sender { get; set ; } /// - /// The message + /// The message /// /// string Message { get; set; } } -} \ No newline at end of file +} diff --git a/Yavsc/Controllers/CommandController.cs b/Yavsc/Controllers/CommandController.cs index f317e48d..5f4db71e 100644 --- a/Yavsc/Controllers/CommandController.cs +++ b/Yavsc/Controllers/CommandController.cs @@ -158,7 +158,8 @@ namespace Yavsc.Controllers _context.RdvQueries.Add(command, GraphBehavior.IncludeDependents); _context.SaveChanges(User.GetUserId()); - var yaev = command.CreateEvent(_localizer); + var yaev = command.CreateEvent(_localizer, "NewCommand"); + MessageWithPayloadResponse grep = null; if (pro.AcceptNotifications @@ -173,13 +174,11 @@ namespace Yavsc.Controllers // both on mailbox and mobile // if (grep==null || grep.success<=0 || grep.failure>0) ViewBag.GooglePayload=grep; - if (grep!=null) - _logger.LogWarning($"Performer: {command.PerformerProfile.Performer.UserName} success: {grep.success} failure: {grep.failure}"); await _emailSender.SendEmailAsync( _siteSettings, _smtpSettings, command.PerformerProfile.Performer.Email, - yaev.Topic+" "+yaev.Sender, + $"{command.Client.UserName} (un client) vous demande un rendez-vous", $"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n" ); } diff --git a/Yavsc/Controllers/Haircut/HairCutCommandController.cs b/Yavsc/Controllers/Haircut/HairCutCommandController.cs index 08830369..66d72803 100644 --- a/Yavsc/Controllers/Haircut/HairCutCommandController.cs +++ b/Yavsc/Controllers/Haircut/HairCutCommandController.cs @@ -25,6 +25,7 @@ namespace Yavsc.Controllers using Microsoft.AspNet.Mvc.Rendering; using System.Collections.Generic; using Yavsc.Models.Messaging; + using PayPal.PayPalAPIInterfaceService.Model; public class HairCutCommandController : CommandController { @@ -47,13 +48,16 @@ namespace Yavsc.Controllers private async Task GetQuery(long id) { - return await _context.HairCutQueries + var query = await _context.HairCutQueries .Include(x => x.Location) .Include(x => x.PerformerProfile) .Include(x => x.Prestation) .Include(x => x.PerformerProfile.Performer) + .Include(x => x.PerformerProfile.Performer.Devices) .Include(x => x.Regularisation) .SingleAsync(m => m.Id == id); + query.SelectedProfile = await _context.BrusherProfile.SingleAsync(b=>b.UserId == query.PerformerId); + return query; } public async Task ClientCancel(long id) { @@ -76,16 +80,82 @@ namespace Yavsc.Controllers ViewData["paymentinfo"] = paymentInfo; command.Regularisation = paymentInfo.DbContent; command.PaymentId = token; + if (paymentInfo!=null) + if (paymentInfo.DetailsFromPayPal!=null) + if (paymentInfo.DetailsFromPayPal.Ack == AckCodeType.SUCCESS) + if (command.ValidationDate ==null) + command.ValidationDate = DateTime.Now; await _context.SaveChangesAsync (User.GetUserId()); - SetViewBagPaymentUrls(id); + if (command.PerformerProfile.AcceptPublicContact) + { + var invoiceId = paymentInfo.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.InvoiceID; + var payerName = paymentInfo.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Name; + var phone = paymentInfo.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Phone; + var payerEmail = paymentInfo.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Payer; + var amount = string.Join(", ", + paymentInfo.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PaymentDetails.Select( + p=> $"{p.OrderTotal.value} {p.OrderTotal.currencyID}")); + var gender = command.Prestation.Gender; + var date = command.EventDate?.ToString("dd MM yyyy hh:mm"); + var lieu = command.Location.Address; + string clientFinal = (gender == HairCutGenders.Women) ? _localizer["Women"] + + " "+_localizer[command.Prestation.Length.ToString()] : _localizer[gender.ToString()] ; + MessageWithPayloadResponse grep = null; + var yaev = command.CreateEvent("PaymentConfirmation", + this._localizer["PaymentConfirmation"], + command.Client.GetSender(), +$@"# Paiment confirmé: {amount} + +Effectué par : {payerName} [{payerEmail}] +Identifiant PayPal du paiment: {token} +Identifiant PayPal du payeur: {PayerID} +Identifiant de la facture sur site: {invoiceId} + + +# La prestation concernée: + +Demandeur: {command.Client.UserName} + +Date: {date} + +Lieu: {lieu} + +Le client final: {clientFinal} + +{command.GetBillText()} + +"); + + if (command.PerformerProfile.AcceptNotifications) { + if (command.PerformerProfile.Performer.Devices.Count > 0) { + var regids = command.PerformerProfile.Performer + .Devices.Select(d => d.GCMRegistrationId); + grep = await _GCMSender.NotifyHairCutQueryAsync(_googleSettings,regids,yaev); + } + // TODO setup a profile choice to allow notifications + // both on mailbox and mobile + // if (grep==null || grep.success<=0 || grep.failure>0) + ViewBag.GooglePayload=grep; + } + + ViewBag.EmailSent = await _emailSender.SendEmailAsync( + _siteSettings, _smtpSettings, + command.PerformerProfile.Performer.Email, + yaev.Reason, + $"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n" + ); + } + else { + // TODO if (AcceptProContact) try & find a bookmaker to send him this query + } + ViewData ["Notify"] = new List { new Notification { title= "Paiment PayPal", body = "Votre paiment a été accépté." } } ; - return View ("Details",command); } @@ -213,7 +283,7 @@ namespace Yavsc.Controllers var brusherProfile = await _context.BrusherProfile.SingleAsync(p=>p.UserId == pro.PerformerId); model.Client = await _context.Users.SingleAsync(u=>u.Id == model.ClientId); model.SelectedProfile = brusherProfile; - var yaev = model.CreateEvent(_localizer, brusherProfile); + var yaev = model.CreateNewHairCutQueryEvent(_localizer); MessageWithPayloadResponse grep = null; if (pro.AcceptPublicContact) @@ -235,7 +305,7 @@ namespace Yavsc.Controllers await _emailSender.SendEmailAsync( _siteSettings, _smtpSettings, model.PerformerProfile.Performer.Email, - yaev.Topic, + yaev.Reason, $"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n" ); } diff --git a/Yavsc/Helpers/BillingHelpers.cs b/Yavsc/Helpers/BillingHelpers.cs index 83df40cf..bbc47dc7 100644 --- a/Yavsc/Helpers/BillingHelpers.cs +++ b/Yavsc/Helpers/BillingHelpers.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Globalization; using System.Linq; using Yavsc.Billing; using Yavsc.Models.Billing; @@ -11,5 +12,11 @@ namespace Yavsc.Helpers public static decimal Addition(this List items) => items.Select(i=>((IBillItem)i)).ToList().Addition(); + public static string GetBillText(this IBillable query) { + string total = query.GetBillItems().Addition().ToString("C", CultureInfo.CurrentUICulture); + string bill = string.Join("\n", query.GetBillItems().Select(l=> $"{l.Name} {l.Description} : {l.UnitaryCost} € " + ((l.Count != 1) ? "*"+l.Count.ToString() : ""))) + + $"\n\nTotal: {total}"; + return bill; + } } } diff --git a/Yavsc/Helpers/EventHelpers.cs b/Yavsc/Helpers/EventHelpers.cs index b321fb4f..a011b066 100644 --- a/Yavsc/Helpers/EventHelpers.cs +++ b/Yavsc/Helpers/EventHelpers.cs @@ -5,15 +5,14 @@ namespace Yavsc.Helpers using Models.Workflow; using Models.Messaging; using Yavsc.Models.Haircut; - using System.Linq; - using System.Globalization; + using Yavsc.Models; public static class EventHelpers { public static RdvQueryEvent CreateEvent(this RdvQuery query, - IStringLocalizer SR) + IStringLocalizer SR, string subtopic) { - var yaev = new RdvQueryEvent + var yaev = new RdvQueryEvent(subtopic) { Sender = query.ClientId, Message = string.Format(SR["RdvToPerf"], @@ -30,30 +29,24 @@ namespace Yavsc.Helpers EventDate = query.EventDate, Location = query.Location, Id = query.Id, - Reason = query.Reason, ActivityCode = query.ActivityCode }; + return yaev; } - public static HairCutQueryEvent CreateEvent(this HairCutQuery query, - IStringLocalizer SR, BrusherProfile bpr) - { - string evdate = query.EventDate?.ToString("dddd dd/MM/yyyy à HH:mm")??"[pas de date spécifiée]"; + + public static HairCutQueryEvent CreateNewHairCutQueryEvent(this HairCutQuery query, + IStringLocalizer SR) + { + string evdate = query.EventDate?.ToString("dddd dd/MM/yyyy à hh:mm")??"[pas de date spécifiée]"; string address = query.Location?.Address??"[pas de lieu spécifié]"; var p = query.Prestation; - string total = query.GetBillItems().Addition().ToString("C",CultureInfo.CurrentUICulture); string strprestation = query.GetDescription(); - string bill = string.Join("\n", query.GetBillItems().Select( - l=> $"{l.Name} {l.Description} {l.UnitaryCost} € " + - ((l.Count != 1) ? "*"+l.Count.ToString() : ""))); - var yaev = new HairCutQueryEvent - { - Topic = - string.Format( - Startup.GlobalLocalizer["HairCutQueryValidation"],query.Client.UserName), - Sender = $"{strprestation} pour {query.Client.UserName}", - Message = + + var yaev = query.CreateEvent("NewHairCutQuery", + string.Format(Startup.GlobalLocalizer["HairCutQueryValidation"],query.Client.UserName), + $"{query.Client.UserName}", $@"Un client vient de valider une demande de prestation à votre encontre: Prestation: {strprestation} @@ -66,29 +59,19 @@ $@"Un client vient de valider une demande de prestation à votre encontre: Facture prévue (non réglée): -{bill} +{query.GetBillText()} +") ; -Total: {total} -" , -Client = new ClientProviderInfo {  - UserName = query.Client.UserName , - UserId = query.ClientId, - Avatar = query.Client.Avatar } , -Previsional = query.Previsional, -EventDate = query.EventDate, -Location = query.Location, -Id = query.Id, -Reason = $"{query.AdditionalInfo}", -ActivityCode = query.ActivityCode - - }; return yaev; } - + public static string GetSender(this ApplicationUser user) + { + return user.UserName+" ["+user.Id+"@"+Startup.Authority+"]"; + } public static HairCutQueryEvent CreateEvent(this HairMultiCutQuery query, IStringLocalizer SR, BrusherProfile bpr) { - var yaev = new HairCutQueryEvent + var yaev = new HairCutQueryEvent("newCommand") { Sender = query.ClientId, Message = string.Format(SR["RdvToPerf"], diff --git a/Yavsc/Helpers/PayPalHelpers.cs b/Yavsc/Helpers/PayPalHelpers.cs index 8a7716a9..575cf1d9 100644 --- a/Yavsc/Helpers/PayPalHelpers.cs +++ b/Yavsc/Helpers/PayPalHelpers.cs @@ -104,6 +104,8 @@ namespace Yavsc.Helpers } }; + var d = new SetExpressCheckoutRequestDetailsType(); + logger.LogInformation($"Creating express checkout for {Startup.PayPalSettings.MerchantAccountUserName} : "+JsonConvert.SerializeObject(coreq)); var response = PayPalService.SetExpressCheckout( coreq, Startup.PayPalSettings.MerchantAccountUserName ); diff --git a/Yavsc/Models/HairCut/HairCutQuery.cs b/Yavsc/Models/HairCut/HairCutQuery.cs index 8022745e..c4ab62ec 100644 --- a/Yavsc/Models/HairCut/HairCutQuery.cs +++ b/Yavsc/Models/HairCut/HairCutQuery.cs @@ -6,6 +6,10 @@ using System.ComponentModel.DataAnnotations.Schema; using Yavsc.Models.Billing; using Yavsc.Models.Relationship; using Yavsc.Billing; +using System.Globalization; +using Yavsc.Helpers; +using Yavsc.Models.Messaging; +using System.Linq; namespace Yavsc.Models.Haircut { @@ -337,5 +341,33 @@ Prestation.Gender == HairCutGenders.Women ? public virtual BrusherProfile SelectedProfile { get; set; } + public HairCutQueryEvent CreateEvent(string subTopic, string reason, string sender, string message) { + + string evdate = EventDate?.ToString("dddd dd/MM/yyyy à HH:mm")??"[pas de date spécifiée]"; + string address = Location?.Address??"[pas de lieu spécifié]"; + var p = Prestation; + string total = GetBillItems().Addition().ToString("C",CultureInfo.CurrentUICulture); + string strprestation = GetDescription(); + string bill = string.Join("\n", GetBillItems().Select( + l=> $"{l.Name} {l.Description} {l.UnitaryCost} € " + + ((l.Count != 1) ? "*"+l.Count.ToString() : ""))); + var yaev = new HairCutQueryEvent(subTopic) + { + Client = new ClientProviderInfo {  + UserName = Client.UserName , + UserId =ClientId, + Avatar = Client.Avatar } , + Previsional = Previsional, + EventDate = EventDate, + Location = Location, + Id = Id, + ActivityCode = ActivityCode, + Reason = reason, + Sender = sender, + Message = message + }; + return yaev; + } + } } diff --git a/Yavsc/Models/HairCut/HairCutQueryEvent.cs b/Yavsc/Models/HairCut/HairCutQueryEvent.cs index 04d18ed2..e176fbd3 100644 --- a/Yavsc/Models/HairCut/HairCutQueryEvent.cs +++ b/Yavsc/Models/HairCut/HairCutQueryEvent.cs @@ -4,11 +4,11 @@ namespace Yavsc.Models.Haircut { public class HairCutQueryEvent : RdvQueryProviderInfo, IEvent { - public HairCutQueryEvent() + public HairCutQueryEvent(string subTopic) { - Topic = "HairCutQuery"; - } + Topic = GetType().Name+"/"+subTopic; + } public string Message { get; @@ -27,9 +27,9 @@ namespace Yavsc.Models.Haircut { get; - set; + private set; } - + HairCutQuery Data { get; set; } } -} \ No newline at end of file +} diff --git a/Yavsc/Models/Messaging/BaseEvent.cs b/Yavsc/Models/Messaging/BaseEvent.cs index b8a7ed6f..ca78c918 100644 --- a/Yavsc/Models/Messaging/BaseEvent.cs +++ b/Yavsc/Models/Messaging/BaseEvent.cs @@ -19,15 +19,13 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -using System.ComponentModel.DataAnnotations; namespace Yavsc.Models.Messaging { using Interfaces.Workflow; - using Yavsc; /// - /// Base event. + /// /// Base event. /// public class BaseEvent : IEvent { @@ -37,29 +35,12 @@ namespace Yavsc.Models.Messaging } public BaseEvent(string topic) { - Topic = topic; + Topic = GetType().Name+"/"+topic; } - public string Topic { get; set; } + public string Topic { get; private set; } public string Sender { get; set; } - public string Message { get; set; } } - public class GeneralEvent: BaseEvent, ITitle - { - /// - /// The title. - /// - [Required(ErrorMessageResourceName="ChooseATitle")] - [Display(Name="Title")] - public string Title { get; set; } - /// - /// The description. - /// - [Required(ErrorMessageResourceName="ChooseADescription")] - [Display(Name="Description")] - public string Description { get; set; } - - } } diff --git a/Yavsc/Models/Messaging/GeneralEvent.cs b/Yavsc/Models/Messaging/GeneralEvent.cs new file mode 100644 index 00000000..a9572d6d --- /dev/null +++ b/Yavsc/Models/Messaging/GeneralEvent.cs @@ -0,0 +1,43 @@ +// +// BaseEvent.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System.ComponentModel.DataAnnotations; + +namespace Yavsc.Models.Messaging +{ +public class GeneralEvent: BaseEvent, ITitle + { + /// + /// The title. + /// + [Required(ErrorMessageResourceName="ChooseATitle")] + [Display(Name="Title")] + public string Title { get; set; } + /// + /// The description. + /// + [Required(ErrorMessageResourceName="ChooseADescription")] + [Display(Name="Description")] + public string Description { get; set; } + + } + +} diff --git a/Yavsc/Models/Messaging/RdvQueryEvent.cs b/Yavsc/Models/Messaging/RdvQueryEvent.cs index 4ed600ed..35a27e8f 100644 --- a/Yavsc/Models/Messaging/RdvQueryEvent.cs +++ b/Yavsc/Models/Messaging/RdvQueryEvent.cs @@ -27,9 +27,10 @@ using Interfaces.Workflow; public class RdvQueryEvent: RdvQueryProviderInfo, IEvent { - public RdvQueryEvent() + + public RdvQueryEvent(string subTopic) { - Topic = "RdvQuery"; + Topic = GetType().Name+"/"+subTopic; } public string Message @@ -44,7 +45,7 @@ public class RdvQueryEvent: RdvQueryProviderInfo, IEvent public string Topic { - get; set; + get; private set; } } diff --git a/Yavsc/Resources/Yavsc.Resources.YavscLocalisation.fr.resx b/Yavsc/Resources/Yavsc.Resources.YavscLocalisation.fr.resx index 24acc24c..27fe25a1 100644 --- a/Yavsc/Resources/Yavsc.Resources.YavscLocalisation.fr.resx +++ b/Yavsc/Resources/Yavsc.Resources.YavscLocalisation.fr.resx @@ -308,6 +308,7 @@ En ligne Seuls les utilisateurs authorisés peuvent contacter un préstataire par courrier. Mot de passe + Confirmation de paiement Version Pdf Date de la prestation Lieu de la pestation