div. Änderngen (Barverkauf, ustva, etc.).
This commit is contained in:
181
SDL/Classes/cFiskaltrustClient.vb
Normal file
181
SDL/Classes/cFiskaltrustClient.vb
Normal file
@@ -0,0 +1,181 @@
|
||||
Imports System.Net.Http
|
||||
Imports System.Text
|
||||
Imports Newtonsoft.Json
|
||||
Imports System.Threading
|
||||
|
||||
Public Class cFiskaltrustClient
|
||||
|
||||
|
||||
Private ReadOnly _baseUrl As String
|
||||
Private ReadOnly _cashboxId As String
|
||||
Private ReadOnly _accessToken As String
|
||||
Private ReadOnly _country As String
|
||||
|
||||
Private Shared ReadOnly _httpClient As New HttpClient()
|
||||
|
||||
Public Sub New(baseUrl As String, cashboxId As String, accessToken As String, country As String)
|
||||
_baseUrl = baseUrl.TrimEnd("/"c)
|
||||
_cashboxId = cashboxId
|
||||
_accessToken = accessToken
|
||||
_country = country
|
||||
End Sub
|
||||
|
||||
' ================================
|
||||
' PUBLIC API
|
||||
' ================================
|
||||
Public Async Function SignReceiptAsync(amount As Double, vat As Double, POS As List(Of EABelegPositionen)) As Task(Of String)
|
||||
|
||||
Dim payload = BuildPayload(amount, vat, POS)
|
||||
Dim endpoint = GetEndpoint()
|
||||
|
||||
Return Await SendAsync(endpoint, payload)
|
||||
|
||||
End Function
|
||||
|
||||
' Optional: Storno Beispiel
|
||||
Public Async Function CancelReceiptAsync(reference As String) As Task(Of String)
|
||||
|
||||
Dim payload = New With {
|
||||
.ftCashBoxID = _cashboxId,
|
||||
.ftPosSystemId = "POS-1",
|
||||
.cbTerminalID = "T1",
|
||||
.cbReceiptReference = reference,
|
||||
.cbReceiptMoment = DateTime.UtcNow.ToString("o"),
|
||||
.ftReceiptCase = 4919338172267102210 ' Storno
|
||||
}
|
||||
|
||||
Return Await SendAsync(GetEndpoint(), payload)
|
||||
|
||||
End Function
|
||||
|
||||
' ================================
|
||||
' CORE HTTP LOGIC (RETRY!)
|
||||
' ================================
|
||||
Private Async Function SendAsync(endpoint As String, payload As Object) As Task(Of String)
|
||||
|
||||
Dim exToThrow As Exception = Nothing
|
||||
|
||||
Dim json As String = JsonConvert.SerializeObject(payload)
|
||||
Dim url = _baseUrl & endpoint
|
||||
|
||||
Dim retries As Integer = 3
|
||||
Dim delayMs As Integer = 500
|
||||
|
||||
For attempt = 1 To retries
|
||||
|
||||
Try
|
||||
Using request As New HttpRequestMessage(HttpMethod.Post, url)
|
||||
|
||||
request.Headers.Add("cashboxid", _cashboxId)
|
||||
request.Headers.Add("accesstoken", _accessToken)
|
||||
|
||||
request.Content = New StringContent(json, Encoding.UTF8, "application/json")
|
||||
|
||||
Dim response = Await _httpClient.SendAsync(request)
|
||||
Dim result = Await response.Content.ReadAsStringAsync()
|
||||
|
||||
' Logging Hook
|
||||
Log($"[{DateTime.Now}] Response ({response.StatusCode}): {result}")
|
||||
|
||||
If response.IsSuccessStatusCode Then
|
||||
Return result
|
||||
End If
|
||||
|
||||
' Retry only on transient errors
|
||||
If CType(response.StatusCode, Integer) >= 500 Then
|
||||
Throw New Exception("Server error: " & result)
|
||||
Else
|
||||
' Client error → no retry
|
||||
Throw New Exception("Client error: " & result)
|
||||
End If
|
||||
|
||||
End Using
|
||||
|
||||
Catch ex As Exception
|
||||
|
||||
Log($"[{DateTime.Now}] Attempt {attempt} failed: {ex.Message}")
|
||||
|
||||
If attempt = retries Then
|
||||
exToThrow = ex
|
||||
End If
|
||||
|
||||
End Try
|
||||
|
||||
If exToThrow IsNot Nothing Then
|
||||
Await Task.Delay(1000) ' ✅ jetzt OK
|
||||
Throw exToThrow
|
||||
End If
|
||||
|
||||
Next
|
||||
|
||||
Throw New Exception("Unexpected error")
|
||||
|
||||
End Function
|
||||
|
||||
' ================================
|
||||
' PAYLOAD BUILDER
|
||||
' ================================
|
||||
Private Function BuildPayload(amount As Double, vat As Double, POS As List(Of EABelegPositionen)) As Object
|
||||
|
||||
' ChargeItems Liste vorbereiten
|
||||
Dim chargeItems = New List(Of Object)
|
||||
|
||||
For Each p In POS
|
||||
chargeItems.Add(New With {
|
||||
.Quantity = p.Anzahl,
|
||||
.Amount = p.Preis,
|
||||
.VATRate = vat,
|
||||
.Description = p.LeistungsBez,
|
||||
.ftChargeItemCase = 4919338167972134929
|
||||
})
|
||||
Next
|
||||
|
||||
' Payload Objekt erstellen
|
||||
Dim payload = New With {
|
||||
.ftCashBoxID = _cashboxId,
|
||||
.ftPosSystemId = "POS-1",
|
||||
.cbTerminalID = "T1",
|
||||
.cbReceiptReference = Guid.NewGuid().ToString(),
|
||||
.cbReceiptMoment = DateTime.UtcNow.ToString("o"),
|
||||
.cbChargeItems = chargeItems,
|
||||
.cbPayItems = New Object() {
|
||||
New With {
|
||||
.Quantity = 1.0,
|
||||
.Amount = amount,
|
||||
.Description = "Cash",
|
||||
.ftPayItemCase = 4919338167972134913
|
||||
}
|
||||
},
|
||||
.ftReceiptCase = 4919338172267102209
|
||||
}
|
||||
|
||||
Return payload
|
||||
|
||||
End Function
|
||||
|
||||
' ================================
|
||||
' ENDPOINT SWITCH
|
||||
' ================================
|
||||
Private Function GetEndpoint() As String
|
||||
Select Case _country
|
||||
Case "DE"
|
||||
Return "/json/v1/Sign"
|
||||
Case "AT"
|
||||
Return "/json/Sign"
|
||||
Case Else
|
||||
Throw New Exception("Unsupported country")
|
||||
End Select
|
||||
End Function
|
||||
|
||||
' ================================
|
||||
' LOGGING (REPLACE IN PROD!)
|
||||
' ================================
|
||||
Private Sub Log(message As String)
|
||||
' 👉 Hier anschließen:
|
||||
' - Datei
|
||||
' - Datenbank
|
||||
' - Serilog / NLog
|
||||
Console.WriteLine(message)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
@@ -1,6 +1,8 @@
|
||||
Imports System.Globalization
|
||||
Imports System.Net.Http
|
||||
Imports System.Text
|
||||
Imports GrapeCity.ActiveReports
|
||||
Imports GrapeCity.DataVisualization.TypeScript
|
||||
Imports GrapeCity.DataVisualization.Options
|
||||
Imports Newtonsoft.json
|
||||
Imports SDL.RKSVServer
|
||||
Imports VERAG_PROG_ALLGEMEIN.DSFinVKService
|
||||
|
||||
@@ -89,6 +91,54 @@ Public Class cRKSV
|
||||
Return False
|
||||
End Function
|
||||
|
||||
|
||||
Shared Function insertRKSVFiskaltrust(ByVal kasse As cRKSV_Kasse, CompanyGUID As String, ByVal umsatzZaehler As Double, ByVal belegDat As DateTime, ByVal steuerSchluessel As Integer, ByVal RKSV_Beleg_Id As Integer, ByVal summeBRUTTO As Double, TEST As Boolean, POS As List(Of EABelegPositionen)) As Boolean
|
||||
Try
|
||||
|
||||
|
||||
Dim credentials As New SDL.RKSVServer.DBUserCredentials
|
||||
|
||||
credentials.Database = "RKSVWcfDB"
|
||||
credentials.Server = "AVISO\SQLEXPRESS"
|
||||
credentials.Username = "Admin"
|
||||
credentials.Password = "verag#2"
|
||||
credentials.CashboxID = kasse.rksv_FT_CashboxID
|
||||
credentials.CompanyGUID = CompanyGUID
|
||||
Dim AccessToken As String = kasse.rksv_FT_AccessToken
|
||||
|
||||
Dim jws As String = String.Empty
|
||||
Dim qr As String = String.Empty
|
||||
Dim ocra As String = String.Empty
|
||||
'Dim answer As String = String.Empty
|
||||
|
||||
Dim Belegnummer = RKSV_Beleg_Id
|
||||
Dim BelegDatumUhrzeit = belegDat ' BELEG.BelegDat
|
||||
|
||||
Dim steuersatz As Double = SQL.getValueTxtBySql("SELECT isnull(tblSteuersätze.Steuersatz,0) FROM tblSteuersätze WHERE tblSteuersätze.Nr='" & steuerSchluessel & "' ", "FMZOLL")
|
||||
|
||||
|
||||
|
||||
Dim BetragSatzNormal = IIf(steuersatz = 0.2, summeBRUTTO, 0.0) 'summe
|
||||
Dim BetragSatzErm1 = IIf(steuersatz = 0.1, summeBRUTTO, 0.0)
|
||||
Dim BetragSatzErm2 = IIf(steuersatz = 0.13, summeBRUTTO, 0.0)
|
||||
Dim BetragSatzNull = IIf(steuersatz = 0.0, summeBRUTTO, 0.0)
|
||||
Dim BetragSatzBesonders = IIf(steuersatz = 0.19, summeBRUTTO, 0.0)
|
||||
Dim StandUmsatzzaehler = umsatzZaehler 'KASSE.rksv_Umsatzzaehler
|
||||
|
||||
Dim countryID As String
|
||||
|
||||
Dim client As New cFiskaltrustClient(kasse.rksv_FT_RestServiceURL, kasse.rksv_FT_CashboxID, kasse.rksv_FT_AccessToken, kasse.rksv_FT_Country)
|
||||
|
||||
Dim result = client.SignReceiptAsync(summeBRUTTO, steuersatz, POS)
|
||||
|
||||
|
||||
Catch ex As Exception
|
||||
MsgBox("Es ist ein Fehler bei der Signatur aufgetreten (insertRKSV): " & vbNewLine & ex.Message & ex.StackTrace)
|
||||
End Try
|
||||
Return False
|
||||
End Function
|
||||
|
||||
|
||||
Shared Function getKB(BELEG As EABeleg, PERSONAL As cPersonal, ByRef KBEntry As cKassenbuch, ByRef KBEntryGB As cKassenbuch, Firma As String) As Boolean
|
||||
Dim j1 = SQL.getValueTxtBySql("SELECT [JournalNr] FROM [tblKassenbuch] " &
|
||||
" WHERE [Mandant]='" & PERSONAL.Mandant & "' AND [Niederlassung]='" & PERSONAL.Niederlassung & "' AND [Benutzer]='" & PERSONAL.ID & "' AND [Geschäftsjahr]='" & cRKSV.getGJ_FIRMA(BELEG.BelegDat, Firma) & "' AND [BelegNr] ='" & BELEG.BelegNr & "' and Steuer <=0 AND Soll <> 0", "FMZOLL")
|
||||
@@ -2354,7 +2404,7 @@ Public Class cRKSV
|
||||
End If
|
||||
|
||||
Dim Buchungstext As String = "Umb.BK / KASSA"
|
||||
if BELEG.ECZahlungsNr IsNot Nothing AndAlso BELEG.ECZahlungsNr <> "" Then
|
||||
If BELEG.ECZahlungsNr IsNot Nothing AndAlso BELEG.ECZahlungsNr <> "" Then
|
||||
Buchungstext &= " " & BELEG.ECZahlungsNr
|
||||
End If
|
||||
|
||||
@@ -2478,7 +2528,7 @@ Public Class cRKSV
|
||||
|
||||
End If
|
||||
|
||||
End Sub
|
||||
End Sub
|
||||
|
||||
Private Shared Sub getDEBDaten(ByRef Mandant As String, ByRef DebKonto As Integer, ByRef c_sprache As String, ByRef c_ustidnr As String, ByRef c_zahlziel As String, ByRef si_tage As Integer, ByRef dec_skonto As Integer, ByRef si_ntage As Integer, ByRef SkontoDatum As Date, ByRef Nettodatum As Date)
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ Public Class cRKSV_Kasse
|
||||
Property rksv_DE_apiToken As Object = Nothing
|
||||
Property rksv_DE_license As Object = Nothing
|
||||
Property rksv_StornoIncreaseBelegCnt As Object = Nothing
|
||||
Property rksv_FT_CashboxID As Object = Nothing
|
||||
Property rksv_FT_AccessToken As Object = Nothing
|
||||
Property rksv_FT_RestServiceURL As Object = Nothing
|
||||
Property rksv_FT_Country As Object = Nothing
|
||||
|
||||
|
||||
Dim SQL As New SQL
|
||||
@@ -224,6 +228,10 @@ Public Class cRKSV_Kasse
|
||||
Me.rksv_DE_apiToken = cSqlDb.checkNullReturnValue(dr.Item("rksv_DE_apiToken"), Nothing)
|
||||
Me.rksv_DE_license = cSqlDb.checkNullReturnValue(dr.Item("rksv_DE_license"), Nothing)
|
||||
Me.rksv_StornoIncreaseBelegCnt = cSqlDb.checkNullBool(dr.Item("rksv_StornoIncreaseBelegCnt"))
|
||||
Me.rksv_FT_CashboxID = cSqlDb.checkNullReturnValue(dr.Item("rksv_FT_CashboxID"), Nothing)
|
||||
Me.rksv_FT_AccessToken = cSqlDb.checkNullReturnValue(dr.Item("rksv_FT_AccessToken"), Nothing)
|
||||
Me.rksv_FT_RestServiceURL = cSqlDb.checkNullReturnValue(dr.Item("rksv_FT_RestServiceURL"), Nothing)
|
||||
Me.rksv_FT_Country = cSqlDb.checkNullReturnValue(dr.Item("rksv_FT_Country"), Nothing)
|
||||
|
||||
End If
|
||||
dr.Close()
|
||||
@@ -261,6 +269,10 @@ Public Class cRKSV_Kasse
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_DE_apiToken", rksv_DE_apiToken))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_DE_license", rksv_DE_license))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_StornoIncreaseBelegCnt", rksv_StornoIncreaseBelegCnt))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_FT_CashboxID", rksv_FT_CashboxID))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_FT_AccessToken", rksv_FT_AccessToken))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_FT_RestServiceURL", rksv_FT_RestServiceURL))
|
||||
list.Add(New VERAG_PROG_ALLGEMEIN.MyListItem2("rksv_FT_Country", rksv_FT_Country))
|
||||
|
||||
|
||||
Return list
|
||||
|
||||
Reference in New Issue
Block a user