HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Számla tétel adatainak létrehozása


Internetes számlázó 8. rész

Példaprogram letöltése

67029 bájt


Most, hogy a számlán már megadhatók a fejléc adatok, melyek az Invoice táblába kerülnek, ideje megvalósítani a számla tételeinek felvételét, melyeket majd az InvoiceDetail táblába tárolhatunk el.

A mellékelt példa fordítása előtt szokás szerint ellenőrizze és szükség esetén javítsa a Constant.pas-ban lévő konstansok értékeit (TEMPLATEPATH, CONNECTIONSTRING, stb.).
Az előző cikkekben már létrehozott NetInvoice virtuális web könyvtár elérési útvonalát módosítsa úgy, hogy az a most mellékelt NetInvoice könyvtárra mutasson.

A számlák tételeinek felvételéhez elkészítjük az invoicenew2.dat állományt. Erre akkor lesz szükség, miután a felhasználó megadta a számla fejléceinek adatait és a Tovább gombra kattintott. Ekkor kerül meghívásra a Command eljárásunk a 13 értékkel. Itt fel kell dolgoztatnunk az adatokat a ProcessNewInvoice1 függvénnyel, mely igaz értéket ad vissza, ha a megadott adatok helyesek voltak. Ekkor felhasználót léptethetjük tovább az invoicenew2.dat-ra, hogy megadja a számlák tétel adatait is. Ha az adatok nem helyesek és a ProcessNewInvoice1 hamis értékkel tér vissza, akkor az error.dat feldolgozásával megjelenítjük a hibaüzenetet a felhasználó felé.
procedure TWebModule1.Command;
…
    13: begin//számlafej proc
      if ProcessNewInvoice1 then begin
        PageProducer1.HTMLFile:=TEMPLATEPATH+'invoicenew2.dat';
        Response.Content:=PageProducer1.Content;
      end else begin
        PageProducer1.HTMLFile:=TEMPLATEPATH+'error.dat';
        Response.Content:=PageProducer1.Content;
      end;
    end;

A ProcessNewInvoice1 az eddigiektől eltérően most még nem tárol adatot, hanem csak ellenőriz. Adattárolásra majd csak akkor kerül sor, ha már számla minden adata rendelkezésre áll.
function TWebModule1.ProcessNewInvoice1: boolean;
begin
  result:=false;
  with Request.QueryFields do begin
Ellenőriznünk kell tehát, hogy meg lett-e adva az összes olyan adat, mely a számla fejlécéhez kel.
    if (Values['invoicedate']='') or (Values['fullfilmentdate']='') then begin
      FMessage.Add('Nem adta meg az összes kötelezően kitöltendő mezőt!');
    end else begin
      try
Teszteljük azt is, hogy a megadott dátumok helyesek-e. Ezt úgy tudjuk leellenőrizni, hogy az StrToDate függvénnyel megpróbáljuk konvertálni a megadott sztringet. Ha itt hiba történik, akkor az except blokkban folytatódik a programunk. Megfigyelhető egy elsőre talán logikátlannak tűnő megvalósítás is. A Values['invoicedate']-el elérjük a HTML Form-on megadott számla dátum mező értékét sztringként. Ezt először konvertáljuk dátummá, majd vissza sztringgé és ezzel az értékkel helyettesítjük a régit. Mire jó ez? Ha a felhasználó a dátum mezőbe csak annyit ír be, hogy 11.15, akkor ez egy helyes dátum, de sokkal szebb a 2001. 11. 15. formában. Ezekkel a konverziókkal elérhetjük ezt a formátumot. Hogy miért kell a régi értéket kicserélnünk az újra a Values tömbben, arra hamarosan fény derül.
        Values['invoicedate']:=DateToStr(StrToDate(Values['invoicedate']));
        if Values['paymentdate']<>'' then begin
          Values['paymentdate']:=DateToStr(StrToDate(Values['paymentdate']));
        end;
        result:=true;
      except
        FMessage.Add('Helytelen a megadott dátum!');
…
A ProcessNewInvoice1 sikeres lefutása után tehát ott tartunk, hogy az invoicenew2.dat-ot kell feldolgozni. Itt gondoskodnunk kell arról is, hogy a felhasználó által megadott számla fejléc adatok ne vesszenek el. Ezt úgy érjük el, hogy az invoicenew2.dat-ba elhelyezünk annyi hidden mezőt, ahány adat megadásra került a számla fejrészében.
<form method=get action="/scripts/NetInvoice.exe">
<input type=hidden name=invoicedate value="<#invoicedate>">
<input type=hidden name=fullfilmentdate value="<#fullfilmentdate>">
<input type=hidden name=paymentdate value="<#paymentdate>">
<input type=hidden name=paymentmode value="<#paymentmode>">
<input type=hidden name=customerid value="<#customerid>">
Amint az látható, a rejtett mezőknek úgy adunk értéket, hogy egy-egy címkét helyezünk el a Value paraméter értékadásánál. Ennek hatására a PageProducer1 az invoicenew2.dat feldolgozásakor a címkék megtalálásánál az OnHTMLTag eseményét aktivizálja azok cseréje érdekében. Itt minden címke a Request.QueryFields.Values tömbből kap értéket. A dátum mezők esetén a már kiegészített dátumokat.
procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String;
    TagParams: TStrings; var ReplaceText: String);
…
                    if TagString='invoicedate' then begin
                      ReplaceText:=Request.QueryFields.Values['invoicedate'];
                    end else begin
                      if TagString='fullfilmentdate' then begin
                        ReplaceText:=Request.QueryFields.Values['fullfilmentdate'];
                      end else begin
…

Az invoicenew2.dat állományban valójában két különálló HTML Form kap helyet. Mind a kettőben szükséges a fenti rejtett mezők tárolása, hiszen mind a két esetben meg kell őriznünk a számla fejléc adatait. Az egyik eset, melyet le kell kezelnünk az lesz, hogy a felhasználó végzett a számla elkészítésével és annak tárolása mellett dönt. A másik eset pedig az, hogy végzett egy új számla tétel felvitelével és ezt szeretné a többi tétel közé felvenni. Ehhez a két esethez két nyomógomb is tartozik: "Számla készítés vége", mellyel az első Form-ot aktivizálhatjuk és befejeztethetjük a számla készítést, illetve a "Tovább" nyomógomb, mellyel az aktuális tételt tudjuk a többi tétel közé felvenni és folytatni a számla készítést.

Nézzük most mi is történik a számlára történő új tétel felvételekor. Ekkor a rejtett command paraméter 14-es értéket kap.
<div class=f12b align=center>Új tétel</div>
<form method=get action="/scripts/NetInvoice.exe">
<input type=hidden name=command value=14>

Ezt a kérést a ProcessNewInvoice2 függvény dolgozza fel. Ha a megadott számla tételeknél nem volt probléma, akkor igaz értékkel tér vissza, különben hamissal. Igaz érték esetén ugyanarra az oldalra irányítjuk vissza a felhasználót, hogy szükség esetén még tudjon új tételt felvenni a számlára, vagy befejezhesse a műveletet. Ezért ekkor ismét az invoicenew2.dat kerül feldolgozásra. Hiba esetén, szokás szerint az error.dat feldolgozásával jelezzük azt.
procedure TWebModule1.Command;
…
    14: begin//új számla tétel
      if ProcessNewInvoice2 then begin
        PageProducer1.HTMLFile:=TEMPLATEPATH+'invoicenew2.dat';
        Response.Content:=PageProducer1.Content;
      end else begin
        PageProducer1.HTMLFile:=TEMPLATEPATH+'error.dat';
        Response.Content:=PageProducer1.Content;
      end;
    end;

A ProcessNewInvoice2 még mindig nem tárol adatokat, csak ellenőrzést végez, hogy a számla tétel adatai helyesen lettek-e megadva.
function TWebModule1.ProcessNewInvoice2: boolean;
begin
  result:=false;
  with Request.QueryFields do begin
    if Values['count']='' then begin
      FMessage.Add('Nem adta meg darabszámot!');
    end else begin
      result:=true;
    end;
  end;
end;

Felmerül a kérdés, hogy miként oldjuk meg azt, hogy a megadott számla tételek ne vesszenek el, bármennyi is legyen belőlük a számla készítés közben. A válasz egyszerű: rejtett mező. Ahogy eltároltuk a HTML Form-on néhány rejtett mezőben a számla fejléc adatait, úgy fogjuk tárolni a számla tétel adatait is. Ennek megvalósítására az invoicenew2.dat mindkét HTML Form-jában elhelyezünk egy-egy <#invoicedetailshidden> nevű címkét és programunkat felkészítjük, hogy ezt cserélje ki az összes számla tétel adatára, melyek rejtett mezőként jelennek meg.

A cserével a GetInvoiceDetailsHiddenList nevű függvényünket bízzuk meg.
procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String;
    TagParams: TStrings; var ReplaceText: String);
…
      if TagString='invoicedetailshidden' then begin
           ReplaceText:=GetInvoiceDetailsHiddenList;
      end;

Ebben a függvényben kell egy olyan sztringet előállítanunk, melyben html kódot generálunk, amelyek tartalmazzák rejtett mezőként az összes eddig felvett számla tételt. Egy ilyen tétel azonosításához elegendő számunkra a Products tábla ProductId mezőjének értéke és az adott tétel darabszáma. A rejtett mezőkben ezt úgy adjuk meg, hogy a pid1 tartalmazza az első számla tétel termék azonosítóját (ProductId), míg a pcount1 az első tétel darabszámát. A pid2 és pcount2 tárolja a második tételt. A számozás pedig addig folytatódik, ahány tétel van a számlán aktuálisan. Az egyszerűbb kezelhetőség érdekében ezt a tétel darabszámot is eltároljuk egy rejtett mezőben, melynek pc nevet adunk.
function TWebModule1.GetInvoiceDetailsHiddenList: string;
var
  i: integer;
  pc: integer;
begin
  result:='';
  with Request.QueryFields do begin
Első nekifutásra azt feltétezzük, hogy még nincs megadva egyetlen tétel sem, így a pc változó értékét nullára állítjuk. Amikor először kerülünk az invoicenew2.dat HTML oldalra, akkor ez igaz is.
    pc:=0;
Ezt követően ellenőrizzük, hogy az adott kérésben szerepel-e a pc változó.
    if Values['pc']<>'' then begin
Ha igen, akkor már van megadott számla tétel, így a pc változónk értéke már nem nulla lesz.
      pc:=StrToInt(Values['pc']);
    end;
Kezdeményezünk egy ciklust, mely az elsőtől az utolsóig végigmegy a pid és pcount rejtett mezőkön és újra generálja azokat az invoicedetailshidden címke cseréjéhez.
    for i:=1 to pc do begin
      result:=result+'<input type=hidden name=pid'+IntToStr(i)+' value="'+Values['pid'+IntToStr(i)]
         +'">';
      result:=result+'<input type=hidden name=pcount'+IntToStr(i)+' value="'+Values['pcount'+IntToStr
         (i)]+'">';
    end;
Ezek után növeljük a darabszámot, mivel a programunk csak akkor juthat erre a pontra, ha a felhasználó egy új tétel felvétele mellett dönt.
    inc(pc);
    if Values['productid']<>'' then begin
Ekkor az új tételhez tartozó adatokat is el kell helyeznünk a rejtett mező eddigi tagjai mellett.
      result:=result+'<input type=hidden name=pid'+IntToStr(pc)+' value="'+Values['productid']+'">';
      result:=result+'<input type=hidden name=pcount'+IntToStr(pc)+' value="'+Values['count']+'">';
      result:=result+'<input type=hidden name=pc value="'+IntToStr(pc)+'">';
    end;
  end;
end;

Most tehát már gondoskodtunk arról, hogy a HTML Form-okban tároljuk rejtett mező formájában mind a számla fejléc adatait, mind a tétel adatait. Most ha a felhasználó úgy döntene, hogy befejezi a számla készítést, akkor az adattároláshoz már minden szükséges adatunk rendelkezésre állna.

Azonban nem foglalkoztunk idáig a számla tételek megjelenítésével, pedig nem ártana megoldanunk azt, hogy az egyesével felvett számla tételek meg is jelenjenek a web oldalon, hogy a számla készítő felhasználónk láthassa, hogy eddig milyen tételeket vett fel. Ezt úgy oldjuk meg, hogy az invoicenew2.dat állományba elhelyezünk egy újabb címkét <#invoicedetails> névvel. Ezt a programunk kicseréli az addig felvett és rejtett mezőben tárolt számla tételek táblázatára.
procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String;
    TagParams: TStrings; var ReplaceText: String);
…
    if TagString='invoicedetails' then begin
         ReplaceText:=GetInvoiceDetailsList;
    end else begin
Ehhez a cseréhez a GetInvoiceDetailsList függvényt hívjuk meg.
function TWebModule1.GetInvoiceDetailsList: string;
…
Itt a szükséges adatbázis kapcsolat megnyitása után egy ciklus segítségével végigmegyünk a rejtett mezőkön, melyekben ott bújnak a tétel adatok eléréséhez szükséges információk.
  result:='';
  with Request.QueryFields do begin
    pc:=0;
    if Values['pc']<>'' then begin
      pc:=StrToInt(Values['pc']);
    end;
    for i:=1 to pc do begin
A ciklusmagon belül az aktuális tételnél a pidx rejtett mező értéke alapján rákeresünk a Products táblában a megfelelő termékre.
      if ds.Locate('ProductID', StrToInt(Values['pid'+IntToStr(i)]), []) then begin
Ez alapján már képesek leszünk az adott termék minden szükséges adatának a megjelenítésére, melynek előállításával a GetRow függvényt bízzuk meg.
        result:=result+GetRow(Values['pcount'+IntToStr(i)]);
      end;
    end;
Mivel itt is előfordulhat az az eset, hogy programunk épp egy új tétel felvétele közben van, így nem csak a rejtett mezőkben lehet megjelenítendő adat, hanem a Request.QueryFields.Values tömbjében is ott lehet az éppen felvett tétel, így ezt is bele kell vennünk a táblázat generálásába.
    if Values['productid']<>'' then begin
      if ds.Locate('ProductID', StrToInt(Values['productid']), []) then begin
        result:=result+GetRow(Values['count']);
      end;
    end;
  end;
  ds.Close;
end;
A GetRow függvény állítja elő e táblázat egy-egy sorát miközben figyelembe veszi a megadott darabszámot, illetve a Products tábla aktuális sorát.
  function GetRow(count: string): string;
  var
    netto, brutto: integer;
  begin
    netto:=StrToInt(count)*ds.Fields[4].AsInteger;
    brutto:=Round(netto*(ds.Fields[5].AsInteger/100+1));
    result:='<tr>'+
      '<td>'+ds.Fields[2].AsString+'</td>'+
      '<td>'+ds.Fields[1].AsString+'</td>'+
      '<td align=right>'+ds.Fields[4].AsString+' Ft</td>'+
      '<td align=right>'+count+' '+ds.Fields[3].AsString+'</td>'+
      '<td align=right>'+IntToStr(netto)+' Ft</td>'+
      '<td align=right>'+ds.Fields[5].AsString+' %</td>'+
      '<td align=right>'+IntToStr(brutto)+' Ft</td>'+
      '</tr>';
  end;

Ezzel nagyjából el is jutottunk addig a pillanatig, hogy a web oldalakon össze tudunk állítani egy komplett számlát. Most jönne a számla tárolása, melyhez a rejtett command paraméter 15-ös értéket rendeltük. Ennek megvalósítására azonban csak sorozatunk következő részében kerül sor.
<form method=get action="/scripts/NetInvoice.exe">
<input type=hidden name=command value=15>





Cikksorozat

#IDKategóriaCikk címeSorozat
3916WindowsA javascript nyelv bemutatása1. rész
3946WindowsJavascript változók és operátorok2. rész
3975WindowsKódvezérlés JScript-ben3. rész
4004WindowsFüggvények és objektumok4. rész
4036WindowsFejlett funkciók a JavaScript nyelvben5. rész
4066WindowsFejlett funkciók a JavaScript nyelvben - folytatás6. rész
4116WindowsReguláris kifejezések7. rész
4145WindowsReguláris kifejezések - folytatás8. rész


Könyv
Ez a cikk megtalálható ebben a könyvben: Delphi Software Offline 2001 évkönyv 671. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |