This commit is contained in:
2022-12-16 06:01:23 +00:00
parent 26c2ae5cc9
commit effd96143f
310 changed files with 48715 additions and 0 deletions

132
server/models/AyContext.cs Normal file
View File

@@ -0,0 +1,132 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Sockeye.Models
{
public partial class AyContext : DbContext
{
public virtual DbSet<SchemaVersion> SchemaVersion { get; set; }
public virtual DbSet<MetricMM> MetricMM { get; set; }
public virtual DbSet<MetricDD> MetricDD { get; set; }
public virtual DbSet<User> User { get; set; }
public virtual DbSet<UserOptions> UserOptions { get; set; }
public virtual DbSet<GlobalBizSettings> GlobalBizSettings { get; set; }
public virtual DbSet<GlobalOpsBackupSettings> GlobalOpsBackupSettings { get; set; }
public virtual DbSet<GlobalOpsNotificationSettings> GlobalOpsNotificationSettings { get; set; }
public virtual DbSet<Event> Event { get; set; }
public virtual DbSet<SearchDictionary> SearchDictionary { get; set; }
public virtual DbSet<SearchKey> SearchKey { get; set; }
public virtual DbSet<FileAttachment> FileAttachment { get; set; }
public virtual DbSet<OpsJob> OpsJob { get; set; }
public virtual DbSet<OpsJobLog> OpsJobLog { get; set; }
public virtual DbSet<Translation> Translation { get; set; }
public virtual DbSet<TranslationItem> TranslationItem { get; set; }
public virtual DbSet<DataListSavedFilter> DataListSavedFilter { get; set; }
public virtual DbSet<DataListColumnView> DataListColumnView { get; set; }
public virtual DbSet<Tag> Tag { get; set; }
public virtual DbSet<FormCustom> FormCustom { get; set; }
public virtual DbSet<FormUserOptions> FormUserOptions { get; set; }
public virtual DbSet<PickListTemplate> PickListTemplate { get; set; }
public virtual DbSet<Memo> Memo { get; set; }
public virtual DbSet<Reminder> Reminder { get; set; }
public virtual DbSet<Review> Review { get; set; }
public virtual DbSet<Customer> Customer { get; set; }
public virtual DbSet<CustomerNote> CustomerNote { get; set; }
public virtual DbSet<HeadOffice> HeadOffice { get; set; }
public virtual DbSet<NotifySubscription> NotifySubscription { get; set; }
public virtual DbSet<NotifyEvent> NotifyEvent { get; set; }
public virtual DbSet<InAppNotification> InAppNotification { get; set; }
public virtual DbSet<NotifyDeliveryLog> NotifyDeliveryLog { get; set; }
public virtual DbSet<Logo> Logo { get; set; }
public virtual DbSet<Report> Report { get; set; }
public virtual DbSet<DashboardView> DashboardView { get; set; }
public virtual DbSet<CustomerNotifySubscription> CustomerNotifySubscription { get; set; }
public virtual DbSet<CustomerNotifyEvent> CustomerNotifyEvent { get; set; }
public virtual DbSet<CustomerNotifyDeliveryLog> CustomerNotifyDeliveryLog { get; set; }
public virtual DbSet<Integration> Integration { get; set; }
public virtual DbSet<IntegrationItem> IntegrationItem { get; set; }
public virtual DbSet<IntegrationLog> IntegrationLog { get; set; }
//Note: had to add this constructor to work with the code in startup.cs that gets the connection string from the appsettings.json file
//and commented out the above on configuring
public AyContext(DbContextOptions<AyContext> options) : base(options)
{ }
//https://stackoverflow.com/a/64053832/8939
public void Replace<TEntity>(TEntity oldEntity, TEntity newEntity) where TEntity : class
{
ChangeTracker.TrackGraph(oldEntity, e => e.Entry.State = EntityState.Deleted);
ChangeTracker.TrackGraph(newEntity, e => e.Entry.State = e.Entry.IsKeySet ? EntityState.Modified : EntityState.Added);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//AUTOMATICALLY MATCH NAMES
//https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
// Replace table names
var entityName = entity.GetTableName().ToLowerInvariant();
if (!entityName.StartsWith("view"))
entity.SetTableName("a" + entityName);
else
entity.SetTableName(entityName);
// Replace column names
foreach (var property in entity.GetProperties())
{
//Any object that has a concurrencytoken field
//set it up to work properly with PostgreSQL
if (property.Name == "Concurrency")
{
property.SetColumnName("xmin");
property.SetColumnType("xid");
property.ValueGenerated = ValueGenerated.OnAddOrUpdate;
property.IsConcurrencyToken = true;
}
else
property.SetColumnName(property.Name.ToLowerInvariant());
}
foreach (var key in entity.GetKeys())
key.SetName(key.GetName().ToLowerInvariant());
foreach (var key in entity.GetForeignKeys())
key.SetConstraintName(key.GetConstraintName().ToLowerInvariant());
foreach (var index in entity.GetIndexes())
index.SetDatabaseName(index.GetDatabaseName().ToLowerInvariant());
}
///////////////////////////////
//SERIALIZED OBJECTS
//
//modelBuilder.Entity<WorkOrder>().Property(z => z.Serial).UseIdentityByDefaultColumn();
//## NOTE: if more added here then must also update globalbizsettingscontroller.seeds and client
//////////////////////////////////////////////////////////////
//-----------
}
}
}

119
server/models/Customer.cs Normal file
View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
//#### MIRRORED IN QBI !!
public class Customer : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
public bool Active { get; set; }
public string Notes { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
//cant use these due to import v7 malformed shit adn can't be arsed to deal with that
//[Url]
public string WebAddress { get; set; }
public string AlertNotes { get; set; }
public bool BillHeadOffice { get; set; }
public long? HeadOfficeId { get; set; }
[NotMapped]
public string HeadOfficeViz { get; set; }
public string TechNotes { get; set; }
public string AccountNumber { get; set; }
public string Phone1 { get; set; }
public string Phone2 { get; set; }
public string Phone3 { get; set; }
public string Phone4 { get; set; }
public string Phone5 { get; set; }
public string EmailAddress { get; set; }
//POSTAL ADDRESS
public string PostAddress { get; set; }
public string PostCity { get; set; }
public string PostRegion { get; set; }
public string PostCountry { get; set; }
public string PostCode { get; set; }
//PHYSICAL ADDRESS
public string Address { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string Country { get; set; }
public string AddressPostal { get; set; }
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
public Customer()
{
Tags = new List<string>();
BillHeadOffice = false;
//UsesBanking = false;
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.Customer; }
}//eoc
}//eons
/*
[AID] [uniqueidentifier] NOT NULL,
[ANAME] [nvarchar](255) NOT NULL,
[ACREATED] [datetime] NULL,
[AMODIFIED] [datetime] NULL,
[AACTIVE] [bit] NOT NULL,
[ACREATOR] [uniqueidentifier] NULL,
[AMODIFIER] [uniqueidentifier] NULL,
[ADISPATCHZONEID] [uniqueidentifier] NULL,
[AWEBADDRESS] [nvarchar](255) NULL,
[APOPUPNOTES] [ntext] NULL,
[ACLIENTGROUPID] [uniqueidentifier] NULL,
[ABILLHEADOFFICE] [bit] NOT NULL,
[AHEADOFFICEID] [uniqueidentifier] NULL,
[ANOTES] [ntext] NULL,
[AREGIONID] [uniqueidentifier] NULL,
[ATECHNOTES] [ntext] NULL,
[AACCOUNTNUMBER] [nvarchar](255) NULL,
[ACUSTOM1] [ntext] NULL,
[ACUSTOM2] [ntext] NULL,
[ACUSTOM3] [ntext] NULL,
[ACUSTOM4] [ntext] NULL,
[ACUSTOM5] [ntext] NULL,
[ACUSTOM6] [ntext] NULL,
[ACUSTOM7] [ntext] NULL,
[ACUSTOM8] [ntext] NULL,
[ACUSTOM9] [ntext] NULL,
[ACUSTOM0] [ntext] NULL,
[AUSESBANKING] [bit] NOT NULL,
[ACONTRACTID] [uniqueidentifier] NULL,
[ACONTRACTEXPIRES] [datetime] NULL,
[ALASTWORKORDERID] [uniqueidentifier] NULL,//dropped case 3536
[ALASTSERVICEDATE] [datetime] NULL,//dropped case 3536
[ADEFAULTSERVICETEMPLATEID] [uniqueidentifier] NULL,
[ACONTACTNOTES] [ntext] NULL,
[ACONTACT] [nvarchar](500) NULL,
[APHONE1] [nvarchar](255) NULL,
[APHONE2] [nvarchar](255) NULL,
[APHONE3] [nvarchar](255) NULL,
[APHONE4] [nvarchar](255) NULL,
[APHONE5] [nvarchar](255) NULL,
[AEMAIL] [nvarchar](255) NULL,
[ASENDNOTIFICATIONS] [bit] NOT NULL,
*/

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class CustomerNote : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long CustomerId { get; set; }
[NotMapped]
public string CustomerViz { get; set; }
[Required]
public long UserId { get; set; }
[NotMapped]
public string UserViz { get; set; }
[Required]
public DateTime NoteDate { get; set; }
public string Notes { get; set; }
public List<string> Tags { get; set; }
//workaround for notification
[NotMapped, JsonIgnore]
public string Name { get; set; }
public CustomerNote()
{
NoteDate = DateTime.UtcNow;
Tags = new List<string>();
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.CustomerNote; }
[JsonIgnore]
public Customer Customer { get; set; }
[JsonIgnore]
public User User { get; set; }
string ICoreBizObjectModel.CustomFields { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}//eoc
}//eons

View File

@@ -0,0 +1,41 @@
using System;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//This model holds the Customer notification deliveries that have been attempted in the past 90 days (cleaned out by corenotifysweeper)
//it is used for verification / troubleshooting purposes from the OPS log
//and also used as a circuit breaker by the corejobnotify to ensure users are not spammed with identical messages
public class CustomerNotifyDeliveryLog
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public DateTime Processed { get; set; }
public long ObjectId { get; set; }
[Required]
public long CustomerNotifySubscriptionId { get; set; }
[Required]
public bool Fail { get; set; }
public string Error { get; set; }
public CustomerNotifyDeliveryLog()
{
Processed = DateTime.UtcNow;
Fail = false;
ObjectId = 0;
}
//linked entity
public CustomerNotifySubscription CustomerNotifySubscription { get; set; }
}//eoc
}//eons

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//Customer notification event
public class CustomerNotifyEvent
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public DateTime Created { get; set; }
public SockType SockType { get; set; }
public long ObjectId { get; set; }
[Required]
public string Name { get; set; }//object name or closest equivalent for display
[Required]
public NotifyEventType EventType { get; set; }
[Required]
public long CustomerId { get; set; }
[Required]
public long CustomerNotifySubscriptionId { get; set; }//source subscription that triggered this event to be created
public decimal DecValue { get; set; }
//date of the event actually occuring, e.g. WarrantyExpiry date. Compared with subscription to determine if deliverable or not
public DateTime EventDate { get; set; }
// public string Subject { get; set; }//email subject line
// public string Message { get; set; }//email body
public CustomerNotifyEvent()
{
Created = EventDate = DateTime.UtcNow;
// IdValue = 0;
DecValue = 0;
SockType = SockType.NoType;
ObjectId = 0;
Name = string.Empty;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.None);
}
//linked entity
// public NotifySubscription NotifySubscription { get; set; }
// public User User { get; set; }
}//eoc
}//eons

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class CustomerNotifySubscription
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long TranslationId { get; set; }
[Required]
public string LanguageOverride { get; set; }
[Required]
public string TimeZoneOverride { get; set; }
[Required]
public string CurrencyName { get; set; }
[Required]
public bool Hour12 { get; set; }
public List<string> CustomerTags { get; set; }//Tags to match customer with this notification
public TimeSpan AdvanceNotice { get; set; }
public long? LinkReportId { get; set; }
//CREATE NOTIFY EVENT CONDITIONS - Following fields are all conditions set on whether to create a notify event or not
public SockType SockType { get; set; }//Note: must be specific object, not global for any object related stuff to avoid many role issues and also potential overload
[Required]
public NotifyEventType EventType { get; set; }
[Required]
public long IdValue { get; set; }//if required, this must match, default is zero to match to not set
public decimal DecValue { get; set; }//if required this must match or be greater or something
public List<string> Tags { get; set; }//Tags to filter an event, object *must* have these tags to generate event related to it (AT TIME OF UPDATE)
[Required]
public string Template { get; set; }
[Required]
public string Subject { get; set; }
//DELIVERY CONDITIONS - following are all conditions on *whether* to deliver the existing notify event or not
public TimeSpan AgeValue { get; set; }//for events that depend on an age of something (e.g. WorkorderStatusAge), This value determines when event has "come of age" but advancenotice controls how far in advance of this delivery is made
public CustomerNotifySubscription()
{
Tags = new List<string>();
SockType = SockType.NoType;
IdValue = 0;
DecValue = 0;
AgeValue = TimeSpan.Zero;
AdvanceNotice = TimeSpan.Zero;
LinkReportId = 0;
}
}//eoc
}//eons

View File

@@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class DashboardView
{
public DashboardView(){
View="[]";//empty view by default
}
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long UserId { get; set; }
[Required]
public string View { get; set; }//JSON Dashboard registry view object
}
}

View File

@@ -0,0 +1,8 @@
namespace Sockeye.Models
{
public class DataListColumnFilter
{
public string op { get; set; }
public string value { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
//this is a hiearchical object so saving as a JSON fragment still best option
public class DataListColumnView
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long UserId { get; set; }//only relevant if non-public for fetching either in list or single (public true OR userid matches)
[Required, MaxLength(255)]
public string ListKey { get; set; }//max 255 characters ascii set
public string Columns { get; set; }//JSON serialized Column array: columns:["PartInventoryTransactionEntryDate","PartName","PartWarehouseName","PartInventoryTransactionQuantity","PartInventoryTransactionDescription","PartInventoryTransactionSource","PartInventoryBalance"]
public string Sort { get; set; }//JSON serialized SortBy Dictionary: sortBy:[{"PartInventoryTransactionEntryDate":"-"}],//All sorted columns here as keyvalue pairs value is a string of "+" for ascending "-" for descending and are IN ORDER of how to be sorted
//
}
}

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
namespace Sockeye.Models
{
public class DataListFilterOption
{
public string Column { get; set; }
public List<DataListColumnFilter> Items { get; set; }
public bool Any { get; set; }//means "or" the filter conditions
public DataListFilterOption()
{
Items = new List<DataListColumnFilter>();
Any = false;
}
}
/*
columns:["PartInventoryTransactionEntryDate","PartName","PartWarehouseName","PartInventoryTransactionQuantity","PartInventoryTransactionDescription","PartInventoryTransactionSource","PartInventoryBalance"]
sortBy:[{"PartInventoryTransactionEntryDate":"-"}],//All sorted columns here as keyvalue pairs value is a string of "+" for ascending "-" for descending and are IN ORDER of how to be sorted
filter:[{column:"PartName",any:true/false,items:[{op: "=",value: "400735"}]}],
clientCriteria:"2" //could be anything here that makes sense to the list, in this case an example customer id for customernotedatalist
columns are represented in a higher level object DataListTableOptions
sort and filter are in here
columns and sort are a singleton per datalistkey,userid persisted automatically (no alternative "views" just one of these). User can set them or reset them to default.
filter is different: user can persist a filter by name for future selection, sharing with others (public). The default filter is no filter.
*/
}

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System;
namespace Sockeye.Models
{
//common base class for data table display at client, reporting and mass bulk operations
public class DataListProcessingBase
{
public string DataListKey { get; set; }
public Dictionary<string, string> SortBy { get; set; }
public List<DataListFilterOption> Filter { get; set; }
public string ClientCriteria { get; set; }
public DateTimeOffset ClientTimeStamp { get; set; }
public DataListProcessingBase()
{
SortBy = new Dictionary<string, string>();
Filter = new List<DataListFilterOption>();
}
}
}

View File

@@ -0,0 +1,15 @@
using Sockeye.Biz;
using Sockeye.DataList;
using Newtonsoft.Json.Linq;
namespace Sockeye.Models
{
public class DataListReportProcessingOptions : DataListSelectedProcessingOptions
{
internal DataListReportProcessingOptions(DataListSelectedRequest request, IDataListProcessing dataList, DataListColumnView savedView, DataListSavedFilter savedFilter, long userId, AuthorizationRoles userRoles) : base(request, dataList, savedView, savedFilter, userId, userRoles)
{
}
public long ReportId { get; set; }
public JToken ClientMeta { get; set; }//meta JSON data passed from client, not part of biz object data
}
}

View File

@@ -0,0 +1,9 @@
using Newtonsoft.Json.Linq;
namespace Sockeye.Models
{
public class DataListReportRequest : DataListSelectedRequest
{
public long ReportId { get; set; }
public JToken ClientMeta { get; set; }//meta JSON data about client for report script processing at server
}
}

View File

@@ -0,0 +1,18 @@
using System;
namespace Sockeye.Models
{
//common base class for REQUESTING a datalist from the client
public class DataListRequestBase
{
public string DataListKey { get; set; }
public string ClientCriteria { get; set; }
public long FilterId {get;set;}
public DateTimeOffset ClientTimeStamp {get;set;}
}
/*
REQUEST
BASE: DataListKey, ClientCriteria, FilterId
TABLEVERSION: Limit, Offset : base
REPORT/BULK OPS VERSION: SockType(socktype),SelectedRowIds(long[]) : base
*/
}

View File

@@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class DataListSavedFilter
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long UserId { get; set; }//only relevant if non-public for fetching either in list or single (public true OR userid matches)
[Required, MaxLength(255)]
public string Name { get; set; }//max 255 characters ascii set
[Required]
public bool Public { get; set; }
[Required]
public bool DefaultFilter { get; set; } //is the users default filter for this listkey
[Required, MaxLength(255)]
public string ListKey { get; set; }//max 255 characters ascii set
public string Filter { get; set; }//JSON serialized List<DataListFilterOption> object of DataListBase
}
}

View File

@@ -0,0 +1,74 @@
using System.Threading.Tasks;
using Sockeye.Biz;
using System.Collections.Generic;
using Sockeye.DataList;
using Newtonsoft.Json;
using EnumsNET;
namespace Sockeye.Models
{
//Used to drive processes that rely on selections made at client from a datalist
//either a preselected list of id's or a datalist key and filterid that can
//be used to rehydrate a list of id's
public class DataListSelectedProcessingOptions : DataListProcessingBase
{
internal DataListSelectedProcessingOptions(
DataListSelectedRequest request,
IDataListProcessing dataList,
DataListColumnView savedView,
DataListSavedFilter savedFilter,
long userId,
AuthorizationRoles userRoles)
{
//set some values from request
base.ClientCriteria = request.ClientCriteria;
base.DataListKey = request.DataListKey;
base.ClientTimeStamp = request.ClientTimeStamp;
//SET SORTBY
base.SortBy = JsonConvert.DeserializeObject<Dictionary<string, string>>(savedView.Sort);
//SET FILTER
if (request.FilterId != 0 && savedFilter != null)
base.Filter = JsonConvert.DeserializeObject<List<DataListFilterOption>>(savedFilter.Filter);
//ADD STATIC SERVER FILTERS
List<DataListFilterOption> StaticServerFilterOptions = new List<DataListFilterOption>();
if (dataList is IDataListInternalCriteria)
StaticServerFilterOptions = ((IDataListInternalCriteria)dataList).DataListInternalCriteria(userId, userRoles, request.ClientCriteria);
//Add the internal filters into the listoptions existing filters
//NOTE: There is currently no overlap between internal filtered columns and filters coming from the client
foreach (DataListFilterOption dfo in StaticServerFilterOptions)
base.Filter.Add(dfo);
}
public static async Task<long[]> RehydrateIdList(DataListSelectedRequest selectedRequest, AyContext ct, AuthorizationRoles userRoles, Microsoft.Extensions.Logging.ILogger log, long userId, long userTranslationId)
{
DataListColumnViewBiz viewbiz = new DataListColumnViewBiz(ct, userId, userTranslationId, userRoles);
var SavedView = await viewbiz.GetAsync(userId, selectedRequest.DataListKey, true);
DataListSavedFilter SavedFilter = null;
if (selectedRequest.FilterId != 0)
{
DataListSavedFilterBiz filterbiz = new DataListSavedFilterBiz(ct, userId, userTranslationId, userRoles);
SavedFilter = await filterbiz.GetAsync(selectedRequest.FilterId);
}
var DataList = DataListFactory.GetAyaDataList(selectedRequest.DataListKey, userTranslationId);
if (DataList == null)
throw new System.ArgumentOutOfRangeException($"DataList \"{selectedRequest.DataListKey}\" specified does not exist");
//check rights
if (!userRoles.HasAnyFlags(DataList.AllowedRoles))
throw new System.UnauthorizedAccessException($"DataList \"{selectedRequest.DataListKey}\" required Roles not found for this user");
DataListSelectedProcessingOptions d = new DataListSelectedProcessingOptions(selectedRequest, DataList, SavedView, SavedFilter, userId, userRoles);
return await Sockeye.DataList.DataListFetcher.GetIdListResponseAsync(ct, d, DataList, userRoles, log, userId, selectedRequest.ReportDesignerSample);
}
}
}

View File

@@ -0,0 +1,14 @@
using Sockeye.Biz;
namespace Sockeye.Models
{
//Request version of selection request used by report and bulk ops
//handles posts from client
public class DataListSelectedRequest : DataListRequestBase
{
public SockType SockType { get; set; }
public long[] SelectedRowIds { get; set; }
public bool IncludeWoItemDescendants {get;set;}
public bool ReportDesignerSample {get;set;}//set if for report designer to limit rows returned to a sensible limit
}
}

View File

@@ -0,0 +1,4 @@
namespace Sockeye.Models
{
public record DataListSortRequest(string ListKey, string[] sortBy, bool[] sortDesc);
}

View File

@@ -0,0 +1,99 @@
using System.Collections.Generic;
using System.Linq;
using Sockeye.DataList;
using Sockeye.Biz;
using Newtonsoft.Json;
namespace Sockeye.Models
{
internal sealed class DataListTableProcessingOptions : DataListProcessingBase
{
internal List<string> Columns { get; set; }
internal const int MaxPageSize = 1000;
internal const int DefaultOffset = 0;
internal const int DefaultLimit = 25;
internal int? Offset { get; set; }
internal int? Limit { get; set; }
//All columns that are hidden but are affecting the query (sorting, filtering)
//so in UI can show that there are hidden columns affecting the result set
internal List<string> HiddenAffectiveColumns { get; set; }
internal DataListTableProcessingOptions(
DataListTableRequest request,
IDataListProcessing dataList,
DataListColumnView savedView,
DataListSavedFilter savedFilter,
long userId,
AuthorizationRoles userRoles)
{
HiddenAffectiveColumns = new List<string>();
//set some values from request
Limit = request.Limit;
Offset = request.Offset;
base.ClientCriteria = request.ClientCriteria;
base.DataListKey = request.DataListKey;
base.ClientTimeStamp = request.ClientTimeStamp;
//SET COLUMNS
Columns = JsonConvert.DeserializeObject<List<string>>(savedView.Columns);
//SET SORTBY
base.SortBy = JsonConvert.DeserializeObject<Dictionary<string, string>>(savedView.Sort);
//SET FILTER
if (request.FilterId != 0 && savedFilter != null)
base.Filter = JsonConvert.DeserializeObject<List<DataListFilterOption>>(savedFilter.Filter);
//ADD STATIC SERVER FILTERS
List<DataListFilterOption> StaticServerFilterOptions = new List<DataListFilterOption>();
if (dataList is IDataListInternalCriteria)
StaticServerFilterOptions = ((IDataListInternalCriteria)dataList).DataListInternalCriteria(userId, userRoles, request.ClientCriteria);
//Add the internal filters into the listoptions existing filters
//NOTE: There is currently no overlap between internal filtered columns and filters coming from the client
foreach (DataListFilterOption dfo in StaticServerFilterOptions)
base.Filter.Add(dfo);
SetHiddenAffectiveColumns(dataList);
}
internal List<string> AllUniqueColumnKeysReferenced
{
get
{
return Columns.Union(base.Filter.Select(z => z.Column).ToList()).ToList();
}
}
//All columns that are hidden but are affecting the query (sorting, filtering)
//so in UI can show that there are hidden columns affecting the result set
internal void SetHiddenAffectiveColumns(IDataListProcessing dataList)
{
foreach (string s in base.Filter.Select(z => z.Column).ToList())
{
if (!s.StartsWith("meta") && !Columns.Contains(s))
{
if (!HiddenAffectiveColumns.Contains(s))
{
HiddenAffectiveColumns.Add(s);
}
}
}
foreach (string s in base.SortBy.Select(z => z.Key).ToList())
{
if (!s.StartsWith("meta") && !Columns.Contains(s))
{
if (!HiddenAffectiveColumns.Contains(s))
{
HiddenAffectiveColumns.Add(s);
}
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
namespace Sockeye.Models
{
public sealed class DataListTableRequest : DataListRequestBase
{
public int? Offset { get; set; }
public int? Limit { get; set; }
}
}

67
server/models/Event.cs Normal file
View File

@@ -0,0 +1,67 @@
using System;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Event log entry
/// </summary>
public class Event
{
public long Id { get; set; }
public uint Concurrency { get; set; }
public DateTime Created { get; set; }
[Required]
public long UserId { get; set; }
//-----------------------------------------
[Required]
public long SockId { get; set; }
[Required]
public SockType SockType { get; set; }
[Required]
public SockEvent SockEvent { get; set; }
[MaxLength(255)]
public string Textra { get; set; }
public Event()
{
Created = System.DateTime.UtcNow;
}
public Event(long userId, long sockId, SockType sockType, SockEvent sockEvent, string textra = null)
{
Created = System.DateTime.UtcNow;
UserId = userId;
SockId = sockId;
SockType = sockType;
SockEvent = sockEvent;
if (textra != null)
{
if (textra.Length > 255)
textra = textra.Substring(0, 255);
Textra = textra;
}
}
public Event(long userId, long sockId, SockType sockType, SockEvent sockEvent, DateTime created, string textra = null)
{
Created = created;
UserId = userId;
SockId = sockId;
SockType = sockType;
SockEvent = sockEvent;
if (textra != null)
{
if (textra.Length > 255)
textra = textra.Substring(0, 255);
Textra = textra;
}
}
}//eoc
}//eons

View File

@@ -0,0 +1,45 @@
using System;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class FileAttachment
{
public FileAttachment()
{
//all start out as synchronized
Exists = true;
}
public long Id { get; set; }
public uint Concurrency { get; set; }
//-----------------------------------------
[Required]
public long AttachToObjectId { get; set; }
[Required]
public SockType AttachToAType { get; set; }//int
[Required]
public string StoredFileName { get; set; }
[Required]
public string DisplayFileName { get; set; }
[Required]
public string ContentType { get; set; }//mime type
[Required]
public DateTime LastModified { get; set; }
public string Notes { get; set; }
[Required]
public long AttachedByUserId { get; set; }
[Required]
public bool Exists { get; set; }//was on disk last sync check
[Required]
public long Size { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/*
## NOTE: there is only one formcustom per socktype, the formkey is the socktype enum name
This is a *GLOBAL* setting that applies to ALL users
for personal form settings (such as used by schedule form) see FormUserOptions.cs
- Like DataFilter, holds a JSON fragment in one field and the form key in another field
- JSON FRAGMENT holds items that differ from stock, Hide not valid for non hideable core fields
- FieldKey "fld"
- Hide "hide"
- Required "required"
- Type One of values from AyDataType but not tags or enum (bool, date, date time, decimal, number, p icklist(FUTURE), and text)
- e.g.: [{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"bool"},{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"text"]
*/
public class FormCustom
{
public long Id { get; set; }//Only one formcustom per object type
public uint Concurrency { get; set; }
[Required, MaxLength(255)]
public string FormKey { get; set; }//max 255 characters ascii set
public string Template { get; set; }//JSON fragment of form customization template, top level is array.
}
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/*
## NOTE: this is for PERSONAL form settings such as schedule, for globally applicable form settings and customization see formcustom.cs
*/
public class FormUserOptions
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required, MaxLength(255)]
public string FormKey { get; set; }//max 255 characters ascii set
[Required]
public string Options { get; set; }//JSON fragment of form customization template, top level is array.
//this is set from logged in user id, not provided
public long UserId { get; set; }
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class GlobalBizSettings
{
//This is the replacement for most of the Global object settings in v7 which has been subdivided further in v8 into backup / ops / notification and this general biz
//this object is only interested in Business object related settings and configuration specifically
public long Id { get; set; }//this is always 1 as there is only ever one single global biz object
public uint Concurrency { get; set; }
//Global settings
//############# NOTE: OTHER AREAS THAT MUST MATCH CHANGES HERE ARE:
//GlobalBizSettingsController::GetClientGlobalBizSettings
//ServerGlobalBizSettings
//Picklist and other searches override the normal case insensitive value
//this is precautionarily added for non latinate languages where it could be an issue
public bool FilterCaseSensitive { get; set; }
//ADDRESS / CONTACT INFO reporting etc
public string WebAddress { get; set; }
public string EmailAddress { get; set; }
public string Phone1 { get; set; }
public string Phone2 { get; set; }
//POSTAL ADDRESS
public string PostAddress { get; set; }
public string PostCity { get; set; }
public string PostRegion { get; set; }
public string PostCountry { get; set; }
public string PostCode { get; set; }
//PHYSICAL ADDRESS
public string Address { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string Country { get; set; }
public string AddressPostal { get; set; }
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
//CUSTOMER ACCESS FEATURES AND SETTINGS
public bool CustomerAllowUserSettings { get; set; }
public List<string> CustomerAllowUserSettingsInTags { get; set; } = new List<string>();
public List<string> AllTags(){
var t=new List<string>();
t.AddRange(this.CustomerAllowUserSettingsInTags);
return t;
}
public GlobalBizSettings()
{
Id = 1;//always 1
FilterCaseSensitive = false;
}
}
//Used internally and at client end as extended rights atop roles system in relation only to Contact (customer type users)
public record CustomerRightsRecord(bool UserSettings, long EntityId, bool EntityActive);
}
/*
CREATE TABLE [dbo].[AGLOBAL](
[ACREATED] [datetime] NULL,
[AMODIFIED] [datetime] NULL,
[ACREATOR] [uniqueidentifier] NULL,
[AMODIFIER] [uniqueidentifier] NULL,
[ATAXPARTPURCHASEID] [uniqueidentifier] NULL,
[ATAXPARTSALEID] [uniqueidentifier] NULL,
[ATAXRATESALEID] [uniqueidentifier] NULL,
[AALLOWSCHEDULECONFLICTS] [bit] NOT NULL,
[ALANGUAGE] [nvarchar](255) NULL,
[AUSEREGIONS] [bit] NOT NULL,
[AWORKORDERCLOSEDSTATUS] [uniqueidentifier] NULL,
[AWORKORDERSUMMARYTEMPLATE] [nvarchar](500) NOT NULL,
[AUSEINVENTORY] [bit] NOT NULL,
[AUNITNAMEFORMAT] [smallint] NULL,
[ASCHEDULEABLEUSERNAMEFORMAT] [smallint] NULL,
[ACJKINDEX] [bit] NOT NULL,
[APARTFORMAT] [smallint] NULL,
[AWORKORDERCLOSEBYAGE] [int] NOT NULL,
[AUSENOTIFICATION] [bit] NOT NULL,
[ANOTIFYSMTPHOST] [nvarchar](255) NULL,
[ANOTIFYSMTPACCOUNT] [nvarchar](255) NULL,
[ANOTIFYSMTPPASSWORD] [nvarchar](255) NULL,
[ANOTIFYSMTPFROM] [nvarchar](255) NULL,
[ACOORDINATESTYLE] [smallint] NULL,
[ADEFAULTLATITUDE] [smallint] NULL,
[ADEFAULTLONGITUDE] [smallint] NULL,
[ADEFAULTSERVICETEMPLATEID] [uniqueidentifier] NULL,
[AMAXFILESIZEMB] [int] NULL,
[ALABORSCHEDUSERDFLTTIMESPAN] [int] NOT NULL,
[ATRAVELDFLTTIMESPAN] [int] NOT NULL,
[ANOTIFYENCRYPTION] [nvarchar](255) NULL,
[ASMTPRETRY] [bit] NOT NULL,
[AFORMCUSTOM] [ntext] NULL,
[ASIGNATURETITLE] [ntext] NULL,
[ASIGNATUREHEADER] [ntext] NULL,
[ASIGNATUREFOOTER] [ntext] NULL,
[ASCHEDUSERNONTODAYSTARTTIME] [datetime] NULL,
[AMAINGRIDAUTOREFRESH] [bit] NOT NULL
*/

View File

@@ -0,0 +1,23 @@
using System;
namespace Sockeye.Models
{
public class GlobalOpsBackupSettings
{
public long Id { get; set; }//this is always 1 as there is only ever one single global Ops object
public uint Concurrency { get; set; }
public bool Active { get; set; }
public DateTime BackupTime { get; set; }
public int BackupSetsToKeep { get; set; }
public bool BackupAttachments { get; set; }
public GlobalOpsBackupSettings()
{
DateTime utcNow = DateTime.UtcNow;
Id = 1;
BackupTime = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 23, 59, 0, DateTimeKind.Local).ToUniversalTime();
BackupSetsToKeep = 1;
Active = true;
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using Sockeye.Biz;
namespace Sockeye.Models
{
public class GlobalOpsNotificationSettings
{
public long Id { get; set; }//this is always 1 as there is only ever one single global Ops object
public uint Concurrency { get; set; }
public bool SmtpDeliveryActive { get; set; }
public string SmtpServerAddress { get; set; }
public string SmtpAccount { get; set; }
public string SmtpPassword { get; set; }
public NotifyMailSecurity ConnectionSecurity { get; set; }
public int SmtpServerPort { get; set; }
public string NotifyFromAddress { get; set; }
public string SockeyeServerURL { get; set; }
public GlobalOpsNotificationSettings()
{
SmtpDeliveryActive = true;
Id = 1;
#if (DEBUG)
SmtpDeliveryActive = true;
SmtpServerAddress = "smtp.fastmail.com";
SmtpAccount = "support@onayanova.com";
SmtpPassword = "mk8pmhzlf5hvzgh5";
ConnectionSecurity = NotifyMailSecurity.SSLTLS;
SmtpServerPort = 465;
NotifyFromAddress = "support@ayanova.com";
SockeyeServerURL = "http://localhost:8080";
#else
SmtpDeliveryActive = false;
SmtpServerAddress = "mail.example.com";
SmtpAccount = "notifydeliverfromaccount@example.com";
SmtpPassword = "examplepassword";
ConnectionSecurity = NotifyMailSecurity.SSLTLS;
SmtpServerPort = 587;
NotifyFromAddress = "noreply@example.com";
SockeyeServerURL = "https://url_to_my_ayanova_app";
#endif
}
}
}

101
server/models/HeadOffice.cs Normal file
View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
public class HeadOffice : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
public bool Active { get; set; }
public string Notes { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
public string WebAddress { get; set; }
public string AccountNumber { get; set; }
public string Phone1 { get; set; }
public string Phone2 { get; set; }
public string Phone3 { get; set; }
public string Phone4 { get; set; }
public string Phone5 { get; set; }
public string EmailAddress { get; set; }
//POSTAL ADDRESS
public string PostAddress { get; set; }
public string PostCity { get; set; }
public string PostRegion { get; set; }
public string PostCountry { get; set; }
public string PostCode { get; set; }
//PHYSICAL ADDRESS
public string Address { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string Country { get; set; }
public string AddressPostal { get; set; }
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
public HeadOffice()
{
Tags = new List<string>();
//UsesBanking = false;
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.HeadOffice; }
}//eoc
}//eons
/*
[AID] [uniqueidentifier] NOT NULL,
[ACREATED] [datetime] NULL,
[AMODIFIED] [datetime] NULL,
[AACTIVE] [bit] NOT NULL,
[ACREATOR] [uniqueidentifier] NULL,
[AMODIFIER] [uniqueidentifier] NULL,
[ANAME] [nvarchar](255) NULL,
[AWEBADDRESS] [nvarchar](255) NULL,
[ACLIENTGROUPID] [uniqueidentifier] NULL,
[ANOTES] [ntext] NULL,
[AREGIONID] [uniqueidentifier] NULL,
[AACCOUNTNUMBER] [nvarchar](255) NULL,
[ACUSTOM1] [ntext] NULL,
[ACUSTOM2] [ntext] NULL,
[ACUSTOM3] [ntext] NULL,
[ACUSTOM4] [ntext] NULL,
[ACUSTOM5] [ntext] NULL,
[ACUSTOM6] [ntext] NULL,
[ACUSTOM7] [ntext] NULL,
[ACUSTOM8] [ntext] NULL,
[ACUSTOM9] [ntext] NULL,
[ACUSTOM0] [ntext] NULL,
[AUSESBANKING] [bit] NOT NULL,
[ACONTRACTID] [uniqueidentifier] NULL,
[ACONTRACTEXPIRES] [datetime] NULL,
[ACONTACTNOTES] [ntext] NULL,
[ACONTACT] [nvarchar](500) NULL,
[APHONE1] [nvarchar](255) NULL,
[APHONE2] [nvarchar](255) NULL,
[APHONE3] [nvarchar](255) NULL,
[APHONE4] [nvarchar](255) NULL,
[APHONE5] [nvarchar](255) NULL,
[AEMAIL] [nvarchar](255) NULL,
*/

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Sockeye.Models
{
/// <summary>
/// Interface for biz object models with standard fields
/// used for batch operations etc
/// </summary>
internal interface ICoreBizObjectModel
{
//Note: almost all biz objects support all these propertys, the exceptions are extremely few so auto-implementing them here
//this is not a public api so I don't care about the "contract" aspect, just practicality
//didn't want to end up with a zillion interfaces for all manner of stuff
public long Id { get; set; }
public uint Concurrency { get; set; }
// public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string Name { get; set; }//any notification on these will require this so making it mandatory but will implement a workaround to return alt fields instead
public bool? Active { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string Wiki { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string CustomFields { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
// public List<string> Tags { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public List<string> Tags { get; set; }//Notification on objects require this so will implement workaround in object instead
public Sockeye.Biz.SockType SType { get; }
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//https://stackoverflow.com/questions/46517584/how-to-add-a-parent-record-with-its-children-records-in-ef-core#46615455
public class Integration
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public Guid IntegrationAppId { get; set; } = Guid.Empty;//Guid of integrating application. All data for it is stored under this guid key. This guid should be fixed and unchanged for all users of the integration app, i.e. it shouldn't be unique to each install but unique to itself once, a publish app id
[Required]
public string Name { get; set; }
public bool Active { get; set; }//integration apps should always check if this is true before working or not and give appropriate error if turned off
public string IntegrationData { get; set; }//foreign object data store for entire integration, can be used for custom data, unused by any Sockeye add-on's, expect json or xml or some other text value here
public List<IntegrationItem> Items { get; set; } = new List<IntegrationItem>();
}//eoc
}//eons
// CREATE TABLE [dbo].[AINTEGRATION](
// [AID] [uniqueidentifier] NOT NULL,
// [ACREATED] [datetime] NULL,
// [AMODIFIED] [datetime] NULL,
// [ACREATOR] [uniqueidentifier] NULL,
// [AMODIFIER] [uniqueidentifier] NULL,
// [AACTIVE] [bit] NOT NULL, <--was set to true at creation of integration in plugins but never used beyond that, was intended to be able to temporarily pause an integration, maybe should enable it to work that way as intended
// [ANAME] [nvarchar](255) NOT NULL,
// [ALASTCONNECT] [datetime] NULL, <=---unused in v7 I'm dropping this as it's always going to be ambiguous and we don't use it anyway, let people put this in the integrationdata as json data in if they want to
// [AIOBJECT] [image] NULL, <--was not used don't bring forward as binary but do bring forward as a IntegrationData string where they can put json or whatever
// [AIOBJECTSIZE] [int] NULL, <- this one either
// [AAPPID] [uniqueidentifier] NOT NULL,
// [AAPPVERSION] [nvarchar](25) NOT NULL, <--unused, not keeping, if people need this they can use the intgrationdata and store as JSON with anything else they need
// [ASYNCCHECKPOINT] [nvarchar](255) NULL, <--unused, not keeping, if people need this they can use the intgrationdata and store as JSON with anything else they need

View File

@@ -0,0 +1,51 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Sockeye.Biz;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//https://stackoverflow.com/questions/46517584/how-to-add-a-parent-record-with-its-children-records-in-ef-core#46615455
public class IntegrationItem
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long IntegrationId { get; set; }
[Required]
public long ObjectId { get; set; }
[Required]
public SockType SockType { get; set; }
[Required]
public string IntegrationItemId { get; set; }//foreign id (e.g. QB Id)
public string IntegrationItemName { get; set; }//foreign object's name for UI, not required if not displayed anywhere
public DateTime? LastSync { get; set; }//optional, used by qbi
public string IntegrationItemData { get; set; }//foreign object data store for this item, unused by any Sockeye add-on's in the past but might be useful for others, expect json or xml or some other text value here
[JsonIgnore]
public Integration Integration { get; set; }
}//eoc
}//eons
// CREATE TABLE [dbo].[AINTEGRATIONMAP](
// [AID] [uniqueidentifier] NOT NULL,
// [ACREATED] [datetime] NOT NULL,
// [AMODIFIED] [datetime] NOT NULL,
// [ACREATOR] [uniqueidentifier] NOT NULL,
// [AMODIFIER] [uniqueidentifier] NOT NULL,
// [AINTEGRATIONID] [uniqueidentifier] NOT NULL,
// [AROOTOBJECTID] [uniqueidentifier] NOT NULL, <--Now "ObjectId"
// [AROOTOBJECTTYPE] [smallint] NOT NULL, <-- now "SockType"
// [AFOREIGNID] [nvarchar](255) NOT NULL, <-- renamed to "IntegrationItemId" still 255 char string
// [ANAME] [nvarchar](255) NULL, <--keep rename to "IntegrationItemName"
// [AFOREIGNCHECKSUM] [nvarchar](255) NULL, drop was not used and thsi is hwat the lastsynch is for anyway
// [ASOCKEYECHECKSUM] [nvarchar](255) NULL, drop was not used and thsi is hwat the lastsynch is for anyway
// [AMAPOBJECT] [image] NULL, Now "IntegrationItemData"
// [AMAPOBJECTSIZE] [int] NULL, dropped, expects to be json data now, size is irrelevant as it's not a binary object anymore
// [ALASTSYNC] [datetime] NOT NULL,

View File

@@ -0,0 +1,34 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Integration log
/// </summary>
public class IntegrationLog
{
public long Id { get; set; }
[Required]
public long IntegrationId { get; set; }
[Required]
public DateTime Created { get; set; }
[Required]
public string StatusText { get; set; }
public IntegrationLog()
{
Created = DateTime.UtcNow;
StatusText = "default / not set";
}
}
}
// CREATE TABLE [dbo].[AINTEGRATIONLOG](
// [ACREATED] [datetime] NOT NULL,
// [ACREATOR] [uniqueidentifier] NOT NULL,
// [AINTEGRATIONID] [uniqueidentifier] NOT NULL,
// [AMESSAGE] [nvarchar](500) NOT NULL

17
server/models/Logo.cs Normal file
View File

@@ -0,0 +1,17 @@
namespace Sockeye.Models
{
public class Logo
{
public long Id { get; set; }
public byte[] Large { get; set; }
public string LargeType {get;set;}
public byte[] Medium { get; set; }
public string MediumType {get;set;}
public byte[] Small { get; set; }
public string SmallType {get;set;}
}
}

61
server/models/Memo.cs Normal file
View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using Sockeye.Biz;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
public class Memo : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }//"subject"
public string Notes { get; set; }//"message"
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
public bool Viewed { get; set; }
public bool Replied { get; set; }
public long? FromId { get; set; }
[NotMapped]
public string FromViz { get; set; }
public long? ToId { get; set; }
[NotMapped]
public string ToViz { get; set; }
public DateTime Sent { get; set; }//redundant but displayed all over the place in the UI so properly redundant
public Memo()
{
Tags = new List<string>();
Sent = DateTime.UtcNow;
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.Memo; }
}//eoc
}//eons
/*
CREATE TABLE [dbo].[AMEMO](
[AID] [uniqueidentifier] NOT NULL,
[ACREATED] [datetime] NULL,
[AMODIFIED] [datetime] NULL,
[ACREATOR] [uniqueidentifier] NULL,
[AMODIFIER] [uniqueidentifier] NULL,
[ASUBJECT] [nvarchar](255) NULL,
[AMESSAGE] [ntext] NULL,
[AFROMID] [uniqueidentifier] NOT NULL,
[ATOID] [uniqueidentifier] NOT NULL,
[AVIEWED] [bit] NOT NULL,
[AREPLIED] [bit] NOT NULL,
*/

33
server/models/MetricDD.cs Normal file
View File

@@ -0,0 +1,33 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Metric for ONE DAY interval stats
/// </summary>
public class MetricDD
{
[Required]
[Key]
public DateTime t { get; set; }
public long AttachmentFileSize { get; set; }
public long AttachmentFileCount { get; set; }
public long AttachmentFilesAvailableSpace { get; set; }
public long UtilityFileSize { get; set; }
public long UtilityFileCount { get; set; }
public long UtilityFilesAvailableSpace { get; set; }
public long DBTotalSize { get; set; }
//ef core requires this
public MetricDD() { t = System.DateTime.UtcNow; }
}//eoc
}//eons

32
server/models/MetricMM.cs Normal file
View File

@@ -0,0 +1,32 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Metric for ONE MINUTE intervals
/// </summary>
public class MetricMM
{
[Required]
[Key]
public DateTime t { get; set; }
public long Allocated { get; set; }
public long WorkingSet { get; set; }
public long PrivateBytes { get; set; }
public double CPU { get; set; }
//ef core requires this
public MetricMM() { }
public MetricMM(long allocated, long workingSet, long privateBytes, double cpu)
{
t = System.DateTime.UtcNow;
Allocated = allocated;
WorkingSet = workingSet;
PrivateBytes = privateBytes;
CPU = cpu;
}
}//eoc
}//eons

View File

@@ -0,0 +1,47 @@
using System;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class InAppNotification
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long UserId { get; set; }
[Required]
public DateTime Created { get; set; }
public SockType? SockType { get; set; }
public long? ObjectId { get; set; }
[Required]
public string Name { get; set; }//object name or closest equivalent for display
[Required]
public NotifyEventType EventType { get; set; }
[Required]
public long NotifySubscriptionId { get; set; }
public string Message { get; set; }
public TimeSpan AgeValue { get; set; }
public decimal DecValue { get; set; }
[Required]
public bool Fetched { get; set; }
public InAppNotification()
{
Created = DateTime.UtcNow;
Fetched = false;
Name = string.Empty;
AgeValue = TimeSpan.Zero;
DecValue = 0m;
}
//linked entity
[JsonIgnore]
public NotifySubscription NotifySubscription { get; set; }
}//eoc
}//eons

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//This model holds the deliveries that have been attempted in the past 90 days (cleaned out by corenotifysweeper)
//it is used for verification / troubleshooting purposes from the OPS log
//and also used as a circuit breaker by the corejobnotify to ensure users are not spammed with identical messages
public class NotifyDeliveryLog
{
public long Id { get; set; }
public uint Concurrency { get; set; }
//public SockType NotifyType { get; set; }
//public long CustomerNotifySubscriptionId {get;set;}
[Required]
public DateTime Processed { get; set; }
public long ObjectId { get; set; }
[Required]
public long NotifySubscriptionId { get; set; }
[Required]
public bool Fail { get; set; }
public string Error { get; set; }
public NotifyDeliveryLog()
{
Processed = DateTime.UtcNow;
Fail = false;
ObjectId = 0;
}
//linked entity
public NotifySubscription NotifySubscription { get; set; }
}//eoc
}//eons

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
//This class holds events that occur in the database for delivery to users
//it's the result of an event happening, not the subscription which is seperate and decides who gets what
//when an object is modified it may create a NotifyEvent record if anyone subscribes to that event
//it will create one of these for every user with that subscription
//which will then be delivered as a notification later when the corejobnotify job runs if it's deliverable
public class NotifyEvent
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public DateTime Created { get; set; }
public SockType SockType { get; set; }
public long ObjectId { get; set; }
[Required]
public string Name { get; set; }//object name or closest equivalent for display
[Required]
public NotifyEventType EventType { get; set; }
[Required]
public long UserId { get; set; }
[Required]
public long NotifySubscriptionId { get; set; }//source subscription that triggered this event to be created
public decimal DecValue { get; set; }
//date of the event actually occuring, e.g. WarrantyExpiry date. Compared with subscription to determine if deliverable or not
public DateTime EventDate { get; set; }
public string Message { get; set; }
public NotifyEvent()
{
Created = EventDate = DateTime.UtcNow;
// IdValue = 0;
DecValue = 0;
SockType = SockType.NoType;
ObjectId = 0;
Name = string.Empty;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.None);
}
//linked entity
// public NotifySubscription NotifySubscription { get; set; }
// public User User { get; set; }
}//eoc
}//eons

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
public class NotifySubscription
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long UserId { get; set; }
public TimeSpan AdvanceNotice { get; set; }
[Required]
public NotifyDeliveryMethod DeliveryMethod { get; set; }
public string DeliveryAddress { get; set; }
public long LinkReportId { get; set; }
//CREATE NOTIFY EVENT CONDITIONS - Following fields are all conditions set on whether to create a notify event or not
public SockType SockType { get; set; }//Note: must be specific object, not global for any object related stuff to avoid many role issues and also potential overload
[Required]
public NotifyEventType EventType { get; set; }
[Required]
public long IdValue { get; set; }//if required, this must match, default is zero to match to not set
public decimal DecValue { get; set; }//if required this must match or be greater or something
public List<string> Tags { get; set; }//Tags to filter an event, object *must* have these tags to generate event related to it (AT TIME OF UPDATE)
//DELIVERY CONDITIONS - following are all conditions on *whether* to deliver the existing notify event or not
public TimeSpan AgeValue { get; set; }//for events that depend on an age of something (e.g. WorkorderStatusAge), This value determines when event has "come of age" but advancenotice controls how far in advance of this delivery is made
public NotifySubscription()
{
Tags = new List<string>();
SockType = SockType.NoType;
IdValue = 0;
DecValue = 0;
AgeValue = TimeSpan.Zero;
AdvanceNotice = TimeSpan.Zero;
LinkReportId = 0;
}
}//eoc
}//eons

69
server/models/OpsJob.cs Normal file
View File

@@ -0,0 +1,69 @@
using System;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
/// <summary>
/// Operations job
/// </summary>
public class OpsJob
{
[Key]
public Guid GId { get; set; }
[Required]
public DateTime Created { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
//------------------------
[Required]
public bool Exclusive { get; set; }//true lock api and don't run other jobs until completed / false=run any time with other jobs async
public DateTime StartAfter { get; set; }
[Required]
public JobType JobType { get; set; }
public JobSubType SubType { get; set; }
public long ObjectId { get; set; }
public SockType SockType { get; set; }
[Required]
public JobStatus JobStatus { get; set; }
/// <summary>
/// Json string of any required extra info for job
/// </summary>
public string JobInfo { get; set; }//json as string of any required extra info for job
public string Progress {get;set;}//any type of text digestible by client showing progress of job, typically just a string i.e. "133/344"
public OpsJob()
{
GId = new Guid();
Created = DateTime.UtcNow;
Name = "new job";
Exclusive = false;
StartAfter = Created;
JobType = JobType.NotSet;
SubType = JobSubType.NotSet;
ObjectId = 0;
SockType = SockType.NoType;
JobStatus = JobStatus.Sleeping;
JobInfo = null;
Progress=string.Empty;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.None);
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Operations job log
/// </summary>
public class OpsJobLog
{
[Key]
public Guid GId { get; set; }
[Required]
public Guid JobId { get; set; }
[Required]
public DateTime Created { get; set; }
[Required]
public string StatusText { get; set; }
public OpsJobLog(){
GId=new Guid();
Created=DateTime.UtcNow;
StatusText="default / not set";
}
}
}

View File

@@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
//See core-picklist-autocomplete-template-system.txt for details
public class PickListTemplate
{
public long Id { get; set; }
public uint Concurrency { get; set; }
public string Template { get; set; }//JSON fragment of picklist template
}
}

75
server/models/Reminder.cs Normal file
View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
public class Reminder : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
// public bool Active { get; set; }
public string Notes { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime StopDate { get; set; }
[Required]
public long UserId { get; set; }
[NotMapped]
public string UserViz { get; set; }
/*
Hexadecimal notation: #RGB[A]
R (red), G (green), B (blue), and A (alpha) are hexadecimal characters (09, AF). A is optional. The three-digit notation (#RGB) is a shorter version of the six-digit form (#RRGGBB). For example, #f09 is the same color as #ff0099. Likewise, the four-digit RGB notation (#RGBA) is a shorter version of the eight-digit form (#RRGGBBAA). For example, #0f38 is the same color as #00ff3388.
*/
[MaxLength(12)]
public string Color { get; set; }
public Reminder()
{
Tags = new List<string>();
Color = "#ffffffff";//white / no color is the default
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.Reminder; }
}//eoc
}//eons
/*
DATES should be indexed for fast viewing
CREATE TABLE [dbo].[ASCHEDULEMARKER](
[AID] [uniqueidentifier] NOT NULL,
[ACREATED] [datetime] NOT NULL,
[ACREATOR] [uniqueidentifier] NOT NULL,
[AMODIFIER] [uniqueidentifier] NOT NULL,
[ANAME] [nvarchar](255) NULL,
[ANOTES] [ntext] NULL,
[AMODIFIED] [datetime] NULL,
[ASTARTDATE] [datetime] NULL,
[ASTOPDATE] [datetime] NULL,
[ASCHEDULEMARKERSOURCETYPE] [smallint] NULL,
[ASOURCEID] [uniqueidentifier] NOT NULL,
[AARGB] [int] NULL,
NOPE: these are for Review, not reminder
[AFOLLOWID] [uniqueidentifier] NULL,
[AFOLLOWTYPE] [smallint] NULL,
[ACOMPLETED] [bit] NOT NULL,
*/

66
server/models/Report.cs Normal file
View File

@@ -0,0 +1,66 @@
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class Report
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
public bool Active { get; set; }
public string Notes { get; set; }
public AuthorizationRoles Roles { get; set; }
[Required]
public SockType SockType { get; set; }
public bool IncludeWoItemDescendants {get;set;}
public string Template { get; set; }
public string Style { get; set; }
public string JsPrerender { get; set; }
public string JsHelpers { get; set; }
[Required]
public ReportRenderType RenderType { get; set; }
//PDF options
//http://www.puppeteersharp.com/api/PuppeteerSharp.PdfOptions.html
public string HeaderTemplate { get; set; }
public string FooterTemplate { get; set; }
public bool DisplayHeaderFooter { get; set; }
public ReportPaperFormat PaperFormat { get; set; }
public bool Landscape { get; set; }
public string MarginOptionsBottom { get; set; }
public string MarginOptionsLeft { get; set; }
public string MarginOptionsRight { get; set; }
public string MarginOptionsTop { get; set; }
public string PageRanges { get; set; }
public bool PreferCSSPageSize { get; set; }
public bool PrintBackground { get; set; }
public decimal Scale { get; set; }
public Report()
{
RenderType = ReportRenderType.PDF;
SockType = SockType.NoType;
Roles = AuthorizationRoles.All;
Active = true;
//these are pdf option defaults as per PuppeteerSharp
DisplayHeaderFooter=false;
PaperFormat=ReportPaperFormat.NotSet;
Landscape=false;
PreferCSSPageSize=false;
PrintBackground=false;
Scale=1;
}
}//eoc
}//eons

86
server/models/Review.cs Normal file
View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
//NOTE: Any non required field (nullable in DB) sb nullable here, i.e. decimal? not decimal,
//otherwise the server will call it an invalid record if the field isn't sent from client
public class Review : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
// public bool Active { get; set; }//NOT USED
public string Notes { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
[Required]
public DateTime ReviewDate { get; set; }
public DateTime? CompletedDate { get; set; }
public string CompletionNotes { get; set; }
[Required]
public long UserId { get; set; }
[NotMapped]
public string UserViz { get; set; }
[Required]
public long AssignedByUserId { get; set; }
[NotMapped]
public string AssignedByUserViz { get; set; }
[Required]
public long ObjectId { get; set; }
[Required]
public SockType SType { get; set; }//int
[NotMapped]
public string ReviewObjectViz { get; set; }
[NotMapped]
public bool OverDue
{
get
{
return (ReviewDate > DateTime.UtcNow);
}
}
public Review()
{
Tags = new List<string>();
}
[NotMapped, JsonIgnore]
public SockType SockType { get => SockType.Review; }
}//eoc
}//eons
/*
DATES should be indexed for fast viewing
CREATE TABLE [dbo].[ASCHEDULEMARKER](
[AID] [uniqueidentifier] NOT NULL,
[ACREATED] [datetime] NOT NULL,
[ACREATOR] [uniqueidentifier] NOT NULL,
[AMODIFIER] [uniqueidentifier] NOT NULL,
[ANAME] [nvarchar](255) NULL,
[ANOTES] [ntext] NULL,
[AMODIFIED] [datetime] NULL,
[ASTARTDATE] [datetime] NULL,
[ASTOPDATE] [datetime] NULL,
[ASCHEDULEMARKERSOURCETYPE] [smallint] NULL,
[ASOURCEID] [uniqueidentifier] NOT NULL,
[AARGB] [int] NULL,
[AFOLLOWID] [uniqueidentifier] NULL,
[AFOLLOWTYPE] [smallint] NULL,
[ACOMPLETED] [bit] NOT NULL,
*/

View File

@@ -0,0 +1,22 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
/// <summary>
/// Sockeye Schema version table
/// </summary>
public class SchemaVersion
{
[Required]
[Key]
public string Id { get; set; }
public int Schema { get; set; }
//ef core requires this
public SchemaVersion() { }
}//eoc
}//eons

View File

@@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class SearchDictionary
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required, MaxLength(255)]
public string Word { get; set; }//max 255 characters ascii set
}
}

View File

@@ -0,0 +1,24 @@
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class SearchKey
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long WordId { get; set; }
[Required]
public long ObjectId { get; set; }
[Required]
public SockType SockType { get; set; }
}
}

17
server/models/Tag.cs Normal file
View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Sockeye.Models
{
public class Tag
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required, MaxLength(255)]
public string Name { get; set; }//max 255 characters
public long RefCount { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class Translation
{
// public Translation() { }
// public Translation(Translation t)
// {
// Id = t.Id;
// Concurrency = t.Concurrency;
// Name = t.Name;
// CjkIndex = t.CjkIndex;
// _translationItems = new List<TranslationItem>();
// foreach (var titem in t.TranslationItems)
// {
// _translationItems.Add(new TranslationItem(titem));
// }
// }
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string BaseLanguage { get; set; }
public bool? Stock { get; set; }
public bool CjkIndex { get; set; }
//Relationship
//was this but..
// public ICollection<TranslationItem> TranslationItems { get; set; }
//Not perhaps so useful here but this is a good way to lazy initialize collections which
//is more efficient when there are many child collections (but when would that ever be desired for Sockeye?)and means no need to null check the collection
//https://stackoverflow.com/a/20773057/8939
private ICollection<TranslationItem> _translationItems;
public virtual ICollection<TranslationItem> TranslationItems
{
get
{
return this._translationItems ?? (this._translationItems = new HashSet<TranslationItem>());
}
}
}//eoc
}//eons

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class TranslationItem
{
public TranslationItem() { }
public TranslationItem(TranslationItem t)
{
Id = t.Id;
Concurrency = t.Concurrency;
Key = t.Key;
Display = t.Display;
TranslationId = t.TranslationId;
}
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Key { get; set; }
//NOTE: due to various UI fuckery this is not set to required here so that the biz object
//validate code can fix it up automatically instead
public string Display { get; set; }
public long TranslationId { get; set; }
//Relation
[JsonIgnore]
public Translation Translation { get; set; }
}
}

149
server/models/User.cs Normal file
View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using Sockeye.Biz;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class dtUser : ICoreBizObjectModel//used to return user object without auth related fields in UserGet route
{
public dtUser()
{
Tags = new List<string>();
}
public long Id { get; set; }
public uint Concurrency { get; set; }
public bool Active { get; set; }
public bool AllowLogin { get; set; }
[Required, MaxLength(255)]
public string Name { get; set; }
public AuthorizationRoles Roles { get; set; }
public UserType UserType { get; set; }
public string EmployeeNumber { get; set; }
public string Notes { get; set; }
public long? CustomerId { get; set; }
public long? HeadOfficeId { get; set; }
public long? VendorId { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTime? LastLogin { get; set; }
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.User; }
public bool IsOutsideUser
{
get
{
return this.UserType == UserType.Customer || this.UserType == UserType.HeadOffice;
}
}
// [JsonIgnore]//hide from being returned (as null anyway) with User object in routes
// public UserOptions UserOptions { get; set; }
}//eoc
public class User : ICoreBizObjectModel
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public bool Active { get; set; }
public bool AllowLogin { get; set; }
[Required, MaxLength(255)]
public string Name { get; set; }
public DateTime? LastLogin { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public bool TwoFactorEnabled { get; set; }
[Required]
public AuthorizationRoles Roles { get; set; }
[Required]
public UserType UserType { get; set; }
[NotMapped]
public string UserTypeViz { get; set; }
[MaxLength(255)]
public string EmployeeNumber { get; set; }
public string Notes { get; set; }
public long? CustomerId { get; set; }
[NotMapped]
public string CustomerViz { get; set; }
public long? HeadOfficeId { get; set; }
[NotMapped]
public string HeadOfficeViz { get; set; }
public long? VendorId { get; set; }
[NotMapped]
public string VendorViz { get; set; }
public string Wiki { get; set; }
public string CustomFields { get; set; }
public List<string> Tags { get; set; }
//======================
//NOT IN DTUSER CLASS
[JsonIgnore]
public string Salt { get; set; }//---
[JsonIgnore]
public string CurrentAuthToken { get; set; }//---
[JsonIgnore]
public string DlKey { get; set; }//---
[JsonIgnore]
public DateTime? DlKeyExpire { get; set; }//---
[JsonIgnore]
public string PasswordResetCode { get; set; }//---
[JsonIgnore]
public DateTime? PasswordResetCodeExpire { get; set; }//---
[JsonIgnore]
public string TotpSecret { get; set; }//---
[JsonIgnore]
public string TempToken { get; set; }//--- Used for TFA verification step 2
//==========================
//relations
//https://docs.microsoft.com/en-us/ef/core/modeling/relationships#other-relationship-patterns
[JsonIgnore]//hide from being returned (as null anyway) with User object in routes
public UserOptions UserOptions { get; set; }
[JsonIgnore]
public Customer Customer { get; set; }
[JsonIgnore]
public HeadOffice HeadOffice { get; set; }
public User()
{
Tags = new List<string>();
}
public bool IsTech
{
get
{
return this.UserType == UserType.ServiceContractor || this.UserType == UserType.Service;
}
}
public bool IsOutsideCustomerContactTypeUser
{
get
{
return this.UserType == UserType.Customer || this.UserType == UserType.HeadOffice;
}
}
[NotMapped, JsonIgnore]
public SockType SType { get => SockType.User; }
}//eoc
}

View File

@@ -0,0 +1,135 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Sockeye.Models
{
public class UserOptions
{
public long Id { get; set; }
public uint Concurrency { get; set; }
[Required]
public long TranslationId { get; set; }
//-------------
//[EmailAddress]
public string EmailAddress { get; set; }
// [Phone]
public string Phone1 { get; set; }
//[Phone]
public string Phone2 { get; set; }
//in v7 this was pager address so not attributing it with Phone as not sure what would be in that field
public string Phone3 { get; set; }
/*
Hexadecimal notation: #RGB[A]
R (red), G (green), B (blue), and A (alpha) are hexadecimal characters (09, AF). A is optional. The three-digit notation (#RGB) is a shorter version of the six-digit form (#RRGGBB). For example, #f09 is the same color as #ff0099. Likewise, the four-digit RGB notation (#RGBA) is a shorter version of the eight-digit form (#RRGGBBAA). For example, #0f38 is the same color as #00ff3388.
*/
[MaxLength(12)]
public string UiColor { get; set; }
//browser forced overrides
public string LanguageOverride { get; set; }
public string TimeZoneOverride { get; set; }
public string CurrencyName { get; set; }
public bool Hour12 { get; set; }
public string MapUrlTemplate { get; set; }
//relations
//https://docs.microsoft.com/en-us/ef/core/modeling/relationships#other-relationship-patterns
[JsonIgnore]//hide from being returned (as null anyway) in routes
public User User { get; set; }
[Required]
public long UserId { get; set; }//will be auto-set by EF due to relationship defined
public UserOptions()
{
CurrencyName = "USD";
Hour12 = true;
UiColor = "#ffffffff";//black is the default
}
}
}
/*
v7 export record sample
{
"DefaultLanguage": "Custom English",
"DefaultServiceTemplateID": "ca83a7b8-4e5f-4a7b-a02b-9cf78d5f983f",
"UserType": 2,
"Active": true,
"ClientID": "00000000-0000-0000-0000-000000000000",
"HeadOfficeID": "00000000-0000-0000-0000-000000000000",
"MemberOfGroup": "0f8a80ff-4b03-4114-ae51-2d13b812dd65",
"Created": "03/21/2005 07:19 AM",
"Modified": "09/15/2015 12:22 PM",
"Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"Modifier": "1d859264-3f32-462a-9b0c-a67dddfdf4d3",
"ID": "1d859264-3f32-462a-9b0c-a67dddfdf4d3",
"FirstName": "Hank",
"LastName": "Rearden",
"Initials": "HR",
"EmployeeNumber": "EMP1236",
"PageAddress": "",
"PageMaxText": 24,
"Phone1": "",
"Phone2": "",
"EmailAddress": "",
"UserCertifications": [
{
"Created": "12/22/2005 02:07 PM",
"Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"Modified": "12/22/2005 02:08 PM",
"Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"ID": "4492360c-43e4-4209-9f33-30691b0808ed",
"UserCertificationID": "b2f26359-7c42-4218-923a-e949f3ef1f85",
"UserID": "1d859264-3f32-462a-9b0c-a67dddfdf4d3",
"ValidStartDate": "2005-10-11T00:00:00-07:00",
"ValidStopDate": "2006-10-11T00:00:00-07:00"
}
],
"UserSkills": [
{
"Created": "12/22/2005 02:06 PM",
"Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"Modified": "12/22/2005 02:08 PM",
"Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"ID": "1dc5ce96-f411-4885-856e-5bdb3ad79728",
"UserSkillID": "2e6f8b65-594c-4f6c-9cd6-e14a562daba8",
"UserID": "1d859264-3f32-462a-9b0c-a67dddfdf4d3"
},
{
"Created": "12/22/2005 02:06 PM",
"Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"Modified": "12/22/2005 02:08 PM",
"Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed",
"ID": "88e476d3-7526-45f5-a0dd-706c8053a63f",
"UserSkillID": "47a4ee94-b0e9-41b5-afe5-4b4f2c981877",
"UserID": "1d859264-3f32-462a-9b0c-a67dddfdf4d3"
}
],
"Notes": "",
"VendorID": "06e502c2-69ba-4e88-8efb-5b53c1687740",
"RegionID": "f856423a-d468-4344-b7b8-121e466738c6",
"DispatchZoneID": "00000000-0000-0000-0000-000000000000",
"SubContractor": false,
"DefaultWarehouseID": "d45eab37-b6e6-4ad2-9163-66d7ba83a98c",
"Custom1": "",
"Custom2": "",
"Custom3": "",
"Custom4": "",
"Custom5": "",
"Custom6": "",
"Custom7": "",
"Custom8": "",
"Custom9": "",
"Custom0": "",
"ScheduleBackColor": -2097216,
"TimeZoneOffset": null
}
*/

View File

@@ -0,0 +1,8 @@
namespace Sockeye.Models
{
//physical
public record AddressRecord(string Name, string Address, string City, string Region, string Country, string AddressPostal, decimal? Latitude, decimal? Longitude);
//postal
public record PostalAddressRecord(string Name, string PostAddress, string PostCity, string PostRegion, string PostCountry, string PostCode);
}

View File

@@ -0,0 +1,19 @@
using System;
using Sockeye.Biz;
using Newtonsoft.Json.Linq;
namespace Sockeye.Models
{
/// <summary>
/// Import data object used by admin->import feature
/// </summary>
public class AyImportData
{
public SockType SockType { get; set; }
public JArray Data { get; set; }
public bool DoImport {get;set;}
public bool DoUpdate {get;set;}
}
}

View File

@@ -0,0 +1,40 @@
using Sockeye.Biz;
using System;
namespace Sockeye.Models
{
/// <summary>
/// Job info fetch data
/// </summary>
public class JobOperationsFetchInfo
{
/// <summary>
/// Identity of the job
/// </summary>
/// <returns> id value of job, can be used to fetch logs</returns>
public Guid GId { get; set; }
/// <summary>
/// Date job was submitted
/// </summary>
/// <returns>UTC date/time</returns>
public DateTime Created { get; set; }
/// <summary>
/// Date of the most recent operation for this job
/// </summary>
/// <returns>UTC date/time</returns>
public DateTime LastAction { get; set; }
/// <summary>
/// Descriptive name of the job
/// </summary>
/// <returns>string</returns>
public string Name { get; set; }
/// <summary>
/// Status of the job
/// </summary>
/// <returns>Job status as string</returns>
public string JobStatus { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace Sockeye.Models
{
/// <summary>
/// Job log item
/// </summary>
public class JobOperationsLogInfoItem
{
public DateTime Created { get; set; }
public string StatusText { get; set; }
public Guid JobId { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
using Sockeye.Biz;
using System;
namespace Sockeye.Models
{
/// <summary>
/// Job Progress
/// </summary>
public class JobProgress
{
/// <summary>
/// Progress string
/// </summary>
/// <returns>string</returns>
public string Progress { get; set; }
/// <summary>
/// Status of the job
/// </summary>
/// <returns>Job status</returns>
public JobStatus JobStatus { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
namespace Sockeye.Models
{
//Used by QBI for part and service /travel rate lists for caching and mapping
public class NameIdActiveChargeCostItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public decimal Cost { get; set; }
public decimal Charge { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace Sockeye.Models
{
public class NameIdActiveItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool? Active { get; set; }
}
}

View File

@@ -0,0 +1,4 @@
namespace Sockeye.Models
{
public record NameIdDefaultItem(long Id, string Name, bool Default);
}

View File

@@ -0,0 +1,10 @@
namespace Sockeye.Models
{
public class NameIdItem
{
public long Id { get; set; }
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace Sockeye.Models
{
/// <summary>
/// Dto object for name only parameters in routes
/// </summary>
public class NameItem
{
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace Sockeye.Models
{
public class NewTextIdConcurrencyTokenItem
{
public long Id { get; set; }
public string NewText { get; set; }
public uint Concurrency { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Sockeye.Models
{
public class ParentAndChildItemId
{
public long ParentId { get; set; }
public long ChildItemId { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using Sockeye.Biz;
namespace Sockeye.Models
{
public class ScheduleItemAdjustParams
{
public SockType Type { get; set; }
public long Id { get; set; }
public long? UserId { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Sockeye.Models
{
public class UploadFileData
{
public string name { get; set; }
public long lastModified { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace Sockeye.Models
{
/// <summary>
/// Uploaded file info in it's temporary state
/// </summary>
public class UploadedFileInfo
{
public string InitialUploadedPathName { get; set; }
public string OriginalFileName { get; set; }
public string MimeType { get; set; }
public DateTime LastModified {get;set;}
}
}