From: kilian Date: Tue, 3 Nov 2020 14:40:59 +0000 (+0100) Subject: invoice report email X-Git-Url: http://cloud.dks.lu/git/?a=commitdiff_plain;h=4f1b3c8c19ac941433aa5c5ade1ece8aa9fd199d;p=invoicejournal.git invoice report email --- diff --git a/desktopapp/js/dataform.js b/desktopapp/js/dataform.js index f90d9c1..22a0e73 100644 --- a/desktopapp/js/dataform.js +++ b/desktopapp/js/dataform.js @@ -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 index 0000000..dce04d6 --- /dev/null +++ b/desktopapp/js/global/email.js @@ -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 diff --git a/desktopapp/js/global/renderer.js b/desktopapp/js/global/renderer.js index f169a2b..0f3a620 100644 --- a/desktopapp/js/global/renderer.js +++ b/desktopapp/js/global/renderer.js @@ -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=""; diff --git a/desktopapp/js/global/report.js b/desktopapp/js/global/report.js index 987a9a6..5ee806b 100644 --- a/desktopapp/js/global/report.js +++ b/desktopapp/js/global/report.js @@ -1,4 +1,4 @@ -const { spawn } = require('child_process'); + //const fs = require('fs'); let report = { id_report: null, diff --git a/desktopapp/js/global/sqlite.js b/desktopapp/js/global/sqlite.js index 2b08b63..ab5f130 100644 --- a/desktopapp/js/global/sqlite.js +++ b/desktopapp/js/global/sqlite.js @@ -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 diff --git a/desktopapp/js/modules/booking.js b/desktopapp/js/modules/booking.js index e1299a6..fc35876 100644 --- a/desktopapp/js/modules/booking.js +++ b/desktopapp/js/modules/booking.js @@ -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', diff --git a/desktopapp/js/modules/invoice.js b/desktopapp/js/modules/invoice.js index c1cd0f1..41d1861 100644 --- a/desktopapp/js/modules/invoice.js +++ b/desktopapp/js/modules/invoice.js @@ -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. + } } diff --git a/desktopapp/js/modules/invoices.js b/desktopapp/js/modules/invoices.js index 33f3cb4..d3ea30e 100644 --- a/desktopapp/js/modules/invoices.js +++ b/desktopapp/js/modules/invoices.js @@ -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 "" + invtypes[value].text + "" } 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 "" + statustypes[value].text + "" } }, - {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 "" + invtypes[value].text + "" } return ""; } }, + {title: "Status", field: "status",headerFilter:"select",width: 125, headerFilterParams:{values:headerstatustypes},formatter:function(cell, formatterParams){ var value = cell.getValue(); return "" + statustypes[value].text + "" } }, + {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); }); }); diff --git a/desktopapp/panels/invoice.html b/desktopapp/panels/invoice.html index f7a5f47..eb5a8c8 100644 --- a/desktopapp/panels/invoice.html +++ b/desktopapp/panels/invoice.html @@ -18,6 +18,7 @@
+
- +
+
diff --git a/desktopapp/panels/invoices.html b/desktopapp/panels/invoices.html index e6306de..61a3660 100644 --- a/desktopapp/panels/invoices.html +++ b/desktopapp/panels/invoices.html @@ -1,14 +1,11 @@
-
- Rechnungen -
-
- 2020 -
+
Rechnungen
+ + + +
\ No newline at end of file diff --git a/dev/mail.bat b/dev/mail.bat new file mode 100644 index 0000000..30520ba --- /dev/null +++ b/dev/mail.bat @@ -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,

' \ No newline at end of file