Primjer koda, zahvala i pitanje

Topics: COM komponenta za fiskalizaciju
Apr 4, 2013 at 5:46 PM
Edited Apr 4, 2013 at 5:47 PM
Kao prvo, zahvala timu koji stoji iza ovog projekta jer radi upravo ono što treba i to na najjednostavniji mogući način. Obzirom na moje skromno znanje i iskustvo VBA, zahvaljujući fiscalizationCOM-u uspio sam u relativno kratkom roku nadograditi svoju staru aplikaciju u Accessu na posve funkcionalnu fiskalnu blagajnu.
Obzirom da nisam u sustavu PDV-a, stvar je dosta pojednostavljena jer ne moram slati podatke o razrađenim poreznim stopama i iznosima, ali ni to nije neki problem za doraditi.

Da ne duljim, stavljam ovdje kod koji sam koristio (kostur je iz dokumentacije fiscalizationCOM-a i rasprava na ovoj stranici, samo sam ga doradio za moje potrebe).

Znači, za echo:

Public Function FiskEcho()
Dim cisInterop As New FiscalizationComInterop
Dim result1, result2
result1 = cisInterop.SendEcho("Test", 0, True)
result2 = cisInterop.SendEcho("Produkcija", 0, False)

MsgBox (result1 & " " & result2)
End Function



za prijavu poslovnog prostora:

Public Function PrijavaPP()
Dim cisInterop As New FiscalizationComInterop
Dim pProstor As New PoslovniProstorType
Dim pAdresniPodatak As New AdresniPodatakType
Dim pAdresa As New AdresaType
Dim cert
Dim ppp
Set ppp = CurrentDb.OpenRecordset("qryPPPrijava")

cisInterop.LogFileName = CurrentProject.Path + "\Log\FiskPP.log"
'Set cert = cisInterop.GetCertificateFile(CurrentProject.Path + "\Cert\fiskal 1 (demo).pfx", <password>) 'DEMO
Set cert = cisInterop.GetCertificateFile(CurrentProject.Path + "\Cert\FISKAL 1.P12", <password>) 'PRODUKCIJSKI

With pAdresa
    .Ulica = ppp.PodUlica 'MDBData.Fields(3)
    .KucniBroj = ppp.PodKBr 'MDBData.Fields(4)
    '.KucniBrojDodatak = "A" 'MDBData.Fields(5)
    .BrojPoste = ppp.PodPostaBr 'MDBData.Fields(6)
    '.Naselje = "Bla" 'MDBData.Fields(7)
    .Opcina = ppp.PodMjesto 'MDBData.Fields(8)
End With

With pAdresniPodatak
    .Item = pAdresa
    '.Item = "OstaliTipoviPP - Ostali tipovi poslovnog prostora"
End With

With pProstor
    .OIB = ppp.PodOIB 'MDBData.Fields(10)
    .OznPoslProstora = ppp.PPOznaka 'MDBData.Fields(0)
    .AdresniPodatak = pAdresniPodatak
    .RadnoVrijeme = "00-24" 'MDBData.Fields(2)
    .DatumPocetkaPrimjene = cisInterop.DateFormatShort("01.04.2013") 'MDBData.Fields(1))
    ' po shemi je tu kratki format datuma, kao da je dodatno vrijeme problem?! :)
    .SpecNamj = <OIB> 'OIB fizičke osobe koja je proizvela programsko rješenje
End With

Dim request As PoslovniProstorZahtjev
Set request = cisInterop.CreateLocationRequest(pProstor)
Call cisInterop.Sign(request, (cert)) ' nije potrebno jer se zove u SendLocationRequest ako već nije potpisan
Dim result As PoslovniProstorOdgovor
'On Error Resume Next
'Set result = cisInterop.SendLocationRequest(request, (cert), 0, True) 'DEMO
Set result = cisInterop.SendLocationRequest(request, (cert), 0, False) 'PRODUKCIJSKI

'Ubaci podatke o prijavi PP
CurrentDb.Execute "INSERT INTO tblPoslProstorPrijava (PPID, PPOdgovorID, PPRadnoVrijeme, PPDatum) VALUES ('" & ppp.PPID & "', '" & result.Id & "', '" & pProstor.RadnoVrijeme & "', '" & Now() & "');"

MsgBox (result.Id)
End Function


i na kraju za fiskalizaciju računa. Budući da nisam u sustavu PDV-a, ovo je znatno pojednostavljeno jer se ne moraju slati podaci o poreznim stopama i iznosima...

Public Function FiskRacun()
' .NET COM Interop
Dim cisInterop As New FiscalizationComInterop

' Set logging
cisInterop.LogFileName = CurrentProject.Path + "\Log\Fiscal.log"

' Demo OIB & certificate
'Dim FileNum As Long
'FileNum = FreeFile
'Close FileNum
'Open CurrentProject.Path + "\Cert\DemoCertificate.txt" For Input As FileNum
'Dim OIB
'Line Input #FileNum, OIB
'Dim certPwd
'Line Input #FileNum, certPwd
'Dim certBase64
'Line Input #FileNum, certBase64

' Get certificate from file or base64 encoded string
'Set cert = cisInterop.GetCertificateString(certBase64, certPwd)

' Certifikat iz datoteke i pass
Dim cert
'Set cert = cisInterop.GetCertificateFile(CurrentProject.Path + "\Cert\fiskal 1 (demo).pfx", <password>) 'DEMO
Set cert = cisInterop.GetCertificateFile(CurrentProject.Path + "\Cert\FISKAL 1.P12", <password>) 'PRODUKCIJSKI

'Pokupi podatke iz frmRacunFisk i ubaci u tablicu
With DoCmd
    .SetWarnings False
    .OpenQuery "qryRacunTempAP"
    .SetWarnings True
End With

'Utrpaj varijable za zahtjev za fiskalizaciju
Dim racunTemp
Set racunTemp = CurrentDb.OpenRecordset("tblRacunTemp")

' Create invoice number
Dim invoiceNr As New BrojRacunaType
With invoiceNr
    .BrOznRac = racunTemp.RacunBroj
    .OznPosPr = racunTemp.PPOznaka
    .OznNapUr = racunTemp.NUOznaka
End With

' Create Racun
Dim invoice As New RacunType
With invoice
    .OIB = racunTemp.PodOIB
    .USustPdv = IIf(racunTemp.PodUSustPDV = 0, False, True)
    .IznosUkupno = Format(Forms!frmRacunFisk!frmRacunFiskSubformArt!Ukupno, "0.00")
    .DatVrijeme = cisInterop.DateFormatLong(racunTemp.DatumRacuna)
    .OznSlijed = OznakaSlijednostiType.OznakaSlijednostiType_P
    .NacinPlac = IIf(racunTemp.NPOznaka = "G", NacinPlacanjaType.NacinPlacanjaType_G, NacinPlacanjaType.NacinPlacanjaType_T)
    .OibOper = racunTemp.BlagajnikOIB
    .NakDost = False
    .BrRac = invoiceNr
End With

' invoice.ZastKod <- filled with generated ZKI code - optional
Call cisInterop.GenerateZki(invoice, (cert))

Dim request As RacunZahtjev
Set request = cisInterop.CreateInvoiceRequest(invoice)

' Call GenerateZki and Sign request - optional
Call cisInterop.Sign(request, (cert))

' Send request
CurrentDb.Execute "UPDATE tblRacunTemp SET DatumSlanja = '" & Now() & "';"
Dim result As RacunOdgovor
'Set result = cisInterop.SendInvoiceRequest(request, (cert), 0, True) 'DEMO
Set result = cisInterop.SendInvoiceRequest(request, (cert), 0, False) 'PRODUKCIJSKI
CurrentDb.Execute "UPDATE tblRacunTemp SET DatumObrade = '" & Now() & "';"

'Ubaci ZKI i JIR u tblRacunTemp
CurrentDb.Execute "UPDATE tblRacunTemp SET tblRacunTemp.ZKI = '" & invoice.ZastKod & "', tblRacunTemp.JIR = '" & result.JIR & "';" '& _
  '  "WHERE tblRacunTemp.RacunBroj='" & invoiceNr.BrOznRac & "' AND tblRacunTemp.DatumRacuna='" & invoice.DatVrijeme & "';"

MsgBox ("ZKI: " & invoice.ZastKod & " JIR: " & result.JIR)
'Prebaci račun u žive tablice i obriši sadržaj temp tablica
With DoCmd
    .SetWarnings False
    .OpenQuery "qryRacunAP"
    .OpenQuery "qryRacunArtAP"
    .OpenQuery "qryRacunArtPorAP"
    .OpenQuery "qryRacunTempDT"
    .OpenQuery "qryRacunArtTempDT"
    .SetWarnings True
End With

End Function


Jednu stvar nisam skužio, kako mogu vidjeti sve propertyje koje se nalaze u klasama RacunOdgovor i PoslovniProstorOdgovor?

Nadao sam se za prijavu poslovnog prostora i fiskalizaciju računa da ću dobiti podatak "Datum i vrijeme obrade" kao odgovor od CIS-a, ali uspjevam izvući samo ID i JIR

Općenito, kako mogu za user-defined klase vidjeti od čega se sastoje? ObjectBrowser mi je daje nikakve informacije o tome.
Coordinator
Apr 5, 2013 at 9:00 AM
Bilo je zabavno sve napravit i to je najvažnije :)

Definicije su u XSD shemi, a to nije baš čitljivo. XSD Shema
Druga opcija je C# generirani kôd po shemi. FiskalizacijaService.cs
To su jedina dva mjesta gdje se mogu pročitati definicije objekata.

Manji je problem u razvoju na .NET-u jer source editori nude sve informacije.
Za VBA bi pomogle definicije interface-a za generirane klase, a za to bi trebalo napisat generator.
Mislio sam i napravit generator nekog helpa po wsdl-u i shemi.......

Uglavnom zasad po XSD shemi odgovori sa servisa(posl. prostor i račun)
<element name="RacunOdgovor">
    <annotation>
      <documentation>
        Odgovor servisa za zaprimanje racuna.
      </documentation>
    </annotation>
    <complexType>
      <sequence>
        <element name="Zaglavlje" type="tns:ZaglavljeOdgovorType" minOccurs="1" maxOccurs="1" />
...
imaju property Zaglavlje u kojem je DatumVrijeme i IdPoruke.
Datum je string(?!), pa bi možda pomogla neka pomoćna metoda da prebaci u DateTime.
<complexType name="ZaglavljeOdgovorType">
    <sequence>
      <element name="IdPoruke" minOccurs="1" maxOccurs="1">
        <annotation>
          <documentation>
            Odabrati:
            Version 1 (MAC address) - ne koristiti
            Version 2 (DCE Security) - bazirano vremenskoj komponenti i
            domeni
            Version 3 (MD5 hash) - osnovni podaci generirano u
            ovisnosti
            o URLu, domeni i sl.
            Version 4 (random) - ne govori
            mnogo
            Version 5 (SHA-1 hash) - preferirano umjesto V3
          </documentation>
        </annotation>
        <simpleType>
               <restriction base="string">
                    <minLength value="0"/>
                    <maxLength value="36"/>
               </restriction>
        </simpleType>
      </element>
      <element name="DatumVrijeme" type="tns:DatumVrijemeType"
        minOccurs="1" maxOccurs="1">
        <annotation>
          <documentation>
            Datum i vrijeme obrade poruke.
          </documentation>
        </annotation>
      </element>
    </sequence>
  </complexType>
Primjer:
' Send request
Dim result As RacunOdgovor
Set result = cisInterop.SendInvoiceRequest((request), (cert), 0, True)
    
MsgBox (result.Jir)

MsgBox (result.Zaglavlje.DatumVrijeme)
Pozdrav
Tomislav
Apr 6, 2013 at 2:02 AM
Super, hvala, i to radi.

ja sam pokušavao s result.DatumVrijeme jer sam u XSD shemi to vidio, ali nisam skužio da mi fali još i Zaglavlje...

Datum ću lagano konvertirati, samo se umjesto "T" između datuma i vremena ubaci " " i to onda mogu ubaciti u Date/Time polje u Accessu (podatak mi treba čisto zbog logiranja uz račun).

Pozdrav
Bruno