Skip to content

Commit

Permalink
Documentation (GitHub markdown).
Browse files Browse the repository at this point in the history
  • Loading branch information
tgrospic committed Dec 9, 2015
1 parent e214eb4 commit 2c49e9a
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 0 deletions.
183 changes: 183 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Fiskalizacija API (CIS)

[![cis version][cis-version-image]][porezna-spec]
[![nuget downloads][nuget-downloads-image]][nuget-url]

.NET (C#) wrapper oko generiranog SOAP klijenta za pozivanje fiskalizacijskog servisa porezne uprave (CIS v1.2).

Sa Microsoft [Wsdl.exe][wsdl.exe] tool-om su generirane proxy klase sa strukturom po WSDL shemi koja je objavljena na stranicama porezne uprave [Tehničke specifikacije][porezna-spec] i koja je uključena u source kôd projekta.
Preko generiranog SOAP klijenta [FiskalizacijaService][fiscalization-service.cs] se rade svi SOAP pozivi prema __CIS__ servisu.

Runtime:
- .NET 3.5
- .NET 4.5 (async)

**Testirano i sa demo certifikatom [Fina okoline 2014/2015][fina-demo-2014].**

**Postoji release [.NET COM komponente][docs-com] sa primjerima za __VBA__, __VBScript__ i __Access__**.

## Cilj projekta

* __uključiti source kôd u postojeći projekt__ umjesto referenciranja third party dll-a,
naravno dostupan i kao [NuGet][nuget-url] package
* jednostavan upgrade u slučaju promjene sheme CIS servisa uz __compile-time check__
* svaki poziv servisa treba automatski odraditi __generiranje ZKI kôda i potpisivanje__, isto tako i __provjeru potpisa CIS odgovora__, ali imati i opcije
`Sign(ICisRequest, X509Certificate2)` i `GenerateZki(RacunType, X509Certificate2)`
* sve __greške__ koje šalje CIS servis pretvoriti u __Exception__-e, unificirati logiranje i imati pregled svih grešaka na jednak način
* ne parsirati raw SOAP poruke, a istovremeno omogućiti potpisivanje i __logiranje raw poruka__

## Instalacija

Kako najjednostavnije uključiti __kôd__ u svoj projekt?!

#### NuGet

Instalacijom [NuGet][nuget-url] package-a kreira se _Cis_ folder u projektu sa source kôdom.

```
PM> Install-Package Cis.Fiscalization
```

[![Nuget screenshot][nuget-screenshot]][nuget-url]

#### Copy

Dovoljno je iskopirati [FiskalizacijaService.cs][fiscalization-service.cs], [Fiscalization.cs][fiscalization.cs] i/ili [Fiscalization.Async.cs][fiscalization-async.cs] (.NET 4.5).

## API

Sastoji od dvije glavne metode (u dva okusa __async__ i sync) za slanje podataka na servis
```cs
public static class Fiscalization
{
// Async .NET 4.5 :: Fiscalization.Async.cs
Task<RacunOdgovor> SendInvoiceAsync(RacunType invoice, X509Certificate2 cert);
Task<PoslovniProstorOdgovor> SendLocationAsync(PoslovniProstorType location, X509Certificate2 cert);

// Sync :: Fiscalization.cs
RacunOdgovor SendInvoice(RacunType invoice, X509Certificate2 cert);
PoslovniProstorOdgovor SendLocation(PoslovniProstorType location, X509Certificate2 cert);
}
```

Svaka metoda još opcionalno prima funkciju `Action<FiskalizacijaService>` za postavljanje
parametara generiranoj proxy klasi __FiskalizacijaService__ (npr. url, timeout...).

Za _RacunType, RacunOdgovor, PoslovniProstorType, PoslovniProstorOdgovor_ i ostale generirane proxy klase vidi source [FiskalizacijaService.cs][fiscalization-service.cs].

Primjer poziva servisa za slanje računa
```cs
// Kreiranje računa za za fiskalizaciju
var invoice = new RacunType()
{
BrRac = new BrojRacunaType()
{
BrOznRac = "1",
OznPosPr = "1",
OznNapUr = "1"
},
DatVrijeme = DateTime.Now.ToString(Fiscalization.DATE_FORMAT_LONG),
IznosUkupno = 3.ToString("N2", CultureInfo.InvariantCulture),
NacinPlac = NacinPlacanjaType.G,
NakDost = false,
Oib = oib,
OibOper = "98642375382",
OznSlijed = OznakaSlijednostiType.N,
Pdv = new[]
{
new PorezType
{
Stopa = 25.ToString("N2", CultureInfo.InvariantCulture),
Osnovica = 2.34.ToString("N2", CultureInfo.InvariantCulture),
Iznos = 0.59.ToString("N2", CultureInfo.InvariantCulture),
}
},
USustPdv = true
};

X509Certificate2 certificate = ...;

// Generiraj ZKI, potpiši, pošalji račun i provjeri potpis CIS odgovora
RacunOdgovor response = await Fiscalization.SendInvoiceAsync(invoice, certificate);

// Odgovor sa JIR-om i zahtjevom (sa header podacima, potpisom) i poslanim računom
string jir = response.Jir;
RacunZahtjev request = (RacunZahtjev)response.Request; // ICisRequest
var isTrue = request.Racun == invoice;

// ili dodatno sa postavljanjem opcija
// fs == instanca generirane proxy klase FiskalizacijaService
RacunOdgovor response = await Fiscalization.SendInvoiceAsync(invoice, certificate, fs =>
{
// SOAP service settings
// Change service URL
// default = Fiscalization.SERVICE_URL_PRODUCTION
fs.Url = Fiscalization.SERVICE_URL_DEMO;

// Set request timeout in miliseconds
// default = 100s
fs.Timeout = 2000;

// Set response signature checking
// default = true
fs.CheckResponseSignature = true;
});
```

## Logiranje raw SOAP poruka

Logiranje se radi preko implementacije partial metode na __FiskalizacijaService__ klasi.
Par linija kôda govori 1000 riječi - __odlazna i dolazna SOAP poruka kao XmlDocument__.

Ovako bi mogao izgledati trace ili file logger
```cs
// MyCisLogger.cs
// Implementacija mora biti u projektu gdje i Cis.FiskalizacijaService klasa
namespace Cis
{
public partial class FiskalizacijaService
{
partial void LogResponseRaw(XmlDocument request, XmlDocument response)
{
// Trace logger
Trace.WriteLine(request.OuterXml);
Trace.WriteLine(response.OuterXml);

// File logger
File.AppendAllText(logFileName, request.OuterXml, Encoding.UTF8);
File.AppendAllText(logFileName, response.OuterXml, Encoding.UTF8);
}
}
}
```

## Testiranje

U [test][test-dir] projektu je [TestEnvironment][test-environment.cs] klasa koja
učitava demo certifikat koji nije uključen u projekt; moguće je
- specificirati OIB, putanju do certifikata (.pfx), lozinku i/ili
- kreirati _DemoCertificate.txt_ sa linijama
- demo OIB poslovnog subjekta
- lozinka certifikata
- certifikat poslovnog subjekta kao _base64_ enkodirani string

## License

[The MIT License (MIT)][license]

[docs-com]: ./docs/fiscalization-com.md
[docs-com-api]: ./docs/fiscalization-com-api.md
[cis-version-image]: ./docs/cis-service-version.svg
[fiscalization.cs]: ./src/Fiscalization/Cis/Fiscalization.cs
[fiscalization-async.cs]: ./src/Fiscalization/Cis/Fiscalization.Async.cs
[fiscalization-service.cs]: ./src/Fiscalization/Cis/FiskalizacijaService.cs
[test-dir]: ./test/Fiscalization
[test-environment.cs]: ./test/Fiscalization/TestEnvironment.cs
[license]: ./LICENSE

[wsdl.exe]: https://msdn.microsoft.com/en-us/library/7h3ystb6(VS.80).aspx
[porezna-spec]: http://www.porezna-uprava.hr/HR_Fiskalizacija/Stranice/Tehni%C4%8Dke-specifikacije.aspx
[nuget-url]: http://nuget.org/packages/Cis.Fiscalization
[nuget-downloads-image]: https://img.shields.io/nuget/dt/Cis.Fiscalization.svg
[nuget-screenshot]: ./docs/nuget_screenshot.png
[fina-demo-2014]: http://www.fina.hr/Default.aspx?sec=1730
20 changes: 20 additions & 0 deletions docs/cis-service-version.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 72 additions & 0 deletions docs/fiscalization-com-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# COM API specifikacija

Ovdje je cijeli COM API zajedno sa helper metodama i field-ovima. Za strukturu generiranih proxy objekata (_RacunType, RacunZahtjev, RacunOdgovor, PoslovniProstorType_, ...) vidi source [FiskalizacijaService.cs][fiscalization-service.cs] ili WSDL shemu.

## FiscalizationComInterop
```vb
' Slanje računa
RacunOdgovor SendInvoice(RacunType, (X509Certificate2), timeout/ms: Int, isDemo: Bool, check_response_signature: Bool)
RacunOdgovor SendInvoiceRequest(RacunZahtjev, (X509Certificate2), timeout/ms: Int, isDemo: Bool, check_response_signature: Bool)

' Slanje poslovnog prostora
PoslovniProstorOdgovor SendLocation(PoslovniProstorType, (X509Certificate2), timeout/ms: Int, isDemo: Bool, check_response_signature: Bool)
PoslovniProstorOdgovor SendLocationRequest(PoslovniProstorZahtjev, (X509Certificate2), timeout/ms: Int, isDemo: Bool, check_response_signature: Bool)

' Echo
String SendEcho(String, timeout/ms: Int, isDemo: Bool)
```

#### Pomoćne metode
```vb
' Generiranje ZKI kôda na računu
GenerateZki(RacunType, (X509Certificate2))

' Kreiranje zahtjeva za račun (ako se koristi SendInvoiceRequest)
RacunZahtjev CreateInvoiceRequest(RacunType)

' Kreiranje zahtjeva za popslovni prostor (ako se koristi SendLocationRequest)
PoslovniProstorZahtjev CreateLocationRequest(PoslovniProstorType)

' Potpisivanje zatjeva (RacunZahtjev ili PoslovniProstorZahtjev)
Sign(zahtjev: ICisRequest, (X509Certificate2))

' Formatiranje datuma u string
' CIS servis sve datume prima kao string - čija je to pametna ideja?!
' isto vrijedi i za brojčane vrijednosti??!!
String DateFormatLong(DateTime)
String DateFormatShort(DateTime)

' Dohvat certifikata i export certifikata
X509Certificate2 GetCertificateRaw(rawCert: byte[], password: String)
X509Certificate2 GetCertificateString(base64Encoded: String, password: String)
X509Certificate2 GetCertificateFile(fileName: String, password: String)
String ExportCertificate(fileName: String, password: String, exportPassword: String)
```

#### Enumeracije su mapirane kao field-ovi
```vb
' Oznaka slijednosti
OznakaSlijednostiType_N
OznakaSlijednostiType_P

' Način plaćanja
NacinPlacanjaType_C
NacinPlacanjaType_G
NacinPlacanjaType_K
NacinPlacanjaType_O
NacinPlacanjaType_T

' Oznaka zatvaranja
OznakaZatvaranjaType_Z
```

#### VBScript - pomoćne metode za konverziju Variant() array-a
Potrebno za popunjavanje poreza na računu
```vb
PorezType[] ToPorezTypeArray(object[] variantArray)
PorezOstaloType[] ToPorezOstaloTypeArray(object[] variantArray)
NaknadaType[] ToNaknadaTypeArray(object[] variantArray)
```

[fiscalization-service.cs]: ../src/Fiscalization/Cis/FiskalizacijaService.cs

Loading

0 comments on commit 2c49e9a

Please sign in to comment.