Portalscripts
ou.cust.ptpINV.lib.curtail
Beinhaltet alle wichtigen Funktionen.
- Name:
ou.cust.ptpINV.lib.curtail - Kategorie:
ptpINVcust
// #import "ou.sp.invplus.server"
context.enableModules();
const Iterators = require("ou.sp.Iterators");
const Report = require("ou.sp.Report");
/**
*
* @returns {{ reportFileNameWithExt: string; report: string, gadget: string }}
*/
const getSettings = () => {
const baseSettings = context.getCustomProperties("ou.cust.ptpINV.curtail").first();
if (!baseSettings) {
throw new Error(context.getFromSystemTable("Kürzungen Einstellungen wurden nicht gefunden"));
}
const properties = baseSettings.getSubProperties();
const defaults = {
reportFileNameWithExt: "Kuerzungsinfo.pdf",
};
return Iterators.reduce(
properties,
(settings, property) => {
settings[property.name] = property.value;
return settings;
},
defaults
);
};
/**
*
* @param {ptpInvoice} docFile
* @returns {PdfSaveResult}
*/
function createReport(docFile) {
const settings = getSettings();
const template = settings.report;
if (!template) {
throw new Error(context.getFromSystemTable("Kürzungen Report ist leer"));
}
const additionalData = getAdditionalDataForReport(docFile);
const report = Report.fromDocFile(docFile, template, additionalData);
return report.saveAsPdf();
}
/**
*
* @param {PdfSaveResult} report
* @param {ptpInvoice} docFile
*/
function uploadReport(report, docFile) {
const settings = getSettings();
deleteExistingReport(docFile);
report.uploadTo(docFile, "attachments", settings.reportFileNameWithExt);
}
/**
*
* @param {ptpInvoice} docFile
*/
function deleteExistingReport(docFile) {
const settings = getSettings();
const register = docFile.getRegisterByName("attachments", false);
const existingDocument = register.getDocumentByName(settings.reportFileNameWithExt);
if (existingDocument) {
if (!register.deleteDocument(existingDocument)) {
throw new Error(register.getLastError());
}
}
}
/**
*
* @param {ptpInvoice} docFile
* @returns
*/
function getAdditionalDataForReport(docFile) {
const entries = JSON.parse(docFile.ufCurtail || "[]");
var fields = {};
if (docFile.ufOriginalNetAmount1 > 0 || docFile.vatRate1 > 0) {
fields["netAmount1"] = {
netAmount: docFile.ufOriginalNetAmount1,
vatRate: docFile.vatRate1,
};
}
if (docFile.ufOriginalNetAmount2 > 0 || docFile.vatRate2 > 0) {
fields["netAmount2"] = {
netAmount: docFile.ufOriginalNetAmount2,
vatRate: docFile.vatRate2,
};
}
if (docFile.ufOriginalNetAmount3 > 0 || docFile.vatRate3 > 0) {
fields["netAmount3"] = {
netAmount: docFile.ufOriginalNetAmount3,
vatRate: docFile.vatRate3,
};
}
const group = entries.reduce((grouped, entry) => {
grouped[entry.field] = grouped[entry.field] || {
vatRate: fields[entry.field].vatRate,
table: {
columns: ["Kommentar", "Benutzer", "Datum", "Nettobetrag"],
rows: [],
},
sumCurtails: 0,
sum: entry.amount,
formattedNetAmount: {
label: "Ursprünglicher Nettobetrag",
value: context.convertNumericToString(fields[entry.field].netAmount),
},
formattedSumCurtails: {
label: "Summe der Kürzungen",
value: "",
},
formattedSum: {
label: "Nettobetrag nach Kürzung",
value: "",
},
};
grouped[entry.field].sumCurtails += entry.amount;
grouped[entry.field].table.rows.push({
comment: entry.comment,
user: entry.user,
date: util.convertDateToString(new Date(entry.date), "dd.mm.yyyy"),
amount: context.convertNumericToString(entry.amount),
});
grouped[entry.field].sum -= entry.amount;
grouped[entry.field].formattedSum.value =
context.convertNumericToString(grouped[entry.field].sum) + " " + docFile.currency;
grouped[entry.field].formattedSumCurtails.value =
context.convertNumericToString(grouped[entry.field].sumCurtails) + " " + docFile.currency;
return grouped;
}, {});
return {
title: "Kürzungsinfo vom " + util.convertDateToString(new Date(), "dd.mm.yyyy"),
vendor: {
label: docFile.getFieldAutoText("vendorName", "label"),
value: "<b>" +
docFile.getFieldAutoText("vendorName") +
"</b><br/>" +
docFile.getFieldAutoText("vendorStreet") +
"<br/>" +
docFile.getFieldAutoText("vendorZipCode") +
" " +
docFile.getFieldAutoText("vendorCity") +
"<br/>",
},
invoiceNumber: {
label: docFile.getFieldAutoText("invoiceNumber", "label"),
value: docFile.getFieldAutoText("invoiceNumber"),
},
invoiceDate: {
label: docFile.getFieldAutoText("invoiceDate", "label"),
value: docFile.getFieldAutoText("invoiceDate"),
},
erpInvoiceNumber: {
label: docFile.getFieldAutoText("erpInvoiceNumber", "label"),
value: docFile.getFieldAutoText("erpInvoiceNumber"),
},
groupedByVatRate: group,
};
}
/**
*
* @param {ptpInvoice} docFile
* @returns {{[key:string]: { netAmount: number, vatRate: number, curtailsAmount: number, diff: number, curtails: Array<Object> }}}
*/
function getCurtails(docFile) {
const entries = JSON.parse(docFile.ufCurtail || "[]");
var fields = {};
if (docFile.ufOriginalNetAmount1 > 0 || docFile.vatRate1 > 0) {
fields["netAmount1"] = {
originalNetAmount: docFile.ufOriginalNetAmount1 || 0,
newNetAmount: 0,
vatRate: docFile.vatRate1 || 0,
curtailsAmount: 0,
curtails: [],
};
}
if (docFile.ufOriginalNetAmount2 > 0 || docFile.vatRate2 > 0) {
fields["netAmount2"] = {
originalNetAmount: docFile.ufOriginalNetAmount2 || 0,
newNetAmount: 0,
vatRate: docFile.vatRate2 || 0,
curtailsAmount: 0,
curtails: [],
};
}
if (docFile.ufOriginalNetAmount3 > 0 || docFile.vatRate3 > 0) {
fields["netAmount3"] = {
originalNetAmount: docFile.ufOriginalNetAmount3 || 0,
newNetAmount: 0,
vatRate: docFile.vatRate3 || 0,
curtailsAmount: 0,
curtails: [],
};
}
entries.forEach((entry) => {
const field = fields[entry.field];
field.curtails.push(entry);
field.curtailsAmount = new Big(field.curtailsAmount)
.plus(entry.amount || 0)
.round(2)
.toNumber();
field.newNetAmount = new Big(field.originalNetAmount)
.minus(field.curtailsAmount || 0)
.round(2)
.toNumber();
});
return fields;
}
module.exports = {
getSettings: getSettings,
createReport: createReport,
deleteExistingReport: deleteExistingReport,
uploadReport: uploadReport,
getCurtails: getCurtails,
};
Gadget_ou.cust.ptpINV.filetype.field.ufCurtail
Gadget im Kürzungsregister
- Name:
Gadget_ou.cust.ptpINV.filetype.field.ufCurtail - Kategorie:
ptpINVcust
context.enableModules();
//#import "Gadget_API_Controller"
function build() {
const lib = require("ou.cust.ptpINV.lib.curtail");
const settings = lib.getSettings();
/** @type {ptpInvoice} */
const docFile = context.file;
const id = "ptpINV-ufCurtail";
const rows = JSON.parse(docFile.ufCurtail || "[]");
const template = settings.gadget;
if (!template) {
throw new Error(context.getFromSystemTable("Kürzungsregister Template ist leer"));
}
if (rows.length <= 0) {
// Initialisieren zusätzlicher Mappenfelder
if (!docFile.ufOriginalNetAmount1) docFile.ufOriginalNetAmount1 = docFile.netAmount1;
if (!docFile.ufOriginalNetAmount2) docFile.ufOriginalNetAmount2 = docFile.netAmount2;
if (!docFile.ufOriginalNetAmount3) docFile.ufOriginalNetAmount3 = docFile.netAmount3;
docFile.sync();
}
this.execute = function () {
var fields = {};
if (docFile.ufOriginalNetAmount1 > 0 || docFile.vatRate1 > 0) {
fields["netAmount1"] = {
netAmount: docFile.ufOriginalNetAmount1,
vatRate: docFile.vatRate1,
vatRateField: "vatRate1",
};
}
if (docFile.ufOriginalNetAmount2 > 0 || docFile.vatRate2 > 0) {
fields["netAmount2"] = {
netAmount: docFile.ufOriginalNetAmount2,
vatRate: docFile.vatRate2,
vatRateField: "vatRate2",
};
}
if (docFile.ufOriginalNetAmount3 > 0 || docFile.vatRate3 > 0) {
fields["netAmount3"] = {
netAmount: docFile.ufOriginalNetAmount3,
vatRate: docFile.vatRate3,
vatRateField: "vatRate3",
};
}
const fieldNames = Object.keys(fields);
const data = {
id: id,
saveField: "ufCurtail",
entries: rows,
fields: fields,
currency: docFile.currency,
tableOptions: {
allowEdit: true,
allowDelete: true,
allowInsert: true,
showFooter: false,
showOptions: false,
emptyMessage: context.getFromSystemTable("filetype.ptpINV.message.noCurtails"),
rows: rows,
columns: {
comment: {
label: "Kommentar",
type: "textarea",
required: true,
selectOnFocus: false,
},
amount: {
label: "Kürzungsbetrag (Netto)",
type: "currency",
width: "150px",
required: true,
defaultValue: 0,
currency: docFile.currency,
},
field: {
label: "Steuersatz",
type: "select",
width: "100px",
defaultValue: fieldNames.length ? fieldNames[0] : "",
entries: fieldNames.map((fieldName) => {
return {
text: fields[fieldName].vatRate.toString(),
value: fieldName,
};
}),
},
user: {
label: "Benutzer",
width: "150px",
defaultValue: context.currentUser,
allowInsert: false,
allowEdit: false,
},
date: {
label: "Datum",
type: "date",
width: "150px",
defaultValue: new Date(),
allowInsert: false,
allowEdit: false,
},
},
},
};
const payload = "<div data-id=" + id + ">" + template + "</div>";
const htmlGadget = new otris.gadget.gui.HTML(payload);
htmlGadget.setContextData(data);
htmlGadget.onGadgetLoad(function () {
var context = documentsContext.getGadgetContext();
if (!context) {
return;
}
var data = context.getContextData();
if (!data) {
return;
}
var fileContext = documentsContext.getFileContext();
data.tableOptions.allowEdit = fileContext.isFileEditMode();
var config = {
el: "div[data-id='" + data.id + "']",
data: () => {
return data;
},
computed: {
editMode: function () {
return fileContext.isFileEditMode();
},
entriesGroupedByVatRate: function () {
return this.entries.reduce((grouped, entry) => {
const field = this.fields[entry.field];
grouped[field.vatRate] = grouped[field.vatRate] || {
netAmount: field.netAmount,
curtails: [],
sumCurtails: 0,
sum: field.netAmount,
};
var amount = entry.amount;
grouped[field.vatRate].sumCurtails += amount;
grouped[field.vatRate].curtails.push(amount);
grouped[field.vatRate].sum -= amount;
return grouped;
}, {});
},
anyPositionMatchingOriginalAmount: function () {
return (
this.entries.length > 0 &&
window.multiTableInstances.invoiceItems.options.rows.some((row) => {
const matches = Object.keys(this.fields).filter(
(fieldName) => this.fields[fieldName].vatRate == row.itemVatRate
);
return matches.length
? this.fields[matches[0]].netAmount === row.itemTotalNetAmount
: false;
})
);
},
},
filters: {
formatNumber: function (value) {
return value ? documents.sdk.utils.formatNumber(value, ",", ".", 2) : "0";
},
},
methods: {
updateRows: function (rows) {
this.entries = rows;
var json = JSON.stringify(rows);
fileContext.setFileFieldValue(this.saveField, json, {
serverMode: true,
});
this.resetNetAmounts(rows);
const curtailsAmountByField = rows.reduce(function (grouped, row) {
grouped[row.field] = grouped[row.field] || 0;
grouped[row.field] += row.amount;
return grouped;
}, {});
for (var fieldName in curtailsAmountByField) {
const curtailsAmount = curtailsAmountByField[fieldName];
const field = this.fields[fieldName];
const netAmountAfterCurtails = new Big(field.netAmount)
.minus(curtailsAmount)
.round(2)
.toNumber();
invplus.utils.setFieldNumberValue(documentsContext, fieldName, netAmountAfterCurtails);
}
this.updateFieldAmounts();
},
resetNetAmounts: function (existingRows) {
Object.keys(this.fields).forEach((fieldName) => {
// If there's a row for current field, continue.
if (existingRows.some((row) => row.field === fieldName && row.amount > 0)) {
return;
}
const field = this.fields[fieldName];
const originalNetAmount = field.netAmount;
invplus.utils.setFieldNumberValue(documentsContext, fieldName, originalNetAmount);
});
},
getCountPositionsByVatRate: function (vatRate) {
var invItem = fileContext.getFileFieldValue("invoiceItems");
var items = JSON.parse(invItem || "[]");
return items.reduce(function (sum, row) {
if (vatRate == row.itemVatRate) {
sum += 1;
}
return sum;
}, 0);
},
updateFieldAmounts: function () {
// weitere Felder updaten...
var calculator = new invplus.calculationAmount(documentsContext);
var sum = calculator.calculate();
// Weitere Berechnungen
//var ufAmount = invplus.utils.getFieldNumberValue(documentsContext, "ufAmountAddTax1") || 0;
// var newAmount = sum.totalAmount + ufAmount;
invplus.utils.setTotalAmount(documentsContext, sum.totalAmount);
invplus.utils.setFieldNumberValue(documentsContext, "totalNetAmount", sum.totalNet);
var rate = invplus.utils.getFieldNumberValue(
documentsContext,
invplus.mapping.cashDiscountFields.cashDiscount1.rate
);
var days = invplus.utils.getFieldNumberValue(
documentsContext,
invplus.mapping.cashDiscountFields.cashDiscount1.days
);
if (isNaN(rate) || isNaN(days)) {
return;
}
var netDays = invplus.utils.getFieldNumberValue(
documentsContext,
invplus.mapping.cashDiscountFields.net.days
);
if (isNaN(netDays)) {
return;
}
var calculatorCashDiscount = new invplus.calculationCashDiscount(documentsContext);
calculatorCashDiscount.calculate();
},
},
};
window.ptpInvoiceCurtailGadget = window.ptpInvoiceCurtailGadget || {};
if (window.ptpInvoiceCurtailGadget[data.id] && window.ptpInvoiceCurtailGadget[data.id].$destroy) {
window.ptpInvoiceCurtailGadget[data.id].$destroy();
}
window.ptpInvoiceCurtailGadget[data.id] = new Vue(config);
});
return htmlGadget.transfer();
};
}
ou.cust.ptpINV.filetype.action.sendCurtail
Wird benötigt für die benutzerdefinierte Aktion sendCurtail
- Name:
ou.cust.ptpINV.filetype.action.sendCurtail - Kategorie:
ptpINVcust
context.enableModules();
try {
if (!mailTemplate) {
throw new Error("Keine E-Mail Vorlage ausgewählt!");
}
const lib = require("ou.cust.ptpINV.lib.curtail");
/** @type {ptpInvoice} */
const docFile = context.file;
const report = lib.createReport(docFile);
lib.uploadReport(report, docFile);
docFile.mailIndicator = "1";
docFile.mailTemplate = mailTemplate;
docFile.sync();
} catch (error) {
context.errorMessage = error.message ? error.message : error;
return -1;
}
Skript-Parameter - mailTemplate
- Name:
mailTemplate - Bezeichnung:
pf:filetype.global.mailTemplate - Typ:
Aufzählung - Aufzählungswerte:
runscript:ou.cust.global.loadMailTemplate
