diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..7db57548
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,23 @@
+{
+ "env": {
+ "browser": true,
+ "commonjs": true,
+ "es6": true,
+ "node": true
+ },
+ "parserOptions": {
+ "ecmaFeatures": {
+ "jsx": true
+ },
+ "sourceType": "module"
+ },
+ "rules": {
+ "no-const-assign": "warn",
+ "no-this-before-super": "warn",
+ "no-undef": "warn",
+ "no-unreachable": "warn",
+ "no-unused-vars": "warn",
+ "constructor-super": "warn",
+ "valid-typeof": "warn"
+ }
+}
\ No newline at end of file
diff --git a/Assets/shoppingcart.svg b/Assets/shoppingcart.svg
new file mode 100644
index 00000000..f49791fd
--- /dev/null
+++ b/Assets/shoppingcart.svg
@@ -0,0 +1,131 @@
+
+
diff --git a/CrossZicMoove.Desktop/CrossZicMoove.Desktop.csproj b/CrossZicMoove.Desktop/CrossZicMoove.Desktop.csproj
new file mode 100644
index 00000000..ddd86ada
--- /dev/null
+++ b/CrossZicMoove.Desktop/CrossZicMoove.Desktop.csproj
@@ -0,0 +1,63 @@
+
+
+
+ Debug
+ AnyCPU
+ {07B9A14B-2D22-4B97-A63C-12B77A7DBB4F}
+ WinExe
+ CrossZicMoove.Desktop
+ CrossZicMoove.Desktop
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ false
+
+
+
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Forms.2.2.0\lib\net45\Eto.dll
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Platform.Gtk.2.2.0\lib\net45\Eto.Gtk2.dll
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Platform.Gtk3.2.2.0\lib\net45\Eto.Gtk3.dll
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Platform.Windows.2.2.0\lib\net45\Eto.WinForms.dll
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Platform.Wpf.2.2.0\lib\net45\Eto.Wpf.dll
+
+
+
+
+
+
+
+
+
+ {3E5584DB-F061-4E7F-B78B-E1830D16E529}
+ CrossZicMoove
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CrossZicMoove.Desktop/Program.cs b/CrossZicMoove.Desktop/Program.cs
new file mode 100644
index 00000000..8d5591d2
--- /dev/null
+++ b/CrossZicMoove.Desktop/Program.cs
@@ -0,0 +1,15 @@
+using System;
+using Eto;
+using Eto.Forms;
+
+namespace CrossZicMoove.Desktop
+{
+ public class Program
+ {
+ [STAThread]
+ public static void Main (string[] args)
+ {
+ new Application (Platform.Detect).Run (new MainForm ());
+ }
+ }
+}
diff --git a/CrossZicMoove.Desktop/Properties/AssemblyInfo.cs b/CrossZicMoove.Desktop/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..777b8367
--- /dev/null
+++ b/CrossZicMoove.Desktop/Properties/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("CrossZicMoove.Desktop")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("Paul Schneider")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/CrossZicMoove.Desktop/packages.config b/CrossZicMoove.Desktop/packages.config
new file mode 100644
index 00000000..ba3f4d1c
--- /dev/null
+++ b/CrossZicMoove.Desktop/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CrossZicMoove/CrossZicMoove.csproj b/CrossZicMoove/CrossZicMoove.csproj
new file mode 100644
index 00000000..abf79385
--- /dev/null
+++ b/CrossZicMoove/CrossZicMoove.csproj
@@ -0,0 +1,60 @@
+
+
+
+ Debug
+ AnyCPU
+ {3E5584DB-F061-4E7F-B78B-E1830D16E529}
+ Library
+ CrossZicMoove
+ CrossZicMoove
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ false
+
+
+
+
+ MainForm.xeto
+
+
+
+
+
+
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Forms.2.2.0\lib\net45\Eto.dll
+
+
+ ..\..\..\.config\NuGet\packages\Portable.Xaml.0.6.1\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Portable.Xaml.dll
+
+
+ ..\..\..\.config\NuGet\packages\Eto.Serialization.Xaml.2.2.0\lib\net45\Eto.Serialization.Xaml.dll
+
+
+
+
+
+
+
+ {67F9D3A8-F71E-4428-913F-C37AE82CDB24}
+ YavscLib
+
+
+
\ No newline at end of file
diff --git a/CrossZicMoove/MainForm.xeto b/CrossZicMoove/MainForm.xeto
new file mode 100644
index 00000000..56c0c1ed
--- /dev/null
+++ b/CrossZicMoove/MainForm.xeto
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CrossZicMoove/MainForm.xeto.cs b/CrossZicMoove/MainForm.xeto.cs
new file mode 100644
index 00000000..63bea621
--- /dev/null
+++ b/CrossZicMoove/MainForm.xeto.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using Eto.Forms;
+using Eto.Drawing;
+using Eto.Serialization.Xaml;
+
+namespace CrossZicMoove
+{
+ public class MainForm : Form
+ {
+ public MainForm ()
+ {
+ XamlReader.Load (this);
+ }
+
+ protected void HandleClickMe (object sender, EventArgs e)
+ {
+ MessageBox.Show ("I was clicked!");
+ }
+
+ protected void HandleQuit (object sender, EventArgs e)
+ {
+ Application.Instance.Quit ();
+ }
+ }
+}
+
diff --git a/CrossZicMoove/Properties/AssemblyInfo.cs b/CrossZicMoove/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..643e0767
--- /dev/null
+++ b/CrossZicMoove/Properties/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("CrossZicMoove")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("Paul Schneider")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/CrossZicMoove/packages.config b/CrossZicMoove/packages.config
new file mode 100644
index 00000000..b4576745
--- /dev/null
+++ b/CrossZicMoove/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e4e887b6..813a5f17 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
C'est une application mettant en oeuvre une prise de contact entre un demandeur de services et son éventuel préstataire associé.
-## Fonctionalités
+## Fonctionalités
Elle est censée aboutir à une prise commande,
un payement du client, à une collecte du retour du client, et à un paiement du prestataire de services.
@@ -17,12 +17,12 @@ du client comme du prestataire.
Ni le client ni le prestataire ne sont anonymes pour l'applications,
il sont même formellement authentifies par l'acquitement d'une première
facturation en ligne, à l'occasion
+
* pour le client, de son acquisition de points contact.
-* pour le prestataire, de la validation de son profile proféssionnel, qui implique l'acquitement
+* pour le prestataire, de la validation de son profile proféssionnel, qui implique l'acquitement
+
de son adhésion forfaitaire.
-## Limitations
+## Limitations
Elle ne prendra pas en charge, du moins pas encore, ni la saisie de structures de projets complexes, ni ticketing associé à la prestation.
-
-
diff --git a/YaDaemon/Program.cs b/YaDaemon/Program.cs
new file mode 100644
index 00000000..3ad428ca
--- /dev/null
+++ b/YaDaemon/Program.cs
@@ -0,0 +1,9 @@
+using System;
+
+class YaDaemon
+{
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello World!");
+ }
+}
diff --git a/YaDaemon/YaDaemon.csproj b/YaDaemon/YaDaemon.csproj
new file mode 100755
index 00000000..abb9969a
--- /dev/null
+++ b/YaDaemon/YaDaemon.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp1.1
+
+
+
diff --git a/YaDaemon/global.json b/YaDaemon/global.json
new file mode 100644
index 00000000..9bead993
--- /dev/null
+++ b/YaDaemon/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "1.0.0-rc4-004771"
+ }
+}
diff --git a/Yavsc/ApiControllers/GCMController.cs b/Yavsc/ApiControllers/GCMController.cs
index aa0ebcd4..5dc97e0b 100644
--- a/Yavsc/ApiControllers/GCMController.cs
+++ b/Yavsc/ApiControllers/GCMController.cs
@@ -61,7 +61,7 @@ public class GCMController : Controller
var latestActivityUpdate = _context.Activities.Max(a=>a.DateModified);
return Json(new {
IsAnUpdate = deviceAlreadyRegistered,
- UpdateActivities = latestActivityUpdate > declaration.LatestActivityUpdate
+ UpdateActivities = (latestActivityUpdate != declaration.LatestActivityUpdate)
});
}
return new BadRequestObjectResult(ModelState);
diff --git a/Yavsc/ApiControllers/HairCutController.cs b/Yavsc/ApiControllers/HairCutController.cs
new file mode 100644
index 00000000..eea1657a
--- /dev/null
+++ b/Yavsc/ApiControllers/HairCutController.cs
@@ -0,0 +1,76 @@
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNet.Mvc;
+using Microsoft.Extensions.OptionsModel;
+using Microsoft.Extensions.Localization;
+
+namespace Yavsc.ApiControllers
+{
+ using YavscLib;
+ using System;
+ using System.Linq;
+ using System.Security.Claims;
+ using Microsoft.Extensions.Logging;
+ using Models;
+ using Services;
+ using Yavsc.Models.Haircut;
+ using Yavsc.Resources;
+
+ [Route("api/haircut")]
+ public class HairCutController : Controller
+ {
+ private ApplicationDbContext _context;
+ private IEmailSender _emailSender;
+ private IGoogleCloudMessageSender _GCMSender;
+ private GoogleAuthSettings _googleSettings;
+ private IStringLocalizer _localizer;
+ private ILogger _logger;
+ private SiteSettings _siteSettings;
+ private SmtpSettings _smtpSettings;
+ private UserManager _userManager;
+
+ public HairCutController(ApplicationDbContext context,
+ IOptions googleSettings,
+ IGoogleCloudMessageSender GCMSender,
+ UserManager userManager,
+ IStringLocalizer localizer,
+ IEmailSender emailSender,
+ IOptions smtpSettings,
+ IOptions siteSettings,
+ ILoggerFactory loggerFactory)
+ {
+ _context = context;
+ _GCMSender = GCMSender;
+ _emailSender = emailSender;
+ _googleSettings = googleSettings.Value;
+ _userManager = userManager;
+ _smtpSettings = smtpSettings.Value;
+ _siteSettings = siteSettings.Value;
+ _localizer = localizer;
+ _logger = loggerFactory.CreateLogger();
+ }
+ public IActionResult Index()
+ {
+ var uid = User.GetUserId();
+ var now = DateTime.Now;
+ var result = _context.HairCutQueries.Where(
+ q=>q.ClientId == uid
+ && q.EventDate > now
+ && q.Status == QueryStatus.Inserted
+ );
+ return Ok(result);
+ }
+
+ [HttpPost]
+ public IActionResult PostQuery (HairCutQuery query )
+ {
+ var uid = User.GetUserId();
+ if (!ModelState.IsValid) {
+ return new BadRequestObjectResult(ModelState);
+ }
+ _context.HairCutQueries.Add(query);
+ _context.Update(uid);
+ return Ok();
+ }
+
+ }
+}
diff --git a/Yavsc/ApiControllers/HairCutQueriesApiController.cs b/Yavsc/ApiControllers/HairCutQueriesApiController.cs
new file mode 100644
index 00000000..88a15171
--- /dev/null
+++ b/Yavsc/ApiControllers/HairCutQueriesApiController.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Mvc;
+using Microsoft.Data.Entity;
+using Yavsc.Models;
+using Yavsc.Models.Haircut;
+using Yavsc.Models.Haircut.Views;
+
+namespace Yavsc.Controllers
+{
+ [Produces("application/json")]
+ [Route("api/haircutquery")]
+ public class HairCutQueriesApiController : Controller
+ {
+ private ApplicationDbContext _context;
+
+ public HairCutQueriesApiController(ApplicationDbContext context)
+ {
+ _context = context;
+ }
+
+
+ // GET: api/HairCutQueriesApi
+ // Get the queries for current
+ // user as a client
+ // To get active queries
+ [HttpGet]
+ public async Task GetHairCutQueries()
+ {
+ IEnumerable info = null;
+ await Task.Run(
+ () =>
+ {
+ var bi = DateTime.Now.AddDays(-15);
+
+ var uid = User.GetUserId();
+
+ var dat = _context.HairCutQueries
+ .Include(q => q.Prestation)
+ .Include(q => q.Client)
+ .Include(q => q.PerformerProfile)
+ .Include(q => q.Location)
+ .Where(q => q.ClientId == uid
+ && (q.EventDate == null || q.EventDate > bi))
+ ;
+ info = dat.ToArray().Select(q => new HaircutQueryClientInfo(q));
+ });
+
+ return Ok(info);
+ }
+
+ // GET: api/HairCutQueriesApi/5
+ [HttpGet("{id}", Name = "GetHairCutQuery")]
+ public async Task GetHairCutQuery([FromRoute] long id)
+ {
+ if (!ModelState.IsValid)
+ {
+ return HttpBadRequest(ModelState);
+ }
+
+ HairCutQuery hairCutQuery = await _context.HairCutQueries.SingleAsync(m => m.Id == id);
+
+ if (hairCutQuery == null)
+ {
+ return HttpNotFound();
+ }
+
+ return Ok(hairCutQuery);
+ }
+
+ // PUT: api/HairCutQueriesApi/5
+ [HttpPut("{id}")]
+ public async Task PutHairCutQuery([FromRoute] long id, [FromBody] HairCutQuery hairCutQuery)
+ {
+ if (!ModelState.IsValid)
+ {
+ return HttpBadRequest(ModelState);
+ }
+
+ if (id != hairCutQuery.Id)
+ {
+ return HttpBadRequest();
+ }
+
+ _context.Entry(hairCutQuery).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!HairCutQueryExists(id))
+ {
+ return HttpNotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return new HttpStatusCodeResult(StatusCodes.Status204NoContent);
+ }
+
+ // POST: api/HairCutQueriesApi
+ [HttpPost]
+ public async Task PostHairCutQuery([FromBody] HairCutQuery hairCutQuery)
+ {
+ if (!ModelState.IsValid)
+ {
+ return HttpBadRequest(ModelState);
+ }
+
+ _context.HairCutQueries.Add(hairCutQuery);
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateException)
+ {
+ if (HairCutQueryExists(hairCutQuery.Id))
+ {
+ return new HttpStatusCodeResult(StatusCodes.Status409Conflict);
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return CreatedAtRoute("GetHairCutQuery", new { id = hairCutQuery.Id }, hairCutQuery);
+ }
+
+ // DELETE: api/HairCutQueriesApi/5
+ [HttpDelete("{id}")]
+ public async Task DeleteHairCutQuery([FromRoute] long id)
+ {
+ if (!ModelState.IsValid)
+ {
+ return HttpBadRequest(ModelState);
+ }
+
+ HairCutQuery hairCutQuery = await _context.HairCutQueries.SingleAsync(m => m.Id == id);
+ if (hairCutQuery == null)
+ {
+ return HttpNotFound();
+ }
+
+ _context.HairCutQueries.Remove(hairCutQuery);
+ await _context.SaveChangesAsync();
+
+ return Ok(hairCutQuery);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _context.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ private bool HairCutQueryExists(long id)
+ {
+ return _context.HairCutQueries.Count(e => e.Id == id) > 0;
+ }
+ }
+}
diff --git a/Yavsc/ApiControllers/PdfEstimateController.cs b/Yavsc/ApiControllers/PdfEstimateController.cs
index 19647868..6cdf3674 100644
--- a/Yavsc/ApiControllers/PdfEstimateController.cs
+++ b/Yavsc/ApiControllers/PdfEstimateController.cs
@@ -2,23 +2,23 @@ using System.IO;
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc;
using System.Web.Routing;
-
-namespace Yavsc.ApiControllers
-{
- using Models;
- using Helpers;
using System.Linq;
using Microsoft.Data.Entity;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
- using System;
- using System.Security.Claims;
using Microsoft.Extensions.Localization;
- using Yavsc.Services;
- using Yavsc.Models.Messaging;
- using Yavsc.ViewModels;
using Microsoft.Extensions.OptionsModel;
+ using System;
+ using System.Security.Claims;
+
+namespace Yavsc.ApiControllers
+{
+ using Models;
+ using Helpers;
+ using Services;
+ using Models.Messaging;
+ using ViewModels.Auth;
[Route("api/pdfestimate"), Authorize]
public class PdfEstimateController : Controller
{
diff --git a/Yavsc/Constants.cs b/Yavsc/Constants.cs
index a2297577..6d340dda 100644
--- a/Yavsc/Constants.cs
+++ b/Yavsc/Constants.cs
@@ -8,9 +8,10 @@ namespace Yavsc
CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company",
UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9 ]*$",
AuthorizePath = "~/authorize",
- TokenPath = "~/token", LoginPath = "~/signin",
+ TokenPath = "~/token",
+ LoginPath = "~/signin",
LogoutPath = "~/signout", UserInfoPath = "~/api/me",
- ApplicationAuthenticationSheme = "ServerCookie",
+ ApplicationAuthenticationSheme = "ServerCookie",
ExternalAuthenticationSheme= "ExternalCookie",
CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}",
DefaultFactor = "Default",
@@ -26,11 +27,11 @@ namespace Yavsc
GCMNotificationUrl = "https://gcm-http.googleapis.com/gcm/send",
KeyProtectorPurpose = "OAuth.AspNet.AuthServer",
UserFilesPath = "/UserFiles",
- AvatarsPath = "/Avatars",
- DefaultAvatar = "/images/Users/icon_user.png",
- AnonAvatar = "/images/Users/icon_anon_user.png";
+ AvatarsPath = "/Avatars",
+ DefaultAvatar = "/images/Users/icon_user.png",
+ AnonAvatar = "/images/Users/icon_anon_user.png";
public static readonly long DefaultFSQ = 1024*1024*500;
-
+
public static readonly Scope[] SiteScopes = {
new Scope { Id = "profile", Description = "Your profile informations" },
new Scope { Id = "book" , Description ="Your booking interface"},
@@ -42,7 +43,8 @@ namespace Yavsc
new Scope { Id = "frontoffice" , Description ="Your front office interface" }
};
-
+ public const string SshHeaderKey = "SSH";
+
private static readonly string[] GoogleScopes = { "openid", "profile", "email" };
public static readonly string[] GoogleCalendarScopes =
{ "openid", "profile", "email", "https://www.googleapis.com/auth/calendar" };
diff --git a/Yavsc/Controllers/AccountController.cs b/Yavsc/Controllers/AccountController.cs
index 46aa79cf..5e0691a0 100644
--- a/Yavsc/Controllers/AccountController.cs
+++ b/Yavsc/Controllers/AccountController.cs
@@ -20,7 +20,7 @@ using Microsoft.Data.Entity;
namespace Yavsc.Controllers
{
- [ServiceFilter(typeof(LanguageActionFilter)), AllowAnonymous]
+ [AllowAnonymous]
public class AccountController : Controller
{
private readonly UserManager _userManager;
@@ -231,12 +231,12 @@ namespace Yavsc.Controllers
// Sign in the user with this external login provider if the user already has a login.
info.ProviderDisplayName = info.ExternalPrincipal.Claims.First(c=>c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")?.Value;
-
+
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (result.Succeeded)
{
_logger.LogInformation(5, $"User logged in with {info.LoginProvider} provider, as {info.ProviderDisplayName} ({info.ProviderKey})." );
-
+
var ninfo = _dbContext.UserLogins.First(l=>l.ProviderKey == info.ProviderKey && l.LoginProvider == info.LoginProvider);
ninfo.ProviderDisplayName = info.ProviderDisplayName;
@@ -361,7 +361,7 @@ namespace Yavsc.Controllers
// Don't reveal that the user does not exist or is not confirmed
if (user == null)
_logger.LogWarning($"ForgotPassword: Email {model.Email} not found");
- else
+ else
_logger.LogWarning($"ForgotPassword: Email {model.Email} not confirmed");
return View("ForgotPasswordConfirmation");
}
diff --git a/Yavsc/Controllers/AdministrationController.cs b/Yavsc/Controllers/AdministrationController.cs
index 2ee03a44..097193cf 100644
--- a/Yavsc/Controllers/AdministrationController.cs
+++ b/Yavsc/Controllers/AdministrationController.cs
@@ -13,7 +13,7 @@ using Yavsc.ViewModels.Administration;
namespace Yavsc.Controllers
{
- [ServiceFilter(typeof(LanguageActionFilter)), Authorize()]
+ [Authorize()]
public class AdministrationController : Controller
{
private readonly UserManager _userManager;
@@ -43,6 +43,24 @@ namespace Yavsc.Controllers
// If some amdin already exists, make this method disapear
var admins = await _userManager.GetUsersInRoleAsync(Constants.AdminGroupName);
if (admins != null && admins.Count > 0) return HttpNotFound();
+
+ // ensure all roles existence
+ foreach (string roleName in new string[] {Constants.AdminGroupName,
+ Constants.StarGroupName, Constants.PerformerGroupName,
+ Constants.FrontOfficeGroupName,
+ Constants.StarHunterGroupName
+ })
+ if (!await _roleManager.RoleExistsAsync(roleName))
+ {
+ var role = new IdentityRole { Name = roleName };
+ var resultCreate = await _roleManager.CreateAsync(role);
+ if (!resultCreate.Succeeded)
+ {
+ AddErrors(resultCreate);
+ return new BadRequestObjectResult(ModelState);
+ }
+ }
+
var user = await _userManager.FindByIdAsync(User.GetUserId());
IdentityRole adminRole;
@@ -53,9 +71,10 @@ namespace Yavsc.Controllers
AddErrors(addToRoleResult);
return new BadRequestObjectResult(ModelState);
}
+
return Ok(new { message = "you owned it." });
}
-
+
[Authorize(Roles = Constants.AdminGroupName)]
[Produces("application/json")]
public async Task Index()
@@ -72,7 +91,9 @@ namespace Yavsc.Controllers
Name = x.Name,
Users = x.Users.Select(u=>u.UserId).ToArray()
});
-
+ ViewBag.ThisAssembly = GetType().Assembly.FullName;
+ ViewBag.RunTimeVersion = GetType().Assembly.ImageRuntimeVersion;
+
return View(new AdminViewModel
{
Roles = roles.ToArray(),
@@ -80,7 +101,7 @@ namespace Yavsc.Controllers
YouAreAdmin = youAreAdmin
});
}
-
+
public IActionResult Role(string id)
{
IdentityRole role = _roleManager.Roles
diff --git a/Yavsc/Controllers/BlogspotController.cs b/Yavsc/Controllers/BlogspotController.cs
index 542443b9..f0778b9f 100644
--- a/Yavsc/Controllers/BlogspotController.cs
+++ b/Yavsc/Controllers/BlogspotController.cs
@@ -11,13 +11,11 @@ using Microsoft.Extensions.OptionsModel;
using Yavsc.Models;
using Yavsc.ViewModels.Auth;
using Microsoft.AspNet.Mvc.Rendering;
-using Yavsc.ViewModels;
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace Yavsc.Controllers
{
- [ServiceFilter(typeof(LanguageActionFilter))]
public class BlogspotController : Controller
{
ILogger _logger;
@@ -65,7 +63,7 @@ namespace Yavsc.Controllers
return View(posts
.OrderByDescending(p => p.DateCreated)
- .Skip(skip).Take(maxLen));
+ .Skip(skip).Take(maxLen).GroupBy(p=>p.Title));
}
[Route("/Title/{id?}")]
@@ -73,7 +71,8 @@ namespace Yavsc.Controllers
public IActionResult Title(string id)
{
var uid = User.GetUserId();
- return View("Index", _context.Blogspot.Include(
+ ViewData["Title"] = id;
+ return View("Title", _context.Blogspot.Include(
b => b.Author
).Where(x => x.Title == id && (x.Visible || x.AuthorId == uid )).ToList());
}
@@ -82,17 +81,19 @@ namespace Yavsc.Controllers
[AllowAnonymous]
public IActionResult UserPosts(string id)
{
- if (string.IsNullOrEmpty(id))
- return View("Index",_context.Blogspot.Include(
- b => b.Author
- ).Where(p => p.Visible));
- if (User.IsSignedIn())
- return View("Index", _context.Blogspot.Include(
+
+ if (string.IsNullOrEmpty(id)) return Index(null);
+ var uid = User.GetUserId();
+ long[] usercircles = _context.Circle.Include(c=>c.Members).Where(c=>c.Members.Any(m=>m.MemberId == uid))
+ .Select(c=>c.Id).ToArray();
+ var result = (User.IsSignedIn())?
+ _context.Blogspot.Include(
b => b.Author
- ).Where(x => x.Author.UserName == id).ToList());
- return View("Index", _context.Blogspot.Include(
+ ).Include(p=>p.ACL).Where(x => x.Author.UserName == id && (x.Visible && (x.ACL.Count==0 || x.ACL.Any(a=> usercircles.Contains(a.CircleId))))):
+ _context.Blogspot.Include(
b => b.Author
- ).Where(x => x.Author.UserName == id && x.Visible).ToList());
+ ).Where(x => x.Author.UserName == id && x.Visible);
+ return View("Index", result.OrderByDescending(p => p.DateCreated).ToList().GroupBy(p=>p.Title));
}
// GET: Blog/Details/5
[AllowAnonymous]
@@ -112,16 +113,17 @@ namespace Yavsc.Controllers
}
if (!await _authorizationService.AuthorizeAsync(User, blog, new ViewRequirement()))
{
- return new ChallengeResult();
+ return new ChallengeResult();
}
return View(blog);
}
// GET: Blog/Create
[Authorize()]
- public IActionResult Create()
+ public IActionResult Create(string title)
{
- return View();
+ var result = new Blog{Title=title};
+ return View(result);
}
// POST: Blog/Create
@@ -131,6 +133,7 @@ namespace Yavsc.Controllers
blog.Rate = 0;
blog.AuthorId = User.GetUserId();
ModelState.ClearValidationState("AuthorId");
+ blog.Id=0;
if (ModelState.IsValid)
{
_context.Blogspot.Add(blog);
@@ -161,11 +164,11 @@ namespace Yavsc.Controllers
ViewBag.ACL = _context.Circle.Where(
c=>c.OwnerId == blog.AuthorId)
.Select(
- c => new SelectListItem
- {
- Text = c.Name,
- Value = c.Id.ToString(),
- Selected = blog.AuthorizeCircle(c.Id)
+ c => new SelectListItem
+ {
+ Text = c.Name,
+ Value = c.Id.ToString(),
+ Selected = blog.AuthorizeCircle(c.Id)
}
);
return View(blog);
@@ -191,7 +194,7 @@ namespace Yavsc.Controllers
_context.SaveChanges(User.GetUserId());
ViewData["StatusMessage"] = "Post modified";
return RedirectToAction("Index");
- }
+ }
else
{
ViewData["StatusMessage"] = "Accès restreint";
diff --git a/Yavsc/Controllers/CommandController.cs b/Yavsc/Controllers/CommandController.cs
index 0f494123..f5f2fa89 100644
--- a/Yavsc/Controllers/CommandController.cs
+++ b/Yavsc/Controllers/CommandController.cs
@@ -18,8 +18,7 @@ namespace Yavsc.Controllers
using Models.Relationship;
using Models.Workflow;
using Services;
-
- [ServiceFilter(typeof(LanguageActionFilter))]
+
public class CommandController : Controller
{
protected UserManager _userManager;
@@ -54,30 +53,30 @@ namespace Yavsc.Controllers
// GET: Command
[Authorize]
- public IActionResult Index()
+ public virtual async Task Index()
{
var uid = User.GetUserId();
- return View(_context.RdvQueries
+ 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)
- .ToList());
+ .ToListAsync());
}
// GET: Command/Details/5
- public IActionResult Details(long? id)
+ public virtual async Task Details(long? id)
{
if (id == null)
{
return HttpNotFound();
}
- RdvQuery command = _context.RdvQueries
+ RdvQuery command = await _context.RdvQueries
.Include(x => x.Location)
.Include(x => x.PerformerProfile)
- .Single(m => m.Id == id);
+ .SingleAsync(m => m.Id == id);
if (command == null)
{
return HttpNotFound();
@@ -128,7 +127,7 @@ namespace Yavsc.Controllers
[ValidateAntiForgeryToken]
public async Task Create(RdvQuery command)
{
-
+
var uid = User.GetUserId();
var prid = command.PerformerId;
if (string.IsNullOrWhiteSpace(uid)
@@ -151,10 +150,10 @@ namespace Yavsc.Controllers
// ModelState.ClearValidationState("Client.Avatar");
// ModelState.ClearValidationState("ClientId");
ModelState.MarkFieldSkipped("ClientId");
-
+
if (ModelState.IsValid)
{
- var existingLocation = _context.Locations.FirstOrDefault( x=>x.Address == command.Location.Address
+ var existingLocation = _context.Locations.FirstOrDefault( x=>x.Address == command.Location.Address
&& x.Longitude == command.Location.Longitude && x.Latitude == command.Location.Latitude );
if (existingLocation!=null) {
diff --git a/Yavsc/Controllers/DjSettingsController.cs b/Yavsc/Controllers/DjSettingsController.cs
index 7053efcc..8ee90a17 100644
--- a/Yavsc/Controllers/DjSettingsController.cs
+++ b/Yavsc/Controllers/DjSettingsController.cs
@@ -1,7 +1,5 @@
-using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
-using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using Yavsc.Models;
using Yavsc.Models.Musical.Profiles;
diff --git a/Yavsc/Controllers/EstimateController.cs b/Yavsc/Controllers/EstimateController.cs
index 01184d20..d001624a 100644
--- a/Yavsc/Controllers/EstimateController.cs
+++ b/Yavsc/Controllers/EstimateController.cs
@@ -16,7 +16,7 @@ namespace Yavsc.Controllers
using Models;
using Models.Billing;
using Models.Workflow;
- using ViewModels;
+ using ViewModels.Auth;
[Authorize]
public class EstimateController : Controller
{
diff --git a/Yavsc/Controllers/GeneralSettingsController.cs b/Yavsc/Controllers/GeneralSettingsController.cs
index 2cfe8743..502b1003 100644
--- a/Yavsc/Controllers/GeneralSettingsController.cs
+++ b/Yavsc/Controllers/GeneralSettingsController.cs
@@ -1,7 +1,5 @@
-using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
-using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using Yavsc.Models;
using Yavsc.Models.Musical.Profiles;
diff --git a/Yavsc/Controllers/HairCutCommandController.cs b/Yavsc/Controllers/HairCutCommandController.cs
index 1a68a76a..6f2c055c 100644
--- a/Yavsc/Controllers/HairCutCommandController.cs
+++ b/Yavsc/Controllers/HairCutCommandController.cs
@@ -21,10 +21,13 @@ namespace Yavsc.Controllers
using Microsoft.AspNet.Http;
using Yavsc.Extensions;
using Yavsc.Models.Haircut;
+ using System.Globalization;
+ using Microsoft.AspNet.Mvc.Rendering;
+ using System.Collections.Generic;
public class HairCutCommandController : CommandController
{
- public HairCutCommandController(ApplicationDbContext context,
+ public HairCutCommandController(ApplicationDbContext context,
IOptions googleSettings,
IGoogleCloudMessageSender GCMSender,
UserManager userManager,
@@ -35,17 +38,89 @@ namespace Yavsc.Controllers
ILoggerFactory loggerFactory) : base(context,googleSettings,GCMSender,userManager,
localizer,emailSender,smtpSettings,siteSettings,loggerFactory)
{
-
+
+ }
+ private async Task GetQuery(long id)
+ {
+ return await _context.HairCutQueries
+ .Include(x => x.Location)
+ .Include(x => x.PerformerProfile)
+ .Include(x => x.Prestation)
+ .Include(x => x.PerformerProfile.Performer)
+ .SingleAsync(m => m.Id == id);
+ }
+ public async Task ClientCancel(long id)
+ {
+ HairCutQuery command = await GetQuery(id);
+ if (command == null)
+ {
+ return HttpNotFound();
+ }
+ return View (command);
}
-
+ public async Task ClientCancelConfirm(long id)
+ {
+ var query = await GetQuery(id);if (query == null)
+ {
+ return HttpNotFound();
+ }
+ var uid = User.GetUserId();
+ if (query.ClientId!=uid)
+ return new ChallengeResult();
+ _context.HairCutQueries.Remove(query);
+ await _context.SaveChangesAsync();
+ return await Index();
+ }
+ public override async Task Index()
+ {
+ var uid = User.GetUserId();
+ return View("Index", await _context.HairCutQueries
+ .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());
+ }
+
+ public override async Task Details(long? id)
+ {
+ if (id == null)
+ {
+ return HttpNotFound();
+ }
+
+ HairCutQuery command = await _context.HairCutQueries
+ .Include(x => x.Location)
+ .Include(x => x.PerformerProfile)
+ .Include(x => x.Prestation)
+ .Include(x => x.PerformerProfile.Performer)
+ .SingleAsync(m => m.Id == id);
+ if (command == null)
+ {
+ return HttpNotFound();
+ }
+
+ return View(command);
+ }
+
+
[HttpPost, Authorize]
[ValidateAntiForgeryToken]
- public async Task CreateHairCutQuery(HairCutQuery command)
+ public async Task CreateHairCutQuery(HairCutQuery model, string taintIds)
{
-
-
var uid = User.GetUserId();
- var prid = command.PerformerId;
+ var prid = model.PerformerId;
+ long[] longtaintIds = null;
+ List colors = null;
+
+ if (taintIds!=null) {
+ longtaintIds = taintIds.Split(',').Select(s=>long.Parse(s)).ToArray();
+ colors = _context.HairTaint.Where(t=> longtaintIds.Contains(t.Id)).ToList();
+ // a Prestation is required
+ model.Prestation.Taints = colors.Select(c =>
+ new HairTaintInstance { Taint = c }).ToList();
+ }
if (string.IsNullOrWhiteSpace(uid)
|| string.IsNullOrWhiteSpace(prid))
throw new InvalidOperationException(
@@ -55,103 +130,133 @@ namespace Yavsc.Controllers
u => u.Performer
).Include(u => u.Performer.Devices)
.FirstOrDefault(
- x => x.PerformerId == command.PerformerId
+ x => x.PerformerId == model.PerformerId
);
- var user = await _userManager.FindByIdAsync(uid);
- command.Client = user;
- command.ClientId = uid;
- command.PerformerProfile = pro;
+ model.PerformerProfile = pro;
// FIXME Why!!
// ModelState.ClearValidationState("PerformerProfile.Avatar");
// ModelState.ClearValidationState("Client.Avatar");
// ModelState.ClearValidationState("ClientId");
- 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 (model.Location!=null) {
+ var existingLocation = await _context.Locations.FirstOrDefaultAsync( x=>x.Address == model.Location.Address
+ && x.Longitude == model.Location.Longitude && x.Latitude == model.Location.Latitude );
- if (existingLocation!=null) {
- command.Location=existingLocation;
- }
- else _context.Attach(command.Location);
+ if (existingLocation!=null) {
+ model.Location=existingLocation;
+ }
+ else _context.Attach(model.Location);
+ }
+ var existingPrestation = await _context.HairPrestation.FirstOrDefaultAsync( x=> model.PrestationId == x.Id );
- _context.HairCutQueries.Add(command, GraphBehavior.IncludeDependents);
- _context.SaveChanges(User.GetUserId());
+ if (existingPrestation!=null) {
+ model.Prestation = existingPrestation;
+ }
+ else _context.Attach(model.Prestation);
- var yaev = command.CreateEvent(_localizer);
+ _context.HairCutQueries.Add(model);
+ await _context.SaveChangesAsync(uid);
+ var brusherProfile = await _context.BrusherProfile.SingleAsync(p=>p.UserId == pro.PerformerId);
+ model.Client = await _context.Users.SingleAsync(u=>u.Id == model.ClientId);
+
+ var yaev = model.CreateEvent(_localizer, brusherProfile);
MessageWithPayloadResponse grep = null;
- if (pro.AcceptNotifications
- && pro.AcceptPublicContact)
+ if (pro.AcceptPublicContact)
{
- if (pro.Performer.Devices.Count > 0) {
- var regids = command.PerformerProfile.Performer
- .Devices.Select(d => d.GCMRegistrationId);
- grep = await _GCMSender.NotifyHairCutQueryAsync(_googleSettings,regids,yaev);
+ if (pro.AcceptNotifications) {
+ if (pro.Performer.Devices.Count > 0) {
+ var regids = model.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;
+ if (grep!=null)
+ _logger.LogWarning($"Performer: {model.PerformerProfile.Performer.UserName} success: {grep.success} failure: {grep.failure}");
}
- // 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;
- 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,
+ model.PerformerProfile.Performer.Email,
yaev.Topic+" "+yaev.Sender,
$"{yaev.Message}\r\n-- \r\n{yaev.Previsional}\r\n{yaev.EventDate}\r\n"
);
}
- ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == command.ActivityCode);
+ else {
+ // TODO if (AcceptProContact) try & find a bookmaker to send him this query
+ }
+ ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == model.ActivityCode);
ViewBag.GoogleSettings = _googleSettings;
- return View("CommandConfirmation",command);
+ var addition = model.Prestation.Addition(brusherProfile);
+ ViewBag.Addition = addition.ToString("C",CultureInfo.CurrentUICulture);
+ return View("CommandConfirmation",model);
}
- ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == command.ActivityCode);
+ ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == model.ActivityCode);
ViewBag.GoogleSettings = _googleSettings;
- return View(command);
-
+ SetViewData(model.ActivityCode,model.PerformerId,model.Prestation);
+ return View("HairCut",model);
}
- [ValidateAntiForgeryToken]
- public ActionResult HairCut(string performerId, string activityCode)
+ public async Task HairCut(string performerId, string activityCode)
{
HairPrestation pPrestation=null;
var prestaJson = HttpContext.Session.GetString("HairCutPresta") ;
if (prestaJson!=null) {
pPrestation = JsonConvert.DeserializeObject(prestaJson);
}
- else pPrestation = new HairPrestation {};
-
+ else {
+ pPrestation = new HairPrestation {};
+ }
+
+ var uid = User.GetUserId();
+ var user = await _userManager.FindByIdAsync(uid);
+
+ SetViewData(activityCode,performerId,pPrestation);
+
+ var perfer = _context.Performers.Include(
+ p=>p.Performer
+ ).Single(p=>p.PerformerId == performerId);
+ var result = new HairCutQuery {
+ PerformerProfile = perfer,
+ PerformerId = perfer.PerformerId,
+ ClientId = uid,
+ Prestation = pPrestation,
+ Client = user
+ };
+
+ return View(result);
+ }
+ private void SetViewData (string activityCode, string performerId, HairPrestation pPrestation )
+ {
ViewBag.HairTaints = _context.HairTaint.Include(t=>t.Color);
+ ViewBag.HairTaintsItems = _context.HairTaint.Include(t=>t.Color).Select(
+ c=>
+ new SelectListItem {
+ Text = c.Color.Name+" "+c.Brand,
+ Value = c.Id.ToString()
+ }
+ );
ViewBag.HairTechnos = EnumExtensions.GetSelectList(typeof(HairTechnos),_localizer);
ViewBag.HairLength = EnumExtensions.GetSelectList(typeof(HairLength),_localizer);
ViewBag.Activity = _context.Activities.First(a => a.Code == activityCode);
ViewBag.Gender = EnumExtensions.GetSelectList(typeof(HairCutGenders),_localizer);
ViewBag.HairDressings = EnumExtensions.GetSelectList(typeof(HairDressings),_localizer);
- ViewBag.ColorsClass = ( pPrestation.Tech == HairTechnos.Color
+ ViewBag.ColorsClass = ( pPrestation.Tech == HairTechnos.Color
|| pPrestation.Tech == HairTechnos.Mech ) ? "":"hidden";
ViewBag.TechClass = ( pPrestation.Gender == HairCutGenders.Women ) ? "":"hidden";
ViewData["PerfPrefs"] = _context.BrusherProfile.Single(p=>p.UserId == performerId);
- var perfer = _context.Performers.Include(
- p=>p.Performer
- ).Single(p=>p.PerformerId == performerId);
- var result = new HairCutQuery {
- PerformerProfile = perfer,
- PerformerId = perfer.PerformerId,
- ClientId = User.GetUserId(),
- Prestation = pPrestation
- };
- return View(result);
}
[HttpPost, Authorize]
[ValidateAntiForgeryToken]
public async Task CreateHairMultiCutQuery(HairMultiCutQuery command)
{
-
+
var uid = User.GetUserId();
var prid = command.PerformerId;
if (string.IsNullOrWhiteSpace(uid)
@@ -174,10 +279,10 @@ namespace Yavsc.Controllers
// ModelState.ClearValidationState("Client.Avatar");
// ModelState.ClearValidationState("ClientId");
ModelState.MarkFieldSkipped("ClientId");
-
+
if (ModelState.IsValid)
{
- var existingLocation = _context.Locations.FirstOrDefault( x=>x.Address == command.Location.Address
+ var existingLocation = _context.Locations.FirstOrDefault( x=>x.Address == command.Location.Address
&& x.Longitude == command.Location.Longitude && x.Latitude == command.Location.Latitude );
if (existingLocation!=null) {
@@ -187,8 +292,10 @@ namespace Yavsc.Controllers
_context.HairMultiCutQueries.Add(command, GraphBehavior.IncludeDependents);
_context.SaveChanges(User.GetUserId());
-
- var yaev = command.CreateEvent(_localizer);
+ var brSettings = await _context.BrusherProfile.SingleAsync(
+ bp=>bp.UserId == command.PerformerId
+ );
+ var yaev = command.CreateEvent(_localizer,brSettings);
MessageWithPayloadResponse grep = null;
if (pro.AcceptNotifications
@@ -219,7 +326,7 @@ namespace Yavsc.Controllers
}
ViewBag.Activity = _context.Activities.FirstOrDefault(a=>a.Code == command.ActivityCode);
ViewBag.GoogleSettings = _googleSettings;
- return View(command);
+ return View("HairCut",command);
}
}
-}
\ No newline at end of file
+}
diff --git a/Yavsc/Controllers/HairPrestationsController.cs b/Yavsc/Controllers/HairPrestationsController.cs
index 116ba040..f77fcd2c 100644
--- a/Yavsc/Controllers/HairPrestationsController.cs
+++ b/Yavsc/Controllers/HairPrestationsController.cs
@@ -12,7 +12,7 @@ namespace Yavsc.Controllers
public HairPrestationsController(ApplicationDbContext context)
{
- _context = context;
+ _context = context;
}
// GET: HairPrestations
diff --git a/Yavsc/Controllers/HomeController.cs b/Yavsc/Controllers/HomeController.cs
index b57a9704..18b434bb 100644
--- a/Yavsc/Controllers/HomeController.cs
+++ b/Yavsc/Controllers/HomeController.cs
@@ -14,8 +14,9 @@ using System.Threading.Tasks;
namespace Yavsc.Controllers
{
using Models;
-
- [ServiceFilter(typeof(LanguageActionFilter)),AllowAnonymous]
+ using YavscLib;
+
+ [AllowAnonymous]
public class HomeController : Controller
{
public IHostingEnvironment Hosting { get; set; }
@@ -34,7 +35,9 @@ namespace Yavsc.Controllers
public async Task Index(string id)
{
-
+ ViewBag.IsFromSecureProx = (Request.Headers.ContainsKey(Constants.SshHeaderKey))? Request.Headers[Constants.SshHeaderKey]=="on" : false ;
+ ViewBag.SecureHomeUrl = "https://"+Request.Headers["X-Forwarded-Host"];
+ ViewBag.SshHeaderKey = Request.Headers[Constants.SshHeaderKey];
var uid = User.GetUserId();
long [] clicked=null;
if (uid==null) {
@@ -48,8 +51,36 @@ namespace Yavsc.Controllers
n=> !clicked.Any(c=>n.Id==c)
);
ViewData["Notify"] = notes;
- return View(DbContext.Activities.Where(a=>a.ParentCode==id && !a.Hidden).Include(a=>a.Forms).Include(a=>a.Children)
- .OrderByDescending(a=>a.Rate));
+ ViewData["HasHaircutCommand"] = DbContext.HairCutQueries.Any
+ (q=>q.ClientId == uid && q.Status < QueryStatus.Failed);
+
+ if (id==null) {
+ // Workaround
+ // NotImplementedException: Remotion.Linq.Clauses.ResultOperators.ConcatResultOperator
+ //
+ // Use Concat()| whatever to do left outer join on ToArray() or ToList(), not on IQueryable
+
+ var legacy = DbContext.Activities
+ .Include(a=>a.Forms).Include(a=>a.Children)
+ .Where(a=> !a.Hidden)
+ .Where(a=> a.ParentCode==null).ToArray();
+ // OMG
+ var hiddenchildren = DbContext.Activities
+ .Include(a=>a.Forms).Include(a=>a.Children)
+ .Where(a=> a.Parent.Hidden && !a.Hidden).ToArray();
+
+ return View(legacy.Concat(hiddenchildren).OrderByDescending(a=>a.Rate));
+ }
+ else {
+ return View(DbContext.Activities
+ .Include(a=>a.Forms).Include(a=>a.Children)
+ .Where(a=>!a.Hidden)
+ .Where(a=> a.ParentCode==id).OrderByDescending(a=>a.Rate));
+
+ }
+
+
+
}
public IActionResult About()
{
diff --git a/Yavsc/Controllers/ManageController.cs b/Yavsc/Controllers/ManageController.cs
index eedfc70d..2a045a96 100644
--- a/Yavsc/Controllers/ManageController.cs
+++ b/Yavsc/Controllers/ManageController.cs
@@ -25,8 +25,9 @@ namespace Yavsc.Controllers
using Models.Relationship;
using PayPal.PayPalAPIInterfaceService;
using PayPal.PayPalAPIInterfaceService.Model;
+ using Yavsc.Models.Bank;
- [Authorize, ServiceFilter(typeof(LanguageActionFilter))]
+ [Authorize]
public class ManageController : Controller
{
private readonly UserManager _userManager;
@@ -88,6 +89,8 @@ namespace Yavsc.Controllers
: message == ManageMessageId.SetActivitySuccess ? _SR["Your activity was set."]
: message == ManageMessageId.AvatarUpdateSuccess ? _SR["Your avatar was updated."]
: message == ManageMessageId.IdentityUpdateSuccess ? _SR["Your identity was updated."]
+ : message == ManageMessageId.SetBankInfoSuccess ? _SR["Vos informations bancaires ont bien été enregistrées."]
+ : message == ManageMessageId.SetAddressSuccess ? _SR["Votre adresse a bien été enregistrée."]
: "";
var user = await GetCurrentUserAsync();
@@ -265,7 +268,7 @@ namespace Yavsc.Controllers
return View();
}
- [HttpGet, Authorize]
+ [HttpGet]
public async Task SetGoogleCalendar(string returnUrl)
{
var credential = await _userManager.GetCredentialForGoogleApiAsync(
@@ -290,8 +293,7 @@ namespace Yavsc.Controllers
return View(new SetGoogleCalendarViewModel { ReturnUrl = returnUrl });
}
- [HttpPost, ValidateAntiForgeryToken,
- Authorize]
+ [HttpPost, ValidateAntiForgeryToken]
public async Task SetGoogleCalendar(SetGoogleCalendarViewModel model)
{
var user = _dbContext.Users.FirstOrDefault(u => u.Id == User.GetUserId());
@@ -302,16 +304,41 @@ namespace Yavsc.Controllers
else return Redirect(model.ReturnUrl);
}
- [HttpGet,Authorize]
+ [HttpGet]
public async Task AddBankInfo()
{
- var user = await _userManager.FindByIdAsync(User.GetUserId());
+ var uid = User.GetUserId();
+ var user = await _dbContext.Users.Include(u=>u.BankInfo).SingleAsync(u=>u.Id==uid);
+
+ return View(user.BankInfo);
+ }
- return View(new AddBankInfoViewModel(
- user.BankInfo));
+ [HttpPost]
+ public async Task AddBankInfo (BankIdentity model)
+ {
+ if (ModelState.IsValid)
+ {
+ // TODO PostBankInfoRequirement & auth
+ var uid = User.GetUserId();
+ var user = _dbContext.Users.Include(u=>u.BankInfo)
+ .Single(u=>u.Id == uid);
+
+ if (user.BankInfo != null)
+ {
+ model.Id = user.BankInfo.Id;
+ _dbContext.Entry(user.BankInfo).State = EntityState.Detached;
+ _dbContext.Update(model);
+ }
+ else {
+ user.BankInfo = model;
+ _dbContext.Update(user);
+ }
+ await _dbContext.SaveChangesAsync();
+ }
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetBankInfoSuccess });
}
- [HttpGet,Authorize]
+ [HttpGet]
public async Task SetFullName()
{
var user = await _userManager.FindByIdAsync(User.GetUserId());
@@ -372,14 +399,14 @@ namespace Yavsc.Controllers
if (result.Succeeded)
{
/* Obsolete : files are no more prefixed using the user name.
-
+
var userdirinfo = new DirectoryInfo(
Path.Combine(_siteSettings.UserFiles.DirName,
oldUserName));
var newdir = Path.Combine(_siteSettings.UserFiles.DirName,
model.NewUserName);
if (userdirinfo.Exists)
- userdirinfo.MoveTo(newdir);
+ userdirinfo.MoveTo(newdir);
*/
await _signInManager.SignInAsync(user, isPersistent: false);
@@ -483,13 +510,13 @@ namespace Yavsc.Controllers
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
- [HttpGet, Authorize]
+ [HttpGet]
public IActionResult SetAvatar()
{
return View();
}
- [HttpGet, Authorize]
+ [HttpGet]
public IActionResult SetActivity()
{
var user = GetCurrentUserAsync().Result;
@@ -520,7 +547,6 @@ namespace Yavsc.Controllers
[HttpPost]
- [Authorize]
public async Task SetActivity(PerformerProfile model)
{
var user = GetCurrentUserAsync().Result;
@@ -529,7 +555,7 @@ namespace Yavsc.Controllers
{
if (ModelState.IsValid)
{
-
+
var exSiren = await _dbContext.ExceptionsSIREN.FirstOrDefaultAsync(
ex => ex.SIREN == model.SIREN
);
@@ -588,7 +614,7 @@ namespace Yavsc.Controllers
return View(model);
}
- [HttpPost, Authorize]
+ [HttpPost]
public async Task UnsetActivity()
{
var user = GetCurrentUserAsync().Result;
@@ -609,12 +635,12 @@ namespace Yavsc.Controllers
[HttpGet, Route("/Manage/Credits")]
public IActionResult Credits()
{
-
+
return View();
}
public Dictionary PaypalConfig {
get {
- var config =
+ var config =
new Dictionary();
config.Add("mode", "sandbox");
config.Add("account1.apiUsername", _payPalSettings.UserId);
@@ -622,7 +648,7 @@ namespace Yavsc.Controllers
config.Add("account1.apiSignature", _payPalSettings.Signature);
return config;
}
- }
+ }
protected IActionResult DoDirectCredit(DoDirectCreditViewModel model)
@@ -679,7 +705,7 @@ namespace Yavsc.Controllers
// Important: The notify URL applies only to DoExpressCheckoutPayment. This value is ignored when set in SetExpressCheckout or GetExpressCheckoutDetails.
requestDetails.PaymentDetails.NotifyURL = model.IpnNotificationUrl.Trim();
- // (Optional) Buyer's shipping address information.
+ // (Optional) Buyer's shipping address information.
AddressType billingAddr = new AddressType();
if (model.FirstName != string.Empty && model.LastName != string.Empty
&& model.Street1 != string.Empty && model.Country != string.Empty)
@@ -708,7 +734,7 @@ namespace Yavsc.Controllers
// Note: You must set the currencyID attribute to one of the 3-character currency codes for any of the supported PayPal currencies.
CurrencyCodeType currency = (CurrencyCodeType)
Enum.Parse(typeof(CurrencyCodeType), model.CurrencyCode);
- BasicAmountType paymentAmount = new BasicAmountType(currency, model.Amount);
+ BasicAmountType paymentAmount = new BasicAmountType(currency, model.Amount);
requestDetails.PaymentDetails.OrderTotal = paymentAmount;
// Invoke the API
@@ -716,17 +742,17 @@ namespace Yavsc.Controllers
wrapper.DoDirectPaymentRequest = request;
// Configuration map containing signature credentials and other required configuration.
- // For a full list of configuration parameters refer in wiki page
+ // For a full list of configuration parameters refer in wiki page
// [https://github.com/paypal/sdk-core-dotnet/wiki/SDK-Configuration-Parameters]
//// TODO clean Dictionary configurationMap = Configuration.GetAcctAndConfig();
// Create the PayPalAPIInterfaceServiceService service object to make the API call
PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(PaypalConfig);
- // # API call
- // Invoke the DoDirectPayment method in service wrapper object
+ // # API call
+ // Invoke the DoDirectPayment method in service wrapper object
DoDirectPaymentResponseType response = service.DoDirectPayment(wrapper);
-
+
// Check for API return status
return setKeyResponseObjects(service, response);
}
@@ -749,7 +775,7 @@ namespace Yavsc.Controllers
}
else
{
- HttpContext.Items.Add("Response_error", null);
+ HttpContext.Items.Add("Response_error", null);
responseParams.Add("Transaction Id", response.TransactionID);
responseParams.Add("Payment status", response.PaymentStatus.ToString());
if(response.PendingReason != null) {
@@ -759,7 +785,7 @@ namespace Yavsc.Controllers
HttpContext.Items.Add("Response_keyResponseObject", responseParams);
return View("APIResponse");
}
-
+
#region Helpers
private void AddErrors(IdentityResult result)
@@ -784,6 +810,9 @@ namespace Yavsc.Controllers
UnsetActivitySuccess,
AvatarUpdateSuccess,
IdentityUpdateSuccess,
+ SetBankInfoSuccess,
+
+ SetAddressSuccess,
Error
}
@@ -794,5 +823,36 @@ namespace Yavsc.Controllers
}
#endregion
+
+ [HttpGet]
+ public async Task SetAddress()
+ {
+ var uid = User.GetUserId();
+ var user = await _dbContext.Users.Include(u=>u.PostalAddress).SingleAsync(u=>u.Id==uid);
+ ViewBag.GoogleSettings = _googleSettings;
+ return View(user.PostalAddress);
+ }
+
+ [HttpPost]
+ public async Task SetAddress(Location model)
+ {
+ if (ModelState.IsValid) {
+ var uid = User.GetUserId();
+
+ var user = _dbContext.Users.Include(u=>u.PostalAddress).Single(u=>u.Id==uid);
+
+ var existingLocation = _dbContext.Locations.FirstOrDefault( x=>x.Address == model.Address
+ && x.Longitude == model.Longitude && x.Latitude == model.Latitude );
+
+ if (existingLocation!=null) {
+ user.PostalAddressId = existingLocation.Id;
+ } else _dbContext.Attach(model);
+ user.PostalAddress = model;
+ await _dbContext.SaveChangesAsync();
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetAddressSuccess });
+ }
+ ViewBag.GoogleSettings = _googleSettings;
+ return View(model);
+ }
}
}
diff --git a/Yavsc/CustumModelBinder.cs b/Yavsc/CustumModelBinder.cs
new file mode 100644
index 00000000..5ba4415f
--- /dev/null
+++ b/Yavsc/CustumModelBinder.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Mvc.ModelBinding;
+
+namespace Yavsc
+{
+ public class MyDecimalModelBinder : IModelBinder
+ {
+
+ public async Task BindModelAsync(ModelBindingContext bindingContext)
+ {
+ ValueProviderResult valueResult = bindingContext.ValueProvider
+ .GetValue(bindingContext.ModelName);
+ decimal actualValue ;
+ ModelStateEntry modelState = new ModelStateEntry();
+ try {
+ actualValue = Decimal.Parse(valueResult.FirstValue, System.Globalization.NumberStyles.AllowDecimalPoint);
+
+ return await ModelBindingResult.SuccessAsync(bindingContext.ModelName,actualValue);
+ }
+ catch (Exception ) {
+ }
+ return await ModelBindingResult.FailedAsync(bindingContext.ModelName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Yavsc/Filters/LanguageActionFilter.cs b/Yavsc/Filters/LanguageActionFilter.cs
deleted file mode 100644
index 61c60b31..00000000
--- a/Yavsc/Filters/LanguageActionFilter.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Globalization;
-
-namespace Yavsc
-{
- using Microsoft.AspNet.Mvc.Filters;
- using Microsoft.Extensions.Logging;
-
- public class LanguageActionFilter : ActionFilterAttribute
- {
- private readonly ILogger _logger;
-
- public LanguageActionFilter(ILoggerFactory loggerFactory)
- {
- _logger = loggerFactory.CreateLogger("LanguageActionFilter");
- }
-
- public override void OnActionExecuting(ActionExecutingContext context)
- {
- string culture = null;
- var routedCulture = context.RouteData.Values["culture"];
- if (routedCulture != null) {
- culture = routedCulture.ToString();
- _logger.LogInformation($"Setting the culture from the URL: {culture}");
-
- }
- else {
- if (context.HttpContext.Request.Headers.ContainsKey("accept-language"))
- {
- // fr,en-US;q=0.7,en;q=0.3
- string spec = context.HttpContext.Request.Headers["accept-language"];
- _logger.LogInformation($"Setting the culture from language header spec: {spec}");
-
- string firstpart = spec.Split(';')[0];
- foreach (string lang in firstpart.Split(','))
- {
- // TODO do it from the given options ...
- // just take the main part :-)
- string mainlang = lang.Split('-')[0];
- if (mainlang=="fr"||mainlang=="en") {
- culture = mainlang;
- _logger.LogInformation($"Setting the culture from header: {culture}");
- break;
- }
- }
- }
- }
- if (culture != null) {
-#if DNX451
- System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
- System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
-#else
- CultureInfo.CurrentCulture = new CultureInfo(culture);
- CultureInfo.CurrentUICulture = new CultureInfo(culture);
-#endif
-}
- base.OnActionExecuting(context);
- }
- }
-}
-
-
diff --git a/Yavsc/Helpers/BankInfoHelpers.cs b/Yavsc/Helpers/BankInfoHelpers.cs
new file mode 100644
index 00000000..74de1bb6
--- /dev/null
+++ b/Yavsc/Helpers/BankInfoHelpers.cs
@@ -0,0 +1,18 @@
+namespace Yavsc.Helpers
+{
+ using Models.Bank;
+ public static class BankInfoHelpers
+ {
+ public static bool IsValid(this BankIdentity info) {
+ return ByIbanBIC(info) || ByAccountNumber(info) ;
+ }
+ public static bool ByIbanBIC(this BankIdentity info) {
+ return (info.BIC != null && info.IBAN != null) ;
+ }
+ public static bool ByAccountNumber(this BankIdentity info){
+
+ return (info.BankCode != null && info.WicketCode != null && info.AccountNumber != null && info.BankedKey >0);
+
+ }
+ }
+}
diff --git a/Yavsc/Helpers/EventHelpers.cs b/Yavsc/Helpers/EventHelpers.cs
index 943c238c..cbb7927c 100644
--- a/Yavsc/Helpers/EventHelpers.cs
+++ b/Yavsc/Helpers/EventHelpers.cs
@@ -12,7 +12,7 @@ namespace Yavsc.Helpers
IStringLocalizer SR)
{
var yaev = new RdvQueryEvent
- {
+ {
Sender = query.ClientId,
Message = string.Format(SR["RdvToPerf"],
query.Client.UserName,
@@ -21,8 +21,8 @@ namespace Yavsc.Helpers
query.ActivityCode)+
"\n"+query.Reason,
Client = new ClientProviderInfo {
- UserName = query.Client.UserName ,
- UserId = query.ClientId,
+ UserName = query.Client.UserName ,
+ UserId = query.ClientId,
Avatar = query.Client.Avatar } ,
Previsional = query.Previsional,
EventDate = query.EventDate,
@@ -34,35 +34,47 @@ namespace Yavsc.Helpers
return yaev;
}
public static HairCutQueryEvent CreateEvent(this HairCutQuery query,
- IStringLocalizer SR)
+ IStringLocalizer SR, BrusherProfile bpr)
{
+ string head = SR["HaircutRdvQuery"];
+ 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;
+ decimal total = query.Prestation.Addition(bpr);
+ string strprestation = $@"Coupe: {p.Cut}, Total: {total}";
+
var yaev = new HairCutQueryEvent
- {
+ {
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,
- Avatar = query.Client.Avatar } ,
- Previsional = query.Previsional,
- EventDate = query.EventDate,
- Location = query.Location,
- Id = query.Id,
- Reason = "Coupe particulier",
- ActivityCode = query.ActivityCode
+ Message = $@"{head}: {query.Client.UserName},
+{evdate},
+{address}
+-----
+{strprestation}
+
+--
+{query.AdditionalInfo}
+" ,
+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 HairCutQueryEvent CreateEvent(this HairMultiCutQuery query,
- IStringLocalizer SR)
+ IStringLocalizer SR, BrusherProfile bpr)
{
var yaev = new HairCutQueryEvent
- {
+ {
Sender = query.ClientId,
Message = string.Format(SR["RdvToPerf"],
query.Client.UserName,
@@ -70,8 +82,8 @@ namespace Yavsc.Helpers
query.Location.Address,
query.ActivityCode),
Client = new ClientProviderInfo {
- UserName = query.Client.UserName ,
- UserId = query.ClientId,
+ UserName = query.Client.UserName ,
+ UserId = query.ClientId,
Avatar = query.Client.Avatar } ,
Previsional = query.Previsional,
EventDate = query.EventDate,
diff --git a/Yavsc/Helpers/HaircutHelpers.cs b/Yavsc/Helpers/HaircutHelpers.cs
new file mode 100644
index 00000000..dea34203
--- /dev/null
+++ b/Yavsc/Helpers/HaircutHelpers.cs
@@ -0,0 +1,130 @@
+using Yavsc.Models.Haircut;
+
+namespace Yavsc.Helpers
+{
+ public static class HaircutHelpers
+ {
+ public static decimal Addition (this HairPrestation p, BrusherProfile profile)
+ {
+ decimal sub=0;
+ // Le shampoing
+ sub += p.Shampoo ? profile.ShampooPrice:0;
+
+ // la coupe
+ sub += p.Cut ? p.Gender == HairCutGenders.Women ?
+ p.Length == HairLength.Long ? profile.WomenLongCutPrice :
+ p.Length == HairLength.HalfLong ? profile.WomenHalfCutPrice :
+ profile.WomenShortCutPrice : p.Gender == HairCutGenders.Man ?
+ profile.ManCutPrice : profile.KidCutPrice : 0;
+
+ // Les techniques
+ switch (p.Tech) {
+ case HairTechnos.Color:
+ bool multicolor = p.Taints.Count>1;
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += sub += multicolor? profile.LongMultiColorPrice : profile.LongColorPrice;
+ break;
+ case HairLength.HalfLong: sub += multicolor? profile.HalfMultiColorPrice : profile.HalfColorPrice;
+ break;
+ default:
+ sub += multicolor? profile.ShortMultiColorPrice : profile.ShortColorPrice;
+ break;
+ }
+ break;
+ case HairTechnos.Balayage:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongBalayagePrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfBalayagePrice;
+ break;
+ default:
+ sub += profile.ShortBalayagePrice;
+ break;
+ }
+ break;
+ case HairTechnos.Defris:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongDefrisPrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfDefrisPrice;
+ break;
+ default:
+ sub += profile.ShortDefrisPrice;
+ break;
+ }
+ break;
+ case HairTechnos.Mech:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongMechPrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfMechPrice;
+ break;
+ default:
+ sub += profile.ShortMechPrice;
+ break;
+ }
+ break;
+ case HairTechnos.Permanent:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongPermanentPrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfPermanentPrice;
+ break;
+ default:
+ sub += profile.ShortPermanentPrice;
+ break;
+ }
+ break;
+
+ }
+
+ // Les coiffages
+ switch (p.Dressing) {
+ case HairDressings.Brushing:
+ switch (p.Gender) {
+ case HairCutGenders.Women:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongBrushingPrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfBrushingPrice;
+ break;
+ default:
+ sub += profile.ShortBrushingPrice;
+ break;
+ }
+ break;
+ case HairCutGenders.Man:
+ sub += profile.ManBrushPrice;
+ break;
+ }
+ break;
+ case HairDressings.Coiffage:
+ // est offert
+ break;
+ case HairDressings.Folding:
+ switch (p.Length) {
+ case HairLength.Long:
+ sub += profile.LongFoldingPrice;
+ break;
+ case HairLength.HalfLong: sub += profile.HalfFoldingPrice;
+ break;
+ default:
+ sub += profile.ShortFoldingPrice;
+ break;
+ }
+ break;
+ }
+
+ // les soins
+ sub += p.Cares ? profile.CarePrice:0;
+ return sub;
+
+ }
+ }
+}
diff --git a/Yavsc/Helpers/UserHelpers.cs b/Yavsc/Helpers/UserHelpers.cs
index 48f7fad1..ba30d013 100644
--- a/Yavsc/Helpers/UserHelpers.cs
+++ b/Yavsc/Helpers/UserHelpers.cs
@@ -19,9 +19,9 @@ namespace Yavsc.Helpers
{
var user = dbContext.Users.FirstOrDefault(u => u.Id == userId);
if (user==null) return Constants.AnonAvatar;
+ if (user.Avatar==null) return Constants.DefaultAvatar;
if (user.Avatar.StartsWith("/"))
{
- // use fmt
FileInfo fi = new FileInfo(user.Avatar);
var ext = fi.Extension;
var avatar = user.Avatar.Substring(0, user.Avatar.Length - ext.Length );
diff --git a/Yavsc/Interfaces/IApplicationUser.cs b/Yavsc/Interfaces/IApplicationUser.cs
deleted file mode 100644
index c1da97c7..00000000
--- a/Yavsc/Interfaces/IApplicationUser.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-
-namespace Yavsc.Interfaces
-{
- public interface IApplicationUser
- {
- IAccountBalance AccountBalance { get; set; }
- IList Book { get; set; }
- IList Circles { get; set; }
- string DedicatedGoogleCalendar { get; set; }
- IList Devices { get; set; }
- ILocation PostalAddress { get; set; }
- IList Posts { get; set; }
- }
-}
diff --git a/Yavsc/Interfaces/ICircleMember.cs b/Yavsc/Interfaces/ICircleMember.cs
index 74528828..78b7e1b5 100644
--- a/Yavsc/Interfaces/ICircleMember.cs
+++ b/Yavsc/Interfaces/ICircleMember.cs
@@ -1,4 +1,6 @@
-namespace Yavsc.Interfaces
+using YavscLib;
+
+namespace Yavsc.Interfaces
{
public interface ICircleMember: IIdentified
{
diff --git a/Yavsc/Interfaces/IFormNode.cs b/Yavsc/Interfaces/IFormNode.cs
deleted file mode 100644
index 16be861e..00000000
--- a/Yavsc/Interfaces/IFormNode.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Yavsc.Interfaces
-{
- public interface IFormNode
- {
-
- T GetControl();
- bool IsUIControl { get; }
- bool IsInputControl { get; }
-
- }
-}
\ No newline at end of file
diff --git a/Yavsc/Interfaces/IGoogleCloudMobileDeclaration.cs b/Yavsc/Interfaces/IGoogleCloudMobileDeclaration.cs
index 2eb1d9b8..020d38a8 100644
--- a/Yavsc/Interfaces/IGoogleCloudMobileDeclaration.cs
+++ b/Yavsc/Interfaces/IGoogleCloudMobileDeclaration.cs
@@ -1,4 +1,6 @@
-namespace Yavsc.Interfaces
+using YavscLib;
+
+namespace Yavsc.Interfaces
{
public interface IGCMDeclaration
{
diff --git a/Yavsc/Interfaces/Workflow/IAccountBalance.cs b/Yavsc/Interfaces/Workflow/IAccountBalance.cs
deleted file mode 100644
index 9579903a..00000000
--- a/Yavsc/Interfaces/Workflow/IAccountBalance.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Yavsc.Interfaces
-{
- public interface IAccountBalance
- {
- long ContactCredits { get; set; }
- decimal Credits { get; set; }
- string UserId { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Yavsc/Interfaces/Workflow/ICircle.cs b/Yavsc/Interfaces/Workflow/ICircle.cs
deleted file mode 100644
index a61f5679..00000000
--- a/Yavsc/Interfaces/Workflow/ICircle.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-
-namespace Yavsc.Interfaces
-{
- public interface ICircle
- {
- long Id { get; set; }
- IList Members { get; set; }
- string Name { get; set; }
- IApplicationUser Owner { get; set; }
- string OwnerId { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Yavsc/Interfaces/Workflow/IContact.cs b/Yavsc/Interfaces/Workflow/IContact.cs
index 8be32e5f..1c5ee5bd 100644
--- a/Yavsc/Interfaces/Workflow/IContact.cs
+++ b/Yavsc/Interfaces/Workflow/IContact.cs
@@ -2,7 +2,6 @@
{
public interface IContact
{
- IApplicationUser Owner { get; set; }
string OwnerId { get; set; }
string UserId { get; set; }
}
diff --git a/Yavsc/Interfaces/Workflow/IPerformerSpecified.cs b/Yavsc/Interfaces/Workflow/IPerformerSpecified.cs
deleted file mode 100644
index 6fee1b53..00000000
--- a/Yavsc/Interfaces/Workflow/IPerformerSpecified.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// INominative.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 .
-
-namespace Yavsc.Interfaces
-{
- public interface IPerformerSpecified {
- string PerformerName { get; set; }
- }
-
-}
diff --git a/Yavsc/Migrations/20170217221646_bookQueryStatus.cs b/Yavsc/Migrations/20170217221646_bookQueryStatus.cs
index 53aac870..9250ac35 100644
--- a/Yavsc/Migrations/20170217221646_bookQueryStatus.cs
+++ b/Yavsc/Migrations/20170217221646_bookQueryStatus.cs
@@ -1,8 +1,8 @@
using Microsoft.Data.Entity.Migrations;
-using Yavsc.Interfaces.Workflow;
namespace Yavsc.Migrations
{
+ using YavscLib;
public partial class bookQueryStatus : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
diff --git a/Yavsc/Migrations/20170317213255_cxRequiresUserName.Designer.cs b/Yavsc/Migrations/20170317213255_cxRequiresUserName.Designer.cs
new file mode 100644
index 00000000..6e275e81
--- /dev/null
+++ b/Yavsc/Migrations/20170317213255_cxRequiresUserName.Designer.cs
@@ -0,0 +1,1408 @@
+using System;
+using Microsoft.Data.Entity;
+using Microsoft.Data.Entity.Infrastructure;
+using Microsoft.Data.Entity.Migrations;
+using Yavsc.Models;
+
+namespace Yavsc.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20170317213255_cxRequiresUserName")]
+ partial class cxRequiresUserName
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.0-rc1-16348");
+
+ modelBuilder.Entity("Microsoft.AspNet.Identity.EntityFramework.IdentityRole", b =>
+ {
+ b.Property("Id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("NormalizedName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .HasAnnotation("Relational:Name", "RoleNameIndex");
+
+ b.HasAnnotation("Relational:TableName", "AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNet.Identity.EntityFramework.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasAnnotation("Relational:TableName", "AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasAnnotation("Relational:TableName", "AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasAnnotation("Relational:TableName", "AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasAnnotation("Relational:TableName", "AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Access.Ban", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("DateCreated");
+
+ b.Property("DateModified");
+
+ b.Property("UserCreated");
+
+ b.Property("UserModified");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Access.BlackListed", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("OwnerId")
+ .IsRequired();
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Access.CircleAuthorizationToBlogPost", b =>
+ {
+ b.Property("CircleId");
+
+ b.Property("BlogPostId");
+
+ b.HasKey("CircleId", "BlogPostId");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.AccountBalance", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("ContactCredits");
+
+ b.Property("Credits");
+
+ b.HasKey("UserId");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.ApplicationUser", b =>
+ {
+ b.Property("Id");
+
+ b.Property("AccessFailedCount");
+
+ b.Property("Avatar")
+ .IsRequired()
+ .HasAnnotation("MaxLength", 512)
+ .HasAnnotation("Relational:DefaultValue", "/images/Users/icon_user.png")
+ .HasAnnotation("Relational:DefaultValueType", "System.String");
+
+ b.Property("BankInfoId");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("DedicatedGoogleCalendar");
+
+ b.Property("DiskQuota")
+ .HasAnnotation("Relational:DefaultValue", "524288000")
+ .HasAnnotation("Relational:DefaultValueType", "System.Int64");
+
+ b.Property("DiskUsage");
+
+ b.Property("Email")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("FullName")
+ .HasAnnotation("MaxLength", 512);
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("NormalizedEmail")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("NormalizedUserName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("PostalAddressId");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasAnnotation("Relational:Name", "EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .HasAnnotation("Relational:Name", "UserNameIndex");
+
+ b.HasAnnotation("Relational:TableName", "AspNetUsers");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Auth.Client", b =>
+ {
+ b.Property("Id");
+
+ b.Property("Active");
+
+ b.Property("DisplayName");
+
+ b.Property("LogoutRedirectUri")
+ .HasAnnotation("MaxLength", 100);
+
+ b.Property("RedirectUri");
+
+ b.Property("RefreshTokenLifeTime");
+
+ b.Property("Secret");
+
+ b.Property("Type");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Auth.RefreshToken", b =>
+ {
+ b.Property("Id");
+
+ b.Property("ClientId")
+ .IsRequired()
+ .HasAnnotation("MaxLength", 50);
+
+ b.Property("ExpiresUtc");
+
+ b.Property("IssuedUtc");
+
+ b.Property("ProtectedTicket")
+ .IsRequired();
+
+ b.Property("Subject")
+ .IsRequired()
+ .HasAnnotation("MaxLength", 50);
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.BalanceImpact", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BalanceId")
+ .IsRequired();
+
+ b.Property("ExecDate");
+
+ b.Property("Impact");
+
+ b.Property("Reason")
+ .IsRequired();
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Bank.BankIdentity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccountNumber")
+ .HasAnnotation("MaxLength", 15);
+
+ b.Property("BIC")
+ .HasAnnotation("MaxLength", 15);
+
+ b.Property("BankCode")
+ .HasAnnotation("MaxLength", 5);
+
+ b.Property("BankedKey");
+
+ b.Property("IBAN")
+ .HasAnnotation("MaxLength", 33);
+
+ b.Property("WicketCode")
+ .HasAnnotation("MaxLength", 5);
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Billing.CommandLine", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Count");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasAnnotation("MaxLength", 512);
+
+ b.Property("EstimateId");
+
+ b.Property("EstimateTemplateId");
+
+ b.Property("UnitaryCost");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Billing.Estimate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AttachedFilesString");
+
+ b.Property("AttachedGraphicsString");
+
+ b.Property("ClientId")
+ .IsRequired();
+
+ b.Property("ClientValidationDate");
+
+ b.Property("CommandId");
+
+ b.Property("CommandType")
+ .IsRequired();
+
+ b.Property("Description");
+
+ b.Property("OwnerId")
+ .IsRequired();
+
+ b.Property("ProviderValidationDate");
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Billing.EstimateTemplate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Description");
+
+ b.Property("OwnerId")
+ .IsRequired();
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Billing.ExceptionSIREN", b =>
+ {
+ b.Property("SIREN");
+
+ b.HasKey("SIREN");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Blog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AuthorId");
+
+ b.Property("Content");
+
+ b.Property("DateCreated");
+
+ b.Property("DateModified");
+
+ b.Property("Photo");
+
+ b.Property("Rate");
+
+ b.Property("Title");
+
+ b.Property("UserCreated");
+
+ b.Property("UserModified");
+
+ b.Property("Visible");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Chat.Connection", b =>
+ {
+ b.Property("ConnectionId");
+
+ b.Property("ApplicationUserId")
+ .IsRequired();
+
+ b.Property("Connected");
+
+ b.Property("UserAgent");
+
+ b.HasKey("ConnectionId");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Drawing.Color", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Blue");
+
+ b.Property("Green");
+
+ b.Property("Name");
+
+ b.Property("Red");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Forms.Form", b =>
+ {
+ b.Property("Id");
+
+ b.Property("Summary");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Haircut.BrusherProfile", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("ActionDistance");
+
+ b.Property("CarePrice");
+
+ b.Property("EndOfTheDay");
+
+ b.Property("FlatFeeDiscount");
+
+ b.Property("HalfBalayagePrice");
+
+ b.Property("HalfBrushingPrice");
+
+ b.Property("HalfColorPrice");
+
+ b.Property("HalfDefrisPrice");
+
+ b.Property("HalfFoldingPrice");
+
+ b.Property("HalfMechPrice");
+
+ b.Property("HalfMultiColorPrice");
+
+ b.Property("HalfPermanentPrice");
+
+ b.Property("KidCutPrice");
+
+ b.Property("LongBalayagePrice");
+
+ b.Property("LongBrushingPrice");
+
+ b.Property("LongColorPrice");
+
+ b.Property("LongDefrisPrice");
+
+ b.Property("LongFoldingPrice");
+
+ b.Property("LongMechPrice");
+
+ b.Property("LongMultiColorPrice");
+
+ b.Property("LongPermanentPrice");
+
+ b.Property("ManBrushPrice");
+
+ b.Property("ManCutPrice");
+
+ b.Property("ShampooPrice");
+
+ b.Property("ShortBalayagePrice");
+
+ b.Property("ShortBrushingPrice");
+
+ b.Property("ShortColorPrice");
+
+ b.Property("ShortDefrisPrice");
+
+ b.Property("ShortFoldingPrice");
+
+ b.Property("ShortMechPrice");
+
+ b.Property("ShortMultiColorPrice");
+
+ b.Property("ShortPermanentPrice");
+
+ b.Property("StartOfTheDay");
+
+ b.Property("WomenHalfCutPrice");
+
+ b.Property("WomenLongCutPrice");
+
+ b.Property("WomenShortCutPrice");
+
+ b.HasKey("UserId");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Haircut.HairCutQuery", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ActivityCode")
+ .IsRequired();
+
+ b.Property("ClientId")
+ .IsRequired();
+
+ b.Property("DateCreated");
+
+ b.Property("DateModified");
+
+ b.Property("EventDate");
+
+ b.Property("LocationId")
+ .IsRequired();
+
+ b.Property("PerformerId")
+ .IsRequired();
+
+ b.Property("PrestationId");
+
+ b.Property("Previsional");
+
+ b.Property("Status");
+
+ b.Property("UserCreated");
+
+ b.Property("UserModified");
+
+ b.Property("ValidationDate");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Haircut.HairMultiCutQuery", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ActivityCode")
+ .IsRequired();
+
+ b.Property("ClientId")
+ .IsRequired();
+
+ b.Property("DateCreated");
+
+ b.Property("DateModified");
+
+ b.Property("EventDate");
+
+ b.Property("LocationId");
+
+ b.Property("PerformerId")
+ .IsRequired();
+
+ b.Property("Previsional");
+
+ b.Property("Status");
+
+ b.Property("UserCreated");
+
+ b.Property("UserModified");
+
+ b.Property("ValidationDate");
+
+ b.HasKey("Id");
+ });
+
+ modelBuilder.Entity("Yavsc.Models.Haircut.HairPrestation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property