|
|
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.
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>
|
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!
|