Odyssey
monthlyBilling.prg
1 <?php
2 /* File: monthlyBilling.prg
3  * Purpose: To initialize grid and CRUD calls on the monthly billing page
4  */
5 $ableToRunBilling = GetAbleToRunBilling($dbh, $Hu);
6 ?>
7 
8 <script type="text/javascript">
9 
10 <?php
11 // Get common JS functions here.
12 getShowWaitFunctions();
13 
14 ?>
15 
16 <?php
17 /**
18  * function ShowWarnings(warnings)
19  * This shows the warnings for things found in billing for example.
20  *
21  * @param array warnings -- Warnings to show.
22  */
23 ?>
24 function ShowWarnings(warnings) {
25  var keys = Object.keys(warnings);
26  $("#warningDiv").empty();
27  if (keys.length == 0) {
28  $("#warningDiv").hide();
29  return;
30  }
31  $("#warningDiv").show();
32  for(var j = 0; j != keys.length; j++) {
33  var cuId = "cu_" + keys[j];
34  var theseKeys = Object.keys(warnings[keys[j]]);
35  $("#warningDiv").append("<div id='" + cuId + "'></div>");
36  for(var i = 0; i != theseKeys.length; i++) {
37  var prodId = "prod_" + theseKeys[i];
38  var prodArray = warnings[keys[j]][theseKeys[i]];
39  $("#" + cuId).append("<div id='" + prodId + "'>" + prodArray.join("<br>") + "</div>");
40  }
41  }
42 
43 }
44 
45 var runBillingDS = null;
46 var runBillingIntervalFunc = null;
47 
48 <?php
49 /**
50  * function InitDataSources()
51  * This initializes all the datasources that already part of a grid.
52  */
53 ?>
54 function InitDataSources() {
55 
56  <?php
57  /**
58  * @var runBillingDS
59  * This provides a place for all the calls of the run billing process.
60  * Each step passes the sid and other information to the next step.
61  * Steps are "gather", "check", "run", and "cleanup."
62  */
63  ?>
64  runBillingDS = new kendo.data.DataSource({
65  transport: {
66  read: {
67  url: "index.prg",
68  dataType: "json",
69  type: "POST",
70  data: {
71  operation: "gatherBillingInfo"
72  }
73  },
74  parameterMap: function(data, type) {
75  showWaitWindow();
76  return data;
77  }
78  },
79  schema: {
80  parse: function (data) {
81 
82 
83  if (data.status !== "000") {
84  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
85 
86  hideWaitWindow();
87 
88  if (data.type == "check") {
89  clearInterval(runBillingIntervalFunc);
90  }
91  } else {
92 
93  switch(data.type) {
94  case "gather":
95  <?php // Now check to see if completed ?>
96 
97  var childCall = "gatherBillingInfoChildren";
98  var childTypes = ["contracts", "estatements", "ivr", "ipay", "timetrack"];
99  var checkRunBillingInterval = <?php echo CheckRunBillingInterval(); ?>;
100 
101  runBillingIntervalFunc = setInterval(function() { runBillingDS.read({operation: "checkBillingInfo", sid: data.sid}); },
102  checkRunBillingInterval);
103 
104  <?php if ($SYSENV["devmode"] == 1) { ?>
105  var parameters = {sid: data.sid, reportDate: data.reportDate, cutoffDate: data.cutoffDate,
106  cutoffTime: data.cutoffTime, operation: childCall, callMy: data.callMy};
107  <?php } else { ?>
108  var parameters = {sid: data.sid, reportDate: data.reportDate, cutoffDate: data.cutoffDate,
109  cutoffTime: data.cutoffTime, operation: childCall};
110  <?php } ?>
111 
112 
113  for (var i = 0; i != childTypes.length; i++) {
114 
115  <?php // Cannot seem to use the same DS for multiple calls at the same time. ?>
116  $.post("index.prg?childType=" + childTypes[i], parameters);
117  }
118  break;
119  case "check":
120  <?php // Logic to go run billing if completed ?>
121  if (data.ready) {
122  clearInterval(runBillingIntervalFunc);
123  runBillingDS.read({operation: "runBilling", sid: data.sid});
124  }
125 
126  break;
127  case "run":
128  runBillingDS.read({operation: "runBillingCleanup", sid: data.sid});
129  break;
130  case "cleanup":
131  <?php // Once completed, call query to get table results ?>
132  $("#billingGrid").data("kendoGrid").dataSource.read();
133  break;
134  case "child":
135  break;
136  }
137  }
138 
139  return [];
140 
141  }
142  }
143  });
144 }
145 
146 <?php
147 /**
148  * function InitMonthlyBilling()
149  * This sets up the main grid for running monthly billing.
150  */
151 ?>
152 function InitMonthlyBilling() {
153  <?php
154  /**
155  * @var grid
156  * This is the main grid for monthly billing. It is three levels.
157  */
158  ?>
159  var grid = $("#billingGrid").kendoGrid({
160  dataSource: {
161  transport: {
162  read: {
163  url: "index.prg",
164  dataType: "json",
165  type: "POST",
166  data: {
167  operation: "monthlyBillingLoad"
168  }
169  },
170  parameterMap: function(data, type) {
171  showWaitWindow();
172  return data;
173  }
174  },
175  schema: {
176  model: {
177  id: "month",
178  fields: {
179  month: {type: "date", editable: false, nullable: false},
180  runDate: {type: "date"},
181  completeDate: {type: "date"},
182  status: {type: "string"},
183  message: {type: "string"},
184  cus: {type: "odata"},
185  mainStatus: {type: "string"}
186  }
187  },
188  parse: function (data) {
189  hideWaitWindow();
190 
191  if (data.status !== "000") {
192  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
193  return [];
194  } else {
195  ShowWarnings(data.warnings);
196 
197  <?php // Check if there is a process running and if so, then display running window ?>
198  <?php if ($ableToRunBilling) { ?>
199  if (!ignoreProgress && data.running.length > 0) {
200  SetupProgressBar(data.running[0].month, kendo.toString(new Date(data.running[0].month), "MMMM yyyy"));
201  }
202  <?php } ?>
203 
204  return data.record;
205  }
206 
207  }
208  }
209  },
210  columns: [
211  {field: "status", hidden: true},
212  {field: "month", title: "Month", format: "{0:MMM yyyy}", width: "15%"},
213  {field: "runDate", title: "Start", format: "{0:MM/dd/yyyy}", width: "15%"},
214  {field: "mainStatus", title: "Main Status", width: "15%"},
215  {field: "completeDate", title: "Completed Date",
216  template: "# if (completeDate == null) { # # } else { # #: kendo.toString(completeDate, 'MM/dd/yyyy') # # } #", width: "15%"}
217  ],
218  toolbar: [<?php if ($ableToRunBilling) { ?> {name: "startBilling", text: "Start Billing"}, <?php } ?> {name: "createReport", text: "Create Report"}],
219  detailTemplate: "<div class=\"grid_12\"><div class=\"errorDiv\"></div></div><div class=\"grid_12\">"
220  + "<div class=\"detailGrid1\" style=\"width:100%\"></div></div>",
221  detailInit: function (eOuter) {
222 
223  var errorMessage = "(No errors)";
224  var errorDiv = eOuter.detailRow.find(".errorDiv");
225  if (eOuter.data.status.trim() != "") {
226  errorMessage = eOuter.data.message;
227  eOuter.masterRow.css({color: "red", fontWeight: "bold"});
228  errorDiv.css({color: "red", fontWeight: "bold"});
229  }
230  errorDiv.text(errorMessage);
231  var detailGrid1 = eOuter.detailRow.find(".detailGrid1").kendoGrid({
232  dataSource: {
233  transport: {
234  read: function (options) {
235  options.success(eOuter.data.cus);
236  }
237  },
238  schema: {
239  model: {
240  id: "cu",
241  fields: {
242  cu: {type: "string", editable: false, nullable: false},
243  totalAmount: {type: "number"},
244  invoices: {type: "odata"},
245  type: {type: "string"},
246  cuName: {type: "string"}
247  }
248  }
249  }
250  },
251  columns: [
252  {field: "cuName", title: "CU"},
253  {field: "cu", title: "CU No.", width: "15%"},
254  {field: "type", title: "Type", width: "15%"},
255  {field: "totalAmount", title: "Total", format: "{0:c}", width: "15%", attributes: {style: "text-align: right;"}}
256  ],
257  detailTemplate: "<div class=\"detailGrid2\"></div>",
258  detailInit: function (eMiddle) {
259  var detailGrid2 = eMiddle.detailRow.find(".detailGrid2").kendoGrid({
260  dataSource: {
261  transport: {
262  read: function (options) {
263  options.success(eMiddle.data.invoices);
264  }
265  },
266  schema: {
267  model: {
268  id: "preInvoiceId",
269  fields: {
270  preInvoiceId: {type: "number", editable: false, nullable: false},
271  featureBillingDetailId: {type: "number"},
272  invoiceDescription: {type: "string"},
273  quantity: {type: "number"},
274  amount: {type: "number"},
275  productDescription: {type: "string"},
276  featureDescription: {type: "string"},
277  quantityLabel: {type: "string"}
278  }
279  }
280  }
281  },
282  columns: [
283  {field: "featureBillingDetailId", title: "Id", width: "8%", attributes: {style: "text-align: right;"}},
284  {field: "productDescription", title: "Product"},
285  {field: "featureDescription", title: "Feature"},
286  {field: "invoiceDescription", title: "Description"},
287  {field: "quantity", title: "Count", template: "#= Number(quantity) # #= quantityLabel #", width: "15%"},
288  {field: "amount", title: "Total", format: "{0:c}", width: "15%", attributes: {style: "text-align: right;"}}
289  ]
290  }).data("kendoGrid");
291  }
292  }).data("kendoGrid");
293  },
294  dataBound: function (eOuter) {
295  $("#billingGrid .k-grid-content .k-master-row").each(function () {
296  if ($(this).find("td:eq(1)").text().trim() != "") {
297  $(this).css({color: "red", fontWeight: "bold"});
298  }
299  });
300 
301 
302  }
303  }).data("kendoGrid");
304 
305 }
306 
307 <?php
308 /**
309  * function SetupReport()
310  * This function sets up the report.
311  * Report is by month and has all the information that the grid has.
312  */
313 ?>
314 function SetupReport() {
315  // Initialize window
316  var reportWindow = $("#reportWindow").kendoWindow({
317  content: {
318  template: kendo.template($("#reportTemplate").html())
319  },
320  modal: true,
321  title: "Get Report For...",
322  visible: false,
323  actions: [],
324  draggable: false,
325  resizable: false,
326  width: 400
327  }).data("kendoWindow");
328 
329  var previousMonth = new Date();
330  previousMonth.setMonth(previousMonth.getMonth() - 1);
331  previousMonth.setDate(1);
332  previousMonth.setHours(0,0,0,0);
333 
334  // Initialize controls
335  var reportMonthPicker = $("#reportMonthPicker").kendoDatePicker({
336  depth: "year",
337  start: "year",
338  format: "MMM yyyy"
339  }).data("kendoDatePicker");
340 
341  // Initialize click events
342  $("#billingGrid").on("click", ".k-grid-createReport", function () {
343  reportMonthPicker.value(previousMonth);
344  reportWindow.open();
345  reportWindow.center();
346  return false;
347  });
348 
349  $("#reportWindow .reportOkayBtn").click(function () {
350  showWaitWindow();
351  reportWindow.close();
352 
353  var simpleReportMonth = '<input name="reportDate" value="' + kendo.toString(reportMonthPicker.value(), "yyyy-MM-dd") + '">';
354  var send = "";
355 
356  if ($("#asCSV").prop("checked")) {
357  send = '<form id="sendForm" style="display:none;" action="index.prg?operation=monthReportCSV" method="POST">';
358  send += simpleReportMonth;
359  send += '</form>';
360  } else {
361  send = '<form id="sendForm" style="display:none;" action="index.prg?page=monthReport" method="POST">';
362  send += simpleReportMonth;
363  send += '</form>';
364  }
365 
366  $("#reportWindow").append(send);
367  $("#sendForm").submit();
368  $("#sendForm").remove();
369  hideWaitWindow();
370  $("#asCSV").prop("checked", false);
371  return false;
372  });
373 
374  $("#reportWindow .reportCancelBtn").click(function () {
375  reportWindow.close();
376  return false;
377  });
378 }
379 
380 <?php
381 /**
382  * function SetupProgressBar(selectedMonth, selectedMonthDisplay)
383  * This function sets up the progress bar.
384  * The progress bar shows up when the page is access when the QWBC is running.
385  *
386  * @param selectedMonth -- the month to see progress.
387  * @param selectedMonthDisplay -- the display of the month.
388  */
389 ?>
390 function SetupProgressBar(selectedMonth, selectedMonthDisplay) {
391  var progressWindow = $("#progressWindow").data("kendoWindow");
392  if (progressWindow == null) {
393  progressWindow = $("#progressWindow").kendoWindow({
394  content: {
395  template: kendo.template($("#progressTemplate").html())
396  },
397  modal: true,
398  title: "QWBC is running",
399  visible: false,
400  actions: [],
401  draggable: false,
402  resizable: false,
403  width: 400
404  }).data("kendoWindow");
405  }
406 
407  showWaitWindow();
408  $.post("index.prg?operation=monthlyProgressLoad", {reportDate: selectedMonth}, function (data) {
409  hideWaitWindow();
410  if (data.status !== "000") {
411  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
412  } else {
413  var progressBar = $("#progressBar").kendoProgressBar({
414  min: 0,
415  max: 1,
416  type: "percent"
417  }).data("kendoProgressBar");
418 
419  var title = "Running for " + selectedMonthDisplay;
420  if (data.record.length > 0) {
421  var record = data.record[0];
422  progressBar.value(record.progress);
423 
424  if (record.type == "QWBC") {
425  title += " (QWBC)";
426  }
427  } else {
428  progressBar.value(0);
429  }
430  progressWindow.title(title);
431 
432  progressWindow.open().center();
433 
434  intervalFunc = setInterval(ProgressIntervalFunction(selectedMonth), 100);
435  }
436  });
437 }
438 
439 var intervalFunc;
440 var previousValue1 = -1;
441 var previousValue2 = -1;
442 var previousValue3 = -1;
443 var ignoreProgress = false;
444 <?php
445 /**
446  * function ProgressIntervalFunction(selectedMonth)
447  * This function is run continually until the process completes or it returns the same values three times.
448  * @param selectedMonth -- month found to have an uncompleted process running
449  */
450 ?>
451 function ProgressIntervalFunction(selectedMonth) {
452  var progressBar = $("#progressBar").data("kendoProgressBar");
453  var progressWindow = $("#progressWindow").data("kendoWindow");
454  showWaitWindow();
455  $.post("index.prg?operation=monthlyProgressLoad", {reportDate: selectedMonth}, function (data) {
456  hideWaitWindow();
457  if (data.status !== "000") {
458  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
459  } else {
460  var progress = data.record[0].progress;
461  progressBar.value(progress);
462 
463  var threeValuesSame = previousValue1 == previousValue2 && previousValue2 == previousValue3 && previousValue1 != -1;
464  ignoreProgress = threeValuesSame;
465  previousValue3 = previousValue2;
466  previousValue2 = previousValue1;
467  previousValue1 = progress;
468 
469  if (progress >= 1 || threeValuesSame) {
470  clearInterval(intervalFunc);
471  progressWindow.close();
472 
473  // Don't bother refreshing if no new processes have finished.
474  if (!threeValuesSame) {
475  $("#billingGrid").data("kendoGrid").dataSource.read();
476  }
477  }
478  }
479  });
480 }
481 
482 <?php if ($ableToRunBilling) { ?>
483 var availableMonths = [];
484 <?php
485 /**
486  * function InitRunBilling()
487  * This function initializes the windows, controls, and click events for running billing.
488  */
489 ?>
490 function InitRunBilling() {
491  var window = $("#startBillingWindow").data("kendoWindow");
492 
493  var monthMap = GetMonthMap();
494 
495  // Initialize windows
496  var window = $("#startBillingWindow").kendoWindow({
497  content: {
498  template: kendo.template($("#startBillingTemplate").html())
499  },
500  modal: true,
501  title: "Start Billing",
502  visible: false,
503  actions: [],
504  draggable: false,
505  resizable: false,
506  width: 400
507  }).data("kendoWindow");
508 
509  var startBillingBtn = $("#billingGrid .k-grid-startBilling").kendoButton({
510  click: function () {
511  $.homecuValidator.setup({formValidate: "billingForm", formStatusField: "formValidateBillingDiv"});
512 
513  var billingMonthPicker = $("#billingMonthPicker").data("kendoDatePicker");
514  var cutoffPicker = $("#cutoffPicker").data("kendoDateTimePicker");
515  if (billingMonthPicker == null) {
516  // Initialize controls
517  cutoffPicker = $("#cutoffPicker").kendoDateTimePicker({
518  format: "yyyy-MM-dd HH:mm:ss",
519  parseFormats: ["yyyy-MM-dd HH:mm:ss"],
520  change: function () {
521  var value = this.value();
522  if (value == null || $("#cutoffPicker").val().trim() == "") {
523  this.value(null);
524  }
525  }
526  }).data("kendoDateTimePicker");
527 
528  billingMonthPicker = $("#billingMonthPicker").kendoDatePicker({
529  depth: "year",
530  start: "year",
531  format: "MMM yyyy",
532  change: function () {
533  var value = this.value();
534  if (value == null || $("#billingMonthPicker").val().trim() == "") {
535  this.value(null);
536  } else {
537  value.setDate(1);
538  value.setHours(0,0,0,0);
539  cutoffPicker.value(GetMonthCutoff(value, monthMap));
540  }
541  }
542  }).data("kendoDatePicker");
543 
544  <?php if ($SYSENV["devmode"] == 1) { ?>
545  var debugDDL = $("#debugDDL").kendoDropDownList({
546  dataSource: ["localhost", "my.homecu.net"],
547  value: "Localhost"
548  }).data("kendoDropDownList");
549  <?php } ?>
550  }
551  billingMonthPicker.value(null);
552  cutoffPicker.value(null);
553 
554  window.open();
555  window.center();
556  return false;
557  }
558  }).data("kendoButton");
559 
560  <?php // Initialize click events ?>
561  $("#startBillingWindow").on("click", ".startBillingBtn", function () {
562  if ($.homecuValidator.validate()) {
563  window.close();
564 
565  <?php // Reset the validator so any errors show up in the main screen yet again. ?>
566  $.homecuValidator.setup({formValidate:'formMain', formStatusField: 'formValidateMainDiv'});
567 
568  var billingMonthPicker = $("#billingMonthPicker").data("kendoDatePicker");
569  var cutoffPicker = $("#cutoffPicker").data("kendoDateTimePicker");
570  var selectedMonth = kendo.toString(new Date(billingMonthPicker.value()), "yyyy-MM-dd");
571  var selectedMonthDisplay = kendo.toString(new Date(billingMonthPicker.value()), "MMMM yyyy");
572  var cutoffDate = kendo.toString(cutoffPicker.value(), "yyyy-MM-dd");
573  var cutoffTime = kendo.toString(cutoffPicker.value(), "HH:mm:ss");
574 
575  var parameters = {reportDate: selectedMonth, cutoffDate: cutoffDate, cutoffTime: cutoffTime};
576 
577  <?php if ($SYSENV["devmode"] == 1) { ?>
578 
579  var debugValue = $("#debugDDL").data("kendoDropDownList").value();
580  switch(debugValue) {
581  case "my.homecu.net":
582  parameters.operation = "gatherBillingInfoOdyssey";
583  break;
584  default:
585  parameters.operation = "gatherBillingInfo";
586  break;
587 
588  }
589  <?php } else { ?>
590  parameters.operation = "gatherBillingInfo";
591  <?php } ?>
592  runBillingDS.read(parameters);
593  }
594  return false;
595  });
596 
597  $("#startBillingWindow").on("click", ".cancelBillingBtn", function() {
598  window.close();
599  return false;
600  })
601 }
602 
603 <?php
604 /* This function gets a list of available months. It first goes through the grid and if there is a month that is incompletely run, that will be in the array.
605 And then it will get months that aren't in the grid.
606  * Parameters: getAllIn6months-- Boolean if true, then the last 6 months will be returned regardless if month hasn't been run, was run successfully,
607  or was run unsuccessfully;
608  * if false, then if there is any incomplete months they will be returned ONLY. If there are no incomplete months, then months in the past 6 months
609  that haven't been run will be returned.
610  * Returns: list of availableMonths in the criteria above
611  */ ?>
612 <?php
613 /**
614  * function GetMonthCutoff(monthDate, monthMap)
615  * This function gets a list of available months.
616  * It first goes through the grid and if there is a month that is incompletely run,
617  * that will be in the array.
618  * And then it will get months that aren't in the grid.
619  *
620  * @param monthDate -- the date of the month.
621  * @param monthMap -- a list of months with start dates and times.
622  */
623 ?>
624 function GetMonthCutoff(monthDate, monthMap) {
625  var monthString = kendo.toString(monthDate, "yyyy-MM-dd");
626  var cutoff = monthMap.map[monthString];
627  var firstOfMonth = new Date(monthDate);
628  var month = firstOfMonth.getMonth() + 1;
629  var year = firstOfMonth.getFullYear();
630  var actualMonth = month - 1;
631  var actualYear = year;
632 
633  if (cutoff == null) {
634  if (monthMap.first == null) { <?php // There isn't anything in the map. ?>
635  if (month == 1) {
636  month = 12;
637  year--;
638  } else {
639  month--;
640  }
641  cutoff = new Date("" + month + "/1/" + year)
642  } else if (firstOfMonth.getTime() >= monthMap.last.getTime()) {
643  monthString = kendo.toString(monthMap.last, "yyyy-MM-dd");
644  cutoff = new Date(monthMap.map[monthString]);
645  } else if (firstOfMonth.getTime() == monthMap.first.getTime()) {
646  monthString = kendo.toString(monthMap.first, "yyyy-MM-dd");
647  cutoff = new Date(monthMap.map[monthString]);
648  } else if (firstOfMonth.getTime() < monthMap.first.getTime()) {
649  cutoff = new Date(monthDate);
650  } else {
651  while (cutoff == null) {
652  month--;
653  if (month == 0) {
654  month = 12;
655  year--;
656  } else if (month == 13) {
657  month = 1;
658  year++;
659  }
660 
661  firstOfMonth = new Date("" + month + "/1/" + year);
662  monthString = kendo.toString(firstOfMonth, "yyyy-MM-dd");
663  cutoff = monthMap.map[monthString] == null ? null : new Date(monthMap.map[monthString]);
664  }
665  }
666  } else {
667  cutoff = new Date(cutoff);
668  }
669 
670  <?php // Set the cutoff to the previous month now that it is found. ?>
671  actualMonth--;
672  if (actualMonth == -1) {
673  actualMonth = 11;
674  actualYear--;
675  } else if (actualMonth == 12) {
676  actualMonth = 0;
677  actualYear++;
678  }
679  cutoff.setFullYear(actualYear, actualMonth, 1);
680  return cutoff;
681 }
682 
683 <?php
684 /**
685  * function GetMonthMap()
686  * This gets the month map.
687  */
688 ?>
689 function GetMonthMap() {
690  var gridData = $("#billingGrid").data("kendoGrid").dataSource.data();
691  var monthMap = {first: null, last: null, map: {}};
692  for(var i = 0; i != gridData.length; i++) {
693  var record = gridData[i];
694  var monthLabel = kendo.toString(record.month, "MMM yyyy");
695  var monthString = kendo.toString(record.month, "yyyy-MM-dd");
696  var cutoff = new Date(record.runDate);
697  monthMap.map[monthString] = cutoff;
698  if (monthMap.first == null || record.month.getTime() < monthMap.first.getTime()) {
699  monthMap.first = new Date(record.month); <?php // So it doesn't point to the same object. ?>
700  }
701  if (monthMap.last == null || record.month.getTime() > monthMap.last.getTime()) {
702  monthMap.last = new Date(record.month);
703  }
704  }
705  return monthMap;
706 }
707 <?php } // End check if user has edit powers ?>
708 
709 $(document).ready(function () {
710  $.homecuValidator.setup({formValidate:'formMain', formStatusField: 'formValidateMainDiv'});
711  InitMonthlyBilling();
712  SetupReport();
713  InitDataSources();
714 
715  <?php if ($ableToRunBilling) { ?>
716  InitRunBilling();
717  <?php } ?>
718 })
719 </script>
720 
721 <?php if ($ableToRunBilling) { ?>
722 <script id="startBillingTemplate" type="text/x-kendo-template">
723  <div class="k-edit-form-container">
724  <div id="formValidateBillingDiv" class="homecu-formStatus k-block k-error-colored" style="display:none;"></div>
725  <form id="billingForm" data-role="validator" novalidate>
726  <div class="container_12">
727  <div class="grid_12">
728  <div class="grid_4 alpha">
729  <label>Month:</label>
730  </div>
731  <div class="grid_7">
732  <input id="billingMonthPicker" name="billingMonth" required data-required-msg="Billing month is required" style="width:100%">
733  </div>
734  <div class="grid_1 omega">
735  <span data-for='billingMonth' class='k-invalid-msg'></span>
736  </div>
737  </div>
738  <div class="grid_12">
739  <div class="grid_4 alpha">
740  <label>Cutoff:</label>
741  </div>
742  <div class="grid_7">
743  <input id="cutoffPicker" name="cutoff" required data-required-msg="Cutoff time is required" style="width:100%">
744  </div>
745  <div class="grid_1 omega">
746  <span data-for='cutoff' class='k-invalid-msg'></span>
747  </div>
748  </div>
749  <?php if ($SYSENV["devmode"] == 1) { ?>
750  <div class="grid_12">
751  <div class="grid_4 alpha">
752  <label>Contract Source:</label>
753  </div>
754  <div class="grid_7">
755  <div id="debugDDL"></div>
756  </div>
757  <div class="grid_1 omega">
758  &nbsp;
759  </div>
760  </div>
761  <?php } ?>
762  </div>
763  </form>
764  <div class="k-edit-buttons k-state-default">
765  <a class="k-button k-button-icontext k-primary startBillingBtn" href="\#">
766  <span class="k-icon k-update"></span>Start
767  </a>
768  <a class="k-button k-button-icontext cancelBillingBtn" href="\#">
769  <span class="k-icon k-cancel"></span>Cancel
770  </a>
771  </div>
772  </div>
773 </script>
774 <script id="progressTemplate" type="text/x-kendo-template">
775  <div class="k-edit-form-container">
776  <div class="container_12">
777  <div class="grid_12">
778  <div id="progressBar" style="width:100%"></div>
779  </div>
780  </div>
781  </div>
782 </script>
783 <?php } ?>
784 <script id="reportTemplate" type="text/x-kendo-template">
785  <div class="k-edit-form-container">
786  <div id="formValidateReportDiv" class="homecu-formStatus k-block k-error-colored" style="display:none;"></div>
787  <form id="reportForm" data-role="validator" novalidate>
788  <div class="container_12">
789  <div class="grid_12">
790  <div class="grid_4 alpha">
791  <label>Month:</label>
792  </div>
793  <div class="grid_7">
794  <input id="reportMonthPicker" name="reportMonth" required data-required-msg="Report month is required" style="width:100%">
795  </div>
796  <div class="grid_1 omega">
797  <span data-for='reportMonth' class='k-invalid-msg'></span>
798  </div>
799  </div>
800  <div class="grid_12">
801  <div class="grid_4 alpha">
802  <label>As CSV:</label>
803  </div>
804  <div class="grid_7">
805  <input id="asCSV" name="asCSV" type="checkbox">
806  </div>
807  <div class="grid_1 omega">
808  <span data-for='asCSV' class='k-invalid-msg'></span>
809  </div>
810  </div>
811  </div>
812  </form>
813  <div class="k-edit-buttons k-state-default">
814  <a class="k-button k-button-icontext k-primary reportOkayBtn" href="\#">
815  <span class="k-icon k-update"></span>Okay
816  </a>
817  <a class="k-button k-button-icontext reportCancelBtn" href="\#">
818  <span class="k-icon k-cancel"></span>Cancel
819  </a>
820  </div>
821  </div>
822 </script>
823 <div id="startBillingWindow"></div>
824 <div id="progressWindow"></div>
825 <div id="reportWindow"></div>
826 <div id="runningWindow"></div>
827 <div class="container_12">
828  <div id="formMain"></div>
829  <div id="formValidateMainDiv" style="display:none;"></div>
830  <div class="grid_12">
831  <div id="warningDiv" class="k-block" style="display:none;"></div>
832  </div>
833  <div class="grid_12">
834  <div id="billingGrid"></div>
835  </div>
836 </div>