invoice report email
authorkilian <ksaffran@dks.lu>
Tue, 3 Nov 2020 14:40:59 +0000 (15:40 +0100)
committerkilian <ksaffran@dks.lu>
Tue, 3 Nov 2020 14:40:59 +0000 (15:40 +0100)
desktopapp/js/dataform.js
desktopapp/js/global/email.js [new file with mode: 0644]
desktopapp/js/global/renderer.js
desktopapp/js/global/report.js
desktopapp/js/global/sqlite.js
desktopapp/js/modules/booking.js
desktopapp/js/modules/invoice.js
desktopapp/js/modules/invoices.js
desktopapp/panels/invoice.html
desktopapp/panels/invoices.html
dev/mail.bat [new file with mode: 0644]

index f90d9c1..22a0e73 100644 (file)
@@ -2,42 +2,12 @@ let dataform = {
   saveform: function(frmid){
     var flds=dataform.getformcontent(frmid,null);
     console.log("TODO: save to db",flds);
-    // flds["fn"] ="saveform";
-    //flds["schemata"]=clientschema;
-    // flds["table"] = frmid;
-    // if (clientschema == null){
-    //   flds["schemata"]=schemata;
-    // }
     delete flds["null"]; 
-    //for (flds in )
-    // db.exec("UPDATE "+  + " set "++"="++" WHERE id="+ )
-    
-    // postData("db.cgi",flds).then(data => {
-    //   if (aftercallback){
-    //     aftercallback(data.result);
-    //     form.formsaved({});
-    //   } else {
-    //     form.formsaved(data.result);
-    //   }
-    // });
     return false;
   },
   saveformdata: function(flds){
-    //flds["fn"] ="saveform";
-    // flds["schemata"]=clientschema;
-    // if (clientschema == null){
-    //   flds["schemata"]=schemata;
-    // }
     delete flds["null"];
     console.log("TODO: save to db",flds);
-    // postData("db.cgi",flds).then(data => {
-    //   if (aftercallback){
-    //     aftercallback(data.result);
-    //     form.formsaved({});
-    //   } else {
-    //     form.formsaved(data.result);
-    //   }
-    // });
     return false;
   },
   formsaved: function(data){
@@ -108,19 +78,16 @@ let dataform = {
           frm[f].checked = false;
         } else if (frm[f].classList.contains("datefield")){
             if (frm[f]._flatpickr){ frm[f]._flatpickr.clear(); }
-        } else if (frm[f].classList.contains("choices__input")){
-          if (choice[frmname][frm[f].id]){
-            choice[frmname][frm[f].id].removeActiveItems();
-          }
-        } else {
+        }  
+        else {
           frm[f].value = "";
         }
       }
       if (frm[f].tagName == 'SELECT'){
         if (frm[f].multiple == true){
-          if (frm[f].classList.contains("choices__input")){
-            choice[frmname][frm[f].id].removeActiveItems();
-          }
+          // if (frm[f].classList.contains("choices__input")){
+          //   choice[frmname][frm[f].id].removeActiveItems();
+          // }
         } else {
           frm[f].value = "";
         }
@@ -300,15 +267,20 @@ let dataform = {
     if (obj.tagName == 'INPUT' || obj.tagName == 'SELECT' || obj.tagName == 'TEXTAREA'){
       if (obj.type == 'checkbox' || obj.type == 'radio'){
         if (obj.checked == true){
-          fdata["value"] = 1;
+          fdata["value"] = "'1'";
         } else {
-          fdata["value"] = null;
+          fdata["value"] = "null";
         }
       }else {
-        fdata["value"] = obj.value;
+        if (obj.value == ''){
+          fdata["value"] = 'null';
+        } else {
+          fdata["value"] = "'" +obj.value + "'";
+        }
+        
       }
     }
-    db.exec("UPDATE "+ fdata["table"]+" SET "+fdata["column"]+"='"+ fdata["value"] + "' WHERE id='" + fdata["id"]+ "';"); 
+    db.exec("UPDATE "+ fdata["table"]+" SET "+fdata["column"]+"="+ fdata["value"] + " WHERE id='" + fdata["id"]+ "';"); 
     return false;
   },
   cleanfield: function(objid){
diff --git a/desktopapp/js/global/email.js b/desktopapp/js/global/email.js
new file mode 100644 (file)
index 0000000..dce04d6
--- /dev/null
@@ -0,0 +1,37 @@
+let email = {
+  openthunderbird: function(maildata){
+    let args =[];
+    let mailcfg =[]
+    mailcfg.push("to='"+ data.to+"'");
+    mailcfg.push("from='"+ data.from +"'");
+    mailcfg.push("subject='"+ data.from +"'");
+    mailcfg.push("format=1"); // format => 1=HTML, 2=text
+    mailcfg.push("body='"+ data.body+"'");
+    mailcfg.push("attachment='"+ data.attachments.join(',')+'"'); 
+    args.push("-compose");
+    args.push(mailcfg.join(","));
+    
+    const mailappout = spawn(preferences.global.mailapp, args);
+    mailappout.stdout.on('data', (data) => {
+
+      console.log(`pdfout stdout: ${data}`);
+    });
+
+    mailappout.stderr.on('data', (data) => {
+     console.error(`pdfout stderr: ${data}`);
+    });
+
+    mailappout.on('close', (code) => {
+      console.log(`pdfout: child process exited with code ${code}`);
+      if (code == 0){
+        console.log("Copy",report.tmpoutput,"to",report.output);
+        if (fs.existsSync(report.output)){
+           fs.unlinkSync(report.output);
+        }
+        fs.copyFileSync(report.tmpoutput,report.output);
+        report.callback({"file":report.reportfile});
+      }
+      
+    });
+  }
+}
\ No newline at end of file
index f169a2b..0f3a620 100644 (file)
@@ -2,6 +2,8 @@ const { dialog } = require('electron');
 const fs = require('fs'); 
 const os = require('os');
 const path = require('path');
+const { spawn } = require('child_process');
+
 let usersystem = {
     profilepath: function(){
         let ppath="";
index 987a9a6..5ee806b 100644 (file)
@@ -1,4 +1,4 @@
-const { spawn } = require('child_process');
+
 //const fs = require('fs');
 let report = {
   id_report: null,
index 2b08b63..ab5f130 100644 (file)
@@ -90,9 +90,28 @@ let db = {
     let sqlvals = [];
     for (var c in data){
       sqlcols.push(c);
-      sqlvals.push("'" + data[c] +"'");
+      if ((data[c] == '') || (data[c] == null)){
+        sqlvals.push('null');
+      } else {
+        sqlvals.push("'" + data[c] +"'");
+      }
+      
     }
     let inssql = "INSERT INTO " + tbl + "(" + sqlcols.join(',') +") VALUES (" + sqlvals.join(',')+ ")";
     return inssql;  
+  },
+  create_replace: function(tbl,data){
+    let sqlcols = [];
+    let sqlvals = [];
+    for (var c in data){
+      sqlcols.push(c);
+      if ((data[c] == '') || (data[c] == null)){
+        sqlvals.push('null');
+      } else {
+        sqlvals.push("'" + data[c] +"'");
+      }
+    }
+    let replsql = "REPLACE INTO " + tbl + "(" + sqlcols.join(',') +") VALUES (" + sqlvals.join(',')+ ");";
+    return replsql;  
   }
 }
\ No newline at end of file
index e1299a6..fc35876 100644 (file)
@@ -4,6 +4,7 @@ let booking = {
       selector: '#invoicebooking_description',
       plugins: 'paste importcss searchreplace autolink directionality visualblocks visualchars template charmap nonbreaking advlist lists  textpattern noneditable charmap autoresize ',
       menubar: false,
+      entity_encoding : 'raw',
       toolbar: 'undo redo | bold italic underline strikethrough | fontsizeselect | outdent indent | forecolor removeformat | charmap',
       toolbar_sticky: true,
       language: 'de',
index c1cd0f1..41d1861 100644 (file)
@@ -10,6 +10,7 @@ let invoice = {
         invoice.current_id = id;
       console.log("ID Invoice:",id);
       db.query("SELECT inv.*,sum(bk.netamount) AS netamount,sum(bk.taxamount) AS vatamount,sum(bk.netamount + bk.taxamount) AS grossamount FROM invoices inv JOIN bookings bk ON (inv.id = bk.id_invoices) WHERE inv.id='"+id+"' GROUP BY inv.id;").then(data => {
+        console.log("invoicedata",data);
         dataform.fillform('invoices',invoice.selects,data);
         invoice.hasPDF(data.pdffile);
         invoice.getBookingData();
@@ -28,7 +29,10 @@ let invoice = {
       "locale": "de",
       onClose: function(selectedDates, dateStr, instance) {
         dataform.savefield(document.getElementById(instance.element.id));
+        //console.log("change DATE");
+        invoice.setDeadlineDate();
         invoice.setReference();
+        
       }
     });
     flatpickr("#invoices_deadlinedate",{altInput: true,
@@ -37,7 +41,7 @@ let invoice = {
       "locale": "de",
       onClose: function(selectedDates, dateStr, instance) {
         dataform.savefield(document.getElementById(instance.element.id));
-          invoice.setDeadlineDays();
+        invoice.setDeadlineDays();
       }
     });
     invoice.selects["invoices_invoicetype"] = new SlimSelect({
@@ -84,19 +88,19 @@ let invoice = {
     invoice.bookingtbl = new Tabulator("#tbl_invoicebookings",{
       headerFilterPlaceholder: "filter...",
       height: "calc(100vh - 60px)",
-      layout: "fitColumns",
+      layout: "fitDataFill",
       selectable: 1,
       rowContext:function(e, row){ e.preventDefault(); },
         columns: [
           //{title:"SKU", field:"sku"},
           {title: "Produkt",field: "displayitem",formatter:"html",width: 300 }, 
           {title: "Anzahl", field: "quantity",hozAlign:"right",width: 50 },
-          {title: "Einheit",field: "unit"},
-          {title: "Preis", field: "unitamount",headerSort: false, formatter:"money",hozAlign:"right", formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2}},
-          {title: "MwSt (%)", field: "vatpercent",headerSort: false, formatter:"money",hozAlign:"right", formatterParams:{  decimal:",",  thousand:".", symbol:"%", symbolAfter:"p", precision:2}},
-          {title: "Netto", field: "netamount",headerSort: false, formatter:"money",hozAlign:"right", formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
-          {title: "MwSt", field: "taxamount",headerSort: false, formatter:"money",hozAlign:"right", formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
-          {title: "Brutto", field: "grossamount",headerSort: false, formatter:"money",hozAlign:"right", formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          {title: "Einheit",field: "unit",width: 80 },
+          {title: "Preis", field: "unitamount",headerSort: false, formatter:"money",hozAlign:"right",width: 80, formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2}},
+          {title: "MwSt (%)", field: "vatpercent",headerSort: false, formatter:"money",hozAlign:"right",width: 70, formatterParams:{  decimal:",",  thousand:".", symbol:"%", symbolAfter:"p", precision:2}},
+          {title: "Netto", field: "netamount",headerSort: false, formatter:"money",hozAlign:"right",width: 100, formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          {title: "MwSt", field: "taxamount",headerSort: false, formatter:"money",hozAlign:"right",width: 90, formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          {title: "Brutto", field: "grossamount",headerSort: false, formatter:"money",hozAlign:"right",width: 100, formatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2},bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
           //,bottomCalcFormatter:"money", bottomCalcFormatterParams:{  decimal:",",  thousand:".", symbol:"€", symbolAfter:"p", precision:2}
       ]
     });
@@ -130,17 +134,19 @@ let invoice = {
       myapp.viewdialog("SelectAddress");
     });
 },
-  changeAccount: function(obj){
+  setAccount: function(obj){
     let adrsel = addresses.tblselector.getSelectedData();
     if (adrsel[0]){
-      document.getElementById("invoices_id_accounts").value= adrsel[0].id;
-      document.getElementById("invoices_accountname").value= adrsel[0].receipient;
-      document.getElementById("invoices_accountaddress").value= adrsel[0].address;
-      document.getElementById("invoices_accountcountry").value= adrsel[0].country;
-      document.getElementById("invoices_accountzip").value= adrsel[0].zip;
-      document.getElementById("invoices_accountcity").value= adrsel[0].city;
-      document.getElementById("invoices_clientnumber").value= adrsel[0].clientnumber;
-      document.getElementById("invoices_vatid").value= adrsel[0].vatid;
+      document.getElementById("invoices_id_accounts").value= adrsel[0].id;dataform.savefield(document.getElementById("invoices_id_accounts"));
+      
+      document.getElementById("invoices_accountname").value= adrsel[0].receipient;dataform.savefield(document.getElementById("invoices_accountname"));
+      document.getElementById("invoices_accountaddress").value= adrsel[0].address;dataform.savefield(document.getElementById("invoices_accountaddress"));
+      document.getElementById("invoices_accountcountry").value= adrsel[0].country;dataform.savefield(document.getElementById("invoices_accountcountry"));
+      document.getElementById("invoices_accountzip").value= adrsel[0].zip;dataform.savefield(document.getElementById("invoices_accountzip"));
+      document.getElementById("invoices_accountcity").value= adrsel[0].city;dataform.savefield(document.getElementById("invoices_accountcity"));
+      document.getElementById("invoices_clientnumber").value= adrsel[0].clientnumber;dataform.savefield(document.getElementById("invoices_clientnumber"));
+      document.getElementById("invoices_accountvatid").value= adrsel[0].vatid;dataform.savefield(document.getElementById("invoices_accountvatid"));
+      myapp.closeDialog("SelectAddress");
     }
   },
   setDeadlineDate: function(){
@@ -150,7 +156,8 @@ let invoice = {
     let dldate =  new Date(invdate);
     dldate.setDate(dldate.getDate() + dldays);
     // console.log("New deadline: " + dldate.toISOString().substring(0,10));
-    dataform.setValue(document.getElementById("invoices_deadlinedate"),dldate.toISOString().substring(0,10));
+    document.getElementById("invoices_deadlinedate")._flatpickr.setDate(moment(dldate).format('YYYY-MM-DD'));
+    dataform.savefield(document.getElementById("invoices_deadlinedate"));
   },
   setDeadlineDays: function(){
     //let invid = document.getElementById("invoices_id").value;
@@ -159,9 +166,13 @@ let invoice = {
     dataform.setValue(document.getElementById("invoices_deadlinedays"),dldate.diff(invdate,'days'));
   },
   setReference(){
-    // console.log("Set Reference");
-    // console.log(data);
-    document.getElementById("invoices_reference").value = data[0]["setinvoicereference"];
+    let invtype = document.getElementById("invoices_invoicetype").value;
+    if ((invtype == 'invoice-out') || (invtype == 'creditnote-out')){
+      document.getElementById("invoices_reference").value = invoice.getNewReference(document.getElementById("invoices_invoicedate").value);
+      dataform.savefield(document.getElementById("invoices_reference"));
+      document.getElementById("invoices_businessyear").value=moment(document.getElementById("invoices_invoicedate").value).format("YYYY");
+      dataform.savefield(document.getElementById("invoices_businessyear"));
+    } 
   },
   addProduct: function(){
     
@@ -216,7 +227,7 @@ let invoice = {
     }
     dataform.setValue(document.getElementById("invoicebooking_taxamount"),vatamount);
     grossamount = parseFloat(netamount) + parseFloat(vatamount);
-    document.getElementById("invoicebooking_grossamount").value = grossamount;
+    document.getElementById("invoicebooking_grossamount").value = grossamount.toFixed(2);
   },
   changedStatus: function(obj){
     if (obj.value == "payed" ){
@@ -370,9 +381,10 @@ let invoice = {
   },
   editBooking: function(){
     let sel = invoice.bookingtbl.getSelectedData();
+    dataform.cleanform("invoicebooking");
     if (sel[0]){
       db.query("select * from bookings where id='"+ sel[0].id +"'").then(bdata => {
-        console.log(bdata);
+        //console.log(bdata);
         dataform.fillform("invoicebooking",{},bdata);
         myapp.viewdialog("InvoiceBooking");
       });
@@ -380,12 +392,19 @@ let invoice = {
   },
   saveBooking: function(){
     let bflds = dataform.getformcontent("invoicebooking",{"bookings":{}});
-    console.log("Fields:",bflds);
-    //invoice.getBookingData();
-    myapp.closeDialog("InvoiceBooking");
+    //console.log("Fields:",bflds);
+    delete bflds.bookings.grossamount;
+    bflds.bookings["id_invoices"]=invoice.current_id;
+    let sql =  db.create_replace("bookings",bflds.bookings);
+    db.execAsync(sql).then(res => {
+      invoice.getBookingData();
+      myapp.closeDialog("InvoiceBooking");  
+    });
+    //console.log(sql);
+    
   },
   sendEmail: function(){
-    preferences.global.
+    
   }
  }
 
index 33f3cb4..d3ea30e 100644 (file)
@@ -70,14 +70,15 @@ let invoices = {
       selectable: 1,
       rowContext:function(e, row){ e.preventDefault(); },
         columns: [
-          {title:"Datum", field:"invoicedate",headerFilter:"input",formatter:"datetime",headerSort:true,formatterParams:{inputFormat:"YYYY-MM-DD",outputFormat:"DD.MM.YYYY",invalidPlaceholder:""}},
-          {title: "Konto", field: "accountname",headerFilter:"input"},
+          {title:"Datum", field:"invoicedate",headerFilter:"input",width: 100,formatter:"datetime",headerSort:true,formatterParams:{inputFormat:"YYYY-MM-DD",outputFormat:"DD.MM.YYYY",invalidPlaceholder:""}},
+          {title: "Typ", field: "invoicetype",headerFilter:"select",width: 180, headerFilterParams:{values:headerinvtypes},formatter:function(cell, formatterParams){ var value = cell.getValue(); if (value){ return "<span class="+ invtypes[value].class+">" + invtypes[value].text + "</span>" } return ""; } },
+          {title: "Konto", field: "accountname",headerFilter:"input",width: 300},
           {title: "Referenz",field: "reference",headerFilter:"input"},
-          {title: "Status", field: "status",headerFilter:"select", headerFilterParams:{values:headerstatustypes},formatter:function(cell, formatterParams){ var value = cell.getValue(); return "<span class="+ statustypes[value].class+">" + statustypes[value].text + "</span>" } },
-          {title: "Netto", field: "netamount",hozAlign:"right",formatter:"money", headerSort: false, formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, },bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
-          {title: "MwSt.", field: "vatamount",hozAlign:"right",formatter:"money", headerSort: false, formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }, bottomCalc:"sum", bottomCalcFormatter:"money", bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
-          {title: "Brutto", field: "grossamount",hozAlign:"right",headerSort: false,formatter:"money",  formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }, bottomCalc:"sum", bottomCalcFormatter:"money", bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
-          {title: "Typ", field: "invoicetype",headerFilter:"select", headerFilterParams:{values:headerinvtypes},formatter:function(cell, formatterParams){ var value = cell.getValue(); if (value){ return "<span class="+ invtypes[value].class+">" + invtypes[value].text + "</span>" } return ""; } },
+          {title: "Status", field: "status",headerFilter:"select",width: 125, headerFilterParams:{values:headerstatustypes},formatter:function(cell, formatterParams){ var value = cell.getValue(); return "<span class="+ statustypes[value].class+">" + statustypes[value].text + "</span>" } },
+          {title: "Netto", field: "netamount",hozAlign:"right",width: 125,formatter:"money", headerSort: false, formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, },bottomCalc:"sum",bottomCalcFormatter:"money",bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          {title: "MwSt.", field: "vatamount",hozAlign:"right",width: 125,formatter:"money", headerSort: false, formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }, bottomCalc:"sum", bottomCalcFormatter:"money", bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          {title: "Brutto", field: "grossamount",hozAlign:"right",width: 125,headerSort: false,formatter:"money",  formatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }, bottomCalc:"sum", bottomCalcFormatter:"money", bottomCalcFormatterParams:{ decimal:",", thousand:".", symbol:"€", symbolAfter:"p", precision:2, }},
+          
       ]
     });
     myapp.loaddialog("confirm").then(result => {
@@ -122,7 +123,7 @@ let invoices = {
         
         db.newuuid().then(newbookingid => {
           db.execAsync("INSERT INTO bookings (id,id_invoices)  VALUES ('"+ newbookingid.id+"','"+ newid.id+"');").then(res => {
-            invoice.viewpanel(newid);
+            invoice.viewpanel(newid.id);
           });
         });
 
index f7a5f47..eb5a8c8 100644 (file)
@@ -18,6 +18,7 @@
 </div>
 <div class="cell-row">
   <div class="container cell" style="max-height: calc(100vh - 56px);width: 400px;background-color: #e4e4e4;overflow-y: scroll;">
+    <form id="frm_invoice">
     <div class="container padding">
       <input class="data_invoices" data-column="id" data-id="" data-table="invoices" id="invoices_id" name="invoices_id" type="hidden" value="">
       <input class="data_invoices" data-column="pdffile" data-id="" data-table="invoices" id=
       </div>
       <div class="row">
         <div class="cell" style="width: 400px;">
-          <label class="label" for="invoices_reference">Referenz</label> <input class="input border text data_invoices" data-column="reference" data-id="" data-table="invoices" id="invoices_reference" name="invoices_reference" onblur=
-          "dataform.savefield(this);" type="text">
+          <label class="label" for="invoices_reference">Referenz</label> <input class="input border text data_invoices" data-column="reference" data-id="" data-table="invoices" id="invoices_reference" name="invoices_reference" onblur="dataform.savefield(this);" type="text">
         </div>
       </div>
       
     </div>
+    </form>
   </div>
   <div class="cell">
     <div id="tbl_invoicebookings"></div>
index e6306de..61a3660 100644 (file)
@@ -1,14 +1,11 @@
 <div class="display-container">
   <div class="container bar toolbar">
     <button class="bar-item toolbarbtn" onclick="index.viewpanel();"><span class="icon-back" style="font-size: 16px;"></span>zurück</button>
-    <div class="bar-item PageHeadTitle">
-      Rechnungen
-    </div><button class="bar-item toolbarbtn" onclick="invoices.loadfilters();"><span class="icon icon-filter" style="font-size: 16px;"></span>Filter</button>
-    <div class="bar-item PageHeadTitle" id="filtername">
-      2020
-    </div><button class="bar-item toolbarbtn right text-red" onclick="invoices.confirmremove();"><span class="icon icon-trash" style="font-size: 16px;"></span>löschen</button> <button class="bar-item toolbarbtn right" onclick=
-    "invoices.duplicate();"><span class="icon icon-duplicate" style="font-size: 16px;"></span>dupl.</button> <button class="bar-item toolbarbtn right" onclick="invoices.edit();"><span class="icon icon-edit" style=
-    "font-size: 16px;"></span>bearb.</button> <button class="bar-item toolbarbtn right" onclick="invoices.add();"><span class="icon icon-add" style="font-size: 16px;"></span>neu</button>
+    <div class="bar-item PageHeadTitle">Rechnungen</div>
+    <button class="bar-item toolbarbtn right text-red" onclick="invoices.confirmremove();"><span class="icon icon-trash" style="font-size: 16px;"></span>löschen</button> 
+    <button class="bar-item toolbarbtn right" onclick="invoices.duplicate();"><span class="icon icon-duplicate" style="font-size: 16px;"></span>dupl.</button> 
+    <button class="bar-item toolbarbtn right" onclick="invoices.edit();"><span class="icon icon-edit" style="font-size: 16px;"></span>bearb.</button> 
+    <button class="bar-item toolbarbtn right" onclick="invoices.add();"><span class="icon icon-add" style="font-size: 16px;"></span>neu</button>
   </div>
 </div>
 <div id="tbl_invoices"></div>
\ No newline at end of file
diff --git a/dev/mail.bat b/dev/mail.bat
new file mode 100644 (file)
index 0000000..30520ba
--- /dev/null
@@ -0,0 +1,3 @@
+@echo off
+
+"C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" -compose "from='ksaffran@dks.lu',to='compabilite@co-labor.lu',subject='Coloradio: facture pour le mois novembre 2020',body='Bonjour,<br/><br/>'
\ No newline at end of file