Kreditoren Statistik
This commit is contained in:
parent
ff6ff80506
commit
520c0e996c
6 changed files with 301 additions and 27 deletions
|
|
@ -1,6 +1,12 @@
|
|||
# Versionen
|
||||
### 1.2.13
|
||||
|
||||
### 1.2.12 (Development)
|
||||
- Payment Statistik
|
||||
- Neue Indexfelder 'invoice.date' 'payment.date'
|
||||
|
||||
**WICHTIG:** Es muss nach dem Update einmal der Index neu berechnet werden.
|
||||
|
||||
### 1.2.12
|
||||
|
||||
- Neue Debitoren/Kreditoren Verwaltung - Zusätzliche E-Mail
|
||||
Realisiert über neue Custom Feld 'textlist'
|
||||
|
|
|
|||
|
|
@ -4,12 +4,19 @@ import java.io.Serializable;
|
|||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.ConversationScoped;
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -37,6 +44,8 @@ public class DebitorStatistikController implements Serializable {
|
|||
@Inject
|
||||
protected DocumentService documentService;
|
||||
|
||||
TreeMap<String, DebitorStatistikData> stats = null;
|
||||
|
||||
@Inject
|
||||
protected WorkflowController workflowController;
|
||||
|
||||
|
|
@ -141,29 +150,42 @@ public class DebitorStatistikController implements Serializable {
|
|||
* Zahlungszeitspanne gruppiert nach monaten
|
||||
*
|
||||
*/
|
||||
public void collect(Date from, Date to) {
|
||||
public Map<String, DebitorStatistikData> getStats() {
|
||||
|
||||
Map<String, DebitorStatistikData> stats = new HashMap<String, DebitorStatistikData>();
|
||||
if (stats != null) {
|
||||
return stats;
|
||||
}
|
||||
|
||||
// recompute
|
||||
stats = new TreeMap<String, DebitorStatistikData>();
|
||||
|
||||
// invoice.date:[20210101 TO 20210201]
|
||||
DateFormat df = new SimpleDateFormat("yyyymmdd");
|
||||
|
||||
String query = "(type:workitemarchive) AND dbtr.number:" + getDbtNr()
|
||||
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5300 TO 5399])";
|
||||
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5900 TO 5999])";
|
||||
|
||||
query = query + " AND (invoice.date:[" + df.format(from) + " TO " + df.format(to) + "])";
|
||||
// query = query + " AND (invoice.date:[" + df.format(from) + " TO " +
|
||||
// df.format(to) + "])";
|
||||
logger.info("query = " + query);
|
||||
try {
|
||||
List<ItemCollection> invoices = documentService
|
||||
.find(query, 9999, 0);
|
||||
.findStubs(query, 9999, 0, "$created", false);
|
||||
|
||||
for (ItemCollection invoice : invoices) {
|
||||
try {
|
||||
|
||||
logger.warning("Rechnung: " + invoice.getUniqueID());
|
||||
Date invoiceDate = invoice.getItemValueDate("invoice.date");
|
||||
Date paymentDate = findLastEventDate(invoice);
|
||||
Date invoiceDueDate = invoice.getItemValueDate("invoice.duedate");
|
||||
Date paymentDate = findPaymentDateByWorkitem(invoice);
|
||||
if (paymentDate == null) {
|
||||
// fall back method
|
||||
logger.warning("Es wurde kein Zahlungseingang gefunden");
|
||||
// paymentDate = findPaymentDateByLog(invoice);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (invoiceDate != null && paymentDate != null) {
|
||||
if (invoiceDate != null && paymentDate != null && invoiceDueDate != null) {
|
||||
// do we have a stats object?
|
||||
DebitorStatistikData statData = stats.get(getYearMonth(invoiceDate));
|
||||
if (statData == null) {
|
||||
|
|
@ -172,6 +194,7 @@ public class DebitorStatistikController implements Serializable {
|
|||
}
|
||||
|
||||
// jetzt irgendwas ausrechnen
|
||||
statData.compute(invoiceDate, invoiceDueDate, paymentDate);
|
||||
|
||||
// .. und wieder speichern
|
||||
stats.put(statData.toString(), statData);
|
||||
|
|
@ -189,8 +212,53 @@ public class DebitorStatistikController implements Serializable {
|
|||
logger.severe("Failed to get statistic: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Step 2: Sort the list based on the alphanumeric order of the keys
|
||||
|
||||
// stats = new TreeMap<>(stats);
|
||||
completeMissingMonths();
|
||||
return stats;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsmethode ergänzt die fehlenden Monate
|
||||
*
|
||||
* @param yearMonths
|
||||
* @return
|
||||
*/
|
||||
private void completeMissingMonths() {
|
||||
if (stats == null || stats.size() < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the list of strings to a list of LocalDate objects
|
||||
List<LocalDate> dates = new ArrayList<>();
|
||||
Set<String> yearMonths = this.stats.keySet();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
|
||||
for (String yearMonth : yearMonths) {
|
||||
dates.add(YearMonth.parse(yearMonth, formatter).atDay(1));
|
||||
}
|
||||
|
||||
// Find the lowest and highest dates
|
||||
LocalDate lowestDate = Collections.min(dates);
|
||||
LocalDate highestDate = Collections.max(dates);
|
||||
|
||||
LocalDate current = lowestDate;
|
||||
current = current.plusMonths(1);
|
||||
while (!current.isAfter(highestDate)) {
|
||||
|
||||
// existiert der monat?
|
||||
String formattedDate = current.format(formatter);
|
||||
DebitorStatistikData entry = stats.get(formattedDate);
|
||||
if (entry == null) {
|
||||
// add missing entry
|
||||
stats.put(formattedDate, new DebitorStatistikData(current.getYear(), current.getMonthValue()));
|
||||
}
|
||||
current = current.plusMonths(1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* returns
|
||||
*
|
||||
|
|
@ -214,7 +282,49 @@ public class DebitorStatistikController implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds the date when a workitem last reached the current task
|
||||
* Finds the payment.date for a invoice.
|
||||
*
|
||||
* Wir suchen alle zugeordneten Zahlungseingägne und nehmen den letzten.
|
||||
*
|
||||
* WICHTIG: Es muss ggf. der index neu aufgebaut werden, da payment.date nun ein
|
||||
* index feld ist
|
||||
*
|
||||
* @param invoice
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Date findPaymentDateByWorkitem(ItemCollection invoice) throws ParseException {
|
||||
|
||||
// Wir selektieren alle Zahlungseingänge interessieren usn aber nur für den
|
||||
// letzten
|
||||
String sQuery = " (type:\"workitem\" OR type:\"workitemarchive\") " + //
|
||||
" AND ($workflowgroup:Zahlungseingang) AND ($workitemref:\""
|
||||
+ invoice.getUniqueID() + "\" )";
|
||||
|
||||
List<ItemCollection> workitems = null;
|
||||
|
||||
try {
|
||||
workitems = documentService.findStubs(sQuery, 99, 0,
|
||||
"payment.date", true);
|
||||
if (workitems.size() > 0) {
|
||||
return workitems.get(0).getItemValueDate("payment.date");
|
||||
}
|
||||
} catch (QueryException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// no date found!
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the date when a workitem last reached the current task 5900 by reading
|
||||
* the eventLog
|
||||
*
|
||||
* This method is not so save as the method findPaymentDateByWorkitem that is
|
||||
* searching the payment workitem.
|
||||
*
|
||||
* 2023-06-28T12:40:17.437|rechnungsausgang-de-1.0|5001.50|5900|
|
||||
*
|
||||
|
|
@ -222,7 +332,7 @@ public class DebitorStatistikController implements Serializable {
|
|||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Date findLastEventDate(ItemCollection invoice) throws ParseException {
|
||||
public Date findPaymentDateByLog(ItemCollection invoice) throws ParseException {
|
||||
|
||||
// Create a SimpleDateFormat instance with the desired format
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
|
|
@ -248,4 +358,92 @@ public class DebitorStatistikController implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Methode baut die Datenstruktur für das Chart Diagram zusammen
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
{
|
||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||
datasets: [{
|
||||
label: 'Dataset 1',
|
||||
//backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
|
||||
//borderColor: window.chartColors.red,
|
||||
borderWidth: 1,
|
||||
data: [
|
||||
70, 70, 70, 70, 79, 50, 50
|
||||
]
|
||||
}, {
|
||||
label: 'Dataset 2',
|
||||
//backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
|
||||
//borderColor: window.chartColors.blue,
|
||||
borderWidth: 1,
|
||||
data: [
|
||||
70, 70, 170, 7, 79, 50, 50
|
||||
]
|
||||
}]
|
||||
}
|
||||
* </pre>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String buildChartData() {
|
||||
|
||||
getStats();
|
||||
|
||||
// build a list of all lables....
|
||||
List<String> statusLabels = new ArrayList<String>();
|
||||
|
||||
Set<String> keys = stats.keySet();
|
||||
for (String _key : keys) {
|
||||
statusLabels.add(_key);
|
||||
}
|
||||
|
||||
String result = "{";
|
||||
|
||||
// Lables
|
||||
result = result + "labels : [ ";
|
||||
result = result + statusLabels.stream().collect(Collectors.joining("','", "'", "'"));
|
||||
result = result + "],";
|
||||
result = result + "datasets: [";
|
||||
|
||||
// Datasets 1
|
||||
result = result + "{label: 'Zahlungsziel',borderWidth: 1,";
|
||||
result = result + " \"backgroundColor\" : [\"#EBA05F\"],";
|
||||
|
||||
result = result + "data: [";
|
||||
for (Map.Entry<String, DebitorStatistikData> entry : stats.entrySet()) {
|
||||
result = result + entry.getValue().getAverageDueDays() + ",";
|
||||
}
|
||||
// cut last comma
|
||||
result = result.substring(0, result.length() - 1);
|
||||
result = result + "]";
|
||||
result = result + "}, ";
|
||||
|
||||
// Datasets 2
|
||||
result = result + "{label: 'Zahldauer',borderWidth: 1,";
|
||||
result = result + " \"backgroundColor\" : [\"#70B088\" ],";
|
||||
|
||||
result = result
|
||||
+ " trendlineLinear: { colorMin: \"red\", colorMax: \"green\", lineStyle: \"dotted\", width: 2 , projection: true },";
|
||||
|
||||
// result = result
|
||||
// + "trendlineLinear: {colorMin: \"red\",colorMax: \"green\", lineStyle:
|
||||
// \"dotted\",width: 2,projection: true},";
|
||||
|
||||
result = result + "data: [";
|
||||
for (Map.Entry<String, DebitorStatistikData> entry : stats.entrySet()) {
|
||||
result = result + entry.getValue().getAveragePaymentDays() + ",";
|
||||
}
|
||||
// cut last comma
|
||||
result = result.substring(0, result.length() - 1);
|
||||
result = result + "]";
|
||||
result = result + "} ";
|
||||
|
||||
// ende
|
||||
result = result + "] }";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,20 @@ package com.alexanderlogistics;
|
|||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Speichert Payment statistik
|
||||
*/
|
||||
public class DebitorStatistikData {
|
||||
private static Logger logger = Logger.getLogger(DebitorStatistikData.class.getName());
|
||||
|
||||
int month;
|
||||
int year;
|
||||
|
||||
int count = 0;
|
||||
int paymentTime; // Zahlungsziel
|
||||
int paymentDays; // Tatsächliche Zahlung
|
||||
int averageDueDays; // Zahlungsziel
|
||||
int averagePaymentDays; // Tatsächliche Zahlung
|
||||
|
||||
public DebitorStatistikData(Date date) {
|
||||
// Create a Calendar instance and set the date
|
||||
|
|
@ -40,8 +42,40 @@ public class DebitorStatistikData {
|
|||
* @param invoiceDate
|
||||
* @param paymentDate
|
||||
*/
|
||||
public void compute(Date invoiceDate, Date paymentDate) {
|
||||
public void compute(Date invoiceDate, Date invoiceDueDate, Date paymentDate) {
|
||||
// und was nun?
|
||||
count++;
|
||||
|
||||
logger.info("...invoiceDate= " + invoiceDate);
|
||||
logger.info("...invoiceDueDate= " + invoiceDueDate);
|
||||
logger.info("...paymentDate= " + paymentDate);
|
||||
|
||||
// Fälligkeit in Tagen
|
||||
long milliseconds1 = invoiceDate.getTime();
|
||||
long milliseconds2 = invoiceDueDate.getTime();
|
||||
// Berechnen Sie die Differenz in Millisekunden
|
||||
long diffMilliseconds = milliseconds2 - milliseconds1;
|
||||
long dueTime = diffMilliseconds / (24 * 60 * 60 * 1000);
|
||||
logger.info("...Fälligkeit in tagen= " + dueTime);
|
||||
averageDueDays = (int) (averageDueDays + dueTime / count);
|
||||
|
||||
// Bezahlt nach Tagen
|
||||
milliseconds1 = invoiceDate.getTime();
|
||||
milliseconds2 = paymentDate.getTime();
|
||||
// Berechnen Sie die Differenz in Millisekunden
|
||||
diffMilliseconds = milliseconds2 - milliseconds1;
|
||||
long paymentTime = diffMilliseconds / (24 * 60 * 60 * 1000);
|
||||
logger.info("...Zahlung erfolgte nach tagen= " + paymentTime);
|
||||
averagePaymentDays = (int) (averagePaymentDays + paymentTime / count);
|
||||
|
||||
}
|
||||
|
||||
public int getAverageDueDays() {
|
||||
return averageDueDays;
|
||||
}
|
||||
|
||||
public int getAveragePaymentDays() {
|
||||
return averagePaymentDays;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
lucence.indexDir=${imixs-office.IndexDir}
|
||||
index.fields=txtsearchstring,txtSubject,txtname,txtEmail,txtUserName,namCreator,txtworkflowgroup,txtworkflowstatus,txtWorkflowAbstract,txtWorkflowSummary,txtworkflowhistory,txtspacename,txtprocessname,_subject,_description,_name,_projectnumber,_projectname,_ordernumber,_contractnumber,datDueDate,txtcommentlog,htmldescription,htmldocumentation,dms,dms_names,invoice.number.stripped,_childitems,$file.names,_VENDOR_NAME,dbtr.number,cdtr.number
|
||||
index.fields.analyze=txtUsername
|
||||
index.fields.noanalyze=type,$UniqueIDRef,$created,$modified,$ModelVersion,$participants,namCreator,$ProcessID,datDate,txtWorkflowGroup,txtemail, datdate, datfrom, datto, numsequencenumber,dms_count,invoice.number,invoice.number.stripped,invoice.duedate,taxonomy.verteilung.stop,taxonomy.sachpruefung.stop,taxonomy.verteilung.start,taxonomy.sachpruefung.start,taxonomy.buchhaltung.start,taxonomy.buchhaltung.stop,dbtr.number,cdtr.number
|
||||
index.fields.store=process.name,txtProcessName,txtWorkflowImageURL
|
||||
index.fields.noanalyze=type,$UniqueIDRef,$created,$modified,$ModelVersion,$participants,namCreator,$ProcessID,datDate,txtWorkflowGroup,txtemail, datdate, datfrom, datto, numsequencenumber,dms_count,invoice.number,invoice.number.stripped,invoice.date,invoice.duedate,taxonomy.verteilung.stop,taxonomy.sachpruefung.stop,taxonomy.verteilung.start,taxonomy.sachpruefung.start,taxonomy.buchhaltung.start,taxonomy.buchhaltung.stop,dbtr.number,cdtr.number,payment.date
|
||||
index.fields.store=process.name,txtProcessName,txtWorkflowImageURL,payment.date,invoice.number,invoice.date,invoice.duedate
|
||||
index.fields.category=space.name,space.ref,taxonomy.verteilung.stop.by,taxonomy.sachpruefung.stop.by,taxonomy.buchhaltung.stop.by
|
||||
office.search.noanalyze=invoice.number,invoice.number.stripped
|
||||
|
||||
|
|
|
|||
18
office-alexander-logistics-app/src/main/webapp/js/chartjs-plugin-trendline.min.js
vendored
Normal file
18
office-alexander-logistics-app/src/main/webapp/js/chartjs-plugin-trendline.min.js
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Minified by jsDelivr using Terser v5.17.1.
|
||||
* Original file: /npm/chartjs-plugin-trendline@2.0.3/src/chartjs-plugin-trendline.js
|
||||
*
|
||||
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
|
||||
*/
|
||||
/*!
|
||||
* chartjs-plugin-trendline.js
|
||||
* Version: 2.0.3
|
||||
*
|
||||
* Copyright 2023 Marcus Alsterfjord
|
||||
* Released under the MIT license
|
||||
* https://github.com/Makanz/chartjs-plugin-trendline/blob/master/README.md
|
||||
*
|
||||
* Mod by: vesal: accept also xy-data so works with scatter
|
||||
*/
|
||||
var pluginTrendlineLinear={id:"chartjs-plugin-trendline",afterDatasetsDraw:function(t){var i,e;for(var s in t.scales)if("x"==s[0]?e=t.scales[s]:i=t.scales[s],e&&i)break;var a=t.ctx;t.data.datasets.forEach((function(i,s){var n=i.alwaysShowTrendline||t.isDatasetVisible(s);if(i.trendlineLinear&&n&&i.data.length>1){var r=t.getDatasetMeta(s);addFitter(r,a,i,e,t.scales[r.yAxisID])}})),a.setLineDash([])}};function addFitter(t,i,e,s,a){var n=e.borderColor||"rgba(169,169,169, .6)",r=e.trendlineLinear.colorMin||n,o=e.trendlineLinear.colorMax||n,l=e.trendlineLinear.width||e.borderWidth,h=e.trendlineLinear.lineStyle||"solid",u=e.trendlineLinear.fillColor;l=void 0!==l?l:3;var d=new LineFitter,m=e.data.findIndex((t=>null!=t)),c=e.data.length-1,x=t.data[m].x,f=t.data[c].x,X="object"==typeof e.data[m];e.data.forEach((function(t,i){if(null!=t)if(["time","timeseries"].includes(s.options.type)){var e=null!=t.x?t.x:t.t;d.add(new Date(e).getTime(),t.y)}else X?isNaN(t.x)||isNaN(t.y)?isNaN(t.x)?isNaN(t.y)||d.add(i,t.y):d.add(i,t.x):d.add(t.x,t.y):d.add(i,t)}));var p,g,v=s.getPixelForValue(d.minx),y=a.getPixelForValue(d.f(d.minx));if(e.trendlineLinear.projection&&d.scale()<0){var w=d.fo();w<d.minx&&(w=d.maxx),p=s.getPixelForValue(w),g=a.getPixelForValue(d.f(w))}else p=s.getPixelForValue(d.maxx),g=a.getPixelForValue(d.f(d.maxx));X||(v=x,p=f);var L=t.controller.chart.chartArea.bottom,F=t.controller.chart.width;if(y>L){var Y=y-L,T=y-g;y=L,v+=F*(Y/T)}else if(g>L){Y=g-L,T=g-y;g=L,p=F-(p-(F-F*(Y/T)))}i.lineWidth=l,"dotted"===h&&i.setLineDash([2,3]),i.beginPath(),i.moveTo(v,y),i.lineTo(p,g);var P=i.createLinearGradient(v,y,p,g);g<y?(P.addColorStop(0,o),P.addColorStop(1,r)):(P.addColorStop(0,r),P.addColorStop(1,o)),i.strokeStyle=P,i.stroke(),i.closePath(),u&&(i.fillStyle=u,i.beginPath(),i.moveTo(v,y),i.lineTo(p,g),i.lineTo(p,L),i.lineTo(v,L),i.closePath(),i.fill())}function LineFitter(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0,this.minx=1e100,this.maxx=-1e100,this.maxy=-1e100}LineFitter.prototype={add:function(t,i){t=parseFloat(t),i=parseFloat(i),this.count++,this.sumX+=t,this.sumX2+=t*t,this.sumXY+=t*i,this.sumY+=i,t<this.minx&&(this.minx=t),t>this.maxx&&(this.maxx=t),i>this.maxy&&(this.maxy=i)},f:function(t){t=parseFloat(t);var i=this.count*this.sumX2-this.sumX*this.sumX;return(this.sumX2*this.sumY-this.sumX*this.sumXY)/i+t*((this.count*this.sumXY-this.sumX*this.sumY)/i)},fo:function(){var t=this.count*this.sumX2-this.sumX*this.sumX;return-((this.sumX2*this.sumY-this.sumX*this.sumXY)/t)/((this.count*this.sumXY-this.sumX*this.sumY)/t)},scale:function(){var t=this.count*this.sumX2-this.sumX*this.sumX;return(this.count*this.sumXY-this.sumX*this.sumY)/t}},"undefined"!=typeof window&&window.Chart&&(window.Chart.hasOwnProperty("register")?window.Chart.register(pluginTrendlineLinear):window.Chart.plugins.register(pluginTrendlineLinear));try{module.exports=exports=pluginTrendlineLinear}catch(t){}
|
||||
//# sourceMappingURL=/sm/a0bca30b6b7f4fbdef5c66a04bd36e4926fa058e81cc14753a8b9dbb36676c5d.map
|
||||
|
|
@ -49,24 +49,42 @@
|
|||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</h:panelGroup>
|
||||
|
||||
|
||||
<!-- Chart Diagramm -->
|
||||
<div id="container" style="width: 75%;">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="#{facesContext.externalContext.requestContextPath}/js/chartjs/chart.min.js?build=#{app.application_build_timestamp}"></script>
|
||||
<script type="text/javascript"
|
||||
src="#{facesContext.externalContext.requestContextPath}/js/chartjs-plugin-trendline.min.js?build=#{app.application_build_timestamp}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
/*<![CDATA[*/
|
||||
var barChartData = #{ debitorStatistikController.buildChartData() };
|
||||
$(document).ready(
|
||||
function () {
|
||||
// update the checkboxes of the stored invoice uniqueIDs
|
||||
// updateInvoiceSelection();
|
||||
|
||||
// update the diagram
|
||||
var ctx = document.getElementById("canvas").getContext("2d");
|
||||
window.myBar = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: barChartData,
|
||||
options: {
|
||||
responsive: true,
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Zahlungsstatistik'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
/*]]>*/
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue