Cortiveo i GEngine - prirucnik

↑ Nazad

Zašto je OTPsoft važan

Klijent za koji je pisan više ne radi sa firmom, ali je klasa ostala kao jedini pun primer kako se paketna štampa radi bez GUI-ja. Sopstveni javadoc joj kaže i šta je trebalo da bude:

„Prvobitno ime klase je Multiprint. Ali zbog teškog roka, kao i necentralizovanog načina programiranja (svaka klasa kontroliše svaki segment štampe, umesto da je jedna klasa zadužena za učitavanje, druga za linkovanje i sortiranje, treća za štampu, za logovanje...) kreiranje ove klase je odloženo."

Kako OTPsoft radi

Ulaz bez GUI-ja je GMenuCallable:

public class OTPsoft implements GMenuCallable {
    @Override
    public GError menuCall(GAppFrame pCallingFrame, String pParameters) { ... }
}

Poslovi su dva paralelna niza spregnuta indeksom counter:

public String[] OTPClassNames = { "PismoPrvoVlasnikKredit????????.txt", ... };  // 18 maski na .208
public Class<?>[] OTPClass    = { Pismo1VlasnikKredit.class, ... };

Petlja: za svaku masku FileRegex nađe fajlove, pa za svaki fajl printAllFiles(OTPClass[counter], put):

obrazac = (Obrazac) printThis.newInstance();
obrazac.mFilename = fileName;
ImportRecord importRecord = new ImportRecord(obrazac);
importRecord.loadData();
obrazac.createObrazacData(importRecord);
obrazac.dbtObrazacParameters.createData();
obrazac.dbtObrazacParameters.set("StartRb", AABroj);
obrazac.dbtObrazacParameters.update();      // BEZ OVOGA SE PARAMETAR NE PAMTI
new ObrazacParameters(obrazac);
PrintType printType = new PrintType();
printType.setS(new PrinterSelector().getCurrent());
printType.print(obrazac, 6, fileName.replace(".txt", ".pdf"), 0.5);
AABroj += obrazac.getCountCoverat();        // AA broj se nastavlja na sledeci posao

Tri zamke u OTPsoft-u (nasledi znanje, ne greške)

  1. 6 nije broj strana. To je odredište štampe: PrintType.java:79, case 6: ObrazacPrintJobToFile = PDF u fajl. (1, 2, 4, 5 su štampači; 3 i 7 zakomentarisani.)
  2. Paralelni nizovi se razilaze. Na .208 maska PismoJemacKreditRodic????????.txt stoji uz klasu PismoJemacKarticaRodic — fajl kaže Kredit, klasa kaže Kartica. Ne znamo da li je namerno; u novom alatu posao je jedan objekat, pa ovo nije moguće.
  3. Sve što se menja pred pokretanje je zakucano u konstruktoru (AABroj = 752482, folder sa nečijeg Desktopa iz 2018), a menuCall ignoriše pParameters — upravo ono mesto gde folder, datum i AA broj treba da ulaze.

Broj strana po klijentu — već postoji u podacima

Ključ za filtriranje koje želimo. Redovi u dbtObrazacH su listovi, a kolona ClientStranaCount kaže koliko listova ima klijent koji počinje tim redom:

// Obrazac.printIzvestaj() — postojeci kod
for (int i = 0; i < dbtObrazacH.getRowCount(); ) {
    result = dbtObrazacH.getRow(i).getInt("ClientStranaCount");
    map.put(result, oldValue + 1);
    i += result;                  // skok na sledeceg klijenta
}
...
if (i <= 3) countCoveratSmall++;  // koverat do 20 g
if (i >  3) countCoveratBig++;    // preko 20 g

Podela „6+ listova" vs „5 i manje" je ista petlja sa drugim pragom — ne nova logika.


Autoprint — novi alat

Živi na .208, D:\data\workspace-grom\GTehnobiro\src\db\tehnobiro\:

AutoprintGate.java        most ka nejavnim clanovima Obrazac-a
autoprint\
    Autoprint.java        pokretac: builder + GMenuCallable
    AutoprintTest.java    gotov posao nad C:\ProgramData\DeveloperTools\TEST
    Job.java              posao = klasa + maska + parametri
    PageGroups.java       klijenti grupisani po broju listova
    NameTemplate.java     ${baza}_${posao}_${datum}_${grupa}.pdf

Kompajlirano na JDK 8 protiv postojećeg Gtehnobiro_...jar, čisto. Nijedna postojeća klasa nije menjana.

Zašto postoji AutoprintGate

mFilename i dbtObrazacParameters su protected, createObrazacData je paketni, konstruktor ImportRecord-a je paketni — a Java paketi nisu hijerarhijski: podpaket db.tehnobiro.autoprint ne vidi ništa od toga. AutoprintGate stoji u db.tehnobiro i prevodi to u javni API. Alternativa je bila menjati Obrazac.java, što nismo hteli.

Ovo je opšta lekcija o Javi: protected i paketni pristup ne nasleđuju se kroz imena paketa.

Upotreba iz koda

new Autoprint()
    .folder("C:\\ProgramData\\DeveloperTools\\TEST\\")
    .job(Pismo1VlasnikKredit.class, "PismoPrvoVlasnikKredit????????.txt")
    .job(Pismo2VlasnikKredit.class, "PismoDrugoVlasnikKredit????????.txt")
    .startRb(752482)
    .fileName("${fajl}_${grupa}.pdf")
    .split("6plus",  6, Integer.MAX_VALUE)
    .split("6minus", 1, 5)
    .dryRun(true)      // samo izmeri i ispisi, ne stampaj
    .run();

Upotreba iz menija

Meni zove menuCall(frame, "") — bez parametara. Zato postoji AutoprintTest: poslovi i folder su u konstruktoru, pa se u Main doda samo

test.addOption(AutoprintTest.class);

Kad se Autoprint zove iz koda ili kad mu dispečer pošalje tekst, parametri rade:

folder=D:\drugi\;startrb=752482;dry=0;factor=0.5;DatumStampe=23.09.2026.

Nepoznat ključ ide kao parametar štampe (dbtObrazacParameters), poznati su folder, startrb, factor, dry, filename.

Šta radi u probnom prolazu

=== baza Tehnobiro (probni prolaz)
  Pismo1VlasnikKredit / PismoPrvoVlasnikKredit20170905.txt: 1240 listova, 380 klijenata
      3 listova : 210 klijenata
      6 listova : 120 klijenata
      9 listova : 50 klijenata
      grupa 6plus (6-+ listova): 170 klijenata
      grupa 6minus (1-5 listova): 210 klijenata
=== kraj: sledeci AA broj = 1

Jedno otvoreno pitanje (i zašto alat neće da nagađa)

ClientStranaCount se čita iz prvog reda klijenta. Ako ta vrednost ne stoji u svakom redu, filter po redovima bi presekao klijenta na pola. Zato:

To je pravilo koje vredi i van ovog alata: provera koja se može izmeriti ne sme da se pretpostavi.

Sledeći korak

  1. U Eclipse-u na .208: F5 pa Build.
  2. Main: test.addOption(AutoprintTest.class) (ako već nije).
  3. Klik na meni → probni prolaz ispisuje merenje u konzolu.
  4. Iz tog ispisa se vidi da li podela sme filterom; onda dryRun(false) i allowRowFilter(true).

Izvor: 04-otpsoft-i-autoprint.md