refactoring messages

vnext
Paul Schneider 7 years ago
parent edd91faa96
commit 6c18f32f61
44 changed files with 602 additions and 303 deletions

@ -0,0 +1,11 @@
MAKE=make
SUBDIRS=Yavsc.Abstract Yavsc
all: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
.PHONY: all $(SUBDIRS)

@ -1,6 +1,5 @@
namespace YaDaemon
{
using YaDaemon;
public class TestDaemonStart
{

@ -1,5 +1,5 @@
CONFIG=Release
VERSION=1.0.5-rc4
VERSION=1.0.5-rc5
PRJNAME=Yavsc.Abstract
PKGFILENAME=$(PRJNAME).$(VERSION).nupkg
DESTPATH=.

@ -0,0 +1,9 @@
namespace Yavsc.Abstract.Messaging
{
public static class MessagingConstants {
public static readonly string TopicGeneral = "/topic/general";
public static readonly string TopicRdvQuery = "/topic/RdvQuery";
public static readonly string TopicEstimation = "/topic/Estimation";
public static readonly string TopicHairCutQuery = "/topic/HairCutQuery";
}
}

@ -25,4 +25,4 @@ using System.Reflection;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.5.*")]
[assembly: AssemblyFileVersion("1.0.5.2")]
[assembly: AssemblyFileVersion("1.0.5.3")]

@ -11,11 +11,8 @@ namespace Yavsc.Interfaces.Workflow {
/// </summary>
/// <returns></returns>
string Sender { get; set ; }
/// <summary>
/// The message
/// </summary>
/// <returns></returns>
string Message { get; set; }
string CreateBody();
}

@ -1,6 +1,6 @@
namespace Yavsc
{
public interface ILocation
public interface ILocation : IPosition
{
string Address { get; set; }
long Id { get; set; }

@ -11,7 +11,7 @@
<iconUrl>https://github.com/pazof/yavsc/blob/vnext/Yavsc/wwwroot/images/yavsc.png</iconUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>
A shared model for a little client/sever app
A shared model for a little client/server app, dealing about establishing some contract, between some human client and provider.
</description>
<summary>
</summary>

@ -114,14 +114,16 @@ namespace Yavsc.Controllers
public IActionResult PostEstimate([FromBody] Estimate estimate)
{
var uid = User.GetUserId();
if (!User.IsInRole(Constants.AdminGroupName))
{
if (estimate.OwnerId==null) estimate.OwnerId = uid;
if (!User.IsInRole(Constants.AdminGroupName)) {
if (uid != estimate.OwnerId)
{
ModelState.AddModelError("OwnerId","You can only create your own estimates");
return HttpBadRequest(ModelState);
}
}
if (estimate.CommandId!=null) {
var query = _context.RdvQueries.FirstOrDefault(q => q.Id == estimate.CommandId);
if (query == null) {

@ -47,23 +47,25 @@ namespace Yavsc.Controllers
long[] usercircles = _context.Circle.Include(c=>c.Members).Where(c=>c.Members.Any(m=>m.MemberId == uid))
.Select(c=>c.Id).ToArray();
IQueryable<BlogPost> posts ;
if (usercircles != null) {
posts = _context.Blogspot.Include(b => b.Author)
var allposts = _context.Blogspot
.Include(b => b.Author)
.Include(p=>p.ACL)
.Include(p=>p.Tags)
.Include(p=>p.Comments)
.Include(p=>p.ACL)
.Where(p=> p.AuthorId == uid || p.Visible &&
(p.ACL.Count == 0 || p.ACL.Any(a=> usercircles.Contains(a.CircleId))))
;
.Where(p=>p.AuthorId == uid || p.Visible);
if (usercircles != null) {
posts = allposts.Where(p=> p.ACL.Count==0 || p.ACL.Any(a=> usercircles.Contains(a.CircleId)))
;
}
else {
posts = _context.Blogspot.Include(b => b.Author)
.Include(p=>p.ACL).Where(p=>p.AuthorId == uid || p.Visible && p.ACL.Count == 0);
posts = allposts.Where(p => p.ACL.Count == 0);
}
return View(posts.OrderByDescending( p=> p.DateCreated)
.GroupBy(p=> p.Title).Skip(skip).Take(maxLen));
var data = posts.OrderByDescending( p=> p.DateCreated).ToArray();
var grouped = data.GroupBy(p=> p.Title).Skip(skip).Take(maxLen);
return View(grouped);
}
[Route("/Title/{id?}")]

@ -174,17 +174,18 @@ namespace Yavsc.Controllers
.Devices.Select(d => d.GCMRegistrationId);
grep = await _GCMSender.NotifyBookQueryAsync(_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;
await _emailSender.SendEmailAsync(
ViewBag.EmailSent = await _emailSender.SendEmailAsync(
_siteSettings, _smtpSettings,
command.PerformerProfile.Performer.UserName,
command.PerformerProfile.Performer.Email,
$"{command.Client.UserName} (un client) vous demande un rendez-vous",
$"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
$"{yaev.CreateBody()}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
);
}
ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == command.ActivityCode);

@ -0,0 +1,78 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.Data.Entity;
namespace Yavsc.Controllers
{
using Models;
using Models.Identity;
public class GCMDevicesController : Controller
{
private ApplicationDbContext _context;
public GCMDevicesController(ApplicationDbContext context)
{
_context = context;
}
// GET: GCMDevices
public async Task<IActionResult> Index()
{
var uid = User.GetUserId();
var applicationDbContext = _context.GCMDevices.Include(g => g.DeviceOwner).Where(d=>d.DeviceOwnerId == uid);
return View(await applicationDbContext.ToListAsync());
}
// GET: GCMDevices/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return HttpNotFound();
}
GoogleCloudMobileDeclaration googleCloudMobileDeclaration = await _context.GCMDevices.SingleAsync(m => m.DeviceId == id);
if (googleCloudMobileDeclaration == null)
{
return HttpNotFound();
}
return View(googleCloudMobileDeclaration);
}
// GET: GCMDevices/Delete/5
[ActionName("Delete")]
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return HttpNotFound();
}
GoogleCloudMobileDeclaration googleCloudMobileDeclaration = await _context.GCMDevices.SingleAsync(m => m.DeviceId == id);
if (googleCloudMobileDeclaration == null)
{
return HttpNotFound();
}
return View(googleCloudMobileDeclaration);
}
// POST: GCMDevices/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
GoogleCloudMobileDeclaration googleCloudMobileDeclaration = await _context.GCMDevices.SingleAsync(m => m.DeviceId == id);
_context.GCMDevices.Remove(googleCloudMobileDeclaration);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
}
}

@ -79,60 +79,30 @@ 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;
bool paymentOk = false;
if (paymentInfo.DetailsFromPayPal != null)
if (paymentInfo.DetailsFromPayPal.Ack == AckCodeType.SUCCESS)
{
// FIXME Assert (command.ValidationDate == null)
if (command.ValidationDate == null) {
paymentOk = true;
command.ValidationDate = DateTime.Now;
}
}
await _context.SaveChangesAsync(User.GetUserId());
SetViewBagPaymentUrls(id);
if (command.PerformerProfile.AcceptPublicContact)
if (command.PerformerProfile.AcceptPublicContact && paymentOk)
{
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()}
");
var yaev = command.CreatePaymentEvent(paymentInfo, _localizer);
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);
grep = await _GCMSender.NotifyAsync(_googleSettings, regids, yaev);
}
// TODO setup a profile choice to allow notifications
// both on mailbox and mobile
@ -144,8 +114,8 @@ Le client final: {clientFinal}
_siteSettings, _smtpSettings,
command.PerformerProfile.Performer.UserName,
command.PerformerProfile.Performer.Email,
yaev.Reason,
$"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
yaev.Topic,
yaev.CreateBody()
);
}
else
@ -321,7 +291,7 @@ Le client final: {clientFinal}
DateTime evdate = yaev.EventDate ?? new DateTime();
var result = await _calendarManager.CreateEventAsync(pro.Performer.Id,
pro.Performer.DedicatedGoogleCalendar,
evdate, 3600, yaev.Topic, yaev.Message,
evdate, 3600, yaev.Topic, yaev.Client.UserName + " : " + yaev.Reason,
yaev.Location?.Address, false
);
if (result.Id == null)
@ -333,8 +303,8 @@ Le client final: {clientFinal}
_siteSettings, _smtpSettings,
pro.Performer.UserName,
pro.Performer.Email,
yaev.Reason,
$"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
$"{yaev.Client.UserName}: {yaev.Reason}",
$"{yaev.Reason}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
);
}
else
@ -456,6 +426,7 @@ Le client final: {clientFinal}
bp => bp.UserId == command.PerformerId
);
var yaev = command.CreateEvent(_localizer, brSettings);
string msg = yaev.CreateBoby();
MessageWithPayloadResponse grep = null;
if (pro.AcceptNotifications
@ -481,7 +452,7 @@ Le client final: {clientFinal}
await _calendarManager.CreateEventAsync(
pro.Performer.Id,
pro.Performer.DedicatedGoogleCalendar,
evdate, 3600, yaev.Topic, yaev.Message,
evdate, 3600, yaev.Topic, msg,
yaev.Location?.ToString(), false
);
}
@ -491,7 +462,7 @@ Le client final: {clientFinal}
command.PerformerProfile.Performer.UserName,
command.PerformerProfile.Performer.Email,
yaev.Topic + " " + yaev.Sender,
$"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
$"{msg}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
);
}
ViewBag.Activity = _context.Activities.FirstOrDefault(a => a.Code == command.ActivityCode);

@ -50,7 +50,7 @@ namespace Yavsc.Controllers
}
else clicked = DbContext.DimissClicked.Where(d=>d.UserId == uid).Select(d=>d.NotificationId).ToArray();
var notes = DbContext.Notification.Where(
n=> !clicked.Any(c=>n.Id==c)
n=> !clicked.Contains(n.Id)
);
this.Notify(notes);
ViewData["HaircutCommandCount"] = DbContext.HairCutQueries.Where(

@ -122,9 +122,10 @@ namespace Yavsc.Controllers
EmailConfirmed = await _userManager.IsEmailConfirmedAsync(user)
};
model.HaveProfessionalSettings = _dbContext.Performers.Any(x => x.PerformerId == user.Id);
var usrActs = _dbContext.UserActivities.Include(a=>a.Does).Where(a=> a.UserId == user.Id);
var usrActs = _dbContext.UserActivities.Include(a=>a.Does).Where(a=> a.UserId == user.Id).ToArray();
model.HaveActivityToConfigure = usrActs.Where( a => ( a.Does.SettingsClassName != null )).Count( a => a.Settings == null)>0;
var usrActToSet = usrActs.Where( a => ( a.Settings == null && a.Does.SettingsClassName != null )).ToArray();
model.HaveActivityToConfigure = usrActToSet .Count()>0;
model.Activity = _dbContext.UserActivities.Include(a=>a.Does).Where(u=>u.UserId == user.Id).ToList();
return View(model);
}

@ -15,12 +15,7 @@ namespace Yavsc.Helpers
var yaev = new RdvQueryEvent(subtopic)
{
Sender = query.ClientId,
Message = string.Format(SR["RdvToPerf"],
query.Client.UserName,
query.EventDate.ToString("dddd dd/MM/yyyy à HH:mm"),
query.Location.Address,
query.ActivityCode)+
"\n"+query.Reason,
Reason = query.Reason,
Client = new ClientProviderInfo { 
UserName = query.Client.UserName ,
UserId = query.ClientId,
@ -46,21 +41,7 @@ namespace Yavsc.Helpers
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}
Client : {query.Client.UserName}
Date: {evdate},
Adresse: {address}
-----
{query.AdditionalInfo}
Facture prévue (non réglée):
{query.GetBillText()}
") ;
$"{query.Client.UserName}") ;
return yaev;
}
@ -74,11 +55,7 @@ Facture prévue (non réglée):
var yaev = new HairCutQueryEvent("newCommand")
{
Sender = query.ClientId,
Message = string.Format(SR["RdvToPerf"],
query.Client.UserName,
query.EventDate.ToString("dddd dd/MM/yyyy à HH:mm"),
query.Location.Address,
query.ActivityCode),
Client = new ClientProviderInfo { 
UserName = query.Client.UserName ,
UserId = query.ClientId,

@ -23,67 +23,29 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Data.Entity;
using Microsoft.AspNet.Identity.EntityFramework;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Compute.v1;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Util.Store;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Util;
namespace Yavsc.Helpers
{
using Models.Google.Messaging;
using Models.Messaging;
using Models;
using Interfaces.Workflow;
using Yavsc.Models.Calendar;
using Google.Apis.Auth.OAuth2;
using Microsoft.Data.Entity;
using Microsoft.AspNet.Identity.EntityFramework;
using Yavsc.Services;
using Google.Apis.Services;
using Google.Apis.Compute.v1;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Util.Store;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Util;
using Models.Calendar;
using Services;
/// <summary>
/// Google helpers.
/// </summary>
public static class GoogleHelpers
{
public static async Task <MessageWithPayloadResponse> NotifyEvent<Event>
(this GoogleAuthSettings googleSettings, IEnumerable<string> regids, Event ev)
where Event : IEvent
{
if (ev == null)
throw new Exception("Spécifier un évènement");
if (ev.Message == null)
throw new Exception("Spécifier un message");
if (ev.Sender == null)
throw new Exception("Spécifier un expéditeur");
if (regids == null)
throw new NotImplementedException("Notify & No GCM reg ids");
var msg = new MessageWithPayload<Event>()
{
notification = new Notification()
{
title = ev.Topic+" "+ev.Sender,
body = ev.Message,
icon = "icon"
},
data = ev,
registration_ids = regids.ToArray()
};
try {
using (var m = new SimpleJsonPostMethod("https://gcm-http.googleapis.com/gcm/send",$"key={googleSettings.ApiKey}")) {
return await m.Invoke<MessageWithPayloadResponse>(msg);
}
}
catch (Exception ex) {
throw new Exception ("Quelque chose s'est mal passé à l'envoi",ex);
}
}
public static ServiceAccountCredential OupsGetCredentialForApi(IEnumerable<string> scopes)
{
var initializer = new ServiceAccountCredential.Initializer(Startup.GoogleSettings.Account.client_email);

@ -59,7 +59,6 @@ namespace Yavsc.Models.Billing
set { AttachedFiles = value.Split(':').ToList(); }
}
[Required]
public string OwnerId { get; set; }
[ForeignKey("OwnerId"),JsonIgnore]

@ -29,12 +29,17 @@ namespace Yavsc.Models.Calendar
/// <summary>
/// Provided event.
/// </summary>
public class ProvidedEvent : YaEvent {
public class ProvidedEvent : BaseEvent {
/// <summary>
/// The privacy.
/// </summary>
[Required]
public Publishing Privacy;
}
public override string CreateBody()
{
throw new System.NotImplementedException();
}
}
}

@ -0,0 +1,76 @@
using Microsoft.Extensions.Localization;
using System.Linq;
using Yavsc.Interfaces.Workflow;
using Yavsc.Models.Haircut;
using Yavsc.ViewModels.PayPal;
using Yavsc.Helpers;
namespace Yavsc.Models.HairCut
{
public class HairCutPayementEvent: IEvent
{
public HairCutPayementEvent(string sender, PaymentInfo info, HairCutQuery query, IStringLocalizer localizer)
{
Sender = sender;
this.query = query;
invoiceId = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.InvoiceID;
payerName = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Name;
phone = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Phone;
payerEmail = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Payer;
amount = string.Join(", ",
info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PaymentDetails.Select(
p => $"{p.OrderTotal.value} {p.OrderTotal.currencyID}"));
gender = query.Prestation.Gender;
date = query.EventDate?.ToString("dd MM yyyy hh:mm");
lieu = query.Location.Address;
clientFinal = (gender == HairCutGenders.Women) ? localizer["Women"] +
" " + localizer[query.Prestation.Length.ToString()] : localizer[gender.ToString()];
token = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.Token;
payerId = info.DetailsFromPayPal.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID;
}
public string Topic => "/topic/HaircutPayment";
public string Sender { get; set; }
HairCutQuery query;
private string invoiceId;
private string payerName;
private string phone;
private string payerEmail;
private string amount;
private HairCutGenders gender;
private string date;
private string lieu;
private string clientFinal;
private string token;
private string payerId;
public string CreateBody()
{
return $@"# 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: {query.Client.UserName}
Date: {date}
Lieu: {lieu}
Le client final: {clientFinal}
{query.GetBillText()}
";
}
}
}

@ -10,6 +10,9 @@ using System.Globalization;
using Yavsc.Helpers;
using Yavsc.Models.Messaging;
using System.Linq;
using Microsoft.Extensions.Localization;
using Yavsc.ViewModels.PayPal;
using Yavsc.Models.HairCut;
namespace Yavsc.Models.Haircut
{
@ -369,9 +372,15 @@ Prestation.Gender == HairCutGenders.Women ?
return bill;
}
public HairCutPayementEvent CreatePaymentEvent(PaymentInfo info, IStringLocalizer localizer)
{
return new HairCutPayementEvent(Client.UserName,info,this, localizer);
}
public virtual BrusherProfile SelectedProfile { get; set; }
public HairCutQueryEvent CreateEvent(string subTopic, string reason, string sender, string message) {
public HairCutQueryEvent CreateEvent(string subTopic, string reason, string sender) {
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é]";
@ -393,8 +402,7 @@ Prestation.Gender == HairCutGenders.Women ?
Id = Id,
ActivityCode = ActivityCode,
Reason = reason,
Sender = sender,
Message = message
Sender = Client.GetSender()
};
return yaev;
}

@ -6,14 +6,20 @@ namespace Yavsc.Models.Haircut
{
public HairCutQueryEvent(string subTopic)
{
Topic = GetType().Name+"/"+subTopic;
Topic = "/topic/HairCutQuery";
if (subTopic!=null) Topic+="/"+subTopic;
}
public string Message
public string CreateBody()
{
get;
return $"{Reason}\r\n-- \r\n{Previsional}\r\n{EventDate}\r\n";
}
set;
public string CreateBoby()
{
return string.Format(Startup.GlobalLocalizer["RdvToPerf"], Client.UserName,
EventDate?.ToString("dddd dd/MM/yyyy à HH:mm"),
Location.Address,
ActivityCode);
}
public string Sender

@ -4,7 +4,7 @@ using Yavsc.Interfaces;
namespace Yavsc.Models.Messaging
{
public enum Reason {
public enum Reason: byte {
Private,
Corporate,
SearchingAPro,
@ -23,6 +23,12 @@ namespace Yavsc.Models.Messaging
public string OwnerId { get; set; }
[ForeignKey("OwnerId")]
public virtual ApplicationUser Owner { get; set; }
public virtual ApplicationUser Owner { get; set; }
public string Message { get; set; }
public override string CreateBody()
{
return $"Annonce de {Owner.UserName}: {For}\n\n{Message}";
}
}
}

@ -28,7 +28,7 @@ namespace Yavsc.Models.Messaging
/// /// Base event.
/// </summary>
public class BaseEvent : IEvent {
public abstract class BaseEvent : IEvent {
public BaseEvent()
{
Topic = GetType().Name;
@ -39,7 +39,8 @@ namespace Yavsc.Models.Messaging
}
public string Topic { get; private set; }
public string Sender { get; set; }
public string Message { get; set; }
abstract public string CreateBody();
}

@ -28,7 +28,7 @@ namespace Yavsc.Models.Messaging
/// <summary>
/// Event pub.
/// </summary>
public class CircleEvent: YaEvent
public class CircleEvent: BaseEvent
{
/// <summary>
/// Gets or sets the circles.
@ -37,7 +37,12 @@ namespace Yavsc.Models.Messaging
[Required(ErrorMessageResourceName="DoSpecifyCircles"),
Display(Name="Circles")]
public virtual List<Circle> Circles{ get; set; }
}
public override string CreateBody()
{
throw new System.NotImplementedException();
}
}
}

@ -7,6 +7,7 @@ namespace Yavsc.Models.Messaging
using Interfaces.Workflow;
using Billing;
using Yavsc.Helpers;
using Yavsc.Models.Workflow;
public class EstimationEvent: IEvent
{
@ -14,7 +15,7 @@ namespace Yavsc.Models.Messaging
{
Topic = "Estimation";
Estimation = estimate;
var perfer = context.Performers.Include(
perfer = context.Performers.Include(
p=>p.Performer
).FirstOrDefault(
p => p.PerformerId == estimate.OwnerId
@ -27,12 +28,16 @@ namespace Yavsc.Models.Messaging
UserId = perfer.PerformerId
};
Sender = perfer.Performer.UserName;
Message = string.Format(SR["EstimationMessageToClient"],perfer.Performer.UserName,
estimate.Title,estimate.Bill.Addition());
_localizer = SR;
}
// TODO via e-mail only: Message = string.Format(
// SR["EstimationMessageToClient"],perfer.Performer.UserName, estimate.Title,estimate.Bill.Addition());
//
ProviderClientInfo ProviderInfo { get; set; }
Estimate Estimation { get; set; }
private PerformerProfile perfer;
public string Topic
{
get; set;
@ -43,9 +48,11 @@ namespace Yavsc.Models.Messaging
get; set;
}
public string Message
private IStringLocalizer _localizer;
public string CreateBody()
{
get; set;
return string.Format(_localizer["EstimationMessageToClient"], perfer.Performer.UserName, this.Estimation.Bill.Addition());
}
}
}

@ -1,43 +0,0 @@
//
// BaseEvent.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// 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 <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Messaging
{
public class GeneralEvent: BaseEvent, ITitle
{
/// <summary>
/// The title.
/// </summary>
[Required(ErrorMessageResourceName="ChooseATitle")]
[Display(Name="Title")]
public string Title { get; set; }
/// <summary>
/// The description.
/// </summary>
[Required(ErrorMessageResourceName="ChooseADescription")]
[Display(Name="Description")]
public string Description { get; set; }
}
}

@ -22,20 +22,19 @@
namespace Yavsc.Models.Messaging
{
using Interfaces.Workflow;
using Yavsc.Abstract.Messaging;
public class RdvQueryEvent: RdvQueryProviderInfo, IEvent
public class RdvQueryEvent: RdvQueryProviderInfo, IEvent
{
public RdvQueryEvent(string subTopic)
public string SubTopic
{
Topic = GetType().Name+"/"+subTopic;
get; private set;
}
public string Message
public RdvQueryEvent(string subTopic)
{
get; set;
Topic = MessagingConstants.TopicRdvQuery;
SubTopic = subTopic;
}
public string Sender
@ -47,6 +46,14 @@ public class RdvQueryEvent: RdvQueryProviderInfo, IEvent
{
get; private set;
}
public string CreateBody()
{
return string.Format(Startup.GlobalLocalizer["RdvToPerf"], Client.UserName,
EventDate?.ToString("dddd dd/MM/yyyy à HH:mm"),
Location.Address,
ActivityCode);
}
}
}

@ -1,48 +0,0 @@
//
// NFEvent.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// 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 <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Messaging
{
/// <summary>
/// NF event.
/// </summary>
public class YaEvent : BaseEvent
{
/// <summary>
/// The NF provider identifier.
/// </summary>
[Display(Name="From")]
public string FromUserName { get; set; }
/// <summary>
/// The event web page.
/// </summary>
[Display(Name="EventWebPage")]
public string EventWebPage { get; set; }
/// <summary>
/// The image locator.
/// </summary>
[Display(Name="Photo")]
public string Photo { get; set; }
}
}

@ -7,7 +7,7 @@ namespace Yavsc.Models.Relationship
/// <summary>
/// Position.
/// </summary>
public class Position
public class Position: IPosition
{
/// <summary>
/// The longitude.

@ -240,6 +240,7 @@
<data name="Full name"><value>Nom complet</value></data>
<data name="EGCMBUTEMAIL"><value>L'envoi du message push a échoué, mais un e-mail a été envoyé</value></data>
<data name="GCM Notifications sent"><value>Message push envoyé</value></data>
<data name="GCM Notification sending failed"><value>L'evoi du message Google Cloud a échoué ...</value></data>
<data name="GiveAnExplicitReason"><value>Dites en plus, ci àprès, à propos de cet évennement</value></data>
<data name="GoogleDidntGeoLocalized"><value>Google n'a pas pu identifier ce lieu</value></data>
<data name="Google calendar"><value>Agenda Google</value></data>
@ -463,5 +464,27 @@ Pour ce faire, suivez le lien suivant : &lt;{1}&gt;.
d'au moins {0} et d'au plus {1} caractère(s). </value></data>
<data name="DetailledMaxStringLength"><value>Ce champ est
d'au plus {0} caractère(s) ({1} en excès). </value></data>
<data name="EmailSentToPerformer"><value>Un message éléctronique a été envoyé au préstataire.</value></data>
<data name="QueryValidatedNonReg"><value>Un client vient de valider une demande de prestation à votre encontre:
Prestation: {0}
Client : {1}
Date: {2},
Adresse: {3}
-----
{4}
Facture prévue (non réglée): {5}</value></data>
<data name="QueryValidatedRegular"><value>Un client vient de valider une demande de prestation à votre encontre:
Prestation: {0}
Client : {1}
Date: {2},
Adresse: {3}
-----
{4}
Facture réglée: {5}</value></data>
</root>

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Yavsc.Interfaces.Workflow;
using Yavsc.Models.Google.Messaging;
using Yavsc.Models.Haircut;
using Yavsc.Models.Messaging;
@ -23,7 +24,9 @@ namespace Yavsc.Services
GoogleAuthSettings googlesettings,
IEnumerable<string> registrationId,
HairCutQueryEvent ev);
Task<MessageWithPayloadResponse> NotifyAsync(
GoogleAuthSettings _googleSettings,
IEnumerable<string> regids,
IEvent yaev);
}
}

@ -11,6 +11,10 @@ using Yavsc.Models;
using Yavsc.Models.Google.Messaging;
using System.Collections.Generic;
using Yavsc.Models.Haircut;
using Yavsc.Interfaces.Workflow;
using System.Linq;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Yavsc.Services
{
@ -19,6 +23,49 @@ namespace Yavsc.Services
// For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713
public class AuthMessageSender : IEmailSender, IGoogleCloudMessageSender
{
private ILogger _logger;
public AuthMessageSender(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<AuthMessageSender>();
}
public async Task <MessageWithPayloadResponse> NotifyEvent<Event>
( GoogleAuthSettings googleSettings, IEnumerable<string> regids, Event ev)
where Event : IEvent
{
if (ev == null)
throw new Exception("Spécifier un évènement");
if (ev.Sender == null)
throw new Exception("Spécifier un expéditeur");
if (regids == null )
throw new NotImplementedException("Notify & No GCM reg ids");
var raa = regids.ToArray();
if (raa.Length<1)
throw new NotImplementedException("No GCM reg ids");
var msg = new MessageWithPayload<Event>()
{
notification = new Notification()
{
title = ev.Topic+" "+ev.Sender,
body = ev.CreateBody(),
icon = "icon"
},
data = ev,
registration_ids = regids.ToArray()
};
_logger.LogInformation("Sendding to Google : "+JsonConvert.SerializeObject(msg));
try {
using (var m = new SimpleJsonPostMethod("https://gcm-http.googleapis.com/gcm/send",$"key={googleSettings.ApiKey}")) {
return await m.Invoke<MessageWithPayloadResponse>(msg);
}
}
catch (Exception ex) {
throw new Exception ("Quelque chose s'est mal passé à l'envoi",ex);
}
}
/// <summary>
///
/// </summary>
@ -30,18 +77,18 @@ namespace Yavsc.Services
/// </returns>
public async Task<MessageWithPayloadResponse> NotifyBookQueryAsync(GoogleAuthSettings googleSettings, IEnumerable<string> registrationIds, RdvQueryEvent ev)
{
return await googleSettings.NotifyEvent<RdvQueryEvent>(registrationIds, ev);
return await NotifyEvent<RdvQueryEvent>(googleSettings,registrationIds, ev);
}
public async Task<MessageWithPayloadResponse> NotifyEstimateAsync(GoogleAuthSettings googleSettings, IEnumerable<string> registrationIds, EstimationEvent ev)
{
return await googleSettings.NotifyEvent<EstimationEvent>(registrationIds, ev);
return await NotifyEvent<EstimationEvent>(googleSettings,registrationIds, ev);
}
public async Task<MessageWithPayloadResponse> NotifyHairCutQueryAsync(GoogleAuthSettings googleSettings,
IEnumerable<string> registrationIds, HairCutQueryEvent ev)
{
return await googleSettings.NotifyEvent<HairCutQueryEvent>(registrationIds, ev);
return await NotifyEvent<HairCutQueryEvent>(googleSettings, registrationIds, ev);
}
public Task<bool> SendEmailAsync(SiteSettings siteSettings, SmtpSettings smtpSettings, string username, string email, string subject, string message)
@ -78,16 +125,21 @@ namespace Yavsc.Services
{
throw new NotImplementedException();
}
public Task<MessageWithPayloadResponse> NotifyAsync(GoogleAuthSettings _googleSettings, IEnumerable<string> regids, IEvent yaev)
{
throw new NotImplementedException();
}
/* SMS with Twilio:
public Task SendSmsAsync(TwilioSettings twilioSettigns, string number, string message)
{
var Twilio = new TwilioRestClient(twilioSettigns.AccountSID, twilioSettigns.Token);
var result = Twilio.SendMessage( twilioSettigns.SMSAccountFrom, number, message);
// Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
Trace.TraceInformation(result.Status);
// Twilio doesn't currently have an async API, so return success.
var Twilio = new TwilioRestClient(twilioSettigns.AccountSID, twilioSettigns.Token);
var result = Twilio.SendMessage( twilioSettigns.SMSAccountFrom, number, message);
// Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
Trace.TraceInformation(result.Status);
// Twilio doesn't currently have an async API, so return success.
return Task.FromResult(result.Status != "Failed");
return Task.FromResult(result.Status != "Failed");
} */
}

@ -28,19 +28,20 @@ namespace Yavsc
var appData = Environment.GetEnvironmentVariable("APPDATA");
if (appData == null)
{
logger.LogWarning("AppData was not found in environment variables");
if (SiteSetup.DataDir == null) {
SiteSetup.DataDir = "AppData"+env.EnvironmentName;
} else logger.LogWarning("existing setting: "+SiteSetup.DataDir);
logger.LogInformation("Using: "+SiteSetup.DataDir);
} else logger.LogInformation("Using value from settings: "+SiteSetup.DataDir);
DirectoryInfo di = new DirectoryInfo(SiteSetup.DataDir);
if (!di.Exists)
{
di.Create();
logger.LogWarning("Created dir : "+di.FullName);
} else logger.LogWarning("existing: "+di.Name);
} else logger.LogInformation("Using existing directory: "+di.Name);
SiteSetup.DataDir = Path.Combine(Directory.GetCurrentDirectory(),di.Name);
Environment.SetEnvironmentVariable("APPDATA", SiteSetup.DataDir);
logger.LogWarning("AppData was not found in env vars, it has been set to : "+
Environment.GetEnvironmentVariable("APPDATA"));
logger.LogWarning("It has been set to : "+Environment.GetEnvironmentVariable("APPDATA"));
}
var creds = GoogleSettings?.Account?.private_key;

@ -22,12 +22,14 @@
if (ViewBag.GooglePayload.failure>0)
{
<h4>@SR["GCM Notification sending failed"]</h4>
}
else {
<!-- email sent -->
<pre><code>@Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.GooglePayload)</code></pre>
}
}
}
@if (ViewBag.EmailSent)
{
<h4>@SR["EmailSentToPerformer"]</h4>
}
</div>

@ -0,0 +1,52 @@
@model Yavsc.Models.Identity.GoogleCloudMobileDeclaration
@{
ViewData["Title"] = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>GoogleCloudMobileDeclaration</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.DeclarationDate)
</dt>
<dd>
@Html.DisplayFor(model => model.DeclarationDate)
</dd>
<dt>
@Html.DisplayNameFor(model => model.GCMRegistrationId)
</dt>
<dd>
@Html.DisplayFor(model => model.GCMRegistrationId)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Model)
</dt>
<dd>
@Html.DisplayFor(model => model.Model)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Platform)
</dt>
<dd>
@Html.DisplayFor(model => model.Platform)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Version)
</dt>
<dd>
@Html.DisplayFor(model => model.Version)
</dd>
</dl>
<form asp-action="Delete">
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" /> |
<a asp-action="Index">Back to List</a>
</div>
</form>
</div>

@ -0,0 +1,48 @@
@model Yavsc.Models.Identity.GoogleCloudMobileDeclaration
@{
ViewData["Title"] = "Details";
}
<h2>Details</h2>
<div>
<h4>GoogleCloudMobileDeclaration</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.DeclarationDate)
</dt>
<dd>
@Html.DisplayFor(model => model.DeclarationDate)
</dd>
<dt>
@Html.DisplayNameFor(model => model.GCMRegistrationId)
</dt>
<dd>
@Html.DisplayFor(model => model.GCMRegistrationId)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Model)
</dt>
<dd>
@Html.DisplayFor(model => model.Model)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Platform)
</dt>
<dd>
@Html.DisplayFor(model => model.Platform)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Version)
</dt>
<dd>
@Html.DisplayFor(model => model.Version)
</dd>
</dl>
</div>
<p>
<a asp-action="Edit" asp-route-id="@Model.DeviceId">Edit</a> |
<a asp-action="Index">Back to List</a>
</p>

@ -0,0 +1,52 @@
@model IEnumerable<Yavsc.Models.Identity.GoogleCloudMobileDeclaration>
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.DeclarationDate)
</th>
<th>
@Html.DisplayNameFor(model => model.GCMRegistrationId)
</th>
<th>
@Html.DisplayNameFor(model => model.Model)
</th>
<th>
@Html.DisplayNameFor(model => model.Platform)
</th>
<th>
@Html.DisplayNameFor(model => model.Version)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.DeclarationDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.GCMRegistrationId)
</td>
<td>
@Html.DisplayFor(modelItem => item.Model)
</td>
<td>
@Html.DisplayFor(modelItem => item.Platform)
</td>
<td>
@Html.DisplayFor(modelItem => item.Version)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.DeviceId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.DeviceId">Delete</a>
</td>
</tr>
}
</table>

@ -41,6 +41,7 @@
@using Microsoft.Extensions.PlatformAbstractions;
@using PayPal.PayPalAPIInterfaceService.Model;
@inject IViewLocalizer LocString
@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
@addTagHelper "*, Yavsc"

@ -10,5 +10,24 @@ namespace test1
{
}
[Fact]
public void PassingTest()
{
Assert.Equal(4, Add(2, 2));
}
[Fact]
public void FailingTest()
{
Assert.Equal(5, Add(2, 2));
}
int Add(int x, int y)
{
return x + y;
}
}
}

@ -1,7 +1,7 @@
{
"sdk": {
"version": "2.0.4",
"runtime": "mono",
"architecture": "x64"
}
}
"sdk": {
"version": "2.0.4",
"runtime": "mono",
"architecture": "x64"
}
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.NET.Test.Sdk" version="15.5.0" targetFramework="net45" />
<package id="xunit" version="2.3.1" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="2.3.1" targetFramework="net45" />
<package id="xunit.runner.console" version="2.3.1" targetFramework="net45" />
</packages>
Loading…