From 0755dd62b3f42d515d7c3b8ad95f0faa72659a45 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Wed, 15 Apr 2015 03:03:20 +0200 Subject: [PATCH] * New features: - New Client at estimation, ala ajax - Admins can now edit user's profiles --- WebControls/InputUserName.cs | 38 +++++ WorkFlowProvider/NpgsqlContentProvider.cs | 58 ++++++- .../FrontOfficeApiController.cs | 69 +++++--- web/ApiControllers/WorkFlowController.cs | 16 +- web/Controllers/AccountController.cs | 66 ++++---- web/Controllers/AdminController.cs | 4 +- web/Controllers/FrontOfficeController.cs | 34 ++-- web/Controllers/HomeController.cs | 6 +- web/Global.asax.cs | 5 + web/Models/App.master | 58 +++---- web/Scripts/form-new-user.js | 5 + web/Theme/dark/croix.png | Bin 0 -> 172 bytes web/Theme/style.css | 27 +-- web/Views/Account/Profile.aspx | 11 +- web/Views/Account/Register.aspx | 2 +- ...{RemoveRoleQuery.aspx => RemoveRole..aspx} | 0 web/Views/Admin/RemoveUser.aspx | 1 + web/Views/Admin/UserList.aspx | 2 +- web/Views/FrontOffice/Estimate.aspx | 158 ++++++++++++++---- web/Views/FrontOffice/Estimates.aspx | 25 ++- web/Views/FrontOffice/Register.ascx | 72 ++++++++ web/Views/RegisterPage.cs | 40 ----- web/Web.config | 2 +- web/Web.csproj | 8 +- yavscModel/LocalizedText.Designer.cs | 6 + yavscModel/LocalizedText.fr.resx | 1 + yavscModel/LocalizedText.resx | 1 + yavscModel/RolesAndMemebers/Profile.cs | 45 +++-- .../RolesAndMemebers/RegisterClientModel.cs | 71 ++++++++ yavscModel/RolesAndMemebers/RegisterModel.cs | 7 + yavscModel/WorkFlow/IContentProvider.cs | 12 +- yavscModel/WorkFlow/WorkFlowManager.cs | 23 ++- yavscModel/YavscModel.csproj | 1 + 33 files changed, 637 insertions(+), 237 deletions(-) create mode 100644 web/Scripts/form-new-user.js create mode 100644 web/Theme/dark/croix.png rename web/Views/Admin/{RemoveRoleQuery.aspx => RemoveRole..aspx} (100%) create mode 100644 web/Views/FrontOffice/Register.ascx delete mode 100644 web/Views/RegisterPage.cs create mode 100644 yavscModel/RolesAndMemebers/RegisterClientModel.cs diff --git a/WebControls/InputUserName.cs b/WebControls/InputUserName.cs index 83cd6c0a..5d121655 100644 --- a/WebControls/InputUserName.cs +++ b/WebControls/InputUserName.cs @@ -49,6 +49,7 @@ namespace Yavsc.WebControls public InputUserName () { Multiple = false; + EmptyValue = null; } /// /// Gets or sets the name. @@ -80,6 +81,20 @@ namespace Yavsc.WebControls ViewState ["Value"] = value; } } + + [Bindable (true)] + [DefaultValue("")] + [Localizable(false)] + public string OnChange { + get { + return (string) ViewState["OnChange"]; + } + set { + ViewState ["OnChange"] = value; + } + } + + /// /// Gets or sets the in role. /// @@ -113,6 +128,21 @@ namespace Yavsc.WebControls } } + + [Bindable (true)] + [DefaultValue(null)] + public string EmptyValue { + get { + return (string) ViewState["EmptyValue"]; + } + set { + ViewState ["EmptyValue"] = value; + + } + } + + + /// /// Renders the contents. /// @@ -122,6 +152,8 @@ namespace Yavsc.WebControls writer.AddAttribute ("id", ID); writer.AddAttribute ("name", Name); writer.AddAttribute ("class", CssClass); + if (!string.IsNullOrWhiteSpace(OnChange)) + writer.AddAttribute ("onchange", OnChange); if (Multiple) writer.AddAttribute ("multiple","true"); writer.RenderBeginTag ("select"); @@ -133,6 +165,12 @@ namespace Yavsc.WebControls if (!string.IsNullOrWhiteSpace (InRole)) { roles = InRole.Split (','); } + if (EmptyValue!=null) { + writer.AddAttribute ("value", ""); + writer.RenderBeginTag ("option"); + writer.Write (EmptyValue); + writer.RenderEndTag (); + } foreach (MembershipUser u in Membership.GetAllUsers()) { // if roles are specified, members must be in one of them if (roles != null) diff --git a/WorkFlowProvider/NpgsqlContentProvider.cs b/WorkFlowProvider/NpgsqlContentProvider.cs index c091ef3e..f580caca 100644 --- a/WorkFlowProvider/NpgsqlContentProvider.cs +++ b/WorkFlowProvider/NpgsqlContentProvider.cs @@ -231,19 +231,65 @@ namespace Yavsc return new bool[] { false, false, true, true }; } } - /// - /// Gets the estimates created for a specified client. + /// Gets the estimates created by + /// or for the given user by user name. /// /// The estimates. - /// Client. - public Estimate[] GetEstimates (string client) + /// user name. + public Estimate[] GetEstimates (string username) { + if (username == null) + throw new InvalidOperationException ( + "username cannot be" + + " null at searching for estimates"); + using (NpgsqlConnection cnx = CreateConnection ()) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = - "select _id from estimate where client = @clid"; - cmd.Parameters.Add ("@clid", client); + "select _id from estimate where client = @uname or username = @uname"; + + cmd.Parameters.Add ("@uname", username); + cnx.Open (); + List ests = new List (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { + while (rdr.Read ()) { + ests.Add(GetEstimate(rdr.GetInt64(0))); + } + } + return ests.ToArray(); + } + } + } + /// + /// Gets the estimates. + /// + /// The estimates. + /// Client. + /// Responsible. + public Estimate[] GetEstimates (string client, string responsible) + { + if (client == null && responsible == null) + throw new InvalidOperationException ( + "client and responsible cannot be" + + " both null at searching for estimates"); + + using (NpgsqlConnection cnx = CreateConnection ()) { + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = + "select _id from estimate where "; + + if (client != null) { + cmd.CommandText += "client = @clid"; + if (responsible != null) + cmd.CommandText += " and "; + cmd.Parameters.Add ("@clid", client); + } + if (responsible != null) { + cmd.CommandText += "username = @resp"; + cmd.Parameters.Add ("@resp", responsible); + } + cnx.Open (); List ests = new List (); using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { diff --git a/web/ApiControllers/FrontOfficeApiController.cs b/web/ApiControllers/FrontOfficeApiController.cs index cd5561cb..6535c12b 100644 --- a/web/ApiControllers/FrontOfficeApiController.cs +++ b/web/ApiControllers/FrontOfficeApiController.cs @@ -179,41 +179,58 @@ namespace Yavsc.ApiControllers }; } + private HttpResponseMessage DefaultResponse() + { + return ModelState.IsValid ? + Request.CreateResponse (System.Net.HttpStatusCode.OK) : + Request.CreateResponse (System.Net.HttpStatusCode.BadRequest, + ValidateAjaxAttribute.GetErrorModelObject (ModelState)); + } + /// /// Register the specified model. /// /// Model. - /// if false, sends a registration validation e-mail. - [Authorize(Roles="Admin")] + [Authorize()] [ValidateAjaxAttribute] - public void Register ([FromBody] RegisterModel model, bool isApprouved=true) + public HttpResponseMessage Register ([FromBody] RegisterModel model) { - MembershipCreateStatus mcs; - var user = Membership.CreateUser ( - model.UserName, - model.Password, - model.Email, - null, - null, - isApprouved, - out mcs); - switch (mcs) { - case MembershipCreateStatus.DuplicateEmail: - ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + + if (ModelState.IsValid) { + if (model.IsApprouved) + if (!Roles.IsUserInRole ("Admin")) + if (!Roles.IsUserInRole ("FrontOffice")) { + ModelState.AddModelError ("IsApprouved", + "Since you're not member of Admin or FrontOffice groups, " + + "you cannot ask for a pre-approuved registration"); + return DefaultResponse (); + } + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + model.UserName, + model.Password, + model.Email, + null, + null, + model.IsApprouved, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + "à un compte utilisateur existant"); - return ; - case MembershipCreateStatus.DuplicateUserName: - ModelState.AddModelError ("UserName", "Ce nom d'utilisateur est " + + break; + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("UserName", "Ce nom d'utilisateur est " + "déjà enregistré"); - return ; - case MembershipCreateStatus.Success: - if (!isApprouved) - Yavsc.Helpers.YavscHelpers.SendActivationEmail (user); - return ; - - default: - throw new Exception ( string.Format( "Unexpected membership creation status : {0}", mcs.ToString() ) ); + break; + case MembershipCreateStatus.Success: + if (!model.IsApprouved) + Yavsc.Helpers.YavscHelpers.SendActivationEmail (user); + break; + default: + break; + } } + return DefaultResponse (); } } } diff --git a/web/ApiControllers/WorkFlowController.cs b/web/ApiControllers/WorkFlowController.cs index 285849a3..ee96bfb2 100644 --- a/web/ApiControllers/WorkFlowController.cs +++ b/web/ApiControllers/WorkFlowController.cs @@ -62,29 +62,29 @@ namespace Yavsc.ApiControllers [HttpGet] [ValidateAjax] [Authorize(Roles="Admin,FrontOffice")] - public void Register([FromBody] RegisterModel model) + public void Register([FromBody] RegisterModel userModel) { if (ModelState.IsValid) { MembershipCreateStatus mcs; var user = Membership.CreateUser ( - model.UserName, - model.Password, - model.Email, + userModel.UserName, + userModel.Password, + userModel.Email, null, null, - model.IsApprouved, + userModel.IsApprouved, out mcs); switch (mcs) { case MembershipCreateStatus.DuplicateEmail: ModelState.AddModelError ("Email", - string.Format(LocalizedText.DuplicateEmail,model.UserName) ); + string.Format(LocalizedText.DuplicateEmail,userModel.UserName) ); return ; case MembershipCreateStatus.DuplicateUserName: ModelState.AddModelError ("UserName", - string.Format(LocalizedText.DuplicateUserName,model.Email)); + string.Format(LocalizedText.DuplicateUserName,userModel.Email)); return ; case MembershipCreateStatus.Success: - if (!model.IsApprouved) + if (!userModel.IsApprouved) YavscHelpers.SendActivationEmail (user); return; default: diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs index c99be3ff..ee4f9095 100644 --- a/web/Controllers/AccountController.cs +++ b/web/Controllers/AccountController.cs @@ -199,17 +199,20 @@ namespace Yavsc.Controllers } /// - /// Profile the specified model. + /// Profile the specified user. /// - /// Model. + /// User name. [Authorize] [HttpGet] - public ActionResult Profile (Profile model) + public ActionResult Profile (string user) { - string username = Membership.GetUser ().UserName; - ViewData ["UserName"] = username; - model = new Profile (ProfileBase.Create (username)); - model.RememberMe = FormsAuthentication.GetAuthCookie (username, true) == null; + ViewData ["ProfileUserName"] = user; + string logdu = Membership.GetUser ().UserName; + ViewData ["UserName"] = logdu; + if (user == null) + user = logdu; + Profile model= new Profile (ProfileBase.Create (user)); + model.RememberMe = FormsAuthentication.GetAuthCookie (user, true) == null; return View (model); } @@ -221,10 +224,17 @@ namespace Yavsc.Controllers [Authorize] [HttpPost] // ASSERT("Membership.GetUser ().UserName is made of simple characters, no slash nor backslash" - public ActionResult Profile (Profile model, HttpPostedFileBase AvatarFile) + public ActionResult Profile (string username, Profile model, HttpPostedFileBase AvatarFile) { - string username = Membership.GetUser ().UserName; - ViewData ["UserName"] = username; + + string logdu = Membership.GetUser ().UserName; + ViewData ["UserName"] = logdu; + if (username != logdu) + if (!Roles.IsUserInRole ("Admin")) + if (!Roles.IsUserInRole ("FrontOffice")) + throw new UnauthorizedAccessException ("Your are not authorized to modify this profile"); + + ProfileBase prtoup = ProfileBase.Create (username); if (AvatarFile != null) { // if said valid, move as avatar file // else invalidate the model @@ -244,24 +254,24 @@ namespace Yavsc.Controllers */ if (ModelState.IsValid) { if (model.avatar != null) - HttpContext.Profile.SetPropertyValue ("avatar", model.avatar); - HttpContext.Profile.SetPropertyValue ("Address", model.Address); - HttpContext.Profile.SetPropertyValue ("BlogTitle", model.BlogTitle); - HttpContext.Profile.SetPropertyValue ("BlogVisible", model.BlogVisible); - HttpContext.Profile.SetPropertyValue ("CityAndState", model.CityAndState); - HttpContext.Profile.SetPropertyValue ("ZipCode", model.ZipCode); - HttpContext.Profile.SetPropertyValue ("Country", model.Country); - HttpContext.Profile.SetPropertyValue ("WebSite", model.WebSite); - HttpContext.Profile.SetPropertyValue ("Name", model.Name); - HttpContext.Profile.SetPropertyValue ("Phone", model.Phone); - HttpContext.Profile.SetPropertyValue ("Mobile", model.Mobile); - HttpContext.Profile.SetPropertyValue ("BankCode", model.BankCode); - HttpContext.Profile.SetPropertyValue ("WicketCode", model.WicketCode); - HttpContext.Profile.SetPropertyValue ("AccountNumber", model.AccountNumber); - HttpContext.Profile.SetPropertyValue ("BankedKey", model.BankedKey); - HttpContext.Profile.SetPropertyValue ("BIC", model.BIC); - HttpContext.Profile.SetPropertyValue ("IBAN", model.IBAN); - HttpContext.Profile.Save (); + prtoup.SetPropertyValue ("avatar", model.avatar); + prtoup.SetPropertyValue ("Address", model.Address); + prtoup.SetPropertyValue ("BlogTitle", model.BlogTitle); + prtoup.SetPropertyValue ("BlogVisible", model.BlogVisible); + prtoup.SetPropertyValue ("CityAndState", model.CityAndState); + prtoup.SetPropertyValue ("ZipCode", model.ZipCode); + prtoup.SetPropertyValue ("Country", model.Country); + prtoup.SetPropertyValue ("WebSite", model.WebSite); + prtoup.SetPropertyValue ("Name", model.Name); + prtoup.SetPropertyValue ("Phone", model.Phone); + prtoup.SetPropertyValue ("Mobile", model.Mobile); + prtoup.SetPropertyValue ("BankCode", model.BankCode); + prtoup.SetPropertyValue ("WicketCode", model.WicketCode); + prtoup.SetPropertyValue ("AccountNumber", model.AccountNumber); + prtoup.SetPropertyValue ("BankedKey", model.BankedKey); + prtoup.SetPropertyValue ("BIC", model.BIC); + prtoup.SetPropertyValue ("IBAN", model.IBAN); + prtoup.Save (); FormsAuthentication.SetAuthCookie (username, model.RememberMe); ViewData ["Message"] = "Profile enregistré, cookie modifié."; diff --git a/web/Controllers/AdminController.cs b/web/Controllers/AdminController.cs index 0a327f78..0e667e71 100644 --- a/web/Controllers/AdminController.cs +++ b/web/Controllers/AdminController.cs @@ -159,12 +159,14 @@ namespace Yavsc.Controllers [Authorize(Roles="Admin")] public ActionResult RemoveUser (string username, string submitbutton) { + ViewData ["usertoremove"] = username; if (submitbutton == "Supprimer") { Membership.DeleteUser (username); ViewData["Message"]= string.Format("utilisateur \"{0}\" supprimé",username); + ViewData ["usertoremove"] = null; } - return RedirectToAction("UserList"); + return View (); } /// /// Removes the role. diff --git a/web/Controllers/FrontOfficeController.cs b/web/Controllers/FrontOfficeController.cs index bbd502bd..92bbd620 100644 --- a/web/Controllers/FrontOfficeController.cs +++ b/web/Controllers/FrontOfficeController.cs @@ -48,11 +48,20 @@ namespace Yavsc.Controllers /// Estimates this instance. /// [Authorize] - public ActionResult Estimates () + public ActionResult Estimates (string client) { string username = Membership.GetUser ().UserName; - - return View (wfmgr.GetEstimates (username)); + Estimate [] estims = wfmgr.GetUserEstimates (username); + ViewData ["UserName"] = username; + ViewData ["ResponsibleCount"] = + Array.FindAll ( + estims, + x => x.Responsible == username).Length; + ViewData ["ClientCount"] = + Array.FindAll ( + estims, + x => x.Client == username).Length; + return View (estims); } /// @@ -63,6 +72,7 @@ namespace Yavsc.Controllers [Authorize] public ActionResult Estimate (Estimate model, string submit) { + string username = Membership.GetUser().UserName; // Obsolete, set in master page ViewData ["WebApiBase"] = Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative); ViewData ["WABASEWF"] = ViewData ["WebApiBase"] + "/WorkFlow"; @@ -75,23 +85,23 @@ namespace Yavsc.Controllers } model = f; ModelState.Clear (); - string username = HttpContext.User.Identity.Name; if (username != model.Responsible && username != model.Client && !Roles.IsUserInRole ("FrontOffice")) throw new UnauthorizedAccessException ("You're not allowed to view this estimate"); - } + } else if (model.Id == 0) { + if (string.IsNullOrWhiteSpace(model.Responsible)) + model.Responsible = username; + } } else { - string username = Membership.GetUser().UserName; + + if (model.Id == 0) // if (submit == "Create") + if (string.IsNullOrWhiteSpace (model.Responsible)) + model.Responsible = username; if (username != model.Responsible && !Roles.IsUserInRole ("FrontOffice")) throw new UnauthorizedAccessException ("You're not allowed to modify this estimate"); - if (model.Id == 0) { - model.Responsible = username; - ModelState.Clear (); - // TODO better, or ensure that the model state is checked - // before insertion - } + if (ModelState.IsValid) { if (model.Id == 0) model = wfmgr.CreateEstimate ( diff --git a/web/Controllers/HomeController.cs b/web/Controllers/HomeController.cs index c5c0587a..9300a66a 100644 --- a/web/Controllers/HomeController.cs +++ b/web/Controllers/HomeController.cs @@ -86,9 +86,13 @@ namespace Yavsc.Controllers /// public ActionResult Index () { - string startPage = WebConfigurationManager.AppSettings ["StartPage"]; + /* + * A very bad idea (a redirect permanent as home page): + * + * string startPage = WebConfigurationManager.AppSettings ["StartPage"]; if (startPage != null) Redirect (startPage); + */ ViewData ["Message"] = LocalizedText.Welcome; return View (); } diff --git a/web/Global.asax.cs b/web/Global.asax.cs index eed3c48b..354ee3dd 100644 --- a/web/Global.asax.cs +++ b/web/Global.asax.cs @@ -48,6 +48,11 @@ namespace Yavsc "Blogs/{action}/{user}/{title}", new { controller = "Blogs", action = "Index", user=UrlParameter.Optional, title = UrlParameter.Optional } ); + routes.MapRoute ( + "Account", + "Account/{action}/{user}", + new { controller = "Account", action = "Index", user=UrlParameter.Optional } + ); routes.MapRoute ( "Default", "{controller}/{action}/{user}/{title}", diff --git a/web/Models/App.master b/web/Models/App.master index 249a99b1..c65d3f50 100644 --- a/web/Models/App.master +++ b/web/Models/App.master @@ -1,15 +1,14 @@ <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> - - - <% ViewState["orgtitle"] = T.GetString(Page.Title); %> - <% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> - +<% +ViewState["orgtitle"] = T.GetString(Page.Title); + Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; + %> - + @@ -23,35 +22,21 @@

<%=ViewState["orgtitle"]%> - "><%= YavscHelpers.SiteName %>

+ <% + if (ViewData["Error"]!=null) { + %>
<%= Html.Encode(ViewData["Error"]) %> +
<% } + if (ViewData["Message"]!=null) { + %>
<%= Html.Encode(ViewData["Message"]) %>
<% } + %> + +
+ - - -<% if (ViewData["Error"]!=null) { %> -
-<%= Html.Encode(ViewData["Error"]) %> -
-<% } %> -<% if (ViewData["Message"]!=null) { %> -
-<%= Html.Encode(ViewData["Message"]) %> -
-<% } %> - - - -
- - - - - -
- - -
- + - + +
<%= Html.ActionLink("Contact","Contact","Home",null, new { @class="footerlink" }) %>
@@ -95,5 +78,4 @@ $( ".bshd" ).on("click",function(e) { } }); - - + \ No newline at end of file diff --git a/web/Scripts/form-new-user.js b/web/Scripts/form-new-user.js new file mode 100644 index 00000000..f58bbcce --- /dev/null +++ b/web/Scripts/form-new-user.js @@ -0,0 +1,5 @@ + +( function($) { + $.fn.formCreateUser = function() { + } + }); \ No newline at end of file diff --git a/web/Theme/dark/croix.png b/web/Theme/dark/croix.png new file mode 100644 index 0000000000000000000000000000000000000000..0a701b9aa6a673c30a3a2bc904ef21d176507673 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uAB#T}@sR2@)1s;*b3=G`DAk4@xYmNj^FwWD( zF+}71+)0i?2NXD%WB>h6(tml>ipMGQw5RH7L*_{)VT?VC_Po27q5G8~r}w9tfwG3@ zO2+!h^&73;AGr35ahpT>SJQyTu%%B*BUjzO{QBR7ueuz4flM9eei&Dav)tI8T=G_G Q0njD}Pgg&ebxsLQ0E! <%= Html.ValidationSummary() %> <% using(Html.BeginForm("Profile", "Account", FormMethod.Post, new { enctype = "multipart/form-data" })) %> <% { %> + + ">
Informations publiques @@ -165,7 +166,13 @@ Avatar ").append(btrm).appendTo("#"+wridval); btrm.click(function (e) {delRow(e);}); $("#"+wridval).click(function(ev){onEditRow(ev);}); - // $("#tbwrts").tablesorter( {sortList: [[0,0], [1,0]]} ); // .update(); - message(false); - }, - dataType: "json", statusCode: { 400: function(data) { $.each(data.responseJSON, function (key, value) { - document.getElementById("Err_" + value.key.replace(".","_")).innerHTML=value.errors.join("
"); + document.getElementById("Err_wr_" + value.key).innerHTML=value.errors.join("
"); }); } }, - error: function (xhr, ajaxOptions, thrownError) { - if (xhr.status != 400) - message(xhr.status+" : "+xhr.responseText+" / "+thrownError);}}); + error: function (xhr, ajaxOptions, thrownError) { + if (xhr.status!=400) + message(xhr.status+" : "+xhr.responseText); + else message(false); + } + }); } function onEditRow(e) { @@ -243,6 +339,7 @@ function addRow(){ } $(document).ready(function () { + $("#btnnewuser").click(addUser); $("#btncreate").click(addRow); $("#btnmodify").click(setRow); $(".row").click(function (e) {onEditRow(e);}); @@ -261,9 +358,4 @@ function addRow(){ <%= LocalizedText.Tex_version %><%= LocalizedText.Pdf_version %> - - - - - - + \ No newline at end of file diff --git a/web/Views/FrontOffice/Estimates.aspx b/web/Views/FrontOffice/Estimates.aspx index bec15cd3..fd1493b2 100644 --- a/web/Views/FrontOffice/Estimates.aspx +++ b/web/Views/FrontOffice/Estimates.aspx @@ -1,8 +1,25 @@ <%@ Page Title="My estimates" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage>" %> -<% foreach (Estimate estim in Model) { %> - <%= Html.ActionLink(estim.Id.ToString(),"Estimate",new {Id=estim.Id}) %> +<% if (((int)ViewData["ResponsibleCount"])>0) { %> +
+Les estimations que vous avez faites (<%=ViewData["ResponsibleCount"]%>):
+<% +foreach (Estimate estim in Model) { + if (string.Compare(estim.Responsible,(string) ViewData["UserName"])==0) { %> + + <%= Html.ActionLink("Titre:"+estim.Title+" Client:"+estim.Client+" Id:"+estim.Id.ToString(),"Estimate",new {Id=estim.Id}) %> +
+ <% }}%> +
<% } %> -
- +
+ Vos estimations <% if (((int)ViewData["ResponsibleCount"])>0) { %> + en tant que client + <% } %> (<%=ViewData["ClientCount"]%>):
+ <% foreach (Estimate estim in Model) { + if (string.Compare(estim.Client,(string)ViewData["UserName"])==0) { %> + <%= Html.ActionLink("Titre:"+estim.Title+" Responsable:"+estim.Responsible+" Id:"+estim.Id.ToString(),"Estimate",new {Id=estim.Id}) %> +
+ <% }} %> +
diff --git a/web/Views/FrontOffice/Register.ascx b/web/Views/FrontOffice/Register.ascx new file mode 100644 index 00000000..7b124ea5 --- /dev/null +++ b/web/Views/FrontOffice/Register.ascx @@ -0,0 +1,72 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("Register")) %> +<% { %> +

Nouvel utilisateur

+
<% if (Roles.IsUserInRole((string)ViewData ["UserName"],"Admin")) { %> This user is Admin. <% } %> - HasBankAccount:<%= Model.HasBankAccount %>, IsBillable:<%=Model.IsBillable%> + HasBankAccount:<%= Model.HasBankAccount %> + <% if (!Model.HasBankAccount) { %> + (IBAN+BIC ou Codes banque, guichet, compte et clé RIB) + <% } %>, IsBillable:<%=Model.IsBillable%> + <% if (!Model.IsBillable) { %> + (un nom et au choix, une adresse postale valide, + ou un téléphone, ou un email, ou un Mobile) <% } %> diff --git a/web/Views/Account/Register.aspx b/web/Views/Account/Register.aspx index d64dc3af..37959928 100644 --- a/web/Views/Account/Register.aspx +++ b/web/Views/Account/Register.aspx @@ -1,4 +1,4 @@ -<%@ Page Title="Register" Language="C#" Inherits="Yavsc.RegisterPage" MasterPageFile="~/Models/App.master" %> +<%@ Page Title="Register" Language="C#" Inherits="System.Web.Mvc.ViewPages" MasterPageFile="~/Models/App.master" %> <%= Html.ValidationSummary() %> diff --git a/web/Views/Admin/RemoveRoleQuery.aspx b/web/Views/Admin/RemoveRole..aspx similarity index 100% rename from web/Views/Admin/RemoveRoleQuery.aspx rename to web/Views/Admin/RemoveRole..aspx diff --git a/web/Views/Admin/RemoveUser.aspx b/web/Views/Admin/RemoveUser.aspx index 5f5ad914..1ce8a3e2 100644 --- a/web/Views/Admin/RemoveUser.aspx +++ b/web/Views/Admin/RemoveUser.aspx @@ -1,6 +1,7 @@ <%@ Page Title="User removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %>
+ <%= Html.ValidationSummary() %> <% using ( Html.BeginForm("RemoveUser","Admin") ) { %> Supprimer l'utilisateur diff --git a/web/Views/Admin/UserList.aspx b/web/Views/Admin/UserList.aspx index 50db2c36..1fa1224c 100644 --- a/web/Views/Admin/UserList.aspx +++ b/web/Views/Admin/UserList.aspx @@ -7,7 +7,7 @@ <%foreach (MembershipUser user in Model){ %>
  • <%=user.UserName%> <%=user.Email%> <%=(user.IsApproved)?"":"("+LocalizedText.Not_Approuved+")"%> <%=user.IsOnline?LocalizedText.Online:LocalizedText.Offline%> <% if (Roles.IsUserInRole("Admin")) { %> - <%= Html.ActionLink(LocalizedText.Remove,"RemoveUserQuery", new { username = user.UserName }, new { @class="actionlink" } ) %> + <%= Html.ActionLink(LocalizedText.Remove,"RemoveUser", new { username = user.UserName }, new { @class="actionlink" } ) %> <% } %>
  • <% }%> diff --git a/web/Views/FrontOffice/Estimate.aspx b/web/Views/FrontOffice/Estimate.aspx index 27d52e3c..bd731670 100644 --- a/web/Views/FrontOffice/Estimate.aspx +++ b/web/Views/FrontOffice/Estimate.aspx @@ -1,6 +1,5 @@ <%@ Page Title="Devis" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> <%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> - - " type="text/css" media="print, projection, screen" /> - + <%= Html.ValidationSummary("Devis") %> <% using (Html.BeginForm("Estimate","FrontOffice")) { %> <%= Html.LabelFor(model => model.Title) %>:<%= Html.TextBox( "Title" ) %> @@ -21,11 +19,25 @@ $("#tbwrts").stupidtable(); <%= Html.Hidden ("Responsible") %> <%= Html.LabelFor(model => model.Client) %>: + <% Client.Value = Model.Client ; %> - + - -<%= Html.ValidationMessage("Client", "*") %> + + <%= Html.ValidationMessage("Client", "*") %>
    <%= Html.LabelFor(model => model.Description) %>:<%=Html.TextArea( "Description") %> <%= Html.ValidationMessage("Description", "*") %> @@ -38,7 +50,6 @@ $("#tbwrts").stupidtable(); <% } %> - <% if (Model.Id>0) { %> @@ -68,13 +79,26 @@ $("#tbwrts").stupidtable();
    <% } %> <% } %> + +
    + + <% ViewData["EstimateId"]=Model.Id; %> +
    var hid=e.delegateTarget.parentNode.parentNode.id; @@ -157,13 +181,17 @@ $("#tbwrts").stupidtable(); // $("#tbwrts").tablesorter( {sortList: [[0,0], [1,0]]} ); // .update(); }, error: function (xhr, ajaxOptions, thrownError) { - message(xhr.status+" : "+xhr.responseText);} + if (xhr.status!=400) + message(xhr.status+" : "+xhr.responseText); + else message(false); + } }); } function setRow() { var wrt = GetWritting(); + clearWrittingValidation(); $.ajax({ url: "<%=Url.Content("~/api/WorkFlow/UpdateWritting")%>", type: 'POST', @@ -176,25 +204,94 @@ $("#tbwrts").stupidtable(); cells[3].innerHTML=wrt.UnitaryCost; message(false); }, - error: function (xhr, ajaxOptions, thrownError) { - message (xhr.status+" : "+xhr.responseText+" / "+thrownError);} + statusCode: { + 400: function(data) { + $.each(data.responseJSON, function (key, value) { + var errspanid = "Err_" + value.key.replace(".","_"); + var errspan = document.getElementById(errspanid); + if (errspan==null) + alert('enoent '+errspanid); + else + errspan.innerHTML=value.errors.join("
    "); + }); + } + }, + error: function (xhr, ajaxOptions, thrownError) { + if (xhr.status!=400) + message(xhr.status+" : "+xhr.responseText); + else message(false); + } }); } - + function addUser() + { + var user={ + UserName: $("#ur_UserName").val(), + Name: $("#ur_Name").val(), + Password: $("#ur_Password").val(), + Email: $("#ur_Email").val(), + Address: $("#ur_Address").val(), + CityAndState: $("#ur_CityAndState").val(), + ZipCode: $("#ur_ZipCode").val(), + Phone: $("#ur_Phone").val(), + Mobile: $("#ur_Mobile").val(), + IsApprouved: true + }; + clearRegistrationValidation(); + $.ajax({ + url: "<%=Url.Content("~/api/FrontOffice/Register")%>", + type: "POST", + data: user, + success: function (data) { + $("#Client option:last").after($('')); + Client.value = user.UserName; + onClientChange(Client.value); + }, + statusCode: { + 400: function(data) { + $.each(data.responseJSON, function (key, value) { + var errspanid = "Err_ur_" + value.key.replace("model.",""); + var errspan = document.getElementById(errspanid); + if (errspan==null) + alert('enoent '+errspanid); + else + errspan.innerHTML=value.errors.join("
    "); + }); + } + }, + error: function (xhr, ajaxOptions, thrownError) { + if (xhr.status!=400) + message(xhr.status+" : "+xhr.responseText); + else message(false); + }}); + } + function clearWrittingValidation() { + $("#Err_wr_Description").text(""); + $("#Err_wr_ProductReference").text(""); + $("#Err_wr_UnitaryCost").text(""); + $("#Err_wr_Count").text(""); + } +function clearRegistrationValidation(){ + $("#Err_ur_Name").text(""); + $("#Err_ur_UserName").text(""); + $("#Err_ur_Mobile").text(""); + $("#Err_ur_Phone").text(""); + $("#Err_ur_Email").text(""); + $("#Err_ur_Address").text(""); + $("#Err_ur_ZipCode").text(""); + $("#Err_ur_CityAndState").text(""); + } function addRow(){ var wrt = GetWritting(); // gets a writting object from input controls var estid = parseInt($("#Id").val()); - - $("#Err_wr_Description").text(""); - $("#Err_wr_ProductReference").text(""); - $("#Err_wr_UnitaryCost").text(""); - $("#Err_wr_Count").text(""); + clearWrittingValidation(); $.ajax({ url: "<%=Url.Content("~/api/WorkFlow/Write?estid=")%>"+estid, type: "POST", data: wrt, + dataType: "json", success: function (data) { wrt.Id = Number(data); wredit(wrt.Id); @@ -211,22 +308,21 @@ function addRow(){ $("
    + + + + + + + + + + + + + + + + + + +
    +<%= Html.LabelFor(model => model.Name) %> + +<%= Html.TextBox( "Name" ) %> +<%= Html.ValidationMessage("Name", "*", new { @id="Err_ur_Name", @class="error" }) %>
    +<%= Html.LabelFor(model => model.UserName) %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*", new { @id="Err_ur_UserName", @class="error" }) %>
    +<%= Html.LabelFor(model => model.Password) %> + +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*", new { @id="Err_ur_Password", @class="error" }) %> +
    +<%= Html.LabelFor(model => model.Email) %> + +<%= Html.TextBox( "Email" ) %> +<%= Html.ValidationMessage("Email", "*", new { @id="Err_ur_Email", @class="error" }) %> +
    +<%= Html.LabelFor(model => model.Address) %> + +<%= Html.TextBox( "Address" ) %> +<%= Html.ValidationMessage("Address", "*", new { @id="Err_ur_Address", @class="error" }) %>
    +<%= Html.LabelFor(model => model.CityAndState) %> + +<%= Html.TextBox( "CityAndState" ) %> +<%= Html.ValidationMessage("CityAndState", "*", new { @id="Err_ur_CityAndState", @class="error" }) %> + + +
    +<%= Html.LabelFor(model => model.ZipCode) %> + +<%= Html.TextBox( "ZipCode" ) %> +<%= Html.ValidationMessage("ZipCode", "*", new { @id="Err_ur_ZipCode", @class="error" }) %>
    +<%= Html.LabelFor(model => model.Phone) %> + +<%= Html.TextBox( "Phone" ) %> +<%= Html.ValidationMessage("Phone", "*", new { @id="Err_ur_Phone", @class="error" }) %>
    +<%= Html.LabelFor(model => model.Mobile) %> + +<%= Html.TextBox( "Mobile" ) %> +<%= Html.ValidationMessage("Mobile", "*", new { @id="Err_ur_Mobile", @class="error" }) %>
    + +<% } %> + + + + diff --git a/web/Views/RegisterPage.cs b/web/Views/RegisterPage.cs deleted file mode 100644 index 90103029..00000000 --- a/web/Views/RegisterPage.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using Yavsc.Model.RolesAndMembers; - - -namespace Yavsc -{ - /// - /// Register page. - /// - public class RegisterPage : System.Web.Mvc.ViewPage - { - /// - /// Initializes a new instance of the class. - /// - public RegisterPage () - { - } - /// - /// The createuserwizard1. - /// - public CreateUserWizard Createuserwizard1; - /// - /// Raises the register send mail event. - /// - /// Sender. - /// E. - public void OnRegisterSendMail(object sender, MailMessageEventArgs e) - { - // Set MailMessage fields. - e.Message.IsBodyHtml = false; - e.Message.Subject = "New user on Web site."; - // Replace placeholder text in message body with information - // provided by the user. - e.Message.Body = e.Message.Body.Replace("<%PasswordQuestion%>", Createuserwizard1.Question); - e.Message.Body = e.Message.Body.Replace("<%PasswordAnswer%>", Createuserwizard1.Answer); -} - } -} - diff --git a/web/Web.config b/web/Web.config index d8adc0d9..4d366441 100644 --- a/web/Web.config +++ b/web/Web.config @@ -285,7 +285,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx - + diff --git a/web/Web.csproj b/web/Web.csproj index a2477f76..6addec92 100644 --- a/web/Web.csproj +++ b/web/Web.csproj @@ -144,7 +144,6 @@ - @@ -239,7 +238,6 @@ - @@ -247,7 +245,6 @@ - @@ -678,6 +675,11 @@ + + + + + diff --git a/yavscModel/LocalizedText.Designer.cs b/yavscModel/LocalizedText.Designer.cs index 5982ea96..a0aa3781 100644 --- a/yavscModel/LocalizedText.Designer.cs +++ b/yavscModel/LocalizedText.Designer.cs @@ -70,6 +70,12 @@ namespace Yavsc.Model { } } + public static string My_Estimates { + get { + return ResourceManager.GetString("My_Estimates", resourceCulture); + } + } + public static string UserName { get { return ResourceManager.GetString("UserName", resourceCulture); diff --git a/yavscModel/LocalizedText.fr.resx b/yavscModel/LocalizedText.fr.resx index e96a510e..7e329027 100644 --- a/yavscModel/LocalizedText.fr.resx +++ b/yavscModel/LocalizedText.fr.resx @@ -47,4 +47,5 @@ Rôle créé Article ajouté au panier Devis non trouvé + Mes estimations diff --git a/yavscModel/LocalizedText.resx b/yavscModel/LocalizedText.resx index ede55f56..c0bd19d7 100644 --- a/yavscModel/LocalizedText.resx +++ b/yavscModel/LocalizedText.resx @@ -49,4 +49,5 @@ Estimate not found This email adress is already used ({0}). This user name is already used ({0}). + My estimates diff --git a/yavscModel/RolesAndMemebers/Profile.cs b/yavscModel/RolesAndMemebers/Profile.cs index a5256e95..f549ff58 100644 --- a/yavscModel/RolesAndMemebers/Profile.cs +++ b/yavscModel/RolesAndMemebers/Profile.cs @@ -168,28 +168,45 @@ namespace Yavsc.Model.RolesAndMembers /// Gets a value indicating whether this instance has bank account. ///
    /// true if this instance has bank account; otherwise, false. - public bool HasBankAccount { get { - return IsBillable - && !string.IsNullOrWhiteSpace (BankCode) - && !string.IsNullOrWhiteSpace (BIC) - && !string.IsNullOrWhiteSpace (IBAN) - && !string.IsNullOrWhiteSpace (WicketCode) - && !string.IsNullOrWhiteSpace (AccountNumber) - && BankedKey != 0; } } + public bool HasBankAccount { + get { + return !( + ( + string.IsNullOrWhiteSpace (BankCode) + || string.IsNullOrWhiteSpace (WicketCode) + || string.IsNullOrWhiteSpace (AccountNumber) + || BankedKey == 0 + ) + && + ( string.IsNullOrWhiteSpace (BIC) + || string.IsNullOrWhiteSpace (IBAN)) + ); } } /// /// Gets a value indicating whether this instance is billable. + /// Returns true when + /// Name is not null and all of + /// Address, CityAndState and ZipCode are not null, + /// or one of Email or Phone or Mobile is not null + /// /// /// true if this instance is billable; otherwise, false. public bool IsBillable { get { + // true if + // Name is not null and + // ( + // (Address and CityAndState and ZipCode) + // or Email or Phone or Mobile + // ) return !string.IsNullOrWhiteSpace (Name) - && !string.IsNullOrWhiteSpace (Address) - && !string.IsNullOrWhiteSpace (CityAndState) - && !string.IsNullOrWhiteSpace (ZipCode) - && !string.IsNullOrWhiteSpace (Email) - && !(string.IsNullOrWhiteSpace (Phone) && - string.IsNullOrWhiteSpace (Mobile)); + && !( ( + string.IsNullOrWhiteSpace (Address) + || string.IsNullOrWhiteSpace (CityAndState) + || string.IsNullOrWhiteSpace (ZipCode)) + && string.IsNullOrWhiteSpace (Email) + && string.IsNullOrWhiteSpace (Phone) + && string.IsNullOrWhiteSpace (Mobile)); } } diff --git a/yavscModel/RolesAndMemebers/RegisterClientModel.cs b/yavscModel/RolesAndMemebers/RegisterClientModel.cs new file mode 100644 index 00000000..3ce4fe1a --- /dev/null +++ b/yavscModel/RolesAndMemebers/RegisterClientModel.cs @@ -0,0 +1,71 @@ +// +// RegisterClientModel.cs +// +// Author: +// Paul Schneider +// +// 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 . + +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace Yavsc.Model.RolesAndMembers +{ + /// + /// Register client model. + /// + public class RegisterClientModel : RegisterModel + { + /// + /// Gets or sets the full name. + /// + /// The full name. + [DisplayName("Nom complet")] + [Required(ErrorMessage="S'il vous plait, saisissez le nom complet")] + public string Name { get; set; } + /// + /// Gets or sets the address. + /// + /// The address. + [DisplayName("Addresse")] + public string Address { get; set; } + /// + /// Gets or sets the state of the city and. + /// + /// The state of the city and. + [DisplayName("Ville")] + public string CityAndState { get; set; } + /// + /// Gets or sets the zip code. + /// + /// The zip code. + [DisplayName("Code postal")] + public string ZipCode { get; set; } + /// + /// Gets or sets the phone. + /// + /// The phone. + [DisplayName("Téléphone fixe")] + public string Phone { get; set; } + /// + /// Gets or sets the mobile. + /// + /// The mobile. + [DisplayName("Téléphone mobile")] + public string Mobile { get; set; } + } +} diff --git a/yavscModel/RolesAndMemebers/RegisterModel.cs b/yavscModel/RolesAndMemebers/RegisterModel.cs index 794e6ae0..2fdc4de2 100644 --- a/yavscModel/RolesAndMemebers/RegisterModel.cs +++ b/yavscModel/RolesAndMemebers/RegisterModel.cs @@ -55,8 +55,15 @@ namespace Yavsc.Model.RolesAndMembers [Required(ErrorMessage = "S'il vous plait, entrez un e-mail valide")] public string Email { get; set; } + /// + /// Gets or sets a value indicating whether this instance is approuved. + /// + /// true if this instance is approuved; otherwise, false. public bool IsApprouved { get; set; } + /// + /// Initializes a new instance of the class. + /// public RegisterModel() { IsApprouved = false; diff --git a/yavscModel/WorkFlow/IContentProvider.cs b/yavscModel/WorkFlow/IContentProvider.cs index 6152b819..68a15511 100644 --- a/yavscModel/WorkFlow/IContentProvider.cs +++ b/yavscModel/WorkFlow/IContentProvider.cs @@ -62,11 +62,19 @@ namespace Yavsc.Model.WorkFlow /// Estimid. Estimate GetEstimate (long estimid); /// - /// Gets the estimates created for a specified client. + /// Gets the estimates created by + /// or for the given user by user name. + /// + /// The estimates. + /// user name. + Estimate [] GetEstimates(string username); + /// + /// Gets the estimates. /// /// The estimates. /// Client. - Estimate [] GetEstimates(string client); + /// Responsible. + Estimate [] GetEstimates(string client, string responsible); /// /// Drops the writting. /// diff --git a/yavscModel/WorkFlow/WorkFlowManager.cs b/yavscModel/WorkFlow/WorkFlowManager.cs index 394bcdbc..22dfb021 100644 --- a/yavscModel/WorkFlow/WorkFlowManager.cs +++ b/yavscModel/WorkFlow/WorkFlowManager.cs @@ -48,15 +48,30 @@ namespace Yavsc.Model.WorkFlow return ContentProvider.GetEstimate (estid); } /// - /// Gets the estimates. + /// Gets the estimates, refering the + /// given client or username . /// /// The estimates. - /// Client. - public Estimate [] GetEstimates (string client) + /// Responsible. + public Estimate [] GetResponsibleEstimates (string responsible) { - return ContentProvider.GetEstimates (client); + return ContentProvider.GetEstimates (null, responsible); } + /// + /// Gets the client estimates. + /// + /// The client estimates. + /// Client. + public Estimate [] GetClientEstimates (string client) + { + return ContentProvider.GetEstimates (client, null); + } + + public Estimate [] GetUserEstimates (string username) + { + return ContentProvider.GetEstimates (username); + } /// /// Gets the stock for a given product reference. /// diff --git a/yavscModel/YavscModel.csproj b/yavscModel/YavscModel.csproj index 4f7a94fa..c6a3c58b 100644 --- a/yavscModel/YavscModel.csproj +++ b/yavscModel/YavscModel.csproj @@ -143,6 +143,7 @@ +