2011. szept. 16.

Egy ÁFA ellenőrzés margójára

Egyik nagyon kedves partnerünk pénzügyi vezetője azzal a kérdéssel fordult hozzám, hogy hol találja az elektronikusan kibocsátott számlákat, mert ÁFA ellenőrzése lesz a cégnek és kérte az APEH (most már inkább NAV), hogy vigye magával.

A válasz nagyon egyszerű volt, hisz az általuk használt, a SAP Business One-hoz megvásárolható e-Doc+ Elektronikus számlázási Add-On egy különálló mappában menti el a kibocsátott elektronikusan aláírt, időbélyeggel ellátott pdf-eket.

Néhány órával később azonban újból hívott és azt mondta, hogy neki nem csak a kibocsátott pdf-ekre, hanem a bennük található adatokra is szüksége van méghozzá az APEH által előírt formátumok valamelyikében. A kéréséhez útmutatásként az alábbi előírást csatolta: 
Az elektronikus számlázás során az adóhatóság által elfogadott fájlformátumok 
Az adózás rendjéről szóló 2003. évi XCII. törvény (Art.) 95. § (3) bekezdése alapján (figyelemmel az Eszr. 3. §-ára is) az adózó az iratokat és az adózással összefüggő, elektronikus adathordozón tárolt adatokat (ide értve az elektronikus úton kibocsátott számlát is) felhívásra az adóhatóság által közzétett formátumban rendelkezésre bocsátja. Az elektronikus úton kibocsátott számlákra vonatkozóan az állami adóhatóság által elfogadott fájlformátumok a következők:
  • .txt formátum (text fájl)
  • bármilyen más olyan ún. print fájl formátum, mely nem formázott szöveget, illetve karaktereket tartalmaz, továbbá nem találhatók a fájlban - a soremelésen és az oldalkezdet jelzésén kívül - utasítások, és a fájl tartalma (a fájlban szereplő szöveg, illetve karakterek) egyértelműen megfeleltethető a kinyomtatott adatoknak (a fájlban szereplő karakterek sorozata, tulajdonsága a papírra történő kinyomtatással sem változik),
  • .csv fájlformátum,
  • .dbf fájlformátum,
  • .mdb fájlformátum,
  • .xls (Excel) fájlformátum,
  • .xml fájlformátum.
Az .xml fájlformátum definícióit a közlemény 3. számú melléklete tartalmazza.
Az előzőekben részletezett fájlformátumokban az elektronikus számlákat kérésre adathordozón (floppyn, CD vagy DVD lemezen, USB csatlakozású adattároló eszközön) kell az adózónak az adóhatóság rendelkezésére bocsátania. 
Fontos kiemelni, hogy az említett fájlformátumok ellenőrzési formátumok, vagyis az adózó bármilyen formátumban kibocsáthatja elektronikus úton a számlát (akár pl. .pdf formátumban is), azonban az adóhatósági ellenőrzéskor az előzőekben említett formátumban kell az adóhatóságnak átadnia azokat. 
Szükséges megjegyezni ugyanakkor, hogy kérésre a fájlok adatszerkezetét is rendelkezésre kell bocsátani, mivel a fájlformátumokon belül is lehetnek eltérések, melyek az ellenőrzés lefolytatását nehezítik.
Miután kapcsolatba léptem az e-Doc+ fejlesztőivel kiderült, hogy nincs még tapasztalatuk ÁFA ellenőrzéssel kapcsolatban, így nem tudtak segíteni. Azt ajánlották, hogy a pdf-eket megnyitva az Adobe Reader programmal mentsem ki a bennük található xml mellékletet, mert az olyan formátumban tartalmazza az adatokat, mint ahogy az APEH várja.

Ez már egy nagyon jó hír volt, hisz így legalább az adatok újbóli előállítását meg lehet spórolni és "csak" a fájlok mentését kell elvégezni.

Az ördög azonban a részletekben rejlik! Több mint 6 ezer számlánál ugyanis már ez az egyszerű megnyitom, kimentem, becsukom, megnyitom, kimentem, becsukom feladat elvégzése is több mint 3 munkanapot venne igénybe!

Első próbálkozás: Írjunk programot!

Fejlesztőként rögtön utána néztem, hogy milyen ingyenes eszközök állnak rendelkezésre. Pár perces googlizás után találtam is egy nagyszerű leírást a stackoverflow.com-on, így miután letöltöttem az iTextSharp könytárat azonnal neki is kezdtem egy kis program összeütésének.

Bár pár perc alatt elkészültem a c#-os átiratával a stackoverflow-n talált java forrásnak, a program sajnos nem akart működni. Egy fél órát küzdöttem, hogy mi a csudáért nem csinálja azt amit kellene (ez a sor nem adta vissza a szükséges értéket: PdfDictionary names = root.getAsDict(PdfName.NAMES);), majd feladtam a küzdelmet és másik megoldás keresésébe kezdtem.

Második nekifutás: Keressünk valami ingyenes programot!

Újabb keresgélés után rátaláltam a végső megoldást jelentő Pdftk nevű programra, amely parancssorból vezérelhetően képes arra, hogy különféle műveleteket hajtson végre pdf fájlokon. 
A programmal kapcsolatban a legnehezebb feladatot a letöltési link megtalálása jelentette, amelyet valamilyen perverzió okán a Version History oldalra helyeztek el.

A megoldás ismertetése

Azzal, hogy meglett az eszköz amivel a feladat elvégezhető, a legnagyobb probléma elhárult. Hátra volt még azonban az, hogy kidolgozzam az elemi lépéseket melyek elvezetnek a végcélhoz.

1 lépés: A program meghívása a több ezer pdf fájlal

Szükség van egy olyan parancs fájlra (batch) amely egyenként meghívja a pdftk programot a megfelelő paraméterezéssel. Mivel több ezer fájlról volt szó, így nem jöhetett számításba, hogy kézzel készítsem el a fájlt. Szükség volt egy olyan parancsra amelyik elvégzi a munka nagy részét.

Erre az alábbi tűnt a legjobb megoldásnak:
dir *.pdf /b /s > osszespdf.bat
A parancs futtatása után előállt az alábbi sorokat (persze nem csak ennyit, hanem az összeset) tartalmazó szöveges fájl:
g:\e-számla\tároló\SBOG - ARInvoice - 8205.pdf
g:\e-számla\tároló\SBOG - ARInvoice - 8206.pdf
g:\e-számla\tároló\SBOG - ARInvoice - 8207.pdf
g:\e-számla\tároló\SBOG - ARInvoice - 8209.pdf
g:\e-számla\tároló\SBOG - ARCorrectionInvoice - 100.pdf
g:\e-számla\tároló\SBOG - ARCorrectionInvoice - 101.pdf
g:\e-számla\tároló\SBOG - ARCorrectionInvoice - 102.pdf
 A fenti sorok egy megfelelő szövegszerkesztővel (notepad++) és némi ötleteléssel gyorsan átalakíthatók az alábbi formátumra:
pdftk\bin\pdftk.exe "SBOG - ARInvoice - 8205.pdf" unpack_files output apehxmls
pdftk\bin\pdftk.exe "SBOG - ARInvoice - 8206.pdf" unpack_files output apehxmls
pdftk\bin\pdftk.exe "SBOG - ARInvoice - 8207.pdf" unpack_files output apehxmls
Már majdnem kész is lennénk, ha az összes pdf-ben nem ugyan az lenne a mellékletként szereplő xml-eknek a neve... Ez egy kicsit megbonyolítja a helyzetet, mert bár kimentődik a melléklet, de a legutolsó fájl mindig felülírja az előzőt.

2. lépés: A feldolgozó batch

Ennek az elkerülésére nem közvetlenül a pdftk.exe-t kell meghívni az osszespdf.bat-ból, hanem egy újabb batch fájlt (mondjuk pdftk.bat), ami elvégzi egyrészt a melléklet kimentését, majd az aktuális xml átnevezését.

Ehhez az alábbihoz hasonló sorokra lesz szükség az osszespdf.bat-ban:
call pdftk.bat ARInvoice-8205  
call pdftk.bat ARInvoice-8206 
A szemfülesek észrevehetik, hogy a pdftk.bat-nak átadott paraméter nevéből ki lett szedve a szóköz. Sajnos erre a paraméter átadás miatt van szükség és persze ehhez nem csak a szöveget kellett módosítani, hanem a fizikai fájlok nevét is... Erre ajánlom a TotalCommander Csoportos átnevezés funkcióját.

Ha sikerült a fentieket elvégezni, akkor már csak az utolsó lépés van vissza, a feldolgozó parancsállomány:
pdftk\bin\pdftk.exe %1.pdf unpack_files output apehxmls
ren apehxmls\*.xml %1._xml
Bár a fenti sorok magukért beszélnek talán annyi magyarázatot fűzhetek hozzá, hogy az első parancs kimenti az aktuális pdf-ből a melléklet xml-t, majd a második parancs átnevezi a könyvtárban található xml fájlokat a pdf-el azonos nevű _xml kiterjesztésű fájllá.

Erre azért van szükség, hogy mindig csak egy - az utolsó - xml kiterjesztésű állomány legyen a könyvtárban.

Mivel az _xml kiterjesztés az nem a legjobb, az osszespdf.bat állomány utolsó parancsának érdemes beilleszteni az alábbit:
ren apehxmls\*._xml *.xml

Végszó

Talán első olvasatra elrettentő, hogy milyen nyakatekerten lehet előállítani a szükséges adatokat, de ilyenkor egyrészt érdemes arra gondolni, hogy csak egyszer kell(ett) kidolgozni a módszert és innentől kezdve, akár több tízezer számla esetén is 5-10 perc alatt produkálhatók a szükséges adatok.

Másrészt pedig 6-8000 ezer számla elektronikus kibocsájtása kb. félmillió forint megtakarítást jelent az SAP Business One-t e-Doc+ Add-On-nal használó cégnek.
Olvasd tovább!

2011. aug. 15.

SAP Business One riportolás MacGyver módra I. rész - Excel táblázat

Biztos hallott már Ön is arról, hogy milyen fantasztikus eszközök állnak az SAP Business One felhasználók rendelkezésére, ha a vállalati adatbázisban tárolt adatokból listákat, kimutatásokat szeretnének létrehozni.

Én magam is írtam egy másik blogon erről már bejegyzést (SAP Crystal Reports bemutató 1. rész), sőt egy kis videóval is színesítettem a száraz szöveget.

Az igazi profinak azonban egy gémkapocs is elég ahhoz, hogy beindítson egy atomerőművet vagy valami hasonlóan nagy bravúrt hajtson végre a keze közelében lévő eszközök segítségével.

Volt a kilencvenes évek közepén egy kalandfilm sorozat, melynek a főszereplője pont arról volt híres, hogy bármiből tudott bombát vagy egyéb más - a szorult helyzetéből menekvést biztosító - eszközt fabrikálni. Nézzük meg, milyen lehetőségeink vannak nekünk, ha csak a kezünk közelében lévő eszközöket szeretnénk használni a riportoláshoz!
Olvasd tovább!

2011. jún. 15.

SMS küldés SAP Business One-ból

Az elmúlt időszakban többekkel beszélgettem akiknek felkeltette az érdeklődését az SAP Business One-hoz kifejlesztett SMS küldő robotunk.

Az alkalmazás arra képes, hogy folyamatosan monitorozza az SAP Business One adatbázisát és ha olyan tranzakciót talál, amelyik megegyezik valamely a programban beállított szabállyal, akkor küld egy e-mail vagy sms értesítőt a - paraméterekben meghatározott tartalommal - a címzettnek.

A legtöbb beszélgetőtársamnak az SMS küldés keltette fel az érdeklődését és nem nagyon értették, hogy miként lehet ezt megoldani anélkül, hogy egy mobiltelefont kapcsolnánk össze a szerverrel.

A megoldás igazából nagyon egyszerű: léteznek olyan internetes szolgáltatások, ahol előre megvásárolhatunk adott számú sms-t amelyeket egy speciális interfészen (http, ftp, soap, smtp, stb.) keresztül küldhetünk el a címzetteknek. Ilyen szolgáltatást nyújt például a Clickatell vagy a Voipbuster, és még persze sokan mások.

Hogy ne csak a programunk rejtett reklámjának tűnjön ez a bejegyzés (egyébként ingyenes ;-) egy nagyon leegyszerűsített példán keresztül nézzük meg közelebbről, miként lehet ezt technikailag kivitelezni.
Olvasd tovább!

2011. máj. 21.

Mire elindul a webáruház


Az elmúlt időszakban egyre több ügyfelünk érdeklődik a webáruházban rejlő lehetőség iránt. Ez azt hiszem, hogy teljesen érhető, hisz ahogy egyre több ember kezdi használni az internetet, egyre többnek lesz igénye, hogy a vásárlásainak is egy részét ott intézze. Talán már az Ön fejében is megfordult, hogy ki kéne próbálni milyen lehetőségeket tartogat.

Nekem a webáruházról manapság már nem a vásárlás, hanem a mögötte meghúzódó informatikai rendszer jut az eszembe. Az, hogy mit és hogyan áramoltassunk a két alkalmazás között (webáruház és az ügyviteli rendszer), milyen szempontokat vegyünk figyelembe a koncepció megalkotása során.

Egy új webáruház kialakítás során első lépésként ki kell dolgozni az értékesítési folyamatot: mit és hogyan szeretnénk értékesíteni, milyen ár(ak)on, milyen készletekből, stb. A koncepció alkotás során azonban sosem szabad elfelejteni, hogy milyen fizika, technológiai közegbe illeszkedik az egész rendszer. A tapasztalatom, hogy a leglényegesebb funkciók viszonylag triviálisan implementálhatók, de előkerülhetnek olyan kérdések, melyek megvalósítása akár jelentős ráfordításokat is igényelhet. 

Mindenkinek mielőtt belekezd egy ilyen projektbe fontos, hogy eldöntse mi a célja a rendszerrel. Egy gépezetként tekint rá, amely képes a beletáplált erőforrásokból valami többet, értékesebbet kihozni vagy pedig egy presztízs beruházásként, amelynél nem számít mibe kerül, nem számít hányan használják, csak az a lényeg, hogy megmutassuk, nekünk van ilyen.

Azt gondolom, hogy ez a bejegyzés főleg azoknak segít, akik szeretnének a leghatékonyabb módot megtalálni, ezért minél többet szeretnének megtudni arról, hogy milyen kérdésekkel kell szembenézniük.

Bár a következőkben főleg technikai dolgokról lesz szó, ne feledje, sokkal fontosabb az, hogy miért akarunk webáruházat, mint az, hogy miként csináljuk meg!
Olvasd tovább!

2011. ápr. 30.

SQL backup visszatöltése korábbi verzióra


Tegnap este az MS SQL szerver egy kellemetlen tulajdonságával szembesült kolléganőm.

Egész napját azzal töltötte, hogy egy több éves vállalati adatbázist az SAP Business One új 8.81-es verziójára átállítsa és egy kicsit gatyába rázzon, mert össze-vissza voltak a cikkszámok és partnerkódok.

A műveletet az egyszerűség miatt a saját gépén, a saját SQL 2008 szerverén végezte. Este felé, amikor elkészült mindennel és gondolta, itt az idő, hogy visszatöltse a produktív szerverre az adatbázist, azzal szembesült, hogy az SQL Management Studio inkompatibilitásra hivatkozva nem hajlandó ezt megtenni. Nem igazán értette a helyzetet, hisz a saját és az ügyfél szerverén is MS SQL 2008 van.

Ezen a ponton léptem be a képbe, majd rövid diskurzus után kiderítettem, hogy 2008 van mindkettőn az igaz, viszont a saját gépén már az újabb R2-es verzió.


Ez a helyzet sajnos nem sok jóval kecsegtetett, amit kolléganőm félig megtört - "Na, akkor már tudom mivel töltöm a hétvégét: kezdem előlről náluk." - mondata is jelzett.

Aki már volt ilyen helyzetben, az tudhatja, hogy egy jó informatikus olyan mint egy bűvész: amikor szembetalálja magát egy problémával, amit első próbálkozással nem tud elhárítani, akkor felkiált: "Nem volt jó ez az ötlet?? Sebaj, van másik!"

Aki ismeri az SQL adatbázis rendszereket, az tudja, hogy az adatok mellett az adatbázisban egyéb más jószágok is vannak: view-k, tárolt eljárások, függvények, stb. Ha nem bírunk egy mentést visszatölteni, akkor a feladatunk az, hogy ezeket az objektumokat és az adatokat átvarázsoljuk valahogy a cél rendszer egy üres adatbázisába.

Egy olyan összetett rendszer, mint amilyen a SAP Business One, rengeteg ilyen objektumot tartalmaz, sőt ezek közül sok titkosított, így gyakorlatilag másolhatatlan. Ezért azt a módszert választottuk, hogy az adatbázis szerkezetét az SAP B1 új vállalat létrehozó funkciójával készítjük el, majd az adattáblákat kiürítjük és szkripttel benyomjuk az adatokat az R2-es adatbázisból.

Első feladat annak az 1200 táblának a teljes kiürítése volt, ami az új adatbázisban megtalálható. Természetesen ezek között a legtöbb üres volt, de hogy melyik nem, azt nagyon nehéz megmondani. Több mint ezer táblát megnyitni és megnézni, hogy van-e benne adat, az legalább 200 perc, ami rengeteg idő.

Sebaj! Írjunk egy szkriptet, ami elkészíti az összes tábla törlő szkriptjét és így fél perc alatt mindent kitörölhetünk. MS SQL esetében ez a script így néz ki:
select 'truncate table ['+name+']' from sysobjects where xtype = 'U'
az eredmény:
truncate table [@BFEXT]
truncate table [@BFEXTDBVERSION]
truncate table [@BOEMAIL]
.
.
truncate table [XRXML]
Az elkészített szkripteket már csak futtatni kell és kész is az üres adatbázis!

Második lépés az adatok kimentése az R2-es adatbázisból. Szerencsére ehhez használható a Management Studio "Generate Scripts..." funkciója, amely megfelelően paraméterezve elkészíti az adatok másolásához szükséges INSERT INTO szkripteket.

Amikor ezzel is megvagyunk, már kezdünk reménykedni benne, hogy a hévégét mégis valami mással tölthetjük. De... de egy újabb problémával kell szembenéznünk: az elkészített szkript 500MB, amit nem tud betölteni a Management Studio. Mit is mond ilyenkor egy jó informatikus?

Sebaj! Biztos van valami parancssori feldolgozó, amivel be lehet tölteni a szkripteket. És tényleg, hisz mi másra szolgálna az SQLCMD.exe?! Megfelelően paraméterezve már el is kezdi a fájl betöltését:
sqlcmd -S server -d database -U user -P pass -i bemeno.sql -o log.txt
Mivel a 30 perces futás alatt még kiderült, hogy milyen felhasználói mezőket felejtettünk el létrehozni az új adatbázisban, néhányszor futtatni kellett a törlő szkripteket is, de 00:50 perckor már megjött a nap végét jelentő hír a kolléganőtől: "Működik!!! Köszi!"

Te kerültél már hasonló kutyarszorítóba, hogy amikor azt gondoltad már csak öt perc és vége az aznapi munkának, akkor egy technikai probléma miatt több órán át kellett még törni a fejed, hogy is old meg a kialakult helyzetet?
Olvasd tovább!