files tree made better.

This commit is contained in:
2019-01-01 16:28:47 +00:00
parent cb96933a25
commit 5b8e9b3975
1633 changed files with 18220 additions and 41869 deletions

View File

@ -0,0 +1,19 @@
using System;
namespace Yavsc.Attributes
{
public class ActivityBillingAttribute : Attribute
{
public string BillingCode { get; private set; }
/// <summary>
/// Identifie une entité de facturation
/// </summary>
/// <param name="billingCode">Code de facturation,
/// Il doit avoir une valeur unique par usage.
/// </param>
public ActivityBillingAttribute(string billingCode) {
BillingCode = billingCode;
}
}
}

View File

@ -0,0 +1,9 @@
using System;
namespace Yavsc.Attributes
{
public class ActivitySettingsAttribute : Attribute
{
}
}

View File

@ -0,0 +1,15 @@
namespace Yavsc.Attributes.Validation
{
public class YaRegularExpression : System.ComponentModel.DataAnnotations.RegularExpressionAttribute {
public YaRegularExpression(string pattern): base (pattern)
{
this.ErrorMessage = pattern;
}
public override string FormatErrorMessage(string name)
{
return ResourcesHelpers.GlobalLocalizer[this.ErrorMessageResourceName];
}
}
}

View File

@ -0,0 +1,37 @@
using System;
namespace Yavsc.Attributes.Validation
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class YaRequiredAttribute : YaValidationAttribute
{
/// <summary>
/// Gets or sets a flag indicating whether the attribute should allow empty strings.
/// </summary>
public bool AllowEmptyStrings { get; set; }
public YaRequiredAttribute (string msg) : base()
{
ErrorMessage = msg;
}
public YaRequiredAttribute ()
{
this.ErrorMessage = ResourcesHelpers.GlobalLocalizer["RequiredField"];
}
public override bool IsValid(object value) {
if (value == null) {
return false;
}
// only check string length if empty strings are not allowed
var stringValue = value as string;
if (stringValue != null && !AllowEmptyStrings) {
return stringValue.Trim().Length != 0;
}
return true;
}
}
}

View File

@ -0,0 +1,58 @@
namespace Yavsc.Attributes.Validation
{
public class YaStringLength: YaValidationAttribute
{
public long MinLen { get; set; } = -1;
private long maxLen;
public YaStringLength(long maxLen) : base(
()=>string.Format(
ResourcesHelpers.GlobalLocalizer["BadStringLength"],
maxLen))
{
this.maxLen = maxLen;
}
private long excedent;
private long manquant;
public override bool IsValid(object value) {
if (value == null) {
return false;
}
string stringValue = value as string;
if (stringValue==null) return false;
if (MinLen>=0)
{
if (stringValue.Length<MinLen)
{
manquant = MinLen-stringValue.Length;
}
return false;
}
if (maxLen>=0)
{
if (stringValue.Length>maxLen) {
excedent = stringValue.Length-maxLen;
return false;
}
}
return true;
}
public override string FormatErrorMessage(string name)
{
if (MinLen<0) {
// DetailledMaxStringLength
return string.Format(
ResourcesHelpers.GlobalLocalizer["DetailledMaxStringLength"],
maxLen,
excedent);
} else
return string.Format(
ResourcesHelpers.GlobalLocalizer["DetailledMinMaxStringLength"],
MinLen,
maxLen,
manquant,
excedent);
}
}
}

View File

@ -0,0 +1,22 @@
using System;
namespace Yavsc.Attributes.Validation
{
public class YaValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
{
public YaValidationAttribute() : base(()=> ResourcesHelpers.GlobalLocalizer["validationError"])
{
}
public YaValidationAttribute(Func<string> acr): base(acr)
{
}
public override string FormatErrorMessage(string name)
{
return ResourcesHelpers.GlobalLocalizer[name];
}
}
}

View File

@ -0,0 +1,56 @@
namespace Yavsc
{
using Yavsc.Models.Auth;
public static class Constants
{
public const string ApplicationName = "Yavsc",
CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company",
UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9._-]*$",
AuthorizePath = "~/authorize",
TokenPath = "~/token",
LoginPath = "~/signin",
LogoutPath = "~/signout", UserInfoPath = "~/api/me",
ApplicationAuthenticationSheme = "ServerCookie",
ExternalAuthenticationSheme= "ExternalCookie",
CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}",
DefaultFactor = "Default",
MobileAppFactor = "Mobile Application",
EMailFactor = "Email",
SMSFactor = "SMS",
AdminGroupName = "Administrator",
PerformerGroupName = "Performer",
StarGroupName = "Star",
StarHunterGroupName = "StarHunter",
BlogModeratorGroupName = "Moderator",
FrontOfficeGroupName = "FrontOffice",
GCMNotificationUrl = "https://gcm-http.googleapis.com/gcm/send",
UserFilesPath = "/files",
AvatarsPath = "/avatars",
GitPath = "/sources",
DefaultAvatar = "/images/Users/icon_user.png",
AnonAvatar = "/images/Users/icon_anon_user.png",
YavscConnectionStringEnvName = "YAVSC_DB_CONNECTION";
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"},  
new Scope { Id = "blog" , Description ="Your blogging interface"},  
new Scope { Id = "estimate" , Description ="Your estimation interface"},  
new Scope { Id = "contract" , Description ="Your contract signature access"}, 
new Scope { Id = "admin" , Description ="Your administration rights on this site"}, 
new Scope { Id = "moderation" , Description ="Your moderator interface"}, 
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" };
public static readonly string NoneCode = "none";
}
}

View File

@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Yavsc.Abstract.FileSystem;
using Yavsc.Billing;
using Yavsc.Models.Billing;
using Yavsc.Services;
namespace Yavsc.Helpers
{
public static class BillingHelpers
{
public static decimal Addition(this List<IBillItem> items) => items.Aggregate<IBillItem, decimal>(0m, (t, l) => t + l.Count * l.UnitaryCost);
public static decimal Addition(this List<CommandLine> items) => items.Select(i=>((IBillItem)i)).ToList().Addition();
public static string GetBillText(this IBillable query) {
string total = query.GetBillItems().Addition().ToString("C", CultureInfo.CurrentUICulture);
string bill = string.Join("\n", query.GetBillItems().Select(l=> $"{l.Name} {l.Description} : {l.UnitaryCost} € " + ((l.Count != 1) ? "*"+l.Count.ToString() : ""))) +
$"\n\nTotal: {total}";
return bill;
}
public static FileInfo GetBillInfo(this IBillable bill, IBillingService service)
{
var suffix = bill.GetIsAcquitted() ? "-ack":null;
var filename = bill.GetFileBaseName(service)+".pdf";
return new FileInfo(Path.Combine(AbstractFileSystemHelpers.UserBillsDirName, filename));
}
}
}

View File

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Yavsc.Server.Model;
namespace Yavsc.Server.Helpers
{
/// <summary>
/// Thanks to Stefan @ Stackoverflow
/// </summary>
public class RequestHelper
{
string WRPostMultipart(string url, Dictionary<string, object> parameters, string authorizationHeader = null)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
if (authorizationHeader != null)
request.Headers["Authorization"] = authorizationHeader;
if (parameters != null && parameters.Count > 0)
{
using (Stream requestStream = request.GetRequestStream())
{
using (WebResponse response = request.GetResponse())
{
foreach (KeyValuePair<string, object> pair in parameters)
{
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
if (pair.Value is FormFile)
{
FormFile file = pair.Value as FormFile;
string header = "Content-Disposition: form-data; name=\"" + pair.Key + "\"; filename=\"" + file.Name + "\"\r\nContent-Type: " + file.ContentType + "\r\n\r\n";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(header);
requestStream.Write(bytes, 0, bytes.Length);
byte[] buffer = new byte[32768];
int bytesRead;
if (file.Stream == null)
{
// upload from file
using (FileStream fileStream = File.OpenRead(file.FilePath))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
fileStream.Close();
}
}
else
{
// upload from given stream
while ((bytesRead = file.Stream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
}
}
else
{
string data = "Content-Disposition: form-data; name=\"" + pair.Key + "\"\r\n\r\n" + pair.Value;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);
requestStream.Write(bytes, 0, bytes.Length);
}
}
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
requestStream.Write(trailer, 0, trailer.Length);
requestStream.Close();
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
return reader.ReadToEnd();
}
} // end WebResponse response
} // end using requestStream
}
else throw new ArgumentOutOfRangeException("no parameter found ");
}
public static async Task<string> PostMultipart(string url, FormFile[] formFiles, string access_token = null)
{
if (formFiles != null && formFiles.Length > 0)
{
var client = new HttpClient();
var formData = new MultipartFormDataContent();
if (access_token != null)
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
foreach (var formFile in formFiles)
{
HttpContent fileStreamContent = new StreamContent(formFile.Stream);
if (formFile.ContentType!=null)
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(formFile.ContentType);
else fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// fileStreamContent.Headers.ContentDisposition = formFile.ContentDisposition!=null? new ContentDispositionHeaderValue(
// formFile.ContentDisposition) : new ContentDispositionHeaderValue("form-data; name=\"file\"; filename=\"" + formFile.Name + "\"");
fileStreamContent.Headers.Add("Content-Disposition", formFile.ContentDisposition);
fileStreamContent.Headers.Add("Content-Length", formFile.Stream.Length.ToString());
//fileStreamContent.Headers.Add("FilePath", formFile.FilePath);
formData.Add(fileStreamContent, "file", formFile.Name);
}
var response = client.PostAsync(url, formData).Result;
if (!response.IsSuccessStatusCode)
{
return null;
}
return await response.Content.ReadAsStringAsync();
} // end if formFiles != null
return null;
}
}
}

View File

@ -0,0 +1,6 @@
using Microsoft.Extensions.Localization;
public static class ResourcesHelpers {
public static IStringLocalizer GlobalLocalizer = null ;
}

View File

@ -0,0 +1,82 @@
//
// PostJson.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.Net;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System;
namespace Yavsc.Server.Helpers
{
/// <summary>
/// Simple json post method.
/// </summary>
public class SimpleJsonPostMethod : IDisposable
{
private HttpWebRequest request=null;
/// <summary>
/// Initializes a new instance of the Yavsc.Helpers.SimpleJsonPostMethod class.
/// </summary>
/// <param name="pathToMethod">Path to method.</param>
public SimpleJsonPostMethod (string pathToMethod, string authorizationHeader = null, string method = "POST")
{
request = (HttpWebRequest) WebRequest.Create (pathToMethod);
request.Method = method;
request.Accept = "application/json";
request.ContentType = "application/json";
request.SendChunked = true;
request.TransferEncoding = "UTF-8";
if (authorizationHeader!=null)
request.Headers["Authorization"]=authorizationHeader;
}
public void Dispose()
{
request.Abort();
}
/// <summary>
/// Invoke the specified query.
/// </summary>
/// <param name="query">Query.</param>
public async Task<TAnswer> Invoke<TAnswer>(object query)
{
using (Stream streamQuery = await request.GetRequestStreamAsync()) {
using (StreamWriter writer = new StreamWriter(streamQuery)) {
writer.Write (JsonConvert.SerializeObject(query));
}}
TAnswer ans = default (TAnswer);
using (WebResponse response = await request.GetResponseAsync ()) {
using (Stream responseStream = response.GetResponseStream ()) {
using (StreamReader rdr = new StreamReader (responseStream)) {
ans = (TAnswer) JsonConvert.DeserializeObject<TAnswer> (rdr.ReadToEnd ());
}
}
response.Close();
}
return ans;
}
}
}

View File

@ -0,0 +1,43 @@
//
// ICalendarManager.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// Copyright (c) 2015 GNU GPL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using Google.Apis.Calendar.v3.Data;
namespace Yavsc.Services
{
using System.Threading.Tasks;
using Yavsc.ViewModels.Calendar;
/// <summary>
/// I calendar manager.
/// </summary>
public interface ICalendarManager {
Task<CalendarList> GetCalendarsAsync (string userId, string pageToken);
Task<Events> GetCalendarAsync (string calid, DateTime minDate, DateTime maxDate, string pageToken);
Task<DateTimeChooserViewModel> CreateViewModelAsync(
string inputId,
string calid, DateTime mindate, DateTime maxdate);
Task<Event> CreateEventAsync(string userId, string calid,
DateTime startDate, int lengthInSeconds, string summary,
string description, string location, bool available);
}
}

View File

@ -0,0 +1,53 @@
// FreeDate.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Free date.
/// </summary>
public interface IFreeDateSet
{
/// <summary>
/// Gets or sets the reference.
/// </summary>
/// <value>The reference.</value>
IEnumerable<Period> Values { get; set; }
/// <summary>
/// Gets or sets the duration.
/// </summary>
/// <value>The duration.</value>
TimeSpan Duration { get; set; }
/// <summary>
/// Gets or sets the attendees.
/// </summary>
/// <value>The attendees.</value>
string UserName { get; set; }
/// <summary>
/// Gets or sets the location.
/// </summary>
/// <value>The location.</value>
string Location { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Yavsc.Interfaces.Workflow;
using Yavsc.Models.Google.Messaging;
using Yavsc.Models.Haircut;
using Yavsc.Models.Messaging;
namespace Yavsc.Services
{
public interface IGoogleCloudMessageSender
{
Task<MessageWithPayloadResponse> NotifyBookQueryAsync(
IEnumerable<string> registrationId,
RdvQueryEvent ev);
Task<MessageWithPayloadResponse> NotifyEstimateAsync(
IEnumerable<string> registrationId,
EstimationEvent ev);
Task<MessageWithPayloadResponse> NotifyHairCutQueryAsync(
IEnumerable<string> registrationId,
HairCutQueryEvent ev);
Task<MessageWithPayloadResponse> NotifyAsync(
IEnumerable<string> regids,
IEvent yaev);
}
}

View File

@ -0,0 +1,34 @@
//
// IScheduledEvent.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc.Models.Calendar
{
public interface IScheduledEvent
{
/// <summary>
/// Gets or sets the period.
/// </summary>
/// <value>The period.</value>
Periodicity Reccurence { get; set; }
Period Period { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace Yavsc.Services
{
public interface ISmsSender
{
Task SendSmsAsync(TwilioSettings settings, string number, string message);
}
}

View File

@ -0,0 +1,7 @@
namespace Yavsc.Server
{
public interface ITranslator
{
string[] Translate (string slang, string dlang, string[] text);
}
}

15
src/Yavsc.Server/Makefile Normal file
View File

@ -0,0 +1,15 @@
SOURCE_DIR=$(HOME)/workspace/yavsc
MAKEFILE_DIR=$(SOURCE_DIR)/scripts/build/make
include $(MAKEFILE_DIR)/versioning.mk
include $(MAKEFILE_DIR)/dnx.mk
all: $(BINTARGETPATH)
$(BINTARGETPATH): ../OAuth.AspNet.AuthServer/bin/$(CONFIGURATION)/OAuth.AspNet.AuthServer.dll ../Yavsc.Abstract/bin/$(CONFIGURATION)/Yavsc.Abstract.dll
../OAuth.AspNet.AuthServer/bin/$(CONFIGURATION)/OAuth.AspNet.AuthServer.dll:
make -C ../OAuth.AspNet.AuthServer
../Yavsc.Abstract/bin/$(CONFIGURATION)/Yavsc.Abstract.dll:
make -C ../Yavsc.Abstract

View File

@ -0,0 +1,34 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Access
{
using Yavsc;
public class Ban : IBaseTrackedEntity
{
public DateTime DateCreated
{
get; set;
}
public DateTime DateModified
{
get; set;
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string UserCreated
{
get; set;
}
public string UserModified
{
get; set;
}
}
}

View File

@ -0,0 +1,18 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Access
{
public class BanByEmail
{
[Required]
public long BanId { get; set; }
[ForeignKey("BanId")]
public virtual Ban UserBan { get; set; }
[Required]
public string email { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Yavsc.Models.Access
{
public class BlackListed: IBlackListed
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public string OwnerId { get; set; }
[ForeignKey("OwnerId"),JsonIgnore]
public virtual ApplicationUser Owner { get; set; }
}
}

View File

@ -0,0 +1,23 @@
namespace Yavsc.Models.Access
{
using System.ComponentModel.DataAnnotations.Schema;
using Models.Relationship;
using Newtonsoft.Json;
using Blog;
using Yavsc.Abstract.Identity.Security;
public class CircleAuthorizationToBlogPost : ICircleAuthorization
{
public long CircleId { get; set; }
public long BlogPostId { get; set; }
[JsonIgnore]
[ForeignKey("BlogPostId")]
public virtual BlogPost Target { get; set; }
[JsonIgnore]
[ForeignKey("CircleId")]
public virtual Circle Allowed { get; set; }
}
}

View File

@ -0,0 +1,50 @@
//
// Publishing.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc.Models.Access
{
/// <summary>
/// Publishing.
/// </summary>
public enum Publishing {
/// <summary>
/// In the context of immediate use, with no related stored content.
/// </summary>
None,
/// <summary>
/// In the context of private use of an uploaded content.
/// </summary>
Private,
/// <summary>
/// In the context of restricted access areas, like circle members views.
/// </summary>
Restricted,
/// <summary>
/// Publishing a content in a public access area.
/// </summary>
Public
}
}

View File

@ -0,0 +1,8 @@
namespace Yavsc.Models.Access
{
public class WhiteCard {
}
}

View File

@ -0,0 +1,105 @@
using System.Collections.Generic;
using Microsoft.AspNet.Identity.EntityFramework;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models
{
using Models.Relationship;
using Models.Identity;
using Models.Chat;
using Models.Bank;
using Models.Access;
using Newtonsoft.Json;
public class ApplicationUser : IdentityUser
{
/// <summary>
/// Another me, as a byte array.
/// This value points a picture that may be used
/// to present the user
/// </summary>
/// <returns>the path to an user's image, relative to it's user dir<summary>
/// <see>Startup.UserFilesOptions</see>
/// </summary>
/// <returns></returns>
[MaxLength(512)]
public string Avatar { get; set; }
[MaxLength(512)]
public string FullName { get; set; }
/// <summary>
/// WIP Paypal
/// </summary>
/// <returns></returns>
[Display(Name="Account balance")]
public virtual AccountBalance AccountBalance { get; set; }
/// <summary>
/// User's posts
/// </summary>
/// <returns></returns>
[InverseProperty("Author"),JsonIgnore]
public virtual List<Blog.BlogPost> Posts { get; set; }
/// <summary>
/// User's contact list
/// </summary>
/// <returns></returns>
[InverseProperty("Owner"),JsonIgnore]
public virtual List<Contact> Book { get; set; }
/// <summary>
/// External devices using the API
/// </summary>
/// <returns></returns>
[InverseProperty("DeviceOwner"),JsonIgnore]
public virtual List<GoogleCloudMobileDeclaration> Devices { get; set; }
[InverseProperty("Owner"),JsonIgnore]
public virtual List<ChatConnection> Connections { get; set; }
/// <summary>
/// User's circles
/// </summary>
/// <returns></returns>
[InverseProperty("Owner"),JsonIgnore]
public virtual List<Circle> Circles { get; set; }
/// <summary>
/// Billing postal address
/// </summary>
/// <returns></returns>
[ForeignKeyAttribute("PostalAddressId")]
public virtual Location PostalAddress { get; set; }
public long? PostalAddressId { get; set; }
/// <summary>
/// User's Google calendar
/// </summary>
/// <returns></returns>
[MaxLength(512)]
public string DedicatedGoogleCalendar { get; set; }
public override string ToString() {
return this.Id+" "+this.AccountBalance?.Credits.ToString()+this.Email+" "+this.UserName+" $"+this.AccountBalance?.Credits.ToString();
}
public BankIdentity BankInfo { get; set; }
public long DiskQuota { get; set; } = 512*1024*1024;
public long DiskUsage { get; set; } = 0;
public long MaxFileSize { get; set; } = 512*1024*1024;
[JsonIgnore][InverseProperty("Owner")]
public virtual List<BlackListed> BlackList { get; set; }
public bool AllowMonthlyEmail { get; set; } = false;
}
}

View File

@ -0,0 +1,10 @@
namespace Yavsc.Models.Auth
{
public enum ApplicationTypes: int
{
JavaScript = 0,
NativeConfidential = 1
};
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Auth
{
public class Client
{
[Key]
public string Id { get; set; }
public string DisplayName { get; set; }
public string RedirectUri { get; set; }
[MaxLength(100)]
public string LogoutRedirectUri { get; set; }
public string Secret { get; set; }
public ApplicationTypes Type { get; set; }
public bool Active { get; set; }
public int RefreshTokenLifeTime { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Auth {
public class ExternalLoginViewModel
{
public string Name { get; set; }
public string Url { get; set; }
public string State { get; set; }
}
public class RegisterExternalBindingModel
{
[Required]
public string UserName { get; set; }
[Required]
public string Provider { get; set; }
[Required]
public string ExternalAccessToken { get; set; }
}
public class ParsedExternalAccessToken
{
public string user_id { get; set; }
public string app_id { get; set; }
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Auth
{
/// <summary>
/// OffLine OAuth2 Token
/// To use against a third party Api
/// </summary>
public partial class OAuth2Tokens
{
/// <summary>
/// Unique identifier, equals the user email from OAuth provider
/// </summary>
/// <returns></returns>
[Key]
public string UserId { get; set; }
/// <summary>
/// Expiration date &amp; time
/// </summary>
/// <returns></returns>
public DateTime Expiration { get; set; }
/// <summary>
/// Expiration time span in seconds
/// </summary>
/// <returns></returns>
public string ExpiresIn { get; set; }
/// <summary>
/// Should always be <c>Bearer</c> ...
/// </summary>
/// <returns></returns>
public string TokenType { get; set; }
/// <summary>
/// The Access Token!
/// </summary>
/// <returns></returns>
public string AccessToken { get; set; }
/// <summary>
/// The refresh token
/// </summary>
/// <returns></returns>
public string RefreshToken { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Auth
{
public class RefreshToken
{
[Key]
public string Id { get; set; }
[Required]
[MaxLength(50)]
public string Subject { get; set; }
[Required]
[MaxLength(50)]
public string ClientId { get; set; }
public DateTime IssuedUtc { get; set; }
public DateTime ExpiresUtc { get; set; }
[Required]
public string ProtectedTicket { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Auth {
public class Scope {
[Key]
public string Id { get; set; }
public string Description { get; set; }
}
}

View File

@ -0,0 +1,20 @@
namespace Yavsc.Models.Auth {
public class UserCredential {
public string UserId { get; set; }
public OAuth2Tokens Tokens { get; set; }
public UserCredential(string userId, OAuth2Tokens tokens)
{
UserId = userId;
Tokens = tokens;
}
public string GetHeader()
{
return Tokens.TokenType+" "+Tokens.AccessToken;
}
}
}

View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models
{
using Yavsc;
public partial class AccountBalance: IAccountBalance {
[Key]
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser Owner { get; set; }
[Required,Display(Name="Credits en €")]
public decimal Credits { get; set; }
public long ContactCredits { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models
{
public partial class BalanceImpact {
[Required,Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required,Display(Name="Impact")]
public decimal Impact { get; set; }
[Required,Display(Name="Execution date")]
public DateTime ExecDate { get; set; }
[Required,Display(Name="Reason")]
public string Reason { get; set; }
[Required]
public string BalanceId { get; set; }
[ForeignKey("BalanceId")]
public virtual AccountBalance Balance { get; set; }
}
}

View File

@ -0,0 +1,63 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Bank
{
public class BankIdentity
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
/// <summary>
/// Gets or sets the BI.
/// </summary>
/// <value>The BI.</value>
[DisplayName("Code BIC")]
[StringLength(15)]
public string BIC { get; set; }
/// <summary>
/// Gets or sets the IBA.
/// </summary>
/// <value>The IBA.</value>
[DisplayName("Code IBAN")]
[StringLength(33)]
public string IBAN { get; set; }
/// <summary>
/// Gets or sets the bank code.
/// </summary>
/// <value>The bank code.</value>
[DisplayName("Code Banque")]
[StringLength(5)]
public string BankCode { get; set; }
/// <summary>
/// Gets or sets the wicket code.
/// </summary>
/// <value>The wicket code.</value>
[DisplayName("Code Guichet")]
[StringLength(5)]
public string WicketCode { get; set; }
/// <summary>
/// Gets or sets the account number.
/// </summary>
/// <value>The account number.</value>
[DisplayName("Numéro de compte")]
[StringLength(15)]
public string AccountNumber { get; set; }
/// <summary>
/// Gets or sets the banked key.
/// </summary>
/// <value>The banked key.</value>
[DisplayName("Clé RIB")]
public int BankedKey { get; set; }
}
}

View File

@ -0,0 +1,48 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Yavsc.Models.Billing
{
using Yavsc.Billing;
public class CommandLine : ICommandLine {
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required,MaxLength(256)]
public string Name { get; set; }
[Required,MaxLength(512)]
public string Description { get; set; }
[Display(Name="Nombre")]
public int Count { get; set; } = 1;
[DisplayFormat(DataFormatString="{0:C}")]
public decimal UnitaryCost { get; set; }
public long EstimateId { get; set; }
[JsonIgnore,NotMapped,ForeignKey("EstimateId")]
virtual public Estimate Estimate { get; set; }
public string Currency
{
get;
set;
} = "EUR";
[NotMapped]
public string Reference {
get {
return "CL/"+this.Id;
}
}
}
}

View File

@ -0,0 +1,10 @@
using Yavsc.Models.Market;
namespace Yavsc.Models.Billing
{
public class ServiceContract<P> where P : Service
{
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Yavsc.Models.Billing
{
using Models.Workflow;
using Newtonsoft.Json;
public partial class Estimate : IEstimate
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public long? CommandId { get; set; }
/// <summary>
/// A command is not required to create
/// an estimate,
/// it will result in a new estimate template
/// </summary>
/// <returns></returns>
[ForeignKey("CommandId"),JsonIgnore]
public RdvQuery Query { get; set; }
public string Description { get; set; }
public string Title { get; set; }
[InverseProperty("Estimate")]
public virtual List<CommandLine> Bill { get; set; }
/// <summary>
/// List of attached graphic files
/// to this estimate, as relative pathes to
/// the command performer's root path.
/// In db, they are separated by <c>:</c>
/// </summary>
/// <returns></returns>
[NotMapped]
public List<string> AttachedGraphics { get; set; }
public string AttachedGraphicsString
{
get { return string.Join(":", AttachedGraphics); }
set { AttachedGraphics = value.Split(':').ToList(); }
}
/// <summary>
/// List of attached files
/// to this estimate, as relative pathes to
/// the command performer's root path.
/// In db, they are separated by <c>:</c>
/// </summary>
/// <returns></returns>
[NotMapped]
public List<string> AttachedFiles { get; set; }
public string AttachedFilesString
{
get { return string.Join(":", AttachedFiles); }
set { AttachedFiles = value.Split(':').ToList(); }
}
public string OwnerId { get; set; }
[ForeignKey("OwnerId"),JsonIgnore]
public virtual PerformerProfile Owner { get; set; }
[Required]
public string ClientId { get; set; }
[ForeignKey("ClientId"),JsonIgnore]
public virtual ApplicationUser Client { get; set; }
[Required]
public string CommandType
{
get; set;
}
public DateTime ProviderValidationDate { get; set; }
public DateTime ClientValidationDate { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Billing
{
public partial class EstimateTemplate
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string Description { get; set; }
public string Title { get; set; }
public List<CommandLine> Bill { get; set; }
[Required]
public string OwnerId { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Billing
{
public class ExceptionSIREN {
[Key,MinLength(9)]
public string SIREN { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using Yavsc.Billing;
namespace Yavsc.Models.Billing   {
public class FixedImpacter : IBillingImpacter
{
public decimal ImpactedValue { get; set; }
public FixedImpacter (decimal impact)
{
ImpactedValue = impact;
}
public decimal Impact(decimal orgValue)
{
return orgValue + ImpactedValue;
}
}
}

View File

@ -0,0 +1,107 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Billing
{
using Newtonsoft.Json;
using Workflow;
using Yavsc.Models.Payment;
using Yavsc;
using Yavsc.Billing;
using Yavsc.Abstract.Workflow;
using Yavsc.Services;
public abstract class NominativeServiceCommand : IBaseTrackedEntity, IDecidableQuery, IIdentified<long>
{
public string GetInvoiceId() { return GetType().Name + "/" + Id; }
public abstract long Id { get; set; }
public abstract string Description { get; set; }
[Required()]
public bool Consent { get; set; }
public DateTime DateCreated
{
get; set;
}
public DateTime DateModified
{
get; set;
}
public string UserCreated
{
get; set;
}
public string UserModified
{
get; set;
}
[DisplayAttribute(Name="Status de la requête")]
public QueryStatus Status { get; set; }
[Required]
public string ClientId { get; set; }
/// <summary>
/// The client
/// </summary>
[ForeignKey("ClientId"),Display(Name="Client")]
public ApplicationUser Client { get; set; }
[Required]
public string PerformerId { get; set; }
/// <summary>
/// The performer identifier
/// </summary>
[ForeignKey("PerformerId"),Display(Name="Préstataire")]
public PerformerProfile PerformerProfile { get; set; }
public DateTime? ValidationDate {get; set;}
[Display(Name="Previsional")]
public decimal? Previsional { get; set; }
/// <summary>
/// The bill
/// </summary>
/// <returns></returns>
[Required]
public string ActivityCode { get; set; }
[ForeignKey("ActivityCode"),JsonIgnore,Display(Name="Domaine d'activité")]
public virtual Activity Context  { get; set ; }
public bool Rejected { get; set; }
public DateTime RejectedAt { get; set; }
public abstract System.Collections.Generic.List<IBillItem> GetBillItems();
public bool GetIsAcquitted()
{
return Regularisation?.IsOk() ?? false;
}
public string GetFileBaseName(IBillingService billingService)
{
string type = GetType().Name;
string ack = GetIsAcquitted() ? "-ack" : null;
var bcode = billingService.BillingMap[type];
return $"facture-{bcode}-{Id}{ack}";
}
[Display(Name = "PaymentId")]
public string PaymentId { get; set; }
[ForeignKey("PaymentId"), Display(Name = "Acquittement de la facture")]
public virtual PayPalPayment Regularisation { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using Yavsc.Billing;
namespace Yavsc.Models.Billing   {
public class ProportionalImpacter : IBillingImpacter
{
public decimal K { get; set; }
public decimal Impact(decimal orgValue)
{
return orgValue * K;
}
}
}

View File

@ -0,0 +1,33 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Billing;
namespace Yavsc.Models.Billing {
public class ReductionCode : IBillingClause
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public ReductionCode(string descr, decimal impact) {
Description = descr;
impacter = new FixedImpacter(impact);
}
public string Description
{
get;
set;
}
IBillingImpacter impacter;
public IBillingImpacter Impacter
{
get
{
return impacter ;
}
private set {
impacter = value;
}
}
}
}

View File

@ -0,0 +1,5 @@
class ChatBilling { 
}

View File

@ -0,0 +1,14 @@
using System;
namespace Yavsc.Models.Billing
{
public partial class histoestim
{
public long _id { get; set; }
public string applicationname { get; set; }
public DateTime datechange { get; set; }
public long estid { get; set; }
public int? status { get; set; }
public string username { get; set; }
}
}

View File

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Newtonsoft.Json;
using Yavsc.Abstract.Identity.Security;
using Yavsc.Interfaces;
using Yavsc.Models.Access;
using Yavsc.Models.Relationship;
namespace Yavsc.Models.Blog
{
public class BlogPost : IBlogPost, ICircleAuthorized, ITaggable<long>, IIdentified<long>
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Display(Name="Identifiant du post")]
public long Id { get; set; }
[Display(Name="Contenu")][StringLength(56224)]
public string Content { get; set; }
[Display(Name="Photo")][StringLength(1024)]
public string Photo { get; set; }
[StringLength(8)]
public string Lang { get; set; }
[Display(Name="Indice de qualité")]
public int Rate { get; set; }
[Display(Name="Titre")][StringLength(1024)]
public string Title { get; set; }
[Display(Name="Identifiant de l'auteur")]
public string AuthorId { get; set; }
[Display(Name="Auteur")]
[ForeignKey("AuthorId"),JsonIgnore]
public ApplicationUser Author { set; get; }
[Display(Name="Visible")]
public bool Visible { get; set; }
[Display(Name="Date de création")]
public DateTime DateCreated
{
get; set;
}
[Display(Name="Créateur")]
public string UserCreated
{
get; set;
}
[Display(Name="Dernière modification")]
public DateTime DateModified
{
get; set;
}
[Display(Name="Utilisateur ayant modifé le dernier")]
public string UserModified
{
get; set;
}
[InverseProperty("Target")]
[Display(Name="Liste de contrôle d'accès")]
public virtual List<CircleAuthorizationToBlogPost> ACL { get; set; }
public bool AuthorizeCircle(long circleId)
{
return ACL?.Any( i=>i.CircleId == circleId) ?? true;
}
public string GetOwnerId()
{
return AuthorId;
}
public ICircleAuthorization[] GetACL()
{
return ACL.ToArray();
}
public void Tag(Tag tag)
{
var existent = Tags.SingleOrDefault(t => t.PostId == Id && t.TagId == tag.Id);
if (existent==null) Tags.Add(new BlogTag { PostId = Id, Tag = tag } );
}
public void Detag(Tag tag)
{
var existent = Tags.SingleOrDefault(t => (( t.TagId == tag.Id) && t.PostId == Id));
if (existent!=null) Tags.Remove(existent);
}
public string[] GetTags()
{
return Tags.Select(t=>t.Tag.Name).ToArray();
}
[InverseProperty("Post")]
public virtual List<BlogTag> Tags { get; set; }
[InverseProperty("Post")]
public virtual List<Comment> Comments { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Relationship;
namespace Yavsc.Models.Blog
{
public partial class BlogTag
{
[ForeignKey("PostId")]
public virtual BlogPost Post { get; set; }
public long PostId { get; set; }
[ForeignKey("TagId")]
public virtual Tag Tag{ get; set; }
public long TagId { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using Yavsc.Models;
namespace Yavsc.Server.Models.Blog
{
public class BlogTrad
{
[Required]
public long PostId { get; set; }
[Required]
public string Lang { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string TraducerId { get; set; }
[ForeignKey("TraducerId"),JsonIgnore]
public ApplicationUser Traducer { set; get; }
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using Yavsc.Attributes.Validation;
using Yavsc.Interfaces;
namespace Yavsc.Models.Blog
{
public class Comment : IComment<long>, IBaseTrackedEntity
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[YaStringLength(1024)]
public string Content { get; set; }
[ForeignKeyAttribute("PostId")][JsonIgnore]
public virtual BlogPost Post { get; set; }
[Required]
public long PostId { get; set; }
public bool Visible { get; set; }
[ForeignKeyAttribute("AuthorId")][JsonIgnore]
public virtual ApplicationUser Author {
get; set;
}
[Required]
public string AuthorId
{
get; set;
}
public string UserCreated
{
get; set;
}
public DateTime DateModified
{
get; set;
}
public string UserModified
{
get; set;
}
public DateTime DateCreated
{
get; set;
}
public long GetReceiverId()
{
return PostId;
}
public void SetReceiverId(long rid)
{
PostId = rid;
}
public long? ParentId { get; set; }
[ForeignKeyAttribute("ParentId")]
public virtual Comment Parent { get; set; }
[InversePropertyAttribute("Parent")]
public virtual List<Comment> Children { get; set; }
}
}

View File

@ -0,0 +1,52 @@
//
// Period.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Hollydays.
/// </summary>
public class Period {
/// <summary>
/// Gets or sets the start.
/// </summary>
/// <value>The start.</value>
[Required,Display(Name="Début")]
public DateTime Start { get; set; }
/// <summary>
/// Gets or sets the end.
/// </summary>
/// <value>The end.</value>
[Required,Display(Name="Fin")]
public DateTime End { get; set; }
public static Period operator ^ (Period foo, Period bar) {
var min = ( DateTime.Compare(foo.Start, bar.Start) > 0 ) ? foo.Start : bar.Start;
var max = ( DateTime.Compare(bar.End, foo.End) > 0 ) ? foo.End : bar.End;
if (DateTime.Compare(max, min)>0) return new Period { Start = min, End = max };
return null;
}
}
}

View File

@ -0,0 +1,59 @@
//
// Periodicity.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Periodicity.
/// </summary>
public enum Periodicity {
/// <summary>
/// On Demand.
/// </summary>
OnDemand=-1,
/// <summary>
/// The daily.
/// </summary>
Daily,
/// <summary>
/// The weekly.
/// </summary>
Weekly,
/// <summary>
/// The monthly.
/// </summary>
Monthly,
/// <summary>
/// The three m.
/// </summary>
ThreeM,
/// <summary>
/// The six m.
/// </summary>
SixM,
/// <summary>
/// The yearly.
/// </summary>
Yearly
}
}

View File

@ -0,0 +1,41 @@
//
// PositionAndKeyphrase.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc.Models.Calendar
{
using Models.Relationship;
/// <summary>
/// Position and keyphrase.
/// </summary>
public class PositionAndKeyphrase {
/// <summary>
/// The phrase.
/// </summary>
public string phrase;
/// <summary>
/// The position.
/// </summary>
public Position pos;
}
}

View File

@ -0,0 +1,45 @@
//
// ProvidedEvent.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
using Yavsc.Models.Messaging;
using Yavsc.Models.Access;
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Provided event.
/// </summary>
public class ProvidedEvent : BaseEvent {
/// <summary>
/// The privacy.
/// </summary>
[Required]
public Publishing Privacy;
public override string CreateBody()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -0,0 +1,64 @@
//
// Schedule.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Calendar.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Le calendrier, l'emploi du temps.
/// </summary>
public class Schedule {
[Key,Required]
public string OwnerId { get; set; }
[ForeignKey("OwnerId")]
[Display(Name="Professionnel")]
public virtual ApplicationUser Owner { get ; set; }
public ScheduledEvent [] Events { get ; set; }
}
}

View File

@ -0,0 +1,45 @@
//
// ScheduledEvent.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Calendar
{
public class ScheduledEvent : IScheduledEvent
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public Period Period
{
get;
set;
}
public Periodicity Reccurence
{
get;
set;
}
}
}

View File

@ -0,0 +1,58 @@
//
// WeekDay.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc.Models.Calendar
{
/// <summary>
/// Week day.
/// </summary>
public enum WeekDay:int {
/// <summary>
/// The monday (0).
/// </summary>
Monday=0,
/// <summary>
/// The tuesday.
/// </summary>
Tuesday,
/// <summary>
/// The wednesday.
/// </summary>
Wednesday,
/// <summary>
/// The thursday.
/// </summary>
Thursday,
/// <summary>
/// The friday.
/// </summary>
Friday,
/// <summary>
/// The saturday.
/// </summary>
Saturday,
/// <summary>
/// The sunday.
/// </summary>
Sunday
}
}

View File

@ -0,0 +1,50 @@
//
// Connection.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Newtonsoft.Json;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Chat
{
public class ChatConnection : Abstract.Streaming.IChatConnection<ChatRoomPresence>
{
[JsonIgnore,Required]
public string ApplicationUserId { get; set; }
[ForeignKey("ApplicationUserId"),JsonIgnore]
public virtual ApplicationUser Owner { get; set; }
[Key]
public string ConnectionId { get; set; }
public string UserAgent { get; set; }
public bool Connected { get; set; }
[InverseProperty("ChatUserConnection")]
public virtual List<ChatRoomPresence> Rooms { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Abstract.Streaming;
namespace Yavsc.Models.Chat
{
public class ChatRoom: IChatRoom<ChatRoomPresence>
{
[StringLengthAttribute(1023,MinimumLength=1)]
public string Topic { get; set; }
[Key]
[StringLengthAttribute(255,MinimumLength=1)]
public string Name { get; set;}
public string ApplicationUserId { get; set; }
[ForeignKey("ApplicationUserId")]
public virtual ApplicationUser Owner { get; set; }
[InverseProperty("Room")]
public virtual List<ChatRoomPresence> UserList { get; set;}
}
}

View File

@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Abstract.Streaming;
namespace Yavsc.Models.Chat
{
public class ChatRoomPresence: IChatRoomUsage
{
public string ChannelName { get; set; }
[ForeignKey("ChannelName")]
public virtual ChatRoom Room { get; set; }
public string ChatUserConnectionId { get; set; }
[ForeignKey("ChatUserConnectionId")]
public virtual ChatConnection ChatUserConnection { get; set; }
public ChatRoomUsageLevel Level
{
get; set;
}
}
}

View File

@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Cratie.AName
{
public class NameSubmission : Submission
{
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
public string FirstChoice {get; set;}
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
public string SecondChoice {get; set;}
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
public string ThirdChoice {get; set;}
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace Yavsc.Models.Cratie
{
public class Option: IBaseTrackedEntity
{
public string CodeScrutin { get; set; }
public string Code { get; set ; }
public string Description { get; set; }
public DateTime DateCreated { get ; set ; }
public string UserCreated { get ; set ; }
public DateTime DateModified { get ; set ; }
public string UserModified { get ; set ; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Cratie
{
public class Scrutin : IBaseTrackedEntity
{
[Key]
public string Code { get; set ; }
public string Description { get ; set ; }
public DateTime DateCreated { get; set; }
public string UserCreated { get; set; }
public DateTime DateModified { get; set; }
public string UserModified { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Cratie
{
public class Submission
{
[ForeignKey("CodeScrutin")]
public virtual Scrutin Context { get; set; }
public string CodeScrutin { get; set ; }
[ForeignKey("CodeOption")]
public virtual Option Choice { get; set; }
public string CodeOption { get; set; }
[ForeignKey("AuthorId")]
public virtual ApplicationUser Author { get; set; }
public string AuthorId { get ; set ;}
}
}

View File

@ -0,0 +1,46 @@
//
// Color.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Drawing
{
public class Color
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public Color(){
}
public Color(Color c)
{
Red=c.Red;
Green=c.Green;
Blue=c.Blue;
Name=c.Name;
}
public byte Red {get;set;}
public byte Green {get;set;}
public byte Blue {get;set;}
public string Name { get; set; }
}
}

View File

@ -0,0 +1,65 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models;
using Yavsc.Models.Calendar;
namespace Yavsc.Server.Models.EMailing
{
public class MailingTemplate : IBaseTrackedEntity
{
/// <summary>
/// Date Created
/// </summary>
/// <returns></returns>
public DateTime DateCreated
{
get;
set;
}
public DateTime DateModified
{
get;
set;
}
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[MaxLengthAttribute(128),MinLength(3)]
public string Topic { get; set; }
/// <summary>
/// Markdown template to process
/// </summary>
/// <returns></returns>
[MaxLengthAttribute(64*1024)]
public string Body { get; set; }
[EmailAddress()]
public string ReplyToAddress { get; set; }
[ForeignKey("ManagerId")]
public virtual ApplicationUser Manager { get; set; }
public Periodicity ToSend { get; set; }
public string ManagerId
{
get;
set;
}
public string UserCreated
{
get;
set;
}
public string UserModified
{
get;
set;
}
}
}

View File

@ -0,0 +1,37 @@
//
// IDocument.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace Yavsc.Models {
public class Parameter {
public string Name { get; set; }
public string Value { get; set; }
}
[Obsolete("Templates are ala Razor")]
public interface IDocument {
string Template { get; set; }
Parameter [] Parameters { get; set; }
}
}

View File

@ -0,0 +1,43 @@
//
// FileRecievedInfo.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Yavsc.Abstract.FileSystem;
namespace Yavsc.Models.FileSystem
{
public class FileRecievedInfo : IFileRecievedInfo
{
public FileRecievedInfo()
{
QuotaOffensed = Overriden = false;
MimeType = DestDir = FileName = null;
}
public string MimeType { get; set; }
public string DestDir { get; set; }
public string FileName { get; set; }
public bool Overriden { get; set; }
public bool QuotaOffensed { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System.IO;
using System.Net.Mime;
namespace Yavsc.Server.Model
{
public class FormFile
{
public string Name { get; set; }
string contentDispositionString;
public string ContentDisposition { get {
return contentDispositionString;
} set {
ContentDisposition contentDisposition = new ContentDisposition(value);
Name = contentDisposition.FileName;
contentDispositionString = value;
} }
public string ContentType { get; set; }
public string FilePath { get; set; }
public Stream Stream { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Forms
{
public class Form
{
[Key]
public string Id {get; set;}
public string Summary { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Forms.Validation
{
public class Method
{
[Key]
public string Name {get; set; }
/// <summary>
/// TODO localisation ...
/// </summary>
/// <returns></returns>
[Required]
public string ErrorMessage { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace Yavsc.Models.Forms.Validation
{
public class Required : Method
{
}
}

View File

@ -0,0 +1,175 @@
//
// BrusherProfile.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Yavsc.Models.Haircut
{
using Workflow;
using Relationship;
using Calendar;
public class BrusherProfile : ISpecializationSettings
{
public BrusherProfile()
{
}
[Key]
public string UserId
{
get; set;
}
[JsonIgnore,ForeignKey("UserId")]
public virtual PerformerProfile BaseProfile { get; set; }
[Display(Name="Portfolio")]
public virtual List<HyperLink> Links { get; set; }
[Display(Name="Rayon d'action"),DisplayFormat(DataFormatString="{0} km")]
public int ActionDistance { get; set; }
/// <summary>
/// StartOfTheDay In munutes
/// </summary>
/// <returns></returns>
[DisplayFormat(ConvertEmptyStringToNull = true, NullDisplayText = "[Pas d'emploi du temps spécifié]")]
[Display(Name="Emploi du temps")]
public virtual Schedule Schedule { get; set; }
[Display(Name="Coupe femme cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal WomenLongCutPrice { get; set; }
[Display(Name="Coupe femme cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal WomenHalfCutPrice { get; set; }
[Display(Name="Coupe femme cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal WomenShortCutPrice { get; set; }
[Display(Name="Coupe homme"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ManCutPrice { get; set; }
[Display(Name="brushing homme"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ManBrushPrice { get; set; }
[Display(Name="Coupe enfant"),DisplayFormat(DataFormatString="{0:C}")]
public decimal KidCutPrice { get; set; }
[Display(Name="Brushing cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongBrushingPrice { get; set; }
[Display(Name="Brushing cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfBrushingPrice { get; set; }
[Display(Name="Brushing cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortBrushingPrice { get; set; }
[Display(Name="couleur cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongColorPrice { get; set; }
[Display(Name="couleur cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfColorPrice { get; set; }
[Display(Name="couleur cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortColorPrice { get; set; }
[Display(Name="couleur multiple cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongMultiColorPrice { get; set; }
[Display(Name="couleur multiple cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfMultiColorPrice { get; set; }
[Display(Name="couleur multiple cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortMultiColorPrice { get; set; }
[Display(Name="permanente cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongPermanentPrice { get; set; }
[Display(Name="permanente cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfPermanentPrice { get; set; }
[Display(Name="permanente cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortPermanentPrice { get; set; }
[Display(Name="défrisage cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongDefrisPrice { get; set; }
[Display(Name="défrisage cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfDefrisPrice { get; set; }
[Display(Name="défrisage cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortDefrisPrice { get; set; }
[Display(Name="mêches sur cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongMechPrice { get; set; }
[Display(Name="mêches sur cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfMechPrice { get; set; }
[Display(Name="mêches sur cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortMechPrice { get; set; }
[Display(Name="balayage cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongBalayagePrice { get; set; }
[Display(Name="balayage cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfBalayagePrice { get; set; }
[Display(Name="balayage cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortBalayagePrice { get; set; }
[Display(Name="Mise en plis cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal LongFoldingPrice { get; set; }
[Display(Name="Mise en plis cheveux mi-longs"),DisplayFormat(DataFormatString="{0:C}")]
public decimal HalfFoldingPrice { get; set; }
[Display(Name="Mise en plis cheveux courts"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShortFoldingPrice { get; set; }
[Display(Name="Shampoing"),DisplayFormat(DataFormatString="{0:C}")]
public decimal ShampooPrice { get; set; }
[Display(Name="Soin"),DisplayFormat(DataFormatString="{0:C}")]
public decimal CarePrice { get; set; }
[Display(Name="Remise au forfait coupe+technique"),DisplayFormat(DataFormatString="{0:C}")]
public decimal FlatFeeDiscount { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Haircut
{
public enum HairCutGenders : int
{
[Display(Name="Femme")]
Women,
[Display(Name="Homme")]
Man,
[Display(Name="Enfant")]
Kid
}
}

View File

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

View File

@ -0,0 +1,428 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Billing;
using Yavsc.Models.Relationship;
using Yavsc.Billing;
using System.Globalization;
using Yavsc.Helpers;
using System.Linq;
using Microsoft.Extensions.Localization;
using Yavsc.ViewModels.PayPal;
using Yavsc.Models.HairCut;
using Yavsc.Abstract.Identity;
namespace Yavsc.Models.Haircut
{
public class HairCutQuery : NominativeServiceCommand
{
// Bill description
string _description = null;
public override string Description
{
get
{
string type = ResourcesHelpers.GlobalLocalizer[this.GetType().Name];
string gender = ResourcesHelpers.GlobalLocalizer[this.Prestation.Gender.ToString()];
return $"{_description} {type} ({gender})";
}
set
{
_description = value;
}
}
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
override public long Id { get; set; }
[Required]
public long PrestationId { get; set; }
[ForeignKey("PrestationId"), Required, Display(Name = "Préstation")]
public virtual HairPrestation Prestation { get; set; }
[ForeignKey("LocationId")]
[Display(Name = "Lieu du rendez-vous")]
[DisplayFormat(ConvertEmptyStringToNull = true, NullDisplayText = "[Pas de lieu spécifié]")]
public virtual Location Location { get; set; }
[Display(Name = "Date et heure")]
[DisplayFormat(NullDisplayText = "[Pas de date ni heure]", ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public DateTime? EventDate
{
get;
set;
}
public long? LocationId
{
get;
set;
}
[Display(Name = "Informations complémentaires"),
StringLengthAttribute(512)]
[DisplayFormat(ConvertEmptyStringToNull = true, NullDisplayText = "[pas d'informations complémentaires]")]
public string AdditionalInfo { get; set; }
public override List<IBillItem> GetBillItems()
{
string longhairsuffix = " (cheveux longs)";
string halflonghairsuffix = " (cheveux mi-longs)";
string shorthairsuffix = " (cheveux courts)";
List<IBillItem> bill = new List<IBillItem>();
if (this.Prestation == null) throw new InvalidOperationException("Prestation property is null");
if (this.SelectedProfile == null) throw new InvalidOperationException("SelectedProfile property is null");
// Le shampoing
if (this.Prestation.Shampoo)
bill.Add(new CommandLine { Name = "Shampoing", Description = "Shampoing", UnitaryCost = SelectedProfile.ShampooPrice });
// la coupe
if (Prestation.Cut)
{
bill.Add(new CommandLine
{
Name = "Coupe",
Description = $"Coupe " +
ResourcesHelpers.GlobalLocalizer[Prestation.Gender.ToString()] + " " +
(Prestation.Gender == HairCutGenders.Women ?
Prestation.Length == HairLength.Long ? longhairsuffix :
Prestation.Length == HairLength.HalfLong ? halflonghairsuffix :
shorthairsuffix : null),
UnitaryCost =
Prestation.Gender == HairCutGenders.Women ?
Prestation.Length == HairLength.Long ? SelectedProfile.WomenLongCutPrice :
Prestation.Length == HairLength.HalfLong ? SelectedProfile.WomenHalfCutPrice :
SelectedProfile.WomenShortCutPrice : Prestation.Gender == HairCutGenders.Man ?
SelectedProfile.ManCutPrice : SelectedProfile.KidCutPrice
});
}
// Les techniques
switch (Prestation.Tech)
{
case HairTechnos.Color:
{
bool multicolor = Prestation.Taints.Count > 1;
string name = multicolor ? "Couleur" : "Multi-couleur";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = multicolor ? SelectedProfile.LongMultiColorPrice :
SelectedProfile.LongColorPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = multicolor ? SelectedProfile.HalfMultiColorPrice : SelectedProfile.HalfColorPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name = name + shorthairsuffix,
UnitaryCost = multicolor ? SelectedProfile.ShortMultiColorPrice : SelectedProfile.ShortColorPrice
});
break;
}
}
break;
case HairTechnos.Balayage:
{
string name = "Balayage";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongBalayagePrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfBalayagePrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortBalayagePrice
});
break;
}
}
break;
case HairTechnos.Defris:
{
string name = "Defrisage";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongDefrisPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfDefrisPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortDefrisPrice
});
break;
}
}
break;
case HairTechnos.Mech:
{
string name = "Mèches";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongMechPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfMechPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortMechPrice
});
break;
}
}
break;
case HairTechnos.Permanent:
{
string name = "Mèches";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongPermanentPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfPermanentPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortPermanentPrice
});
break;
}
}
break;
}
// Les coiffages
switch (Prestation.Dressing)
{
case HairDressings.Brushing:
{
string name = "Brushing";
switch (Prestation.Gender)
{
case HairCutGenders.Women:
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongBrushingPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfBrushingPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortBrushingPrice
});
break;
}
break;
case HairCutGenders.Man:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ManBrushPrice
});
break;
}
}
break;
case HairDressings.Coiffage:
// est offert
/* bill.Add(new CommandLine
{
Name = "Coiffage (offert)",
UnitaryCost = 0m
}); */
break;
case HairDressings.Folding:
{
string name = "Mise en plis";
switch (Prestation.Length)
{
case HairLength.Long:
bill.Add(new CommandLine
{
Name = name,
Description = name + longhairsuffix,
UnitaryCost = SelectedProfile.LongFoldingPrice
});
break;
case HairLength.HalfLong:
bill.Add(new CommandLine
{
Name = name,
Description = name + halflonghairsuffix,
UnitaryCost = SelectedProfile.HalfFoldingPrice
});
break;
default:
bill.Add(new CommandLine
{
Name = name,
Description = name + shorthairsuffix,
UnitaryCost = SelectedProfile.ShortFoldingPrice
});
break;
}
}
break;
}
// les soins
if (Prestation.Cares)
{
bill.Add(new CommandLine
{
Name = "Soins",
Description = "Soins",
UnitaryCost = SelectedProfile.CarePrice
});
}
return bill;
}
public HairCutPayementEvent CreatePaymentEvent(PaymentInfo info, IStringLocalizer localizer)
{
return new HairCutPayementEvent(Client.UserName, info, this, localizer);
}
public virtual BrusherProfile SelectedProfile { get; set; }
public HairCutQueryEvent CreateEvent(string subTopic, string reason, string sender)
{
string evdate = EventDate?.ToString("dddd dd/MM/yyyy à HH:mm") ?? "[pas de date spécifiée]";
string address = Location?.Address ?? "[pas de lieu spécifié]";
var p = Prestation;
string total = GetBillItems().Addition().ToString("C", CultureInfo.CurrentUICulture);
string strprestation = Description;
string bill = string.Join("\n", GetBillItems().Select(
l => $"{l.Name} {l.Description} {l.UnitaryCost} € " +
((l.Count != 1) ? "*" + l.Count.ToString() : "")));
var yaev = new HairCutQueryEvent(subTopic)
{
Client = new ClientProviderInfo
{
UserName = Client.UserName,
UserId = ClientId,
Avatar = Client.Avatar
},
Previsional = Previsional,
EventDate = EventDate,
Location = Location,
Id = Id,
ActivityCode = ActivityCode,
Reason = reason,
Sender = sender,
BillingCode = BillingCodes.Brush
};
return yaev;
}
}
}

View File

@ -0,0 +1,41 @@
using Yavsc.Interfaces.Workflow;
namespace Yavsc.Models.Haircut
{
public class HairCutQueryEvent : RdvQueryProviderInfo, IEvent
{
public HairCutQueryEvent(string subTopic)
{
Topic = "/topic/HairCutQuery";
if (subTopic!=null) Topic+="/"+subTopic;
}
public string CreateBody()
{
return $"{Reason}\r\n-- \r\n{Previsional}\r\n{EventDate}\r\n";
}
public string CreateBoby()
{
return string.Format(ResourcesHelpers.GlobalLocalizer["RdvToPerf"], Client.UserName,
EventDate?.ToString("dddd dd/MM/yyyy à HH:mm"),
Location.Address,
ActivityCode);
}
public string Sender
{
get;
set;
}
public string Topic
{
get;
private set;
}
HairCutQuery Data { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Haircut
{
public enum HairDressings {
Coiffage,
Brushing,
[Display(Name="Mise en plis")]
Folding
}
}

View File

@ -0,0 +1,12 @@
namespace Yavsc.Models.Haircut
{
public enum HairLength : int
{
HalfLong=0,
Short=1,
Long=2
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Billing;
using Yavsc.Models.Relationship;
using Yavsc.Billing;
namespace Yavsc.Models.Haircut
{
public class HairPrestationCollectionItem {
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public long PrestationId { get; set; }
[ForeignKeyAttribute("PrestationId")]
public virtual HairPrestation Prestation { get; set; }
public long QueryId { get; set; }
[ForeignKeyAttribute("QueryId")]
public virtual HairMultiCutQuery Query { get; set; }
}
public class HairMultiCutQuery : NominativeServiceCommand
{
// Bill description
string _customDescription = null;
public override string Description
{
get {
return _customDescription ?? "Prestation en coiffure à domicile [commande groupée]" ;
}
set {
_customDescription = value;
}
}
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
override public long Id { get; set; }
[InversePropertyAttribute("Query")]
public virtual List<HairPrestationCollectionItem> Prestations { get; set; }
public Location Location { get; set; }
public DateTime EventDate
{
get;
set;
}
public override List<IBillItem> GetBillItems()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Yavsc.Models.Haircut
{
public class HairPrestation
{
// Homme ou enfant => Coupe seule
// Couleur => Shampoing
// Forfaits : Coupe + Technique
// pas de coupe => technique
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Display(Name="Longueur de cheveux")]
public HairLength Length { get; set; }
[Display(Name="Pour qui")]
public HairCutGenders Gender { get; set; }
[Display(Name="Coupe")]
public bool Cut { get; set; }
[Display(Name="Coiffage")]
public HairDressings Dressing { get; set; }
[Display(Name="Technique")]
public HairTechnos Tech { get; set; }
[Display(Name="Shampoing")]
public bool Shampoo { get; set; }
[Display(Name="Couleurs"),JsonIgnore,InverseProperty("Prestation")]
public virtual List<HairTaintInstance> Taints { get; set; }
[Display(Name="Soins")]
public bool Cares { get; set; }
}
public class HairTaintInstance {
public long TaintId { get; set; }
[ForeignKey("TaintId")]
public virtual HairTaint Taint { get; set; }
public long PrestationId { get; set; }
[ForeignKey("PrestationId")]
public virtual HairPrestation Prestation { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Haircut
{
using Drawing;
public class HairTaint
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set;}
public string Brand { get; set; }
[Required]
public long ColorId { get; set; }
[ForeignKeyAttribute("ColorId")]
public virtual Color Color {get; set;}
}
}

View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Haircut
{
public enum HairTechnos
{
[Display(Name="Aucune technique spécifique")]
NoTech,
[Display(Name="Couleur")]
Color,
[Display(Name="Permantante")]
Permanent,
[Display(Name="Défrisage")]
Defris,
[Display(Name="Mêches")]
Mech,
Balayage
}
}

View File

@ -0,0 +1,65 @@
using System;
namespace Yavsc.Haircut
{
public interface IProviderInfo
{
string UserId
{
get;
set;
}
string UserName
{
get;
set;
}
string Avatar
{
get;
set;
}
}
public interface IHaircutQuery
{
IProviderInfo ProviderInfo
{
get;
set;
}
long Id
{
get;
set;
}
IHairPrestation Prestation
{
get;
set;
}
long Status
{
get;
set;
}
ILocation Location
{
get;
set;
}
DateTime EventDate
{
get;
set;
}
}
}

View File

@ -0,0 +1,19 @@
namespace Yavsc
{
public interface IHairPrestation
{
long Id { get; set; }
int Length { get; set; }
int Gender { get; set; }
bool Cut { get; set; }
int Dressing { get; set; }
int Tech { get; set; }
bool Shampoo { get; set; }
long[] Taints { get; set; }
bool Cares { get; set; }
}
}

View File

@ -0,0 +1,73 @@
//
// HaircutQueryInfo.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2015 - 2017 Paul Schneider
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.ComponentModel.DataAnnotations;
using Yavsc.Abstract.Identity;
using Yavsc.Models.Relationship;
namespace Yavsc.Models.Haircut.Views
{
public class HaircutQueryProviderInfo : HaircutQueryComonInfo {
public HaircutQueryProviderInfo(HairCutQuery query) : base (query)
{
ClientInfo = new UserInfo(query.Client.Id, query.Client.UserName, query.Client.Avatar);
}
public UserInfo ClientInfo { get; set; }
}
public class HaircutQueryClientInfo : HaircutQueryComonInfo {
public HaircutQueryClientInfo(HairCutQuery query) : base (query)
{
var user = query.PerformerProfile.Performer;
ProviderInfo = new UserInfo(user.Id, user.UserName, user.Avatar);
}
public UserInfo ProviderInfo { get; set; }
}
public class HaircutQueryComonInfo
{
public HaircutQueryComonInfo(HairCutQuery query)
{
Id = query.Id;
Prestation = query.Prestation;
Status = query.Status;
Location = query.Location;
EventDate = query.EventDate;
AdditionalInfo = query.AdditionalInfo;
}
public long Id { get; set; }
public HairPrestation Prestation { get; set; }
public QueryStatus Status { get; set; }
public virtual Location Location { get; set; }
public DateTime? EventDate
{
get;
set;
}
[Display(Name="Informations complémentaires")]
public string AdditionalInfo { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Attributes.Validation;
namespace Yavsc.Models.IT.Evolution
{
public class Feature
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[YaStringLength(256,MinLen=3)]
public string ShortName { get; set; }
[YaStringLength(10*1024,MinLen=3)]
public string Description { get; set; }
public FeatureStatus Status { get; set; }
}
}

View File

@ -0,0 +1,18 @@
namespace Yavsc.Models.IT.Evolution
{
/// <summary>
/// A Feature status
/// <c>Ko</c>: A Bug has just been discovered
/// <c>InSane</c>: This feature is not correctly integrating its ecosystem
/// <c>Obsolete</c>: This will be replaced in a short future, or yet has been replaced
/// with a better solution.
/// <c>Ok</c> : nothing to say
/// </summary>
public enum FeatureStatus: int
{
Requested,
Accepted,
Rejected,
Implemented
}
}

View File

@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Attributes.Validation;
using Yavsc.Models.IT.Evolution;
namespace Yavsc.Models.IT.Fixing
{
public class Bug
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[ForeignKey("FeatureId")]
public virtual Feature False { get; set; }
public long? FeatureId { get; set; }
[YaStringLength(1024)]
public string Title { get; set; }
[YaStringLength(4096)]
public string Description { get; set; }
public BugStatus Status { get; set; }
}
}

View File

@ -0,0 +1,17 @@
namespace Yavsc.Models.IT.Fixing
{
/// <summary>
/// Bug status:
/// * Inserted -> Confirmed|FeatureRequest|Feature|Rejected
/// * Confirmed -> Fixed
/// * FeatureRequest -> Implemented
/// </summary>
public enum BugStatus : int
{
Inserted,
Confirmed,
Rejected,
Feature,
Fixed
}
}

View File

@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Yavsc.Abstract.IT;
using Yavsc.Billing;
using Yavsc.Models.Billing;
using Yavsc.Server.Models.IT.SourceCode;
namespace Yavsc.Server.Models.IT
{
public class Project : NominativeServiceCommand, IProject
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override long Id { get; set; }
public string OwnerId { get; set; }
/// <summary>
/// This field is something like a key,
/// since it is required non null,
/// and is the key of the foreign GitRepositoryReference entity.
///
/// As a side effect, there's no project without valid git reference in db.
/// </summary>
/// <returns></returns>
[Required]
public string Name { get; set; }
public string Version { get; set; }
[InverseProperty("TargetProject")]
public virtual List<ProjectBuildConfiguration> Configurations { get; set; }
[Required]
public long GitId { get; set; }
[ForeignKey("GitId")]
public virtual GitRepositoryReference Repository { get; set; }
List<IBillItem> bill = new List<IBillItem>();
public void AddBillItem(IBillItem item)
{
bill.Add(item);
}
public override List<IBillItem> GetBillItems()
{
return bill;
}
public IEnumerable<string> GetConfigurations()
{
return Configurations.Select(c => c.Name);
}
string description;
public override string Description
{
get { return description; }
set { description = value; }
}
}
}

View File

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Server.Models.IT
{
public class ProjectBuildConfiguration
{
/// <summary>
/// A Numerical Id
/// </summary>
/// <value></value>
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required]
public string Name { get; set; }
public long ProjectId { get; set; }
[ForeignKey("ProjectId")]
public virtual Project TargetProject { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using Yavsc.Abstract.Interfaces;
namespace Yavsc.Server.Models.IT.SourceCode
{
public abstract class Batch<TInput> : IBatch<TInput, bool>
{
public string WorkingDir { get; set; }
public string LogPath { get; set; }
public Action<bool> ResultHandler { get; private set; }
public string []Args { get; set; }
public abstract void Launch(TInput Input);
}
}

View File

@ -0,0 +1,53 @@
// // GitClone.cs
// /*
// paul 21/06/2018 11:27 20182018 6 21
// */
using System.Diagnostics;
using System.IO;
using System;
namespace Yavsc.Server.Models.IT.SourceCode
{
public class GitClone : SingleCmdProjectBatch
{
public GitClone(string repo) : base(repo,"git")
{
}
public override void Launch(Project input)
{
if (input==null) throw new ArgumentNullException("input");
LogPath = $"{input.Name}.git-clone.ansi.log";
// TODO honor Args property
// Model annotations => input.Repository!=null => input.Name == input.Repository.Path
var prjPath = Path.Combine(WorkingDir, input.Name);
var repoInfo = new DirectoryInfo(prjPath);
var gitCmd = repoInfo.Exists ? "pull" : "clone --depth=1";
var cloneStart = new ProcessStartInfo
( _cmdPath, $"{gitCmd} {input.Repository.Url} {input.Repository.Path}" )
{
WorkingDirectory = WorkingDir,
RedirectStandardOutput = true,
UseShellExecute = false
};
// TODO make `.ansi.log` a defined constant.
var logFile = new FileInfo
( Path.Combine
( _repositoryRootPath, $"{input.Name}.ansi.log" ));
using (var stream = logFile.Create())
using (var writer = new StreamWriter(stream))
{
var process = Process.Start(cloneStart);
// TODO publish the starting log url ...
while (!process.HasExited)
{
if (process.StandardOutput.Peek() > -1)
writer.WriteLine(process.StandardOutput.ReadLine());
}
}
if (ResultHandler!=null) ResultHandler(true);
}
}
}

View File

@ -0,0 +1,32 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models;
namespace Yavsc.Server.Models.IT.SourceCode
{
public class GitRepositoryReference
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required]
public string Path { get; set; }
[StringLength(2048)]
public string Url { get; set; }
[StringLength(512)]
public string Branch { get; set; }
[StringLength(1024)]
public string OwnerId { get; set; }
[ForeignKey("OwnerId")]
public virtual ApplicationUser Owner { get; set; }
public override string ToString()
{
return $"[Git ref {Path} {Branch} {Url}]";
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Diagnostics;
using System.IO;
namespace Yavsc.Server.Models.IT.SourceCode
{
public class ProjectBuild : SingleCmdProjectBatch
{
public ProjectBuild(string repoRoot): base(repoRoot, "make")
{
}
public override void Launch(Project input)
{
if (input==null) throw new ArgumentNullException("input");
LogPath = $"{input.Name}.{_cmdPath}.ansi.log";
// TODO honor Args property
// Model annotations => input.Repository!=null => input.Name == input.Repository.Path
var prjPath = Path.Combine(WorkingDir, input.Name);
var repoInfo = new DirectoryInfo(prjPath);
var args = string.Join(" ", Args);
var cloneStart = new ProcessStartInfo
( _cmdPath, args )
{
WorkingDirectory = prjPath,
RedirectStandardOutput = true,
UseShellExecute = false
};
// TODO make `.ansi.log` a defined constant.
var logFile = new FileInfo
( Path.Combine
( _repositoryRootPath, $"{input.Name}.ansi.log" ));
using (var stream = logFile.Create())
using (var writer = new StreamWriter(stream))
{
var process = Process.Start(cloneStart);
// TODO announce ...
while (!process.HasExited)
{
if (process.StandardOutput.Peek() > -1)
writer.WriteLine(process.StandardOutput.ReadLine());
}
}
if (ResultHandler!=null) ResultHandler(true);
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.IO;
namespace Yavsc.Server.Models.IT.SourceCode
{
public abstract class SingleCmdProjectBatch : Batch<Project>
{
protected string _repositoryRootPath;
protected string _cmdPath ;
public SingleCmdProjectBatch (string repoRoot, string cmdPath)
{
_cmdPath = cmdPath;
_repositoryRootPath = repoRoot;
WorkingDir = _repositoryRootPath;
var fie = new DirectoryInfo(WorkingDir);
if (!fie.Exists)
throw new Exception ($"This directory doesn't exist: {WorkingDir},\nand cannot be used as a repository.");
}
}
}

View File

@ -0,0 +1,7 @@
namespace Yavsc.Models {
public interface IUnit<VType> {
string Name { get; }
bool CanConvertFrom(IUnit<VType> other);
VType ConvertFrom (IUnit<VType> other, VType orgValue) ;
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Models.Identity
{
public class BlackListedUserName : IWatchedUserName {
[Key]
[StringLength(1024)]
public string Name { get; set;}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Yavsc.Models.Identity
{
[JsonObject]
public class GoogleCloudMobileDeclaration {
[Required]
public string GCMRegistrationId { get; set; }
[Key,Required]
public string DeviceId { get; set; }
public string Model { get; set; }
public string Platform { get; set; }
public string Version { get; set; }
public string DeviceOwnerId { get; set; }
public DateTime DeclarationDate { get; set; }
/// <summary>
/// Latest Activity Update
///
/// Let's says,
/// the latest time this device downloaded functional info from server
/// activity list, let's say, promoted ones, those thar are at index, and
/// all others, that are not listed as unsupported ones (not any more, after
/// has been annonced as obsolete a decent laps of time).
///
/// In order to say, is any activity has changed here.
/// </summary>
/// <returns></returns>
public DateTime LatestActivityUpdate { get; set; }
[JsonIgnore,ForeignKey("DeviceOwnerId")]
public virtual ApplicationUser DeviceOwner { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More