1 line
12 KiB
Plaintext
1 line
12 KiB
Plaintext
{"Name":"Labor Billing & Hours Grouped By Technician","Active":true,"Notes":"Custom Prepare to group by the technician, and get running totals of NC, Billable and Actual for grouping AND for all wo records in this report","Roles":51182,"AType":37,"IncludeWoItemDescendants":false,"Template":"<html>\n<body>\n <div>\n <table>\n <thead>\n <tr>\n <th colspan=\"1\"></th>\n <th colspan=\"2\">{{ayT \"WorkOrder\"}}</th> \n <th colspan=\"7\">{{ayT \"WorkOrderItemLaborServiceStartDate\"}} / {{ayT \"WorkOrderItemLaborServiceStopDate\"}} </th> \n <th colspan=\"3\">{{ayT \"WorkOrderItemLaborServiceRateID\"}}</th>\n <th colspan=\"3\">{{ayT \"ListPrice\"}}</th>\n \n <th colspan=\"2\">Actual Start minus Stop</th>\n <th colspan=\"2\">{{ayT \"WorkOrderItemLaborNoChargeQuantity\"}}</th>\n <th colspan=\"2\">{{ayT \"WorkOrderItemLaborServiceRateQuantity\"}}</th>\n <th colspan=\"2\">{{ayT \"NetPrice\"}}</th>\n </tr>\n </thead>\n <tbody>\n {{#each ayReportData}}\n <tr>\n <th colspan=\"2\" class=\"leftlean\">{{ayT 'WorkOrderItemLaborList'}} for </th>\n <td colspan=\"5\">{{group}}</td>\n <th colspan=\"17\" class=\"leftlean\"># of labor items: {{count}}</th>\n </tr>\n \n {{#each items}}\n <tr>\n <td colspan=\"1\"> </td>\n <td colspan=\"2\">{{Serial}}</td> \n <td colspan=\"7\">{{ayDateTime ServiceStartDate}} to {{ayDateTime ServiceStopDate}}</td> \n <td colspan=\"3\">{{ServiceRateViz}}</td>\n <td colspan=\"3\">{{ayCurrency PriceViz}} {{UnitOfMeasureViz}}</td>\n \n <td colspan=\"2\">{{ayDecimal diffHours}}</td>\n <td colspan=\"2\">{{NoChargeQuantity}}</td>\n <td colspan=\"2\">{{ServiceRateQuantity}}</td>\n <td colspan=\"2\">{{ayCurrency NetViz}}</td>\n </tr>\n {{/each}}\n <tr>\n <th colspan=\"24\"> </th>\n </tr>\n <tr>\n <th colspan=\"16\" class=\"rightlean\">Total {{ayT \"WorkOrderItemLaborServiceRateQuantity\"}} + {{ayT \"WorkOrderItemLaborNoChargeQuantity\" }} = {{EachGroupWOLaborsNCQtyplusBillableQty}} for {{group}}</th> \n <td colspan=\"2\">{{ayDecimal EachGroupWOActualHoursQty}}</td>\n <td colspan=\"2\">{{EachGroupWOLaborsNCQty}}</td>\n <td colspan=\"2\">{{EachGroupWOLaborsBillableQty}}</td>\n <td colspan=\"2\">{{ayCurrency EachGroupWOLaborsNetViz}}</td>\n </tr>\n <tr>\n <td colspan=\"24\"> </td>\n </tr>\n {{/each}}\n </tbody>\n </table>\n\n <table><!-- footer is in its own table so displays once at end of report-->\n <tfoot>\n <tr>\n <th colspan=\"4\"> </th>\n <th colspan=\"4\">Total {{ayT 'WorkOrderItemLaborList'}} records</th>\n <th colspan=\"4\">Total Combined {{ayT \"WorkOrderItemLaborServiceRateQuantity\"}} & {{ayT \"WorkOrderItemLaborServiceRateQuantity\"}}</th>\n <th colspan=\"4\">Total {{ayT \"WorkOrderItemLaborNoChargeQuantity\"}}</th>\n <th colspan=\"4\">Total {{ayT \"WorkOrderItemLaborServiceRateQuantity\"}}</th> \n <th colspan=\"4\">Total {{ayT \"NetPrice\"}}</th>\n </tr>\n <tr>\n <!-- note no #each encompasses here - the data below is from Prepare's reportData.xxxx as in reportData.AllWOLaborsNetViz --> \n <td colspan=\"4\"> </td>\n <td colspan=\"4\">{{AllWOLaborsCount}}</td>\n <td colspan=\"4\">{{AllWOLaborsNCQtyplusBillableQty}}</td>\n <td colspan=\"4\">{{AllWOLaborsNCQty}}</td>\n <td colspan=\"4\">{{AllWOLaborsBillableQty}}</td> \n <td colspan=\"4\">{{ayCurrency AllWOLaborsNetViz}}</td>\n </tr> \n </tfoot>\n </table>\n </div>\n</body>\n\n</html>","Style":".singlePage\r\n{\r\npage-break-after: always;\r\n\r\n}\r\nbody {\r\n font-family: 'Helvetica', 'Helvetica Neue', Arial, sans-serif; \r\n}\r\n\r\n.reporttitle { \r\n margin-bottom: 20pt; \r\n font-weight: bold; \r\n font-size: 14pt; \r\n color: #9e9e9e;\r\n text-align: left;\r\n} \r\n\r\ntable { \r\n border-collapse: collapse;\r\n white-space: pre-wrap;\r\n width: 100%; \r\n table-layout: fixed;\r\n }\r\n\r\nth {\r\n height: 30px;\r\n font-size: 10pt; \r\n color: #9e9e9e;\r\n}\r\n\r\ntfoot th{\r\n border-top: solid 1pt #9e9e9e;\r\n height: 50px;\r\n text-align: center;\r\n}\r\n\r\ntbody td {\r\n padding: 10px;\r\n word-wrap: break-word;\r\n font-size: 9pt;\r\n text-align: center;\r\n}\r\n\r\ntbody tr:nth-child(even) {\r\n background-color: #f8f8f8; /* MUST checkmark Print background in PDF Options for this to show */\r\n}\r\n\r\ntfoot td{\r\n font-size: 10pt;\r\n text-align: center;\r\n }\r\n\r\n.rightlean {\r\n text-align: right;\r\n}\r\n.leftlean {\r\n text-align: left;\r\n}\r\n.centerlean {\r\n text-align: center;\r\n}\r\n\r\n\r\n.fontgreen {\r\n color: green;\r\n}\r\n.fontblue {\r\n color: blue;\r\n}\r\n.fontred {\r\n color:red;\r\n font-weight: bold;\r\n}\r\n.fontpurple {\r\n color: purple;\r\n}\r\n","JsPrerender":"async function ayPrepareData(reportData) {\n\nawait ayGetTranslations([\"Total\", \"WorkOrder\", \"WorkOrderList\", \"WorkOrderItemLaborList\", \"WorkOrderItemLaborUserID\", \"WorkOrderItemLaborServiceRateID\", \"ListPrice\", \"WorkOrderItemLaborServiceRateQuantity\", \"WorkOrderItemLaborServiceDetails\", \"WorkOrderItemLaborNoChargeQuantity\", \"WorkOrderItemLaborServiceStartDate\", \"WorkOrderItemLaborServiceStopDate\", \"NetPrice\"]);\n\n\n\t//below is the code to group by the technician - the UserViz\n\tlet ret = [];\n //iterate workorders -> items -> workorder item labors\n reportData.ayReportData.forEach(workorder => {\n workorder.Items.forEach(workorderitem => {\n workorderitem.Labors.forEach(labor => {\n //new shape of data required for report\n let record = {\n Serial: workorder.Serial,\n ServiceRateViz: labor.ServiceRateViz,\n PriceViz: labor.PriceViz,\n UnitOfMeasureViz: labor.UnitOfMeasureViz,\n ServiceStartDate: labor.ServiceStartDate,\n ServiceStopDate: labor.ServiceStopDate,\n NoChargeQuantity: labor.NoChargeQuantity,\n ServiceRateQuantity: labor.ServiceRateQuantity,\n\t\t\t\t\tServiceDetails: labor.ServiceDetails,\n NetViz: labor.NetViz\n };\n\n //Find or create group and insert this record \n let groupObject = ret.find(z => z.group == labor.UserViz);\n if (groupObject != undefined) {\n //there is already a matching group in the return array so just push this record into it\n groupObject.items.push(record);\n //update the count for this group's items\n groupObject.count++;\n } else {\n //No group yet, so start a new one in the ret array and push this record into it\n ret.push({ group: labor.UserViz, items: [record], count: 1 });\n }\n\n })\n })\n });\n\n //replace the ayReportData with our new shaped format of data\n reportData.ayReportData = ret;\n\n \n//below to get running totals of THE DATA returned above\n\n\t//below declares variables for running total for ALL\n\treportData.AllWOLaborsNCQty = 0; \n\treportData.AllWOLaborsBillableQty = 0;\n\treportData.AllWOLaborsNCQtyplusBillableQty = 0; \n\treportData.AllWOLaborsNetViz = 0;\n\t\n\treportData.AllWOLaborsCount = 0;\n\n \t\t\n\n\t\t\t\tfor (const EachGroup of reportData.ayReportData) \n\t\t\t\t{\n\t\t\t\t//below declares a key on the entire grouping to hold running totals for each labor record for each Item for EachWO for each \"items\" \n\t\t\t\tEachGroup.EachGroupWOLaborsNCQty = 0;\n\t\t\t\tEachGroup.EachGroupWOLaborsBillableQty = 0;\n\t\t\t\tEachGroup.EachGroupWOLaborsNCQtyplusBillableQty = 0;\n\t\t\t\tEachGroup.EachGroupWOLaborsNetViz = 0;\n\t\t\t\tEachGroup.EachGroupWOActualHoursQty = 0;\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\t for (const groupitem of EachGroup.items) \n\t\t\t\t\t\t \t{\n\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsCount += 1;\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\tif (groupitem.ServiceStartDate != null && groupitem.ServiceStopDate != null) \n\t\t\t\t\t\t\t\t\t\t{\n\n\t\t\t\t\t\t\t\t\t\t\tvar dateTime1 = new Date (groupitem.ServiceStopDate);\n\t\t\t\t\t\t\t\t\t\t\tvar dateTime2 = new Date (groupitem.ServiceStartDate);\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\tvar diffMillis = (dateTime1.getTime() - dateTime2.getTime()); \n\t\t\t\t\t\t\t\t\t\t\tgroupitem.diffHours = ((diffMillis/3600) / 1000)\n\n\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOActualHoursQty += groupitem.diffHours;\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (groupitem.NoChargeQuantity != null) \n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOLaborsNCQty += groupitem.NoChargeQuantity;\t\n\t\t\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOLaborsNCQtyplusBillableQty += groupitem.NoChargeQuantity;\t\n\t\t\t\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsNCQty\t+= groupitem.NoChargeQuantity;\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsNCQtyplusBillableQty += groupitem.NoChargeQuantity;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (groupitem.ServiceRateQuantity != null) \n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOLaborsBillableQty += groupitem.ServiceRateQuantity; \n\t\t\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOLaborsNCQtyplusBillableQty += groupitem.ServiceRateQuantity;\n\t\t\t\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsBillableQty += groupitem.ServiceRateQuantity; \n\t\t\t\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsNCQtyplusBillableQty += groupitem.ServiceRateQuantity; \n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (groupitem.NetViz != null) \n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tEachGroup.EachGroupWOLaborsNetViz += groupitem.NetViz;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\treportData.AllWOLaborsNetViz += groupitem.NetViz; //this is the actual adding to running total for all\n\t\t\t\t\t\t\t\t\t\t\t\t}\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t \t\t\n\t\t\t\t\t\t \t}\n\t\t\t\t}\n\t\t\t\n\n\t//return the data into the pipeline to send to the report template \n\treturn reportData;\n}\n\n\n\n","JsHelpers":"","RenderType":0,"HeaderTemplate":"<span></span>","FooterTemplate":"<span style=\"font-size:6pt;width: 94%; text-align:left; \"> Printed date: <span class=\"date\"></span> </span>\n<span style=\"font-size:6pt;width: 94%; text-align: right; \">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span> </span>","DisplayHeaderFooter":true,"PaperFormat":10,"Landscape":true,"MarginOptionsBottom":"20mm","MarginOptionsLeft":"20mm","MarginOptionsRight":"15mm","MarginOptionsTop":"15mm","PageRanges":null,"PreferCSSPageSize":false,"PrintBackground":true,"Scale":1.00000} |