From 334e00ba43f23d85a0581c9e1c9919a25a50b043 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Sun, 20 Nov 2022 23:58:03 +0000 Subject: [PATCH] case 4310 --- devdocs/todo.txt | 31 ------- .../AyaNova/Controllers/EnumListController.cs | 1 + .../AyaNova/Controllers/NotifyController.cs | 88 +++++++++++++++++++ server/AyaNova/biz/AyaEvent.cs | 3 +- server/AyaNova/biz/NotifyEventType.cs | 2 +- server/AyaNova/util/AySchema.cs | 27 +++++- 6 files changed, 118 insertions(+), 34 deletions(-) diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 7a45738d..98663127 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -1,33 +1,2 @@ - - todo: clean up solutions.txt and research.txt and move into a consolidated coding focused how-to.md doc - - -Printed date: 11/18/22 Page 1 of 1 -MyHeaderCopy value is:{ "Id": 544, "Concurrency": 41215105, "Serial": 544, "Notes": -"one\nUpdated on render at Fri Nov 18 2022 14:37:44 GMT-0800 (Pacific Standard Time)", -"Wiki": null, "CustomFields": {}, "Tags": [], "CustomerId": 17, "CustomerViz": "Adams, Gleason -and Runolfsson", "CustomerTechNotesViz": null, "CustomerPhone1Viz": "697.907.8664 -x7787", "CustomerPhone2Viz": "(406) 837-7972 x321", "CustomerPhone3Viz": "416-306- -6458", "CustomerPhone4Viz": "", "CustomerPhone5Viz": "", "CustomerEmailAddressViz": -"Carmella.Kohler97@example.com", "ProjectId": null, "ProjectViz": null, -"InternalReferenceNumber": null, "CustomerReferenceNumber": null, -"CustomerContactName": null, "FromQuoteId": null, "FromPMId": null, "CreatedDate": "2022- -11-18T19:10:26.870114Z", "ServiceDate": "2022-11-18T19:10:20.989Z", "CompleteByDate": -null, "DurationToCompleted": "00:00:00", "InvoiceNumber": null, "CustomerSignature": null, -"CustomerSignatureName": null, "CustomerSignatureCaptured": null, "TechSignature": null, -"TechSignatureName": null, "TechSignatureCaptured": null, "Onsite": true, "ContractId": null, -"ContractViz": "-", "LastStatusId": null, "PostAddress": "6901 Langosh Village", "PostCity": -"Emardhaven", "PostRegion": "Georgia", "PostCountry": "Saint Vincent and the Grenadines", -"PostCode": "12106-4039", "Address": "174 Yost Corners", "City": "Emardhaven", "Region": -"Georgia", "Country": "Saint Vincent and the Grenadines", "Latitude": -81.3414, "Longitude": -74.8858, "IsLockedAtServer": false, "AlertViz": "", "FromQuoteViz": null, "FromPMViz": null, -"LastStateUserViz": null, "LastStateNameViz": null, "LastStateColorViz": null, -"LastStateCompletedViz": false, "LastStateLockedViz": false, "IsCompleteRecord": true, -"UserIsRestrictedType": false, "UserIsTechRestricted": false, "UserIsSubContractorFull": false, -"UserIsSubContractorRestricted": false, "UserCanViewPartCosts": true, -"UserCanViewLaborOrTravelRateCosts": true, "UserCanViewLoanerCosts": true } - - -{"id":544,"concurrency":41215105,"serial":544,"notes":"top","wiki":null,"customFields":{},"tags":[],"customerId":17,"customerTechNotesViz":null,"customerPhone1Viz":"697.907.8664 x7787","customerPhone2Viz":"(406) 837-7972 x321","customerPhone3Viz":"416-306-6458","customerPhone4Viz":"","customerPhone5Viz":"","customerEmailAddressViz":"Carmella.Kohler97@example.com","projectId":null,"internalReferenceNumber":null,"customerReferenceNumber":null,"customerContactName":null,"fromQuoteId":null,"fromPMId":null,"createdDate":"2022-11-18T19:10:26.870114Z","serviceDate":"2022-11-18T19:10:20.989Z","completeByDate":null,"durationToCompleted":"00:00:00","invoiceNumber":null,"customerSignature":null,"customerSignatureName":null,"customerSignatureCaptured":null,"techSignature":null,"techSignatureName":null,"techSignatureCaptured":null,"onsite":true,"contractId":null,"lastStatusId":null,"postAddress":"6901 Langosh Village","postCity":"Emardhaven","postRegion":"Georgia","postCountry":"Saint Vincent and the Grenadines","postCode":"12106-4039","address":"174 Yost Corners","city":"Emardhaven","region":"Georgia","country":"Saint Vincent and the Grenadines","latitude":-81.3414,"longitude":74.8858,"isLockedAtServer":false,"fromQuoteViz":null,"fromPMViz":null,"lastStateUserViz":null,"lastStateNameViz":null,"lastStateColorViz":null,"lastStateCompletedViz":false,"lastStateLockedViz":false,"isCompleteRecord":true,"userIsRestrictedType":false,"userIsTechRestricted":false,"userIsSubContractorFull":false,"userIsSubContractorRestricted":false,"userCanViewPartCosts":true,"userCanViewLaborOrTravelRateCosts":true,"userCanViewLoanerCosts":true,"isDirty":true} \ No newline at end of file diff --git a/server/AyaNova/Controllers/EnumListController.cs b/server/AyaNova/Controllers/EnumListController.cs index da2f4ff1..3f42d5ae 100644 --- a/server/AyaNova/Controllers/EnumListController.cs +++ b/server/AyaNova/Controllers/EnumListController.cs @@ -542,6 +542,7 @@ namespace AyaNova.Api.Controllers // ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventCopyOfCustomerNotification"], Id = (long)NotifyEventType.CopyOfCustomerNotification }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventWorkorderCreatedForCustomer"], Id = (long)NotifyEventType.WorkorderCreatedForCustomer }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventPMGenerationFailed"], Id = (long)NotifyEventType.PMGenerationFailed }); + ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventDirectSMTPMessage"], Id = (long)NotifyEventType.DirectSMTPMessage }); } else if (keyNameInLowerCase == StringUtil.TrimTypeName(typeof(NotifyDeliveryMethod).ToString()).ToLowerInvariant()) diff --git a/server/AyaNova/Controllers/NotifyController.cs b/server/AyaNova/Controllers/NotifyController.cs index 39003614..9f22ea7c 100644 --- a/server/AyaNova/Controllers/NotifyController.cs +++ b/server/AyaNova/Controllers/NotifyController.cs @@ -11,6 +11,7 @@ using System.Linq; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using AyaNova.Util; namespace AyaNova.Api.Controllers { @@ -227,6 +228,93 @@ namespace AyaNova.Api.Controllers [Required] public List Users { get; set; } } + + /// + /// Send direct SMTP message notification so single object / address + /// Note: adds to queue, not instantly sent + /// + /// NoContent on success or error + [HttpPost("direct-smtp")] + public async Task SendNotifySmtpDirectMessage([FromBody] NotifyDirectSMTP notifyDirectSMTP) + { + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + + //validate + + if (string.IsNullOrWhiteSpace(notifyDirectSMTP.ToAddress)) + { + //We need to fetch the address from the object type and id + //if no id then can skip the rest here + if (notifyDirectSMTP.ObjectId == 0) + { + return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_MISSING_PROPERTY, "ObjectId", "No address or object id specified, no where to send this")); + } + //get the address + switch (notifyDirectSMTP.AType) + { + case AyaType.NoType: + return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_MISSING_PROPERTY, "ToAddress", "No address or object type and id specified no where to send this")); + case AyaType.Customer: + var CustomerInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == notifyDirectSMTP.ObjectId).Select(x => new { x.Name, x.EmailAddress, x.Active }).FirstAsync(); + if (string.IsNullOrWhiteSpace(CustomerInfo.EmailAddress)) + return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_MISSING_PROPERTY, "EmailAddress", $"Customer {CustomerInfo.Name} doesn't have an email address no where to send this")); + if (CustomerInfo.Active == false) + return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "Active", $"Customer {CustomerInfo.Name} is not active, only active customers can be emailed directly")); + notifyDirectSMTP.ToAddress = CustomerInfo.EmailAddress; + break; + default: + return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "AType", "Specified Type not supported for 'on request' smtp")); + + } + } + var UserId = UserIdFromContext.Id(HttpContext.Items); + + IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer; + try + { + if (!ServerGlobalOpsSettingsCache.Notify.SmtpDeliveryActive) + { + await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, + $"Email notifications are set to OFF at server, unable to send 'on request' type SMTP notification subject:{notifyDirectSMTP.Subject}", + "Error", + null, + UserId); + log.LogInformation($"** WARNING: SMTP notification is currently set to Active=False; unable to send 'on request' type SMTP notification subject:{notifyDirectSMTP.Subject} **"); + + } + else + await m.SendEmailAsync(notifyDirectSMTP.ToAddress, "Test from Notification system", "This is a test to confirm notification system is working", ServerGlobalOpsSettingsCache.Notify); + + } + catch (Exception ex) + { + await NotifyEventHelper.AddOpsProblemEvent("SMTP direct message failed", ex); + return StatusCode(500, new ApiErrorResponse(ApiErrorCode.API_SERVER_ERROR, null, ExceptionUtil.ExtractAllExceptionMessages(ex))); + } + + return NoContent(); + } + + public class NotifyDirectSMTP + { + public NotifyDirectSMTP() + { + + } + + public long ObjectId { get; set; } = 0; + public AyaType AType { get; set; } = AyaType.NoType; + public string ToAddress { get; set; } + public string Subject { get; set; } + public string TextBody { get; set; } + public string HTMLBody { get; set; } + } + //------------ diff --git a/server/AyaNova/biz/AyaEvent.cs b/server/AyaNova/biz/AyaEvent.cs index deaf12bd..549cc0cb 100644 --- a/server/AyaNova/biz/AyaEvent.cs +++ b/server/AyaNova/biz/AyaEvent.cs @@ -26,7 +26,8 @@ namespace AyaNova.Biz AttachmentModified = 11, EraseAllData = 12, ResetSerial = 13, - UtilityFileDownload = 14 + UtilityFileDownload = 14, + DirectSMTP = 15//NotifyEventDirectSMTPMessage key can work for this too //NEW ITEMS REQUIRE translation KEYS and update CLIENT ay-history.vue code in eventypes list and translation fetcher diff --git a/server/AyaNova/biz/NotifyEventType.cs b/server/AyaNova/biz/NotifyEventType.cs index 0f573286..6f441306 100644 --- a/server/AyaNova/biz/NotifyEventType.cs +++ b/server/AyaNova/biz/NotifyEventType.cs @@ -60,7 +60,7 @@ Inspiring quotes used to help complete this huge project by myself PMGenerationFailed = 32, //indicates there was a failure during PM generation with error //SendUserCredentials = 33, //XXXXXXX Internal System use only: When user generates new credentials and sends them this is the notification type for that see UserBiz GenerateCredsAndEmailUser ReviewImminent = 34,//*Review object, Advance notice setting tag conditional - + DirectSMTPMessage= 35 //Used internally when sending a message via email directly to a Customer (initially) and possibly other objects in future. Shows in sent log but not user subscribable diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 36c054ed..cedcd25a 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -20,7 +20,7 @@ namespace AyaNova.Util /////////// CHANGE THIS ON NEW SCHEMA UPDATE //////////////////// //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!! - private const int DESIRED_SCHEMA_LEVEL = 11; + private const int DESIRED_SCHEMA_LEVEL = 12; internal const long EXPECTED_COLUMN_COUNT = 1380; internal const long EXPECTED_INDEX_COUNT = 161; @@ -1685,6 +1685,31 @@ CREATE OR REPLACE VIEW public.viewpartinventorylist await SetSchemaLevelAsync(++currentSchema); } + ////////////////////////////////////////////////// + // + // case 4173 + // + if (currentSchema < 12) + { + LogUpdateMessage(log); + + //english translations + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'NotifyEventDirectSMTPMessage', 'On request SMTP' FROM atranslation t where t.baselanguage = 'en'"); + + //spanish translations + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'NotifyEventDirectSMTPMessage', 'Bajo petición SMTP' FROM atranslation t where t.baselanguage = 'es'"); + + //french translations + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'NotifyEventDirectSMTPMessage', 'SMTP demandé' FROM atranslation t where t.baselanguage = 'fr'"); + + //german translations + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'NotifyEventDirectSMTPMessage', 'Auf Anfrage SMTP' FROM atranslation t where t.baselanguage = 'de'"); + + await SetSchemaLevelAsync(++currentSchema); + } + + + //#########################################