diff --git a/docs/8.0/ayanova/docs/ay-report-edit.md b/docs/8.0/ayanova/docs/ay-report-edit.md index 0040be74..3bb56436 100644 --- a/docs/8.0/ayanova/docs/ay-report-edit.md +++ b/docs/8.0/ayanova/docs/ay-report-edit.md @@ -535,7 +535,9 @@ While it is possible to login via a script using alternate credentials and acces ### API convenience functions -The following functions are provided to assist with API usage from your ayPrepareData custom function: +The following functions are provided to assist with API usage from your ayPrepareData custom function. + +Note that by default the authentication token supplied is the same as the currently logged in User so you can only perform actions that the currently logged in User could also perform in the AyaNova application. For example if the currently logged in User doesn't have rights to modify or retreive an object it won't work here either. _GET_ diff --git a/docs/8.0/ayanova/docs/changelog.md b/docs/8.0/ayanova/docs/changelog.md index c316e749..7d201cbe 100644 --- a/docs/8.0/ayanova/docs/changelog.md +++ b/docs/8.0/ayanova/docs/changelog.md @@ -10,6 +10,13 @@ See the [upgrade instructions](ops-upgrade.md) section of this manual for detail ## 2022 +### AyaNova 8.0.23 (2022-11-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) + +#### Added + +- Server, App, Documentation: Added [ayPutToAPI](ay-report-edit.md#api-convenience-functions) API convenience method to report renderer +- App: added `z_ayPutToAPI work order` example report to show how to use the new put method added to update a work order on render + ### AyaNova 8.0.22 (2022-11-14) #### Changed diff --git a/server/AyaNova/resource/rpt/stock-report-templates/z_ayPutToAPI work order.ayrt b/server/AyaNova/resource/rpt/stock-report-templates/z_ayPutToAPI work order.ayrt new file mode 100644 index 00000000..21122bd3 --- /dev/null +++ b/server/AyaNova/resource/rpt/stock-report-templates/z_ayPutToAPI work order.ayrt @@ -0,0 +1 @@ +{"Name":"z_ayPutToAPI work order","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\n//---------\n//get a __COPY__ of header portion only of work order, exclude the Items and States collections\n//which are not required because we are submitting a post to the header route only in this example.\n//See how AyaNova does it for other areas of a work order being updated by viewing the \"network\" tab in \n//the web browser developer console as changes are made to a work order in AyaNova UI that you want to replicate\n//in code here\n//A __COPY__ is made here because we don't want to modify the work order object itself which is about to be rendered\n//\n//copy the work order header portion only omitting the Items and States sub collections which are not used when updating the work order header \n//of an existing work order\nconst {Items, States, ...copyOfWoHeaderOnly} = EachWO;\n//change the Notes field which shows as \"Summary\" in the user interface of a work order\ncopyOfWoHeaderOnly.Notes=`${copyOfWoHeaderOnly.Notes}\\nUpdated on render at ${Date()}`;\n//Use the PUT method to update the work order header\nawait ayPutToAPI(\"workorder\", copyOfWoHeaderOnly);\n//----------\n\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\n // //Add the data to the main report data object\n // //so it's available to the template\n // reportData.myData = {\n // ServerInfo: await ayGetFromAPI(\"server-info\")\n // };\n\n \n\n //Example API POST method to fetch data from api server\n //using the \"search\" route\n\n // //construct the POST object\n // let searchPostData = { phrase: \"example\" };\n\n // reportData.myData.SearchResults = await ayPostToAPI(\"search\", searchPostData);\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