From a2f90215e56ca256c07a7c9227352d8c5dc1256c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Thu, 21 May 2026 21:45:59 +0200 Subject: [PATCH 1/3] dodani projekti valjda kako treba :S --- .../MAES.Fiskal.Example.csproj | 10 ++++++++ MAES.Fiskal.Example/Program.cs | 1 + MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj | 25 +++++++++++++++++++ MAES.Fiskal.Tests/UnitTest1.cs | 10 ++++++++ .../MAES.Fiskal.csproj | 0 Reference.cs => MAES.Fiskal/Reference.cs | 0 .../ReferenceTypeExtensions.cs | 0 7 files changed, 46 insertions(+) create mode 100644 MAES.Fiskal.Example/MAES.Fiskal.Example.csproj create mode 100644 MAES.Fiskal.Example/Program.cs create mode 100644 MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj create mode 100644 MAES.Fiskal.Tests/UnitTest1.cs rename MAES.Fiskal.csproj => MAES.Fiskal/MAES.Fiskal.csproj (100%) rename Reference.cs => MAES.Fiskal/Reference.cs (100%) rename ReferenceTypeExtensions.cs => MAES.Fiskal/ReferenceTypeExtensions.cs (100%) diff --git a/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj b/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj new file mode 100644 index 0000000..ed9781c --- /dev/null +++ b/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/MAES.Fiskal.Example/Program.cs b/MAES.Fiskal.Example/Program.cs new file mode 100644 index 0000000..1bc52a6 --- /dev/null +++ b/MAES.Fiskal.Example/Program.cs @@ -0,0 +1 @@ +Console.WriteLine("Hello, World!"); diff --git a/MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj b/MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj new file mode 100644 index 0000000..a8c1ca7 --- /dev/null +++ b/MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj @@ -0,0 +1,25 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MAES.Fiskal.Tests/UnitTest1.cs b/MAES.Fiskal.Tests/UnitTest1.cs new file mode 100644 index 0000000..0e9c35b --- /dev/null +++ b/MAES.Fiskal.Tests/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace MAES.Fiskal.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} diff --git a/MAES.Fiskal.csproj b/MAES.Fiskal/MAES.Fiskal.csproj similarity index 100% rename from MAES.Fiskal.csproj rename to MAES.Fiskal/MAES.Fiskal.csproj diff --git a/Reference.cs b/MAES.Fiskal/Reference.cs similarity index 100% rename from Reference.cs rename to MAES.Fiskal/Reference.cs diff --git a/ReferenceTypeExtensions.cs b/MAES.Fiskal/ReferenceTypeExtensions.cs similarity index 100% rename from ReferenceTypeExtensions.cs rename to MAES.Fiskal/ReferenceTypeExtensions.cs From df8e386c2cc05d150aa12a3220577c84aaaf62b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Thu, 21 May 2026 23:14:11 +0200 Subject: [PATCH 2/3] scaffoldano sve, sad treba napravit taj cicd --- .gitignore | 2 + .vscode/launch.json | 23 ++++++ .vscode/tasks.json | 40 ++++++++++ .../MAES.Fiskal.Example.csproj | 4 + MAES.Fiskal.Example/Program.cs | 47 ++++++++++- MAES.Fiskal.Tests/FiskalTests.cs | 77 +++++++++++++++++++ MAES.Fiskal.Tests/UnitTest1.cs | 10 --- MAES.Fiskal/MAES.Fiskal.csproj | 4 +- MAES.Fiskal/Reference.cs | 2 +- README.md | 6 +- 10 files changed, 198 insertions(+), 17 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 MAES.Fiskal.Tests/FiskalTests.cs delete mode 100644 MAES.Fiskal.Tests/UnitTest1.cs diff --git a/.gitignore b/.gitignore index 0808c4a..bab20a4 100644 --- a/.gitignore +++ b/.gitignore @@ -480,3 +480,5 @@ $RECYCLE.BIN/ # Vim temporary swap files *.swp + +*.p12 \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2a7d506 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Tests", + "type": "coreclr", + "program": "${workspaceFolder}/MAES.Fiskal.Tests/bin/Debug/net10.0/MAES.Fiskal.Tests.dll", + "request": "launch", + "preLaunchTask": "Test", + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Example", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "Build Example", + "program": "${workspaceFolder}/MAES.Fiskal.Example/bin/Debug/net10.0/MAES.Fiskal.Example.exe", + "cwd": "${workspaceFolder}/MAES.Fiskal.Example", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 228dbd8..be64f7b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -45,6 +45,46 @@ ], "dependsOn": "Pack", "problemMatcher": [] + }, + { + "label": "Test", + "type": "shell", + "command": "dotnet", + "args": [ + "test", + "${workspaceFolder}/MAES.Fiskal.Tests", + "--verbosity", + "normal" + ], + "group": { + "kind": "test", + "isDefault": true + }, + "problemMatcher": "$msCompile" + }, + { + "label": "Build Example", + "type": "shell", + "command": "dotnet", + "args": [ + "build", + "${workspaceFolder}/MAES.Fiskal.Example", + "--configuration", + "Debug" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Run Example", + "type": "shell", + "command": "dotnet", + "args": [ + "run", + "--project", + "${workspaceFolder}/MAES.Fiskal.Example" + ], + "dependsOn": "Build Example", + "problemMatcher": [] } ], "inputs": [ diff --git a/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj b/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj index ed9781c..0a3a7fa 100644 --- a/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj +++ b/MAES.Fiskal.Example/MAES.Fiskal.Example.csproj @@ -7,4 +7,8 @@ enable + + + + diff --git a/MAES.Fiskal.Example/Program.cs b/MAES.Fiskal.Example/Program.cs index 1bc52a6..8cb021d 100644 --- a/MAES.Fiskal.Example/Program.cs +++ b/MAES.Fiskal.Example/Program.cs @@ -1 +1,46 @@ -Console.WriteLine("Hello, World!"); +using System.Security.Cryptography.X509Certificates; +using System.ServiceModel.Security; +using MAES.Fiskal; + +var invoice = new RacunType +{ + BrRac = new BrojRacunaType + { + BrOznRac = "1", // Invoice number (incremental for each receipt) + OznPosPr = "POSL1", // Workspace code + OznNapUr = "1" // Cash reegister number + }, + DatVrijeme = DateTime.Now.ToString("dd.MM.yyyyTHH:mm:ss"), // DateTime of invoice + IznosUkupno = "12.50", // Total amount (must be format 0.00) + NakDost = false, + Oib = "18945722090", // Identification number of company + OibOper = "18945722090", // Odentitfication numer of person operating POS + OznSlijed = OznakaSlijednostiType.N, + Pdv = [ // Taxes list + new () + { + Stopa = "25.00", // Tax percentage (must be format 0.00) + Osnovica = "10.00", // Tax base (must be format 0.00) + Iznos = "2.50" // Tax amount (must be format 0.00) + } + ], + USustPdv = true, // Does company falls under tax obligation laws + NacinPlac = NacinPlacanjaType.G // Type of payment (G - Cash, K - Cards, etc...) +}; + +// !! Disable certificate validation (for testing purposes only, do not use in production) !! +ReferenceTypeExtensions.SslCertificateAuthentification = new() +{ + CertificateValidationMode = X509CertificateValidationMode.None, + RevocationMode = X509RevocationMode.NoCheck +}; + +// Load certificate from file (ensure you have a valid .p12 in execution directory) +X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile("cert.p12", ""); + +// Send invoice to fiskalization api (ensure you have access to test api and correct url) +var res = await invoice.SendAsync(certificate, "https://cistest.apis-it.hr:8449/FiskalizacijaServiceTest"); + +// Check for errors and print JIR +if(res.Greske != null && res.Greske.Length != 0) Console.WriteLine(string.Join(", ", res.Greske.Select(g => g.PorukaGreske))); +else Console.WriteLine($"JIR: {res.Jir}"); \ No newline at end of file diff --git a/MAES.Fiskal.Tests/FiskalTests.cs b/MAES.Fiskal.Tests/FiskalTests.cs new file mode 100644 index 0000000..54bff77 --- /dev/null +++ b/MAES.Fiskal.Tests/FiskalTests.cs @@ -0,0 +1,77 @@ +namespace MAES.Fiskal.Tests; + +using System.Security.Cryptography.X509Certificates; +using System.ServiceModel.Security; + +public class FiskalTests +{ + X509Certificate2 certificate => X509CertificateLoader.LoadPkcs12FromFile("cert.p12", ""); + + string testUrl => "https://cistest.apis-it.hr:8449/FiskalizacijaServiceTest"; + + RacunType invoice = new () + { + BrRac = new BrojRacunaType + { + BrOznRac = "1", + OznPosPr = "POSL1", + OznNapUr = "1" + }, + DatVrijeme = DateTime.Now.ToString("dd.MM.yyyyTHH:mm:ss"), + IznosUkupno = "100.00", + Oib = "18945722090", + OibOper = "18945722090", + OznSlijed = OznakaSlijednostiType.N, + Pdv = [ new() { Stopa = "25.00", Osnovica = "80.00", Iznos = "20.00" } ], + USustPdv = true, + NacinPlac = NacinPlacanjaType.G + }; + + [Fact] + public void GenerateZKI() + { + var zki = invoice.ZKI(certificate); + + Assert.NotNull(zki); + Assert.NotEmpty(zki); + Assert.True(zki.Length > 20); + } + + [Fact] + public async Task SendInvoice() + { + ReferenceTypeExtensions.SslCertificateAuthentification = new() + { + CertificateValidationMode = X509CertificateValidationMode.None, + RevocationMode = X509RevocationMode.NoCheck + }; + + var response = await invoice.SendAsync(certificate, testUrl); + + Assert.NotNull(response); + Assert.NotEmpty(response.Jir); + } + + // This test cannot succeed because test api doesnt have invoices + // [Fact] + // public async Task FiscalizeInvoiceTip_WithCertificate_ShouldReturnJir() + // { + // ReferenceTypeExtensions.SslCertificateAuthentification = new() + // { + // CertificateValidationMode = X509CertificateValidationMode.None, + // RevocationMode = X509RevocationMode.NoCheck + // }; + + // var napojnicaData = new NapojnicaType + // { + // iznosNapojnice = "10.00", + // nacinPlacanjaNapojnice = NacinPlacanjaType.G + // }; + + // var response = await invoice.ToRacunNapojnicaType(napojnicaData).SendAsync(certificate, testUrl); + + // Assert.NotNull(response); + + // if(response.NapojnicaOdgovor.Greske != null && response.NapojnicaOdgovor.Greske.Length > 0) throw new Exception($"{string.Join(", ", response.NapojnicaOdgovor.Greske.Select(g => g.PorukaGreske))}"); + // } +} \ No newline at end of file diff --git a/MAES.Fiskal.Tests/UnitTest1.cs b/MAES.Fiskal.Tests/UnitTest1.cs deleted file mode 100644 index 0e9c35b..0000000 --- a/MAES.Fiskal.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MAES.Fiskal.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} diff --git a/MAES.Fiskal/MAES.Fiskal.csproj b/MAES.Fiskal/MAES.Fiskal.csproj index a30cfe8..a6c9f30 100644 --- a/MAES.Fiskal/MAES.Fiskal.csproj +++ b/MAES.Fiskal/MAES.Fiskal.csproj @@ -25,8 +25,8 @@ - - + + diff --git a/MAES.Fiskal/Reference.cs b/MAES.Fiskal/Reference.cs index 2686cc6..4cc42d6 100644 --- a/MAES.Fiskal/Reference.cs +++ b/MAES.Fiskal/Reference.cs @@ -9,7 +9,7 @@ namespace MAES.Fiskal { - + #pragma warning disable 1591 [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] [System.ServiceModel.ServiceContractAttribute(Namespace="http://www.apis-it.hr/fin/2012/services/FiskalizacijaService", ConfigurationName="MAES.Fiskal.FiskalizacijaPortType")] diff --git a/README.md b/README.md index 96cbf90..5e7ecf3 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ using MAES.Fiskal; BrRac = new BrojRacunaType { BrOznRac = "1", // Invoice number (incremental for each receipt) - OznPosPr = "POSL_1", // Workspace code + OznPosPr = "POSL1", // Workspace code OznNapUr = "1" // Cash reegister number }, DatVrijeme = DateTime.Now.ToString("dd.MM.yyyyTHH:mm:ss"), // DateTime of invoice @@ -87,9 +87,9 @@ using MAES.Fiskal; Iznos = "2.50" // Tax amount (must be format 0.00) } ], - Pnp = [], // Fill tax on spending if nececary :S + Pnp = [], // Fill tax on spending if nececary :S (if empty it this must not be present or fucking xml will start retardmaxxing) USustPdv = true, // Does company falls under tax obligation laws - NacPlac = NacinPlacanjaType.G // Type of payment (G - Cash, K - Cards, etc...) + NacinPlac = NacinPlacanjaType.G // Type of payment (G - Cash, K - Cards, etc...) }; ``` 2. Send invoice From 6ac47c0e3594e18e9bed0212e455439b575b0f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Thu, 21 May 2026 23:28:44 +0200 Subject: [PATCH 3/3] dodan dotnet-ci --- .github/workflows/dotnet-ci.yml | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/dotnet-ci.yml diff --git a/.github/workflows/dotnet-ci.yml b/.github/workflows/dotnet-ci.yml new file mode 100644 index 0000000..f8378e8 --- /dev/null +++ b/.github/workflows/dotnet-ci.yml @@ -0,0 +1,68 @@ +name: .NET CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + name: Build and test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Restore dependencies + run: dotnet restore MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj + + - name: Run tests + run: dotnet test MAES.Fiskal.Tests/MAES.Fiskal.Tests.csproj --configuration Release --no-restore + + pack-and-publish: + name: Pack and publish package + needs: test + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Restore dependencies + run: dotnet restore MAES.Fiskal/MAES.Fiskal.csproj + + - name: Determine package version + id: version + run: | + VERSION_PREFIX=$(grep -oPm1 "(?<=)[^<]+" MAES.Fiskal/MAES.Fiskal.csproj) + PACKAGE_VERSION="${VERSION_PREFIX%.*}.${GITHUB_RUN_NUMBER}" + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV + echo "Pack version: $PACKAGE_VERSION" + + - name: Pack library + run: dotnet pack MAES.Fiskal/MAES.Fiskal.csproj --configuration Release --output ./artifacts --no-restore /p:PackageVersion=${{ env.PACKAGE_VERSION }} + + - name: Publish package to NuGet + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} + run: | + dotnet nuget push "./artifacts/*.nupkg" \ + --api-key "$NUGET_API_KEY" \ + --source https://api.nuget.org/v3/index.json \ + --skip-duplicate