App-Link #1021 alternative Geräte-, Software-Verwaltung mit Boardmitteln von LibreOffice -- {-0}

per
- LibreOffice Writer
- Extras
- Literaturdatenbank

und den erfassten Daten
- in einer PostgreSQL-Datenbank

Per Serien-PDF oder Etiketten-Funktion können die Daten weiterverwendet werden.



z.B.

/public/LibreOffice_Literatur_Geraete_Kauf_Miete_Leasing_Lizenz.png


/public/Serien-PDFs----per-SQL-Abfrage.png

CREATE TABLE frepjs2000.Literatur


(
Kurzbezeichnung varchar(255),
Typ varchar(255),
Jahr varchar(255),
Autoren varchar(255),
--
verlag varchar(255),
--
Titel varchar(255),
Herausgeber varchar(255),
Adresse varchar(255),
ISBN varchar(255),
Kapitel varchar(255),
Seiten varchar(255),
Ausgabe varchar(255),
Buchtitel varchar(255),
Band varchar(255),
Ausgabeart varchar(255),
Organisation varchar(255),
Institution varchar(255),
Universitaet varchar(255),
Berichtsart varchar(255),
Monat varchar(255),
Journal varchar(255),
Nummer varchar(255),
Serien varchar(255),
Anmerkung varchar(255),
Notiz varchar(255),
URL varchar(255),
Benutzerdefiniertes_Feld_1 varchar(255),
Benutzerdefiniertes_Feld_2 varchar(255),
Benutzerdefiniertes_Feld_3 varchar(255),
Benutzerdefiniertes_Feld_4 varchar(255),
Benutzerdefiniertes_Feld_5 varchar(255),
Lokale_Kopie varchar(255),
--
CONSTRAINT Literatur_pkey PRIMARY KEY (Kurzbezeichnung)
)
;

GRANT INSERT, DELETE, SELECT, UPDATE ON TABLE frepjs2000.Literatur
TO frepjs2000_role;
- 1 -    (TxtDoc-2026-06-03.html)


App-Link #994 Ad hoc Reports aufbauend auf bestehenden Views in App-Schemen als Text oder CSV -- {0r}

Voraussetzungen für einen AReport:
- Schemen sind zulässig
- Angemeldeter Benutzer ist berechtigt
- View endet mit dem Namen "_qry"


Vorteile:
- Wenn bereits passende Views vorhanden sind,
kann man diese ohne Programmänderung verfügbar machen. ( Berechtigung prüfen )

- Man kann nach einem beliebigen Text in den Zeilen filtern. (z.B. Erfolg)

- Die Ausgabe ist als Text(html) oder csv möglich.

- Neben "download" steht auch die Funktion "als eMail senden" zur Verfügung.
(auch bei verwalteten Gastsitzungen möglich -- https://support.google.com/chrome/a/answer/3017014)



Nachteil:
- z.B. keine Summen -- also eher CSV nutzen und per Tabellenkalkulation nutzen.

--> https://jobst-software.net/frepjs2000/AReport?nur_AREPORT=Bestandsliste&report_search_text=%25&format=html


/public/js_es6_adhoc_report_auswahl.png


- 2 -    (TxtDoc-2026-06-03.html)


App-Link #1023 Zeiten erfassen und dann die Leistungsabrechnung erstellen -- {1}

Voraussetzungen sind:

- Auftrag mit PosNr "aL2..." (z.B. aL26015-do-Supp) ist angelegt
und
- Leistungszeiten werden mit Angabe der Auftrags-PosNr eingetragen.



Die Rechnungs-Menge entspricht den Stunden der Zeiteingabe
und -Preis, -Rabatt dann lt. Auftragsposition.


z.B.

/public/Zeiterfassung_Leistungsabrechnung.png


--> /ahr_cal/Hr_Calendar_Pflege?submitaction=%2F%3D%2F&datatable_primarykey=12


- 3 -    (TxtDoc-2026-06-03.html)


App-Link #1018 Zeit -- per Desktop Warten und Auswerten -- {1}

Office-Funktionen
- Pivot (Kreuztabellen)
- Charts (Diagramme)
- Seriendokumente (Etiketten, Mail, ...)
- Import / Export
- Abfragen / Reports

Als Datenquelle stehen die Tabellen, Abfragen (Views) und Funktionen der SQL zur Verfügung.
Die Berechtigung ergibt sich aus der Anmeldung und der damit verbundenen Rolle.

z.B.

/public/js_es6_minierp_beta.png


--> /ahr_cal/?submitaction=%2F%3D%2F&datatable_primarykey=12

ev. weitere Funktionen


- Anfrage
- Angebot
- Lieferschein
- Rechnung
- Mahnung


Eingabe
-------
- ein Mastersatz für alle o.g. Funktionen
- Detailformular mit Positionen (Artikel, Menge, Preis, Rabatt) einmal für alle Funktionen
( der historisch genaue Inhalt lässt sich über Archiv - .pdf's ermitteln )

Bericht: ev. als Text- oder Tabellendokument -- ev. direkt durchsuch-, bearbeit- und versendbar
Status: Wenn Angebots-, Lieferschein-Datum eingegeben wurde, dann ist Das der Status (also z.B. geliefert)
Dateien: Die Datensätze Anfrage, Artikel, Adressen haben jeweils ein autom. angelegtes Verzeichnis
Archiv: Dokumente werden als .pdf unter o.g. Dateien gepeichert und z.B. per Mail versandt
- 4 -    (TxtDoc-2026-06-03.html)


App-Link #958 Kosten -- Online Spesen -- {1}

Für alle Kosten im Aussendienst zu verwenden.

Bei Problemen: +43 664 3376423


Dateien bevorzugt als kompakte .html oder .txt angeben bzw. anlegen.

--> https://jobst-software.net/aea_cos/

Hinweis: Bitte vorerst nur den Steuercode 0 (0%) verwenden, da die Buchhaltung diese Arbeit übernimmt.
- 5 -    (TxtDoc-2026-06-03.html)


App-Detail #1025 HTML-Anwendungen ohne Web-Server -- {2}

Es gibt Seiten, die haben alle Daten dabei.

Oder ein Server bzw. Webservice eines Dritten,
stellt die Daten zur Verfügung.

Dann könnte eine HTML-Datei reichen,
um per
- TypeScript/JavaScript HTML CSS
die Daten zu nutzen.

/public/js_es6_app_stempelkarte.png


--> http://kantn.jobst-software.net:8080/aussendienst4/stempelkarte4.html

HTML kann einfach sein (<h3>Überschrift</h3> <p>Text</p> <h3>...</h3> <p>...)


und samt
- CSS
- JavaScript
- ohne Zusatzsoftware
anzeig- und druckbar per Browser.
( z.B. kann man mit einer HTML-Datei eine kleine App umsetzen )


HTML funktioniert mit
- HTTP-Servern
- Dateiservern
- SQL (die den Datentyp XML kennt)
- ...
und kann vom jeweiligen Berechtigungssystem profitieren.

HTML kann man auch so gestalten, dass es maschinenlesbar (XML) ist.
- 6 -    (TxtDoc-2026-06-03.html)


App-Link #968 ATodo -- für Termine, für die es bei Auftr. & Co keine Zeilen gibt -- {2}

Also Todo für den Rest,
und man hat es im
- Kalender für Alles
- Protokoll.

--> /a_todo4/


- 7 -    (TxtDoc-2026-06-03.html)


App-Link #987 ATodo -- individuelle Felder ohne Datenbank/Programm-Änderung per PostgreSQL-Json-Feld und HTML-Dialog -- {d}

für
- Ad-hoc-Bereitschaft
- Ad-hoc-Inventur
- Ad-hoc-Test
- ...

Meist mit "Details" tituliert.
Der modale Details-Dialog öffnet sich nach klick ins Datenfeld.


z.B.

ADialog-Umsetzung

/public/js_es6_atodo_bereitschaft.png


--> /a_todo4/?submitaction=%2F%3D%2F&datatable_primarykey=12


- 8 -    (TxtDoc-2026-06-03.html)


App-Link #960 Zeit -- Online Hr Calendar -- {l100-cal}

Bitte Urlaube möglichst 2 Wochen vorher eintragen 
(bei mehr als 2 Tagen 1 Monat vorher)

--> /ahr_cal/


- 9 -    (TxtDoc-2026-06-03.html)


App-Link #961 Umfragen -- Online Q&A -- {l100-qa}

Nicht abgegebene Umfragen,
werden als Stimmenthaltung gewertet.

Bei entsprechender Beteiligung,
gilt dann die Mehrheit der Abgaben.

--> /aqa_quest/


- 10 -    (TxtDoc-2026-06-03.html)


App-Link #957 Zeit -- Eingabe-Urlaub -- {l110-cal}

Die Zeitsumme sollte die normale Arbeitszeit des jeweiligen Tages ergeben.

z.B. bei Vollzeit
- Mo bis Do 8 Stunden
- und Fr 4 Stunden

- 11 -    (TxtDoc-2026-06-03.html)


App-Link #1039 Office und dann ...

Die Nutzung eines Datenbankservers ist die logische strukturelle Weiterentwicklung
eines begonnenen Datenbankprojektes.

Z.B. Übertragung der Datentabellen auf einen SQL-Server.

Im Office bleibt dann die Funktionalität
und im SQL-System 100% der Daten.

Damit sind in den MDB/ACCDB/ODT-Dateien keine Daten mehr
und man hat folgende Optionen
- ReadOnly-Modus
- Arbeit mit einer Kopie
- oder Software-Vereilung wie bei anderen Programmen

Die Installation von ODBC/SDBC-Treibern auf allen Clients ist zusätzlich erforderlich.
( die Office Installation ist weiterhin erforderlich )







Oder weg von klassischen Datenbank-Abfragen und Berichten

z.B. mit Power BI und Power Query
und/oder automatisieren

--> https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-query-overview#the-query-ribbon


--> /ainfojs2000/InfoPrint_Default?only_REPORT_KNZ=TxtDoc&search_text=automatisieren


- 12 -    (TxtDoc-2026-06-03.html)


App-Link #1038 KORE / Kalkulationsbasis per SQL-View und Office-Grundfunktionen

ermitteln und darstellen.



z.B.

/public/kore_ergebnis.png


--> /aea_cos/Ea_Cost_Pflege?submitaction=%2F%3D%2F&datatable_primarykey=8

bericht... sort bericht_grp_text konto_grp1, ...


------------ ---- ---------------- ---------------
Kalkulation 11 Btto Umsatz 040
Kalkulation 13 Prop. Vertriebsk. 190
Kalkulation 15 * UMSATZ 040 190

Kalkulation 17 Materialeinzelk. 240
Kalkulation 18 Prop. Mat. Gemeink. 270
Kalkulation 20 = Material 240 270
Kalkulation 30 * DB 1 040 190 240 270

Kalkulation 32 Lohneinzelk. 360
Kalkulation 34 Lohngemeink. 370
Kalkulation 36 = Lohnk. 360 370
Kalkulation 42 = Prop. Einzelk. 240 360
Kalkulation 40 = Fert. Kosten 360 370
Kalkulation 45 = Prop. Gemeink. 270 370
Kalkulation 47 = Herstellk. 240 270 360 370
Kalkulation 50 * DB 2 040 190 240 270 360 370

Kalkulation 55 Fixk. 750

Kalkulation 60 * ERGEBNIS 040 190 240 270 360 370 750

create view aea_cos.konten_grp_berichte_qry as


SELECT
cos_id, vorgang_knz, adressnr, bericht_name, bericht_sort, bericht_grp_text,
--
konto_grp_texts,
round( kore_saldo, 0) as kore_saldo,
--
min_konto_grp, min_konto_grp_text,
max_konto_grp, max_konto_grp_text,
--
case
when bericht_grp_text = '* UMSATZ' and (kore_saldo - prop_vertriebsk) <> 0 then round( prop_vertriebsk / (kore_saldo - prop_vertriebsk) * 100, 2)
when bericht_grp_text = '= Material' and (kore_saldo - prop_mat_gemeink) <> 0 then round( prop_mat_gemeink / (kore_saldo - prop_mat_gemeink) * 100, 2)
when bericht_grp_text = '= Lohnk.' and (kore_saldo - lohngemeink) <> 0 then round( lohngemeink / (kore_saldo - lohngemeink) * 100, 2)
end as prop_k_p,
--
prop_vertriebsk, prop_mat_gemeink, lohngemeink
--
FROM
aea_cos.konten_grp_berichte_raw
order by
1, 2, 3, 4, 5, 6, 7
;
- 13 -    (TxtDoc-2026-06-03.html)


App-Link #1035 Mit SPICE oder VNC auf virtuelle Maschinen zuzugreifen

Damit 
- Zwischenablage
- höhere/dynamische Auflösung
funktioniert,
ist auf dem Clientsystem ein passender Gast-Treiber erforderlich.






Konfigration z.B. per virt-manager

/public/virt-anzeige-spice-vnc.png


--> https://de.wikipedia.org/wiki/SPICE_(Protokoll)

Zugriff von Ausserhalb z.B. mit dem remote-viewer



remote-viewer spice://10.110.10.101:5999

oder

remote-viewer vnc://10.110.10.101:5982
- 14 -    (TxtDoc-2026-06-03.html)


App-Detail #1034 HTML-Tabelle ohne Web-Server mit Webservice als Datenquelle

z.B. für eine Datenquellen, 
für die man eine URL hat
und man als Tabelle anzeigen möchte.
( Cross-Origin ist hier zu beachten )




z.B. "Tabelle"

--> http://kantn.jobst-software.net:8080/aussendienst4/preferences.html


/public/einstellungen_tabelle_html.png

man kann mit wenig HTML / TypeScript/JavaScript auskommen,


wenn Cross-Origin und Authentifizierung bereits gelöst sind.



<html>
<head>
<title>Einstellungen - Tabelle</title>

<style>
td {
border: solid 1px darkGray; min-width: 2rem; padding: 0.2rem;
}
</style>

<script type="module" >
"use strict";

window.addEventListener( "load", function() {
const select_url = getEinstellungen_Tabelle_Select_url();
fetch( select_url, { credentials: 'include' })
.then( (response) => response.text() )
.then( (text) => {
const table_ele = document.getElementById("d-print-table");
const json_doc = JSON.parse( text);
fill_table( document, table_ele, json_doc);
})
.catch( function( exc) {
alert( "fetch failed (" + exc + ")");
});
});


function fill_table( html_doc, table_ele, json_doc) {
const tag_names = [ "th", "td" ];
for( let tag_name_i=0; tag_name_i < tag_names.length; tag_name_i++ ) {
let tag_name = tag_names[ tag_name_i];
let trs = json_doc;
for( let tr_i=0; tr_i < ( tag_name == "th" && trs.length >= 1 ? 1 : trs.length ); tr_i++ ) {
let tr = trs[ tr_i];

let tr_ele = html_doc.createElement( "tr");
table_ele.appendChild( tr_ele);

let tds = tr;
Object.entries( tds).forEach( ( [fdName, fdValue]) => {
let td_ele = html_doc.createElement( tag_name);
tr_ele.appendChild( td_ele);

td_ele.innerText = ( tag_name == "th" ? fdName : fdValue );
});
}
}
}


function getEinstellungen_Tabelle_Select_url() {
const select = getEinstellungen_Tabelle_Select();
const select_sql = select[ "sql"];
const json_parameters = JSON.stringify( select[ "param"]);

const select_url = "/MywebDb3Servlet" + "?sql=" + encodeURIComponent( select_sql) + "&parameters=" + encodeURIComponent( json_parameters);
return select_url;
}


function getEinstellungen_Tabelle_Select() {
const select_sql = "select _id, PREFERENCE_KEY, PREFERENCE_VALUE from Preferences order by _id";
return { sql: select_sql, param: [] };
}
</script>
</head>

<body>



<h1>Einstellungen - Tabelle</h1>


<table id="d-print-table" >


</table>


</body>
</html>
- 15 -    (TxtDoc-2026-06-03.html)


App-Link #1033 Script/Runtime/VM-Sprachen mit Fehlerbehandlung und zwingend automatischer Speicherverwaltung

z.B.


try {
dokument.speichern();

datenbank.commit();

status_anzeigen("Daten gespeichert");

}
catch() {
datenbank.rollback();

meldung("speichern fehlgeschlagen");
}


Also, versuche zu speichern:
- wenn's klappt, alles festschreiben
- wenn nicht, alles rückgängig machen und den User informieren





Buffer-Overflows sollten in Script/Runtime/VM-Sprachen auch nicht vorkommen.
( z.B. TypeScript/JavaScript, Java, C#, ... )

Diese benutzen jedoch Bibliotheken, die's ev. mit dem Speicher nicht so genau nehmen.
Oder man benutzt unsafe-Blöcke oder unglückliche Compilerschalter.
( Undefiniertes Verhaltung (UB) glänzt am besten durch Abwesenheit )

C++ ohne UB geht auch -- z.B. mit C++/CLI


jedoch nicht ISO C++ konform.
( Alles mit ^ ist hier auch verwalteter Speicher )


public ref class IntDotnetClass
{
public: int IntValue;

public: IntDotnetClass()
{
this->IntValue = 0;
}


public: virtual ~IntDotnetClass()
{
System::Console::WriteLine("~destruct IntDotnetClass" + IntValue.ToString());
}


public: int operator=( const int IntValue)
{
this->IntValue = IntValue;

return this->IntValue;
}

public: virtual System::String^ ToString() override
{
return IntValue.ToString();
}

};

Weiters stehen zur Vermeidung von Speicherproblemen


- Rust
- Fil-C
- Valgrind
- und ev. bald TrapC
zur Verfügung.
- 16 -    (TxtDoc-2026-06-03.html)


Software #1032 was bei der Beschaffung ev. zu beachten ist

- von was/wem wird man direkt und indirekt abhängig

- Funktionen
- Mandantenfähig

- Betrieb beim ... auf ... unter ...
- Testsystem ohne zusaetzliche Lizenzkosten

- Datenmigration ...
- Individuelle Anpassungen durch den Auftragnehmer mit Leuten in ... und Umsetzung in ...
- Individuelle Anpassungen durch den Auftraggeber auch moeglich -- die Software bleibt im Support und nach Updates intakt

- Der Auftraggeber hat alle Sourcen und Werkzeuge, um Anpassungen durchfuehren zu können und produktiv in Einsatz zu bringen

- Neue Felder fuer wesentliche Tabellen/Formulare ohne Programmieraufwand
- Neue Abfragen/Berichte mit geringem Programmieraufwand
- stabile Datenbank mit gängigen Schnittstellen
- Nach Strukturerweiterung an der Datenbank bleibt die Software im Support

- Geplante Mindestnutzung bis ...
- Die Software sollte in ... gesetzeskonform betreibbar sein
- Der Auftraggeber kann bei Kündigung des Supports unbefristet und ohne Kosten die Software weiterbetreiben

- Auf aktuellen und gängigen Desktopsystemen ohne Setup am Arbeitsplatz nutzbar

- ev. Opensource -- im Browser nutzbar -- mit Handy nutzbar -- Dateien zu jedem Datensatz speicherbar

- Für Kommunikation, Test und Setup ist ... zuständig

...

- 17 -    (TxtDoc-2026-06-03.html)


App-Link #1031 es wird Zeit, Webservices per ODBC direkt zu nutzen

Z.B. mit Office am Desktop 
und man nutzt Webservices als Datenquelle in Abfragen und Berichten.

Sync oder XML-Transfer sind vielfach nützlich,
aber direktzugriff per Abfrage/View/Pivot/Chart können aktuelle Daten liefern.

Es gibt Anbieter für ODBC-Treiber und auch Reporttools,
die direkt Webservices nutzen können.




s.a.

--> https://www.google.com/search?q=odbc+http+rest


/public/office_direktzugriff_auf_webservice_per_ODBC.png


- 18 -    (TxtDoc-2026-06-03.html)


App-Link #1030 XML-Dokumente vs. Datenbankreplikation

Wenn es 
- um einen One-Way Datentransfer
geht,
wird - bei Verfügbarkeit - heute wahrscheinlich die Datenbankreplikation genommen.


Ein Dokument erzeugen
- auf einen anderen Server transportieren
und dort wieder einarbeiten ?
( JA, wenn kein Aufwand )





s.a.:
- https://www.postgresql.org/docs/current/logical-replication-subscription.html





Oder klassisch mit XML-Dokument:

/public/simple_order_hardcopy.png


--> https://jobst-software.com/demo/simple_order/so_stammdaten.xml

z.B.




CREATE PUBLICATION orb1_publi3


FOR TABLE eina.einausgaben, eina.sachkonten, eina.bberichtepos, eina.wreports
WITH (publish = 'insert, update, delete', publish_via_partition_root = false);




CREATE SUBSCRIPTION orb1_pi_subscri3

CONNECTION 'host=192.168.18.8 port=5432 user=postgres password=... dbname=orb1 connect_timeout=10 sslmode=prefer'
PUBLICATION orb1_publi3
WITH (connect = true, enabled = true, create_slot = true, slot_name = orb1_pi_subscri3, synchronous_commit = 'off');
- 19 -    (TxtDoc-2026-06-03.html)


App-Link #1029 XML-Validierung vs. Webservice

Wenn die XML-Validierung "valid" ergibt
und der Server ein Dokument trotzdem nicht annimmt.

Wie kann das denn sein ?
z.B.
- die Artikelnummer, Kundennummer, ... kennt der Server nicht (mehr)


Für was auf der Client-Seite validieren
und nicht gleich den Server fragen,
ob er ein Dokument annehmen würde ?

Daher ist "well-formed" heute meist "gut genug".

/public/gjs_htmlxml.png


- 20 -    (TxtDoc-2026-06-03.html)


App-Link #1028 KVM und QEMU -- z.B. 20 VMs mit einem 64GB Image

Vorteile:
---------

- nur ein grosses Basis-Image (z.B. 64GB)

- nur das Overlay ub2604a-d1.qcow2 braucht Updates

- wenn das Update Nachteile bringt, das Backup des Basis-Images zurückholen,
die z.B. 20 Overlays neu erstellen und virsh reboot 20x




Nachteile:
----------

- Backup und Rebase nach jedem Update erforderlich
und dann die z.B. 20 Overlays neu erstellen

- alle Nutzer müssen mit den Funktionen des Basis-Images auskommen
und alle Nutzer sind im Basis-Image anzulegen

- alle Nutzer verlieren nach einem Update des Basis-Images alle Daten und Einstellungen
(also Daten sind ausschliesslich auf einem Server zu speichern)

- Änderungswünsche für Einstellungen sind erst nach Update des Basis-Image erfüllbar

- nach einem Update schaut mein Rechner exakt gleich aus, wie bei 19 anderen Leuten

https://jobst-software.net/public/virt-manager.png


--> https://wiki.ubuntuusers.de/virt-manager/

Backup


( das Base-Image wird nie benutzt,
also kann man es - ausser beim rebasen - immer starten )


BAKFILENAME=backup_ub2604a_`date +%Y%m%d-%H%M%S`.tgz

tar cvzf .../backup/$BAKFILENAME ub2604a.qcow2

Update


VM bzw. Overlay ub2604a-d1.qcow2 starten und updaten

Rebase


dno=1

qemu-img rebase -F qcow2 -b ub2604a.qcow2 ub2604a-d$dno.qcow2
qemu-img commit ub2604a-d$dno.qcow2
rm ub2604a-d$dno.qcow2

Overlays neu erstellen


virsh destroy 20x


for dno in `seq 1 20`
do
qemu-img create -f qcow2 -F qcow2 -b ub2604a.qcow2 ub2604a-d$dno.qcow2
done

virsh start 20x
- 21 -    (TxtDoc-2026-06-03.html)


App-Link #1027 PostgreSQL -- Zugriff auf Daten auf Zeilenebene zu steuern

per
- User
- Rollen-Hierarchie
- Grundberechtigungen lesen, einfügen, ändern und löschen
- und POLICIES

/public/sql_berechtigungen.png


--> https://www.postgresql.org/docs/current/ddl-rowsecurity.html

z.B.:




INTRANET-User (z.B. für interne Verwaltung mit Nutzung von Browser und Anwendungen mit direktem SQL-Connect(Office))
-------------


GRANT SELECT, INSERT, DELETE, UPDATE ON TABLE a_todo4.ATodo_Pos TO a_todorole;

CREATE POLICY Todo_Pos_a_todorole_select ON a_todo4.ATodo_Pos
AS PERMISSIVE
FOR ALL TO a_todorole USING (true);

z.B.




ONLINE-User (z.B. für Aussendienst)
-----------


GRANT SELECT, INSERT, DELETE, UPDATE ON TABLE a_todo4.ATodo_Pos TO a_todoonlineuser_role;

CREATE POLICY Todo_Pos_a_todoonlineuser_role ON a_todo4.ATodo_Pos
AS PERMISSIVE
FOR ALL TO a_todoonlineuser_role
USING ( TODO_ID in ( select TODO_ID from a_todo4.ATodo where current_setting('app.client_user', true) = adressnr ) )
WITH CHECK ( TODO_ID in ( select TODO_ID from a_todo4.ATodo where current_setting('app.client_user', true) = adressnr ) );

z.B.:




DEMO-User
---------


GRANT SELECT ON TABLE a_todo4.ATodo_Pos TO ahp_w3_extuser_role;

CREATE POLICY Todo_Pos_DEMO_ahp_w3_extuser_role ON a_todo4.ATodo_Pos
AS PERMISSIVE FOR SELECT TO ahp_w3_extuser_role
USING ( TODO_ID in ( select TODO_ID from a_todo4.ATodo where 'demo-online' = adressnr ) );
- 22 -    (TxtDoc-2026-06-03.html)


App-Link #1026 Kantn -- Kantinen-Bestellung erfassen und abrechnen

Benutzer:
- Benutzer
- Kantine Benutzername "kantine"
- Administrator

Bestellmöglichkeit:
- Anzeige für die aktuelle Woche
- für die Folgewoche (lt. Einstellung)
- nur ein Menü ausgewählbar oder abbestellen

Administration:
- Benutzer pflegen
- bestellte Essen eines Mitarbeiters (auch rückwirkend) abbestellen
- Einstellungen (Preise, Geschlossene Tage, Link zur Menübeschreibung, ...)
- Listen -- z.B. "Alle Bestellzeilen sortiert nach ..."
- Versendung einer eMail an den Lieferanten durch Cronjob
- Datei zur Verrechnung nach Vorgaben der Lohnbuchhaltung






Demo ( User: kunde mit Kennwort 'xxxx' )

--> http://kantn.jobst-software.net:5000


/public/kantn_administration.png


- 23 -    (TxtDoc-2026-06-03.html)


App-Link #1024 Lager -- z.B. Abgänge und Zugänge direkt aus den aktuellen Bewegungsdaten bilden

Zusammen mit den aktuellen Stammdaten,
ergibt sich der aktuelle Bedarf.

/public/js_es6_minierp_report_beta.png


--> https://jobst-software.net/al_storage/?submitaction=%2F%3D%2F&datatable_primarykey=6

Auch hier, trägt die Last die SQL


Webanwendung und/oder Office ist für Eingabe und Anzeige.


Die SQL kümmert sich um
- Tabellen -- Abfragen
- Benutzer -- Rollen -- Berechtigungen
- Integrität
- Grundlagen für Reports / PDFs


Sparsamer Umgang mit Scripts/Makros fördert
- Systemunabhängigkeit
und
- Sicherheit
- 24 -    (TxtDoc-2026-06-03.html)


App-Detail #1022 KORE / Logistik -- z.B. eine Palette und die Details

Details lassen sich per Kopfrechnung weniger gut überschlagen.

Dafür hat man ev. eine SQL samt Tools.




z.B.

/public/Artikel_AParts.png


--> https://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-RECURSIVE

Eine SQL kann auch helfen mit rekursiven Strukturen umzugehen.



z.B.:


WITH RECURSIVE included_parts( t_nr, apart_artikelnr, artikelnr, par_menge, t1_x_menge) AS (
SELECT 1 as t_nr, apart_artikelnr, artikelnr, 1::numeric as par_menge, menge::numeric as t1_x_menge
FROM frepjs2000.Artikel_AParts WHERE artikelnr like '%Pal%'
UNION ALL
SELECT (t_nr + 1) as t_nr, p.apart_artikelnr, p.artikelnr, (par_menge * 1)::numeric as par_menge, (p.menge * pr.t1_x_menge)::numeric as t1_x_menge
FROM included_parts pr
join frepjs2000.Artikel_AParts p on pr.apart_artikelnr = p.artikelnr
)
SELECT
string_agg( inc_pr.t_nr::varchar, ' ') as t_nrs,
--
inc_pr.artikelnr,
round( SUM( inc_pr.par_menge), 4) as menge,
string_agg( distinct art.mengen_einheit, ' ') as mengen_einheit,
--
inc_pr.apart_artikelnr as t_artikelnr,
round( SUM( inc_pr.t1_x_menge), 4) as t1_x_menge,
string_agg( distinct ap_art.mengen_einheit, ' ') as t_meh,
string_agg( concat( f_n(inc_pr.t1_x_menge), f_meh( ' ', ap_art.mengen_einheit) ), ' + ') as t1_x_menge_dets,
string_agg( concat( inc_pr.apart_artikelnr, ' ', f_n(inc_pr.t1_x_menge), f_meh( ' ', ap_art.mengen_einheit) ), ' + ') as t1_x_menge_dets_ex
FROM included_parts inc_pr
join frepjs2000.artikel art on inc_pr.artikelnr = art.artikelnr
join frepjs2000.artikel ap_art on inc_pr.apart_artikelnr = ap_art.artikelnr
GROUP BY
inc_pr.artikelnr, inc_pr.apart_artikelnr
;
- 25 -    (TxtDoc-2026-06-03.html)


App-Link #1019 Kosten -- per Desktop Warten und Auswerten

Office-Funktionen
- Pivot (Kreuztabellen)
- Charts (Diagramme)
- Seriendokumente (Etiketten, Mail, ...)
- Import / Export
- Abfragen / Reports

Als Datenquelle stehen die Tabellen, Abfragen (Views) und Funktionen der SQL zur Verfügung.
Die Berechtigung ergibt sich aus der Anmeldung und der damit verbundenen Rolle.

z.B.

/public/kosten_auswerten.png


/public/Serien-PDFs----per-SQL-Abfrage.png


- 26 -    (TxtDoc-2026-06-03.html)


App-Link #1017 Umfragen -- per Desktop Warten und Auswerten

Office-Funktionen
- Pivot (Kreuztabellen)
- Charts (Diagramme)
- Seriendokumente (Etiketten, Mail, ...)
- Import / Export
- Abfragen / Reports

Als Datenquelle stehen die Tabellen, Abfragen (Views) und Funktionen der SQL zur Verfügung.
Die Berechtigung ergibt sich aus der Anmeldung und der damit verbundenen Rolle.

z.B.

/public/Umfragen_per_Desktop_Warten_und_Auswerten.png


/public/Serien-PDFs----per-SQL-Abfrage.png


- 27 -    (TxtDoc-2026-06-03.html)


App-Detail #1016 JSON-Inhalte per SQL-Views nutzen

z.B. als Journal: 

create or replace view al_storage.l_storage_lagerjournal_raw_raw_LF as
select all
5 as STORAGE_ID, Posid as STORAGE_POS_ID, Posid as BUCH_NR, 'LF' as INP_KNZ, 'Abg' AS ABG_ZUG_KNZ,
'central'::character varying(50) AS LAGERORT, apos.apos_details->>'Lager'::character varying(50) AS GEGENBUCH_LAGERORT,
a.LieferDatum as BEWEGUNGS_DATUM, ARTIKELNR, ART_BEZEICHNUNG, (MENGE * -1) AS BEWEGUNGS_MENGE,
concat('ANr: ', a.ANr, ', ', 'Liefer-Adr: ', a.LieferAdressNr) as BUCHUNGSTEXT,
aPOS_details, erfasst_am::timestamp without time zone as created_at
FROM frepjs2000.AngebotePos apos join frepjs2000.Anfragen a on apos.ANr = a.ANr
where apos.apos_details->>'Lager' is not null
--
union all
--
select all
5 as STORAGE_ID, Posid as STORAGE_POS_ID, Posid as BUCH_NR, 'LF' as INP_KNZ, 'Zug' AS ABG_ZUG_KNZ,
apos.apos_details->>'Lager'::character varying(50) AS LAGERORT, 'central'::character varying(50) AS GEGENBUCH_LAGERORT,
a.LieferDatum as BEWEGUNGS_DATUM, ARTIKELNR, ART_BEZEICHNUNG, MENGE AS BEWEGUNGS_MENGE,
concat('ANr: ', a.ANr, ', ', 'Liefer-Adr: ', a.LieferAdressNr) as BUCHUNGSTEXT,
aPOS_details, erfasst_am::timestamp without time zone as created_at
FROM frepjs2000.AngebotePos apos join frepjs2000.Anfragen a on apos.ANr = a.ANr
where apos.apos_details->>'Lager' is not null
--
order by 1, 2
;

- 28 -    (TxtDoc-2026-06-03.html)


App-Detail #1015 XML-Inhalte per SQL-Views nutzen

z.B. als Auswahlliste: 

create or replace view ahp_w3_start.INET_ANFRAGE_LIST as
SELECT
substr( cast( (xpath( '/article/h3/a/text()', content_elements))[1] as varchar), 1, 1) as ART_TITLE_OG,
concat( 'zu ', cast( (xpath( '/article/h3/a/text()', content_elements))[1] as varchar)) as ART_TITLE,
concat( 'Anfrage zu ', cast( (xpath( '/article/h3/a/text()', content_elements))[1] as varchar)) as ART_TITLE_TEXT
from
ahp_w3_start.inet_content_qry
where
xml_is_well_formed_document( cast( content_elements as text)) = true
and xpath_exists('/article/h3/a/text()', content_elements) = true
order by
1, 2
;

- 29 -    (TxtDoc-2026-06-03.html)


App-Detail #1014 zeitliche Optimierung von Views

Das geht mit Indizes, löschen alter Daten, ...

oder Materialized Views.



z.B. in der Variante Materialized View - Table wird refreshed, wenn die Grunddaten sich ändern:
( Verwendung: db.refresh_materialized_viewsAsync(); dbTab = new SqlTab( db, ..., "al_storage.l_storage_lagerjournal_qry", ...) )



CREATE SEQUENCE al_storage.L_Storage_audit_dmlno_seq;

grant usage on al_storage.L_Storage_audit_dmlno_seq TO al_storageextuser_role, ahp_w3_extuser_role;

CREATE TABLE al_storage.L_Storage_audit
(
dml_id numeric( 14, 0) NOT NULL default 0,
--
dmlno numeric( 14, 0) NOT NULL,
dmloperation varchar(10) NOT NULL,
dmltime timestamp without time zone NOT NULL,
dmluser varchar(50) ,
dmlclient_addr varchar(50) ,
--
dml_details json,
--
CONSTRAINT L_Storage_audit_pk PRIMARY KEY ( dmlno ),
CONSTRAINT L_Storage_audit_chk_dml_id CHECK ( dml_id = 0 )
);


grant select, update on al_storage.L_Storage_audit to al_storageonlineuser_role, al_storagerole, al_storageextuser_role;


INSERT INTO al_storage.l_storage_audit( dmlno, dmloperation, dmltime ) VALUES ( 0, 'init', now() );


CREATE or replace FUNCTION al_storage.L_Storage_audit_tf() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$
DECLARE
L_Storage_audit_dmlno int;
L_Storage_audit_dml_details json;
BEGIN
IF (TG_OP = 'DELETE') THEN
SELECT to_json( OLD.*) into L_Storage_audit_dml_details;
ELSE
SELECT to_json( NEW.*) into L_Storage_audit_dml_details;
END IF;

SELECT nextval('al_storage.L_Storage_audit_dmlno_seq') into L_Storage_audit_dmlno;

update al_storage.L_Storage_audit
SET DMLNO = L_Storage_audit_dmlno, dmloperation = TG_OP, dmltime = now(),
dmluser = user, dmlclient_addr = inet_client_addr()::varchar(50), dml_details = L_Storage_audit_dml_details;

IF (TG_OP = 'DELETE') THEN
RETURN OLD;
ELSE
RETURN NEW;
END IF;
END;
$BODY$;


CREATE TRIGGER L_Storage_audit_aiud AFTER INSERT OR DELETE OR UPDATE ON al_storage.L_Storage FOR EACH ROW EXECUTE FUNCTION al_storage.L_Storage_audit_tf();
CREATE TRIGGER L_StoragePos_audit_aiud AFTER INSERT OR DELETE OR UPDATE ON al_storage.L_StoragePos FOR EACH ROW EXECUTE FUNCTION al_storage.L_Storage_audit_tf();

-- --- --- ---

CREATE or replace FUNCTION al_storage.refresh_materialized_views() RETURNS integer SECURITY DEFINER AS $$
DECLARE
audit_tab_dmlno int;
lrr_mv_audit_dmlno int;
BEGIN
SELECT max(dmlno) from al_storage.L_Storage_audit into audit_tab_dmlno;

SELECT min(audit_dmlno) from al_storage.l_storage_lagerjournal_raw_raw into lrr_mv_audit_dmlno;
if audit_tab_dmlno is null or lrr_mv_audit_dmlno is null or audit_tab_dmlno <> lrr_mv_audit_dmlno then

refresh materialized view CONCURRENTLY al_storage.l_storage_lagerjournal_raw_raw;
return 1;
end if;

RETURN 0;
END;
$$ LANGUAGE plpgsql;


ALTER FUNCTION al_storage.refresh_materialized_views() OWNER TO al_storagerole;

FUNCTION al_storage.l_storage_artikelkonto_qry_refresh() TO al_storagerole WITH GRANT OPTION;

-- --- --- ---

create materialized view al_storage.l_storage_lagerjournal_raw_raw as
select all
s_audit.dmlno as audit_dmlno,
STORAGE_ID, STORAGE_POS_ID, STORAGE_POS_ID as BUCH_NR, 'L' as INP_KNZ, 'Abg' AS ABG_ZUG_KNZ,
ABG_LAGERORT AS LAGERORT, ZUG_LAGERORT AS GEGENBUCH_LAGERORT, BEWEGUNGS_DATUM, ARTIKELNR, ART_BEZEICHNUNG, (BEWEGUNGS_MENGE * -1) AS BEWEGUNGS_MENGE, BUCHUNGSTEXT,
STORAGE_POS_details, created_at
FROM
al_storage.L_Storage_audit s_audit,
al_storage.L_StoragePos stor_pos
--
union all
--
select all
s_audit.dmlno as audit_dmlno,
STORAGE_ID, STORAGE_POS_ID, STORAGE_POS_ID as BUCH_NR, 'L' as INP_KNZ, 'Zug' AS ABG_ZUG_KNZ,
ZUG_LAGERORT AS LAGERORT, ABG_LAGERORT AS GEGENBUCH_LAGERORT, BEWEGUNGS_DATUM, ARTIKELNR, ART_BEZEICHNUNG, BEWEGUNGS_MENGE, BUCHUNGSTEXT,
STORAGE_POS_details, created_at
FROM
al_storage.L_Storage_audit s_audit,
al_storage.L_StoragePos stor_pos
--
order by 1, 2
;

CREATE UNIQUE INDEX l_storage_lagerjournal_raw_raw_uidx on al_storage.l_storage_lagerjournal_raw_raw ( STORAGE_ID, STORAGE_POS_ID, ABG_ZUG_KNZ );

ALTER materialized view al_storage.l_storage_lagerjournal_raw_raw OWNER TO al_storagerole;

- 30 -    (TxtDoc-2026-06-03.html)


App-Detail #1013 Access/ODBC Details dokumentieren

z.B.:
-----
- Feld "Strasse"

"EventProcPrefix": "Strasse", "Name": "Strasse", "ControlType": 109, "ControlSource": "Strasse", "DecimalPlaces": 255, "StatusBarText": "AdrZl3", "EnterKeyBehavior": "Falsch", "AllowAutoCorrect": "Wahr", "Visible": "Wahr", "DisplayWhen": 0, "Vertical": "Falsch", "Enabled": "Wahr", "Locked": "Falsch", "FilterLookup": 1, "AutoTab": "Falsch", "TabStop": "Wahr", "TabIndex": 4, "ScrollBars": 0, "Left": 1814, "Top": 1814, "Width": 3515, "Height": 340, "ForeColor": 0, "TextAlign": 0, "ColumnWidth": -1, "ColumnOrder": 0, "ColumnHidden": "Falsch", "Section": 0, "InSelection": "Falsch", "LineSpacing": 0




Wenn man die Details einfangen kann,
bekommt man z.B. einen Formularentwurf.
( alternativ mit Textdateien per backupMod.bas )

--> https://jobst-software.com/forms11.gif


--> https://jobst-software.com/download/backupMod.bas

(Script)



z.B.:
-----
Eine Tabelle mit
- Anwendungsnamen
- Objekt-Typ
- Objekt-Namen
- Feld-namen
- Eigenschaften
generieren.


AcApp AcObjType AcObj AcFd AcProps
--------------------------------------------------------
...
fri Form Adress-Pflege Strasse "Name": "Strasse", ...
fri Form Adress-Pflege Plz "Name": "Plz", ...
...




Public Function accweb_AcObjs_to_Tab()
Dim dbs As Database
Set dbs = DBEngine(0)(0)

Dim not_propNames As String
Let not_propNames = "DateCreated, LastUpdated, ..."


Dim acFds As Recordset
Set acFds = dbs.OpenRecordset("SELECT * from AcFds")


accweb_AcObj_to_Tab dbs, "Table", dbs.TableDefs, not_propNames, acFds
accweb_AcObj_to_Tab dbs, "Query", dbs.QueryDefs, not_propNames, acFds

accweb_AcObj_to_Tab dbs, "Form", dbs.Containers("Forms").Documents, not_propNames, acFds

accweb_AcObj_to_Tab dbs, "Report", dbs.Containers("Reports").Documents, not_propNames, acFds


acFds.Close
Set acFds = Nothing
End Function


Sub addAcFds_rec(dbs As Database, acFds As Recordset, acObjType As String, acObj_Name As String, fd_Name As String, props As String)
acFds.AddNew
acFds("AcApp") = dbs.Name
acFds("AcObjType") = acObjType
acFds("AcObj") = acObj_Name
acFds("AcFd") = fd_Name
acFds("AcProps") = props
acFds.Update
End Sub


Sub accweb_AcObj_to_Tab(dbs As Database, acObjType As String, acObjs, not_propNames As String, acFds As Recordset)
On Error GoTo Err_exportAll

Dim curState As String
Let curState = ""

Dim eleName As String
Let eleName = ""

Dim acEle_i As Integer
For acEle_i = 0 To acObjs.Count - 1
If Left(acObjs(acEle_i).Name, 1) <> "~" Then
Dim acObj As Object
Set acObj = acObjs(acEle_i)

eleName = acObj.Name

Dim r As String
Let r = parseAcObj_Properties(acObj.Properties, not_propNames)

addAcFds_rec dbs, acFds, acObjType, eleName, "-", r

Debug.Print acObjType & " -- " & r
Debug.Print


If acObjType = "Form" Then DoCmd.OpenForm eleName, acDesign
If acObjType = "Report" Then DoCmd.OpenReport eleName, acViewDesign

Dim ctrs
Set ctrs = Nothing

If acObjType = "Form" Then Set ctrs = Forms(eleName).Controls
If acObjType = "Report" Then Set ctrs = Reports(eleName).Controls


If Not (ctrs Is Nothing) Then
Dim c_i As Integer
For c_i = 0 To (ctrs.Count - 1)
Dim c As Object
Set c = ctrs(c_i)

Dim c_r As String
Let c_r = parseAcObj_Properties(c.Properties, not_propNames)

addAcFds_rec dbs, acFds, acObjType, acObj.Name, c.Name, c_r

Debug.Print eleName & " -- " & c_r
Debug.Print
Next
End If

If acObjType = "Form" Then DoCmd.Close acForm, eleName
If acObjType = "Report" Then DoCmd.Close acForm, eleName

curState = "eleName=" & eleName & "."



End If
Next acEle_i

Exit Sub

Err_exportAll:
Dim dlgRes As Integer
Let dlgRes = MsgBox(Error & " " & Err & " in '" & curState & "'", 48 Or 2)

If dlgRes = 5 Then
Resume Next

ElseIf dlgRes = 4 Then
Resume

End If

Exit Sub
End Sub

Public Function parseAcObj_Properties(o, not_propNames As String)
Dim res As String
Let res = ""

Dim p_i As Integer
For p_i = 0 To (o.Count - 1)
Dim p As Object
Set p = o(p_i)

Dim propName As String
Let propName = p.Name


If InStr(propName, "Border") = 1 Or InStr(propName, "Is") = 1 Or InStr(propName, "Can") = 1 Or InStr(propName, "Old") = 1 Or InStr(propName, "Special") = 1 Then
Rem ign.
ElseIf InStr(propName, "Back") = 1 Then
Rem ign.
ElseIf InStr(propName, "Font") >= 1 Or InStr(propName, "Margin") >= 1 Then
Rem ign.
ElseIf InStr(", " & not_propNames & ",", ", " & propName) = 0 Then
Dim v
Let v = Null

On Error Resume Next
v = p.value

If Err = 0 Then
Dim t As String
Let t = valQte(v)

If t <> "" Then
res = res & IIf(res = "", "", ", ") & Chr(34) & propName & Chr(34) & ": " & t
End If
End If

On Error GoTo 0
End If
Next p_i

parseAcObj_Properties = res
End Function


Public Function valQte(v) As String
Dim res As String
Let res = ""

If Not IsEmpty(v) Then
If Not IsNull(v) Then
If IsNumeric(v) And IsNumeric("" & v) Then
res = "" & v
ElseIf v <> "" Then
res = Chr(34) & Replace("" & v, Chr(34), "'") & Chr(34)
End If
End If
End If

valQte = res
End Function
- 31 -    (TxtDoc-2026-06-03.html)


ADialog #1012 Bereitschaft

<dialog id="dialog_todo_pos_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />
<label>von</label> <input name="von" type="time" />
<label>bis</label> <input name="bis" type="time" />
<hr />
<label>erreichbar unter</label> <input name="erreichbar_unter" />
<label>Bemerkung</label> <input name="Bemerkung" />
<hr />
<label>Status</label> <input name="Bereitschaft_Status" list="Bereitschaft_Status_LIST" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>




<datalist id="Bereitschaft_Status_LIST">
<option>vorgeschlagen<option>
<option>beauftragt<option>
</datalist>

- 32 -    (TxtDoc-2026-06-03.html)


App-Link #1008 Zeit -- Archiv

Eingabe im Feld Details - Archiv

- ab dem eingegebenen Datum, werden die Daten in der Web-Pflege nicht mehr angezeigt

- die Berechtigung bleibt jedoch erhalten
- die Daten können weiterhin gedruckt werden (passende URL ist Voraussetzung)
(z.B. unter "fällig" und "Protokoll", existierende Links in Mails, ...)
- auch in Access oder LibreOffice-Base/Calc sind die Zeilen weiterhin sichtbar
(für Desktop-Anwendungen sind jedoch die Online-Rollen nicht vorgesehen)



Der Details-Dialog ist folgendermassen definiert:

--> https://jobst-software.net/ainfojs2000/InfoPrint_Default?only_REPORT_KNZ=TxtDoc&search_text=%20%231001%20


- 33 -    (TxtDoc-2026-06-03.html)


ADialog_Hr_Cal #1001 Hr_Cal_Details

<dialog id="dialog_ahr_cal_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />

<label>Archiv</label> <input name="Archiv" type="date"
placeholder="im Archiv ab (Wartung, dann per User mit ahr_cal_archive_role)" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>

--> /ahr_cal/?submitaction=%2F%3D%2F&datatable_primarykey=12


- 34 -    (TxtDoc-2026-06-03.html)


AReport #1000 FSammlung_qry

{
"SELECT_FDNAMES": "inv_bew_am, adresse, kategorie, bezeichnung, ek",
"FROM_SCHEMA": "a_todo4",
"FROM_QRY": "FSammlung_qry"
}

- 35 -    (TxtDoc-2026-06-03.html)


ADialog #996 FSammlung

<dialog id="dialog_todo_pos_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />
<label>Kategorie</label> <input name="Kategorie" list="Kategorie_LIST" />
<label>Bezeichnung</label> <input name="Bezeichnung" />
<hr />
<label>Zustand</label> <input name="Zustand" />
<hr />
<label>EK</label> <input name="EK" type="number" />
<label>mögl. VK</label> <input name="VK" type="number" />
<hr />
<label>Stand</label> <input name="Stand" type="date" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>


<datalist id="Kategorie_LIST">
<option>Kamera<option>
<option>DVD<option>
<option>Bild<option>
</datalist>

- 36 -    (TxtDoc-2026-06-03.html)


AReport #993 Bestandsliste

{
"SELECT_FDNAMES": "vorgang_knz, adressnr, beldatum, artikelnr, lagerort, bewegungs_menge",
"FROM_SCHEMA": "al_storage",
"FROM_QRY": "l_storage_bestandsliste_qry"
}

--> https://jobst-software.net/frepjs2000/AReport?nur_AREPORT=Bestandsliste&report_search_text=%25&format=csv


- 37 -    (TxtDoc-2026-06-03.html)


AReport #990 Saldenliste

{
"SELECT_FDNAMES": "cos_id, vorgang_knz, adressnr, konto, konto_text, s_betrag, h_betrag",
"FROM_SCHEMA": "aea_cos",
"FROM_QRY": "buchhaltung_saldenliste_vorgang_qry"
}

--> https://jobst-software.net/frepjs2000/AReport?nur_AREPORT=Saldenliste&report_search_text=%25&format=html


- 38 -    (TxtDoc-2026-06-03.html)


ADialog #986 Standarddialog

<dialog id="dialog_todo_pos_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />
<label>Betrag</label> <input name="Betrag" list="TODO_POS_BETRAG_LIST" type="number" />
<label>ANr</label> <input name="ANr" list="TODO_POS_ANR_LIST" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>


<datalist id="TODO_POS_ANR_LIST"> <!-- lt. SQL-View TODO_POS_ANR_LIST -->
$DATA_OPTIONS.TODO_POS_ANR_LIST.ANR_OG.ANR.ANR_TEXT
</datalist>

<datalist id="TODO_POS_BETRAG_LIST"> <!-- lt. SQL-View TODO_POS_BETRAG_LIST -->
$DATA_OPTIONS.TODO_POS_BETRAG_LIST.BETRAG_OG.BETRAG.BETRAG_TEXT
</datalist>

- 39 -    (TxtDoc-2026-06-03.html)


ADialog #985 Ad-hoc-Inventur

<dialog id="dialog_todo_pos_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />
<label>Menge</label> <input name="Menge" type="number" />
<label>Ort</label> <input name="Ort" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>

--> https://jobst-software.net/a_todo4/?submitaction=%2F%3D%2F&datatable_primarykey=5


- 40 -    (TxtDoc-2026-06-03.html)


ADialog #984 Ad-hoc-Test

<dialog id="dialog_todo_pos_details">
<form> <input name="json_input_ele_no" readonly type="hidden" />
<label>Test</label> <input name="Test" />
<label>Ergebnis</label> <input name="Ergebnis" />
</form>

<button name="btnOK" >OK</button>
<button name="btnCancel" >abbrechen</button>
</dialog>

- 41 -    (TxtDoc-2026-06-03.html)


App-Link #983 Wiederkehrende Wartungen von Geräten, Software etc.

sind folgendermaßen anzulegen:
------------------------------

- WSTATE -- mit Text "wart-..."

- BDATUM -- letzes Datum der Wartung. Nach einer Wartung ist dieses Datum auf "heute" zu setzen.

- ADRESSE -- Zyklus z.B. "wart-jaehrl:", "wart-monatl:", "wart-woechentl:2", "wart-taegl:"

- VORGANGSTEXT -- sollte angeben, was zu tun, prüfen und beachten ist.


Wenn man nur die fälligen Geräte sehen will, muss man sich mit einem User anmelden,
der Mitglied der SQL-Rolle "eina_wart_offen_role" ist.


Ein Protokoll ist per LibreOffice Base bzw. der VIEW wart_journal_raw abzurufen.



z.B.

--> https://jobst-software.net/ainfojs2000/Info_Pflege?submitaction=%2F%3D%2F&datatable_primarykey=982


- 42 -    (TxtDoc-2026-06-03.html)


Server-VM #982 VM -- js-es6 -- Aussendienst4_AT

Server für Webanwendung "Aussendienst4_AT" mit Nutzung von PostgreSQL und JavaScript es6.








Hilfe zu Wiederkehrende Wartungen
unter:

--> https://jobst-software.net/ainfojs2000/InfoPrint_Default?only_REPORT_KNZ=TxtDoc&search_text=%20%23983%20


- 43 -    (TxtDoc-2026-06-03.html)


App-Link #980 Stammdaten -- Texte -- Wartung

Selten zu ändernde Stammdaten (z.B. Konten, Steuercodes, Auswahlmöglichkeiten, ...) 
sind mit LibreOffice Base intern zu pflegen.

--> /frepjs2000/Fr_Konditionen_Allgemein


- 44 -    (TxtDoc-2026-06-03.html)


App-Link #979 Stammdaten -- Texte -- Basis

Auswahllisten (z.B. ERLEDIGT_LIST)
haben meist eine PostgreSQL-View als Basis
und liefern unter Berücksichtigung der Berechtigung (Rolle)
eine passende Liste.

- 45 -    (TxtDoc-2026-06-03.html)


App-Link #971 Info -- Berechtigungen

Damit Info-Zeilen/Beiträge für Alle per Hilfe-Button 
sichtbar werden,
ist
- im Feld WSTATE 'aktiv-onlineuser-extuser'
- umd eine Zeile mit ADRESSE 'demo-online'
einzutragen.

- 46 -    (TxtDoc-2026-06-03.html)


AJob #970 AAudit-Druck nach UPDATE "Druck RE - Abo"

{
"acal_text": "%IST%",
{ "dmloperation": "UPDATE", "ADRESSE": "Druck RE - Abo" }
}

- 47 -    (TxtDoc-2026-06-03.html)


App-Link #969 ATodo -- mögliche Basis für Eigenentwicklung

Die Todo ist eine einfache Anwendung 
und könnte als Basis für individuelles Eigenes sein.

Oder man löst damit autom. Jobs aus.

--> /a_todo4/?submitaction=%2F%3D%2F&datatable_primarykey=2&job=Druck+RE+-+Abo


--> /a_todo4/


- 48 -    (TxtDoc-2026-06-03.html)


AJob #967 AAudit-Mail nach INSERT einn_ausg

{
"acal_text": "%PLAN%",
{ "dmloperation": "INSERT", "einn_ausg": "-" }
}
Bitte genehmigen oder ablehnen.
- 49 -    (TxtDoc-2026-06-03.html)


AJob #966 AAudit-Mail nach INSERT Urlaub

{
"acal_text": "%",
{ "dmloperation": "INSERT", "zeitart": "Urlaub" }
}

Bitte genehmigen oder ablehnen.



m.f.g.
AAudit
- 50 -    (TxtDoc-2026-06-03.html)


App-Link #963 Umfragen -- Online (extern)

Manche Umfragen sind Online 
- nicht
- oder mit erheblichen Aufwand verbunden
und sollten dann besser wie vorgesehen umgesetzt werden.


z.B.

--> https://wien.arbeiterkammer.at/beratung/Wohnen/Wohnen_im_Eigentum/Beschlussfassung_der_Eigentuemergemeinschaft.html


- 51 -    (TxtDoc-2026-06-03.html)


App-Link #962 Zeit -- Urlaubsanspruch (extern)



--> https://www.oesterreich.gv.at/lexicon/U/Seite.991623.html


- 52 -    (TxtDoc-2026-06-03.html)


App-Link #959 Kosten -- Link auf FinanzOnline (extern)



--> https://finanzonline.bmf.gv.at/fon/


--> https://formulare.bmf.gv.at/service/formulare/inter-Steuern/pdfs/2024/E1a.pdf

Zugangsdaten lt. interner Dokumentation.
- 53 -    (TxtDoc-2026-06-03.html)

INTRANET