diff --git a/server/AyaNova/biz/BizObjectExistsInDatabase.cs b/server/AyaNova/biz/BizObjectExistsInDatabase.cs index 31caa303..14d33686 100644 --- a/server/AyaNova/biz/BizObjectExistsInDatabase.cs +++ b/server/AyaNova/biz/BizObjectExistsInDatabase.cs @@ -155,6 +155,8 @@ namespace AyaNova.Biz // return await ct.ServiceBank.AnyAsync(z => z.Id == id); case AyaType.CustomerServiceRequest: return await ct.CustomerServiceRequest.AnyAsync(z => z.Id == id); + case AyaType.CustomerNotifySubscription: + return await ct.CustomerNotifySubscription.AnyAsync(z => z.Id == id); default: throw new System.NotSupportedException($"AyaNova.Biz.BizObjectExistsInDatabase::ExistsAsync type {aType.ToString()} is not supported"); } diff --git a/server/AyaNova/biz/BizObjectFactory.cs b/server/AyaNova/biz/BizObjectFactory.cs index 2efec0f0..f3077886 100644 --- a/server/AyaNova/biz/BizObjectFactory.cs +++ b/server/AyaNova/biz/BizObjectFactory.cs @@ -143,6 +143,8 @@ namespace AyaNova.Biz // return new ServiceBankBiz(ct, userId, translationId, roles); case AyaType.CustomerServiceRequest: return new CustomerServiceRequestBiz(ct, userId, translationId, roles); + case AyaType.CustomerNotifySubscription: + return new CustomerNotifySubscriptionBiz(ct, userId, translationId, roles); case AyaType.TaskGroup: return new TaskGroupBiz(ct, userId, translationId, roles); case AyaType.UnitMeterReading: diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs index 29492982..3a7da4f4 100644 --- a/server/AyaNova/biz/BizRoles.cs +++ b/server/AyaNova/biz/BizRoles.cs @@ -68,6 +68,22 @@ namespace AyaNova.Biz Select = AuthorizationRoles.All }); + + //////////////////////////////////////////////////////////// + //CUSTOMER PROXY NOTIFICATION SUBSCRIPTIONS + // + roles.Add(AyaType.CustomerNotifySubscription, new BizRoleSet() + { + Change = AuthorizationRoles.BizAdmin + | AuthorizationRoles.Service, + ReadFullRecord = AuthorizationRoles.BizAdminRestricted + | AuthorizationRoles.ServiceRestricted + | AuthorizationRoles.Tech + | AuthorizationRoles.SalesRestricted + , + Select = AuthorizationRoles.All + }); + //////////////////////////////////////////////////////////// //Contract // diff --git a/server/AyaNova/biz/CustomerNotifySubscriptionBiz.cs b/server/AyaNova/biz/CustomerNotifySubscriptionBiz.cs new file mode 100644 index 00000000..55087f37 --- /dev/null +++ b/server/AyaNova/biz/CustomerNotifySubscriptionBiz.cs @@ -0,0 +1,175 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using AyaNova.Util; +using AyaNova.Api.ControllerHelpers; +using AyaNova.Models; +using System.Linq; + +namespace AyaNova.Biz +{ + internal class CustomerNotifySubscriptionBiz : BizObject//, IJobObject, ISearchAbleObject + { + internal CustomerNotifySubscriptionBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) + { + ct = dbcontext; + UserId = currentUserId; + UserTranslationId = userTranslationId; + CurrentUserRoles = UserRoles; + BizType = AyaType.CustomerNotifySubscription; + } + + internal static CustomerNotifySubscriptionBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) + { + if (httpContext != null) + return new CustomerNotifySubscriptionBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); + else + return new CustomerNotifySubscriptionBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //EXISTS + internal async Task ExistsAsync(long id) + { + return await ct.CustomerNotifySubscription.AnyAsync(z => z.Id == id); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //CREATE + // + internal async Task CreateAsync(CustomerNotifySubscription newObject) + { + await ValidateAsync(newObject); + if (HasErrors) + return null; + else + { + newObject.Tags = TagBiz.NormalizeTags(newObject.Tags); + newObject.CustomerTags = TagBiz.NormalizeTags(newObject.CustomerTags); + + await ct.CustomerNotifySubscription.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.CustomerTags, null); + return newObject; + } + } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // GET + // + internal async Task GetAsync(long id, bool logTheGetEvent = true) + { + var ret = await ct.CustomerNotifySubscription.AsNoTracking().SingleOrDefaultAsync(z => z.Id == id); + if (logTheGetEvent && ret != null) + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, AyaEvent.Retrieved), ct); + return ret; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //UPDATE + // + internal async Task PutAsync(CustomerNotifySubscription putObject) + { + //TODO: Must remove all prior events and replace them + + var dbObject = await GetAsync(putObject.Id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + if (dbObject.Concurrency != putObject.Concurrency) + { + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + putObject.CustomerTags = TagBiz.NormalizeTags(putObject.CustomerTags); + putObject.Tags = TagBiz.NormalizeTags(putObject.Tags); + await ValidateAsync(putObject); + if (HasErrors) return null; + ct.Replace(dbObject, putObject); + if (HasErrors) return null; + try + { + await ct.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!await ExistsAsync(putObject.Id)) + AddError(ApiErrorCode.NOT_FOUND); + else + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.Tags, dbObject.Tags); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.CustomerTags, dbObject.CustomerTags); + return putObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DELETE + // + internal async Task DeleteAsync(long id) + { + + using (var transaction = await ct.Database.BeginTransactionAsync()) + { + var dbObject = await GetAsync(id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND); + return false; + } + //ValidateCanDelete(dbObject); + if (HasErrors) + return false; + { + var IDList = await ct.Review.AsNoTracking().Where(x => x.AType == AyaType.CustomerNotifySubscription && x.ObjectId == id).Select(x => x.Id).ToListAsync(); + if (IDList.Count() > 0) + { + ReviewBiz b = new ReviewBiz(ct, UserId, UserTranslationId, CurrentUserRoles); + foreach (long ItemId in IDList) + if (!await b.DeleteAsync(ItemId, transaction)) + { + AddError(ApiErrorCode.CHILD_OBJECT_ERROR, null, $"Review [{ItemId}]: {b.GetErrorsAsString()}"); + return false; + } + } + } + ct.CustomerNotifySubscription.Remove(dbObject); + await ct.SaveChangesAsync(); + + //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.EventType.ToString(), ct); + await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.CustomerTags); + + + await transaction.CommitAsync(); + + return true; + } + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //VALIDATION + // + private async Task ValidateAsync(CustomerNotifySubscription proposedObj) + { + await Task.CompletedTask; + + } + + + ///////////////////////////////////////////////////////////////////// + + }//eoc + + +}//eons + diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs index ab5dec53..ab1c1504 100644 --- a/server/AyaNova/models/AyContext.cs +++ b/server/AyaNova/models/AyContext.cs @@ -127,6 +127,8 @@ namespace AyaNova.Models public virtual DbSet ViewPartInventoryRequestList { get; set; } public virtual DbSet ViewScheduleWorkOrder { get; set; } + public virtual DbSet CustomerNotifySubscription { 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 diff --git a/server/AyaNova/resource/de.json b/server/AyaNova/resource/de.json index b3f4eca0..d657711d 100644 --- a/server/AyaNova/resource/de.json +++ b/server/AyaNova/resource/de.json @@ -181,6 +181,8 @@ "CustomerNoteNoteDate": "Datum der Anmerkung", "CustomerNoteNotes": "Anmerkungen", "CustomerNotes": "Allgemeine Anmerkungen", + "CustomerNotifySubscription": "Abonnement für Kundenbenachrichtigungen", + "CustomerNotifySubscriptionList":"Abonnements für Kundenbenachrichtigungen", "CustomerPhone1": "Geschäftstelefon", "CustomerPhone2": "Fax", "CustomerPhone3": "Festnetztelefon", diff --git a/server/AyaNova/resource/en.json b/server/AyaNova/resource/en.json index 738f981a..a4e1d35f 100644 --- a/server/AyaNova/resource/en.json +++ b/server/AyaNova/resource/en.json @@ -181,6 +181,8 @@ "CustomerNoteNoteDate": "Note Date", "CustomerNoteNotes": "Notes", "CustomerNotes": "General Notes", + "CustomerNotifySubscription": "Customer notification subscription", + "CustomerNotifySubscriptionList":"Customer notification subscriptions", "CustomerPhone1": "Business", "CustomerPhone2": "Fax", "CustomerPhone3": "Home", diff --git a/server/AyaNova/resource/es.json b/server/AyaNova/resource/es.json index a2d3f973..22391cdc 100644 --- a/server/AyaNova/resource/es.json +++ b/server/AyaNova/resource/es.json @@ -181,6 +181,8 @@ "CustomerNoteNoteDate": "Fecha nota", "CustomerNoteNotes": "Notas", "CustomerNotes": "Notas generales", + "CustomerNotifySubscription": "Suscripción de notificación al cliente", + "CustomerNotifySubscriptionList":"Suscripciones de notificaciones de clientes", "CustomerPhone1": "Teléfono", "CustomerPhone2": "Fax", "CustomerPhone3": "Teléfono de casa", diff --git a/server/AyaNova/resource/fr.json b/server/AyaNova/resource/fr.json index e126e966..ea0b6f12 100644 --- a/server/AyaNova/resource/fr.json +++ b/server/AyaNova/resource/fr.json @@ -181,6 +181,8 @@ "CustomerNoteNoteDate": "Date de note", "CustomerNoteNotes": "Remarques", "CustomerNotes": "Notes générales", + "CustomerNotifySubscription": "Abonnement aux notifications clients", + "CustomerNotifySubscriptionList":"Abonnements aux notifications client", "CustomerPhone1": "Téléphone de travail", "CustomerPhone2": "Fax", "CustomerPhone3": "Téléphone fixe", diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 9e536898..2b16a953 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -363,124 +363,6 @@ $BODY$; "); - - /* - - -- FUNCTION: public.aygetnameex(bigint, integer) - -- DROP FUNCTION IF EXISTS public.aygetnameex(bigint, integer); - - CREATE OR REPLACE FUNCTION PUBLIC.AYGETNAMEEX(AYOBJECTID bigint, AYATYPE integer, TRANSLATIONID integer) RETURNS text LANGUAGE 'plpgsql' COST 100 STABLE PARALLEL UNSAFE AS $BODY$ - DECLARE - aytable TEXT DEFAULT ''; - aynamecolumn TEXT DEFAULT 'name'; - aytkey TEXT DEFAULT 'no'; - returnstr TEXT DEFAULT ''; - BEGIN - case ayatype - when 0 then aytkey= 'NoType'; - when 1 then aytkey= 'Global'; - when 2 then return 'FormUserOptions'; - when 3 then aytable = 'auser'; - when 4 then aytkey= 'ServerState'; - when 5 then aytkey= 'License'; - when 6 then aytkey= 'LogFile'; - when 7 then aytkey= 'PickListTemplate'; - when 8 then aytable = 'acustomer'; - when 9 then aytkey= 'ServerJob'; - when 10 then aytable = 'acontract'; - when 11 then aytkey= 'TrialSeeder'; - when 12 then aytkey= 'ServerMetrics'; - when 13 then aytable = 'atranslation'; - when 14 then aytkey= 'UserOptions'; - when 15 then aytable = 'aheadoffice'; - when 16 then aytable = 'aloanunit'; - when 17 then aytable = 'afileattachment'; aynamecolumn ='displayfilename'; - when 18 then aytable = 'adatalistsavedfilter'; - when 19 then aytable = 'aformcustom'; aynamecolumn = 'formkey'; - when 20 then aytable = 'apart'; - when 21 then aytable = 'apm'; aynamecolumn ='serial'; - when 22 then aytkey= 'PMItem'; - when 23 then aytkey= 'WorkOrderItemExpense'; - when 24 then aytkey= 'WorkOrderItemLabor'; - when 25 then aytable = 'aproject'; - when 26 then aytable = 'apurchaseorder'; aynamecolumn = 'serial'; - when 27 then aytable = 'aquote'; aynamecolumn = 'serial'; - when 28 then aytkey= 'QuoteItem'; - when 29 then aytkey= 'WorkOrderItemLoan'; - when 30 then aytkey= 'WorkOrderItemPart'; - when 31 then aytable = 'aunit'; aynamecolumn = 'serial'; - when 32 then aytable = 'aunitmodel'; aynamecolumn = 'name'; - when 33 then aytable = 'avendor'; - when 34 then aytable = 'aworkorder'; aynamecolumn = 'serial'; - when 35 then aytkey= 'WorkOrderItem'; - when 36 then aytkey= 'WorkOrderItemExpense'; - when 37 then aytkey= 'WorkOrderItemLabor'; - when 38 then aytkey= 'WorkOrderItemLoan'; - when 39 then aytkey= 'WorkOrderItemPart'; - when 40 then aytkey= 'WorkOrderItemPartRequest'; - when 41 then aytkey= 'WorkOrderItemScheduledUser'; - when 42 then aytkey= 'WorkOrderItemTask'; - when 43 then aytkey= 'WorkOrderItemTravel'; - when 44 then aytkey= 'WorkOrderItemUnit'; - when 45 then aytkey= 'WorkOrderItemScheduledUser'; - when 46 then aytkey= 'WorkOrderItemTask'; - when 47 then aytkey= 'GlobalOps'; - when 48 then aytkey= 'BizMetrics'; - when 49 then aytkey= 'Backup'; - when 50 then aytable = 'ainappnotification'; - when 51 then aytkey= 'NotifySubscription'; - when 52 then aytable = 'areminder'; - when 53 then aytkey= 'UnitMeterReading'; - when 54 then aytable = 'acustomerservicerequest'; - when 56 then aytkey= 'OpsNotificationSettings'; - when 57 then aytable = 'areport'; - when 58 then aytkey= 'DashBoardView'; - when 59 then aytable = 'acustomernote'; aynamecolumn = 'notedate'; - when 60 then aytable = 'amemo'; - when 61 then aytable = 'areview'; - when 62 then aytable = 'aservicerate'; - when 63 then aytable = 'atravelrate'; - when 64 then aytable = 'ataxcode'; - when 65 then aytable = 'apartassembly'; - when 66 then aytable = 'apartwarehouse'; - when 67 then aytable = 'apartinventory'; aynamecolumn='description'; - when 68 then return format('DataListColumnView %L', ayobjectid); - when 71 then aytable = 'aworkorderstatus'; - when 72 then aytable = 'aTaskGroup'; - when 73 then aytkey= 'WorkOrderItemOutsideService'; - when 74 then aytable = 'aWorkOrderItemPriority'; - when 75 then aytable = 'aWorkOrderItemStatus'; - when 76 then aytkey= 'WorkOrderItemTravel'; - when 77 then aytkey= 'WorkOrderItemUnit'; - when 78 then aytable = 'aquotestatus'; - when 79 then aytkey= 'WorkOrderItemOutsideService'; - when 80 then aytkey= 'WorkOrderItemExpense'; - when 81 then aytkey= 'WorkOrderItemLabor'; - when 82 then aytkey= 'WorkOrderItemLoan'; - when 83 then aytkey= 'WorkOrderItemPart'; - when 84 then aytkey= 'WorkOrderItemPartRequest'; - when 85 then aytkey= 'WorkOrderItemScheduledUser'; - when 86 then aytkey= 'WorkOrderItemTask'; - when 87 then aytkey= 'WorkOrderItemTravel'; - when 88 then aytkey= 'WorkOrderItemUnit'; - when 89 then aytkey= 'WorkOrderItemOutsideService'; - else - RETURN returnstr; - end case; - - IF aytkey='no' then - EXECUTE format('SELECT %I FROM %I WHERE id = %L', aynamecolumn, aytable, ayobjectid) INTO returnstr; - else - EXECUTE format('select display from atranslationitem where translationid=%L and key=%L', TRANSLATIONID, aytkey) INTO returnstr; - END if; - RETURN returnstr; - END; - $BODY$; - - - ALTER FUNCTION PUBLIC.AYGETNAME(bigint, integer) OWNER TO POSTGRES; - */ - //Name fetcher function //CoreBizObject ADD here await ExecQueryAsync(@" @@ -573,7 +455,7 @@ BEGIN when 81 then aytkey= 'WorkOrderItemLabor'; when 82 then aytkey= 'WorkOrderItemLoan'; when 83 then aytkey= 'WorkOrderItemPart'; - when 84 then aytkey= 'WorkOrderItemPartRequest'; + when 84 then aytkey= 'CustomerNotifySubscription'; when 85 then aytkey= 'WorkOrderItemScheduledUser'; when 86 then aytkey= 'WorkOrderItemTask'; when 87 then aytkey= 'WorkOrderItemTravel';