From 544e4fc1afc0759b7281eac51338b0733d8e7c9c Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 22 Nov 2022 00:11:15 +0000 Subject: [PATCH] case 4310 --- devdocs/todo.txt | 76 +++++++++++++++++++ docs/8.0/ayanova/docs/changelog.md | 3 +- docs/8.0/ayanova/mkdocs.yml | 2 +- .../AyaNova/Controllers/NotifyController.cs | 3 + ..._API send SMTP from work order report.ayrt | 1 + 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 server/AyaNova/resource/rpt/stock-report-templates/z_API send SMTP from work order report.ayrt diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 63379256..9f2ad0b1 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -1,2 +1,78 @@ todo: clean up solutions.txt and research.txt and move into a consolidated coding focused how-to.md doc todo: test regular notification after case 4310 isn't broken by changes to mail delivery system +{[ + { + "Id": 544, + "Concurrency": 41215321, + "Serial": 544, + "Notes": "top\nUpdated on render at Fri Nov 18 2022 15:34:53 GMT-0800 (Pacific Standard Time)", + "Wiki": null, + "CustomFields": { + "c1": "Here is some custom text", + "c2": "2022-11-18T08:00:00Z", + "c3": "true" + }, + "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": "johncrdnl@gmail.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.341400, + "Longitude": 74.885800, + "Items": [], + "States": [], + "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 + } +]} \ No newline at end of file diff --git a/docs/8.0/ayanova/docs/changelog.md b/docs/8.0/ayanova/docs/changelog.md index c582ad3b..12344e79 100644 --- a/docs/8.0/ayanova/docs/changelog.md +++ b/docs/8.0/ayanova/docs/changelog.md @@ -10,11 +10,12 @@ See the [upgrade instructions](ops-upgrade.md) section of this manual for detail ## 2022 -### AyaNova 8.0.24 (2022-11-20) +### AyaNova 8.0.24 (2022-11-21) #### Added - Server: Added new internal API route `/api/v8/notify/direct-smtp` to support on demand notification scenarios +- Server: Report api utility methods ayPutToAPI, ayPostToAPI, ayGetFromAPI throwing exception on empty return body (202, 204 results) ### AyaNova 8.0.23 (2022-11-18) diff --git a/docs/8.0/ayanova/mkdocs.yml b/docs/8.0/ayanova/mkdocs.yml index 0b88cfc9..2e9d0d8f 100644 --- a/docs/8.0/ayanova/mkdocs.yml +++ b/docs/8.0/ayanova/mkdocs.yml @@ -7,7 +7,7 @@ theme: site_name: AyaNova manual site_dir: '../../../server/AyaNova/wwwroot/docs' strict: true -copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-11-20 +copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-11-21 extra: generator: false # Extensions diff --git a/server/AyaNova/Controllers/NotifyController.cs b/server/AyaNova/Controllers/NotifyController.cs index 4b23972e..78a04f33 100644 --- a/server/AyaNova/Controllers/NotifyController.cs +++ b/server/AyaNova/Controllers/NotifyController.cs @@ -233,6 +233,9 @@ namespace AyaNova.Api.Controllers /// Send direct SMTP message notification so single object / address /// Server notification settings must be set and active /// Currently supported types are Customer, HeadOffice, Vendor, User + /// WARNING: be careful using this method; high volume emailing or spam-like behavior + /// could result in a ban or block of your mail account or mail server or domain + /// /// /// Accepted on success or error [HttpPost("direct-smtp")] diff --git a/server/AyaNova/resource/rpt/stock-report-templates/z_API send SMTP from work order report.ayrt b/server/AyaNova/resource/rpt/stock-report-templates/z_API send SMTP from work order report.ayrt new file mode 100644 index 00000000..7ead2b0a --- /dev/null +++ b/server/AyaNova/resource/rpt/stock-report-templates/z_API send SMTP from work order report.ayrt @@ -0,0 +1 @@ +{"Name":"z_API send SMTP from work order report","Active":true,"Notes":"Example shows how to update a work order header field via an API PUT call when that work order is rendered.","Roles":124927,"AType":34,"IncludeWoItemDescendants":false,"Template":"\n\n\n\n\t
\n\t\t{{#each ayReportData}}\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if CustomerContactName}}\n\t\t\t\t\t{{else}}{{/if}}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\n\n\t\t\t\t{{#each Items}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\n\t\t\t\t\n\n\t\t\t\t{{#each Units}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/each}}\n\t\t\t\t\n\n\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{#each ScheduledUsers}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/each}}\n\t\t\t\t\n\n\t\t\t\t{{#if Tasks}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/if}}\n\t\t\t\t{{#each Tasks}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if_eq Status 2}}\n\t\t\t\t\t{{else}}{{/if_eq}}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/each}}\n\t\t\t\t\n\t\t\t\t{{#if Tasks}}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/if}}\n\n\t\t\t\t{{#if Parts}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/if}}\n\t\t\t\t{{#each Parts}}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if Serials}} \n\t\t\t\t\t{{else}} {{/if}}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/each}}\n\t\t\t\t\n\t\t\t\t{{#if Parts}}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/if}}\n\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{{/each}}\n\t\t\t\t\n\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if TechSignature}} \n\t\t\t\t\t{{else}}{{/if}}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if CustomerSignature}} \n\t\t\t\t\t{{else}}{{/if}}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if TechSignatureCaptured}} \n\t\t\t\t\t{{else}}{{/if}}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{{#if CustomerSignatureCaptured}} \n\t\t\t\t\t{{else}}{{/if}}\n\t\t\t\t\n\t\t\t\n\t\t
{{ayT 'Customer'}}{{CustomerViz}}{{../ayServerMetaData.CompanyName}}
{{ayT 'AddressTypePhysical'}}{{Address}}, {{City}}{{ayT 'WorkOrderSerialNumber'}}{{Serial}}
{{ayT 'WorkOrderCustomerContactName'}}{{CustomerContactName}} {{CustomerPhone1Viz}}\n\t\t\t\t\t\t{{CustomerEmailAddressViz}}{{CustomerPhone1Viz}} {{CustomerEmailAddressViz}}{{ayT 'WorkOrderServiceDate'}}{{ayDate ServiceDate}}
 
 
{{ayT 'WorkOrderSummary'}}{{Notes}}
{{ayT 'WorkOrderCloseByDate'}}{{ayDateTime CompleteByDate}}
{{ayT 'CustomerTechNotes'}}{{CustomerTechNotesViz}}
{{ayT\n\t\t\t\t\t\t'WorkOrderItemPriorityID'}}\n\t\t\t\t\t\t{{WorkOrderItemPriorityNameViz}}{{ayT 'WorkOrderItemRequestDate'}}{{ayDateTime RequestDate}}{{ayT\n\t\t\t\t\t\t'WorkOrderItemWorkOrderStatusID'}}\n\t\t\t\t\t\t{{WorkOrderItemStatusNameViz}}
{{ayT 'WorkOrderItemSummary'}} #{{Sequence}}{{Notes}}
{{ayT 'WorkOrderItemTechNotes'}}{{TechNotes}}
{{ayT 'Unit'}}{{UnitViz}} {{UnitModelNameViz}}
 
{{ayT 'NotifyEventScheduledOnWorkorder'}}{{UserViz}}As expected?Actual
 {{ayT 'WorkOrderItemScheduledUserStartDate'}}{{ayDateTime StartDate}}
 {{ayT 'WorkOrderItemScheduledUserStopDate'}}{{ayDateTime StopDate}}
 {{ayT 'WorkOrderItemScheduledUserServiceRateID'}}{{ServiceRateViz}}
 {{ayT 'WorkOrderItemScheduledUserEstimatedQuantity'}}{{EstimatedQuantity}}
 
{{ayT 'WorkOrderItemTaskWorkOrderItemTaskCompletionType'}}{{ayT 'WorkOrderItemTasks'}}
{{StatusViz}}\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{{Task}}
 
{{ayT 'WorkOrderItemPartQuantity'}}{{ayT 'WorkOrderItemPartPartWarehouseID'}}{{ayT 'Part'}}{{ayT 'WorkOrderItemPartUsed'}}
{{Quantity}}{{PartWarehouseViz}}{{PartNameViz}} {{PartDescriptionViz}}   {{ayT\n\t\t\t\t\t\t'PurchaseOrderItemSerialNumbers'}}: {{Serials}} {{PartNameViz}} {{PartDescriptionViz}}\n\t\t\t\t\t\t\n\t\t\t\t\t
 
{{ayT 'WorkOrderItemLaborServiceDetails'}}
 
 
 
 
 
{{ayT 'TechSignature'}}\n\t\t\t\t\t\t
\n\t\t\t\t\t
 {{ayT 'CustomerSignature'}}\n\t\t\t\t\t\t
\n\t\t\t\t\t
 
Date {{ayDateTime TechSignatureCaptured}} \n\t\t\t\t\t\t
\n\t\t\t\t\t
 Date {{ayDateTime CustomerSignatureCaptured}}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t{{/each}}\n\t
\n\n\n","Style":".singlePage\n{\npage-break-after: always;\n}\n\nbody {\n font-family: 'Helvetica', 'Helvetica Neue', Arial, sans-serif; \n}\n\n.reporttitle { \n margin-bottom: 20pt; \n font-weight: bold; \n font-size: 13pt; \n} \n\n\ntable { \n table-layout: fixed; \n font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;\n border-collapse: collapse;\n white-space: pre-wrap;\n font-size: 8pt;\n width: 100%;\n }\n\n\nth {\n height: 30px;\n text-align: left;\n color: #9e9e9e;\n}\n\n\ntbody tr {\n height: 10px;\n word-wrap: break-word;\n}\n\ntbody tr:nth-child(even) {\n background-color: #f8f8f8; /* MUST checkmark Print background in PDF Options for this to show */\n}\n\n\n.fontgreen {\n color: green;\n}\n.fontblue {\n color: blue;\n}\n.fontred {\n color:red;\n}\n\n\n.rightlean {\n text-align: right;\n}\n.leftlean {\n text-align: left;\n}\n.centerlean {\n text-align: center;\n}","JsPrerender":"async function ayPrepareData(reportData) {\n //this function (if present) is called with the report data \n //before the report is rendered\n //modify data as required here and return it to change the data before the report renders\n //see the help documentation for details\n\n await ayGetTranslations([\"WorkOrderCloseByDate\", \"WorkOrderServiceDate\", \"WorkOrderSerialNumber\", \"Customer\", \"WorkOrderSummary\", \"Unit\", \"WorkOrderItemSummary\", \"WorkOrderItemPartQuantity\", \"AddressTypePhysical\", \"WorkOrderCustomerContactName\", \"CustomerTechNotes\", \"WorkOrderItemTechNotes\", \"Part\", \"WorkOrderItemPartUsed\", \"WorkOrderItemPartPartWarehouseID\", \"PurchaseOrderItemSerialNumbers\", \"WorkOrderItemLaborServiceDetails\", \"WorkOrderItemScheduledUser\", \"NotifyEventScheduledOnWorkorder\", \"WorkOrderItemScheduledUserEstimatedQuantity\", \"WorkOrderItemScheduledUserStartDate\", \"WorkOrderItemScheduledUserStopDate\", \"WorkOrderItemScheduledUserServiceRateID\", \"WorkOrderItemTasks\", \"WorkOrderItemTaskWorkOrderItemTaskCompletionType\", \"CustomerSignature\", \"TechSignature\", \"WorkOrderItemPriorityID\", \"WorkOrderItemWorkOrderStatusID\", \"WorkOrderItemRequestDate\"]);\n\n //below checks if any parts have Serials to remove carriage returns so parts serials display on same line\n for (const EachWO of reportData.ayReportData) {\n for (const Item of EachWO.Items) {\n for (const Part of Item.Parts) {\n if (Part.Serials != null) {\n let s = Part.Serials;\n Part.Serials = s.replace(/[\\n\\r]+/g, ' ');\n }\n }\n }\n\n ////////////////////////////////////////////\n // Send an email on prepare \n // This example requires AyaNova 8.0.24 or newer\n // Note: this block of code is the only modification to the \n // stock work order report\n //\n\n //WARNING: Be *very* careful using this method, sending too high a volume of email\n //or engaging in what may be seen as spammy behavior could lead to having your \n //account, mail server or domain black listed. Make sure the recipients are expecting\n //to receive mail from you and provide an opt out procedure\n\n //Here, we'll use the CustomerEmailAddressViz property of the work order\n //as the email address directly.\n //See the API console https://ayanova.com/docs/api-console/ \n //for route notify/direct-smtp alternative options for addressing\n \n if (!!EachWO.CustomerEmailAddressViz.trim()) {\n \n let emailObject = {\n \"objectId\": 0,\n \"aType\": 0,\n \"toAddress\": EachWO.CustomerEmailAddressViz,\n \"subject\": `AttN:${EachWO.CustomerViz}`,\n \"textBody\": `WO: ${EachWO.Serial} test message plain text body`,\n \"htmlBody\": `

WO: ${EachWO.Serial}

test html format message text

`\n }\n await ayPostToAPI(\"notify/direct-smtp\", emailObject);\n }\n //////////////////////////////////////////////\n\n \n }\n\n\n return reportData;\n}","JsHelpers":"//custom helper so can do a direct comparison - i.e. if value equals xxxx, then show, else show yyyyy\n\nHandlebars.registerHelper('if_eq', function(a, b, opts) {\n if(a == b) // Or === depending on your needs\n return opts.fn(this);\n else\n return opts.inverse(this);\n});\n\n","RenderType":0,"HeaderTemplate":"  ","FooterTemplate":"                Printed date: PDFDate\nPage of                ","DisplayHeaderFooter":true,"PaperFormat":10,"Landscape":false,"MarginOptionsBottom":"15mm","MarginOptionsLeft":"20mm","MarginOptionsRight":"15mm","MarginOptionsTop":"10mm","PageRanges":null,"PreferCSSPageSize":false,"PrintBackground":true,"Scale":1.00000} \ No newline at end of file