diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..48c0133 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "javapi4swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/bastie/JavApi4Swift.git", + "state" : { + "revision" : "e899d8d6c8a728aacff85c01368ee861312d5280", + "version" : "0.7.3" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift index adb2d66..bbee440 100644 --- a/Package.swift +++ b/Package.swift @@ -13,6 +13,12 @@ let package = Package( targets: ["LStXML2Code"]), .executable(name: "BMF2Code", targets: ["BMF2Code"]) ], + dependencies: [ + .package( + url: "https://github.com/bastie/JavApi4Swift.git", + from: "0.7.3" + ) + ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. @@ -20,7 +26,9 @@ let package = Package( name: "LStXML2Code"), .testTarget( name: "LStXML2CodeTests", - dependencies: ["LStXML2Code"]), + dependencies: ["LStXML2Code", + .product(name: "JavApi", package: "JavApi4Swift") + ]), .executableTarget( name: "BMF2Code", dependencies: ["LStXML2Code"]), diff --git a/Sources/BMF2Code/BMF2Code.swift b/Sources/BMF2Code/BMF2Code.swift index e7ba2ad..a8ec59e 100644 --- a/Sources/BMF2Code/BMF2Code.swift +++ b/Sources/BMF2Code/BMF2Code.swift @@ -6,12 +6,14 @@ import Foundation import LStXML2Code @main +/// Quelletxtgenerator zur Nutzung des durch das BMF bereitgestellten Pseudo-Quelltext zur Berechnung der Lohnsteuerabzüge bei der Einkommensteuer. public struct BMF2Code { - - public static let VERSION = "0.2.1" + /// Interne Version + public static let VERSION = "1.0.0" // MARK: main entry point + /// Einsprungspunkt der Kommandozeilenanwendung static func main () { var cmdLineArgs = CommandLine.arguments #if DEBUG @@ -78,6 +80,11 @@ public struct BMF2Code { // MARK: handling argument // handwritten parameter evaluation + /// Evaluierung der Parameter + /// - Parameters: + /// - Parameter arguments die Argumente to verarbeitet werden sollen + /// - Parameter reversedCall Information, ob die Funktion sich selbst aufgerufen hat + /// - Returns lediglich die benötigten Parameter zur weiteren Verarbeitung func evalArgs (arguments : [String], reversedCall : Bool = false) -> [String:String] { let supportedLang = ["java", "swift"] let supportedLanguages = "\(supportedLang)".replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "\"", with: "") diff --git a/Sources/BMF2Code/JavaEncoding.swift b/Sources/BMF2Code/JavaEncoding.swift index 25256aa..adac466 100644 --- a/Sources/BMF2Code/JavaEncoding.swift +++ b/Sources/BMF2Code/JavaEncoding.swift @@ -5,6 +5,11 @@ import LStXML2Code import Foundation + +/// Java8 Encoding +/// +/// Das ``JavaEncoding`` nutzt den durch das [ITZBund](https://www.itzbund.de) verwendete +/// Java8 Quelltext in den exec Anweisungen. open class JavaEncoding : AbstractTreeEncoding { public func encode(_ value: AbstractTree) throws -> Data? { @@ -25,6 +30,9 @@ open class JavaEncoding : AbstractTreeEncoding { var result = "" var intend = 0 + + /// Durchlaufen des Baumes zur Quelltextgenerierung + /// - Parameter node der aktuell zu betrachtende Baumknoten open func traverse (node : Node) { var output = "" for _ in 0.. Data? { @@ -13,17 +17,21 @@ open class SwiftEncoding : AbstractTreeEncoding { /// Generated with BMF2Code v\(BMF2Code.VERSION) @\(Date()) import Foundation + import JavApi + + public typealias BigDecimal = java.math.BigDecimal + """) traverse(node: root) - result.append (getAdditionalTypes()) + // not good but work - modify source after generation // add initalizer let parts = result.split(separator: "{",maxSplits: 1) result = "\(parts[0]) {\n\n" result.append(" public init (\n") - for (offset,name) in inputVars.keys.enumerated() { + for (offset,name) in Array(inputVars.keys).sorted(by: {$0 < $1}).enumerated() { result.append(" ") let type = inputVars[name]! result.append("\(name) : \(type) = \(type)()") @@ -40,7 +48,6 @@ open class SwiftEncoding : AbstractTreeEncoding { result.append("}") result.append("\n\(parts[1])") - let asString = result //"\(value.getRoot())" return asString.data(using: .utf8) } @@ -311,118 +318,4 @@ open class SwiftEncoding : AbstractTreeEncoding { } return swiftType } - - public func getAdditionalTypes() -> String { - var result = "" - // MARK: additional Type BigInteger - result.append( - """ - - /// BigDecimal implementation in Swift - see JavApi⁴Swift project - public struct BigDecimal : CustomStringConvertible { - - private var scale : Int = Int.max - private var roundingMode : Int = ROUND_UNSET - - public static let ZERO = BigDecimal(0.0) - public static let ONE = BigDecimal(1.0) - public static let ROUND_UP = 0 - public static let ROUND_DOWN = 1 - public static let ROUND_UNSET = -1 - - private var value : Double - public init (_ newValue : Double = 0.0) { - self.value = newValue - } - public init (_ newValue : Int) { - self.value = Double(newValue) - } - public init (_ newValue : Int64) { - self.value = Double(newValue) - } - - public static func valueOf (_ newValue : Int) -> BigDecimal { - return BigDecimal(newValue) - } - public static func valueOf (_ newValue : Int64) -> BigDecimal { - return BigDecimal(newValue) - } - public static func valueOf (_ newValue : Double) -> BigDecimal { - return BigDecimal(newValue) - } - - public func subtract (_ bd : BigDecimal) -> BigDecimal { - let value : Double = self.value - bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - - public func multiply (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value * bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func divide (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value / bd.value - var result = BigDecimal(value) - result.scale = max(self.scale,bd.scale) - result.roundingMode = self.roundingMode - return result - } - public func divide (_ bd : BigDecimal, _ accuracy : Int, _ round : Int) -> BigDecimal{ - let value : Double = self.value / bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func add (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value + bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func setScale (_ newScale : Int, _ roundingMode : Int = BigDecimal.ROUND_UNSET) -> BigDecimal { - var result = BigDecimal(self.value) - result.scale = newScale - result.roundingMode = roundingMode - return result - } - - public func compareTo (_ bg : BigDecimal) -> Int { - if self.roundingMode == BigDecimal.ROUND_UNSET && bg.roundingMode == BigDecimal.ROUND_UNSET { - if self.value == bg.value {return 0} - if self.value > bg.value {return 1} - return -1 - } - let newScale = max (self.scale, bg.scale) - let factor : Int = (pow (10,newScale) as NSDecimalNumber).intValue - let quotiend : Double = Double(factor) - - let roundedSelf = Int (Double(Int(self.value * quotiend)) / quotiend) - let roundedBg = Int (Double(Int(bg.value * quotiend)) / quotiend) - - if roundedSelf == roundedBg {return 0} - if roundedSelf > roundedBg {return 1} - return -1 - } - - public func longValue () -> Int64 { - return Int64(self.value) - } - } - """) - - - // ---------------- - return result - } - } - - diff --git a/Sources/LStXML2Code/LStXML2Code.docc/Architecture.md b/Sources/LStXML2Code/LStXML2Code.docc/Architecture.md index ac59e21..c715b0d 100644 --- a/Sources/LStXML2Code/LStXML2Code.docc/Architecture.md +++ b/Sources/LStXML2Code/LStXML2Code.docc/Architecture.md @@ -8,9 +8,9 @@ Die Architektur ist darauf ausgelegt die unterliegende XML Struktur der eingeles ### Überführen des XML in eine Struktur -Swift unterstützt mit dem Protokoll `Codable` das (nicht ganz so) einfache Serialisieren und Deserialisieren von mehr oder weniger komplexen Strukturen. Da das Eingabeformat ein valides XML Dokument ist nutzen wir zum Einlesen statt einem `Decoder` den SAX-Parser ``PAPXmlParser``. +Swift unterstützt mit dem Protokoll `Codable` das (nicht ganz so) einfache Serialisieren und Deserialisieren von mehr oder weniger komplexen Strukturen. Da das Eingabeformat ein valides XML Dokument ist nutzen wir zum Einlesen statt einem `Decoder` den SAX-Parser `PAPXmlParser`. -Aufgabe des ``PAPXmlParser`` ist es die XML Struktur in eine Baumstruktur zu überführen, den ``PAPTree``. Der ``PAPTree`` ist als interne IO-Struktur nach außen nicht sichtbar sondern wird über die Transformation in den ``AbstractTree`` überführt. Der ``PAPTree`` implemetiert hierfür das Protokoll `Encodable`. Dies geschieht über die Implementation der Schnittstelle `Encodable` in ``AbstractTreeEncoder``, welche jedoch die eigentlich Aufgabe in die Implementierung ``AbstractTreeEncoding`` delegiert. +Aufgabe des `PAPXmlParser` ist es die XML Struktur in eine Baumstruktur zu überführen, den ``PAPTree``. Der ``PAPTree`` ist als interne IO-Struktur nach außen nicht sichtbar sondern wird über die Transformation in den ``AbstractTree`` überführt. Der ``PAPTree`` implemetiert hierfür das Protokoll `Encodable`. Dies geschieht über die Implementation der Schnittstelle `Encodable` in ``AbstractTreeEncoder``, welche jedoch die eigentlich Aufgabe in die Implementierung ``AbstractTreeEncoding`` delegiert. **Nur die ``AbstractTreeEncoding`` Implementation bedarf einer Anpassung, bei nicht strukturellen Änderungen dess XML.** diff --git a/Tests/LStXML2CodeTests/LStXML2CodeTests.swift b/Tests/LStXML2CodeTests/LStXML2CodeTests.swift index c04f29f..9ad83ce 100644 --- a/Tests/LStXML2CodeTests/LStXML2CodeTests.swift +++ b/Tests/LStXML2CodeTests/LStXML2CodeTests.swift @@ -1,10 +1,13 @@ import XCTest @testable import LStXML2Code +import JavApi + final class LStXML2CodeTests: XCTestCase { func testExample() throws { - let calculator = Lohnsteuer2023AbJuliBig(LZZ: 1, STKL : 1, RE4:BigDecimal(2500000)) + let calculator = Lohnsteuer2023AbJuliBig(LZZ: 1,RE4: java.math.BigDecimal(2500000),STKL: 1) calculator.MAIN() + /* print ( """ BK = \(calculator.BK) @@ -25,6 +28,27 @@ final class LStXML2CodeTests: XCTestCase { WVFRBO = \(calculator.WVFRBO) WVFRBM = \(calculator.WVFRBM) """) + */ + + // must be set + XCTAssertEqual(calculator.VFRB, 123000) + XCTAssertEqual(calculator.LSTLZZ, 176700) + XCTAssertEqual(calculator.WVFRB, 834700) + // must be zero + XCTAssertEqual(calculator.BK, 0) + XCTAssertEqual(calculator.BKS, 0) + XCTAssertEqual(calculator.BKV, 0) + XCTAssertEqual(calculator.SOLZLZZ, 0) + XCTAssertEqual(calculator.SOLZS, 0) + XCTAssertEqual(calculator.SOLZV, 0) + XCTAssertEqual(calculator.STS, 0) + XCTAssertEqual(calculator.STV, 0) + XCTAssertEqual(calculator.VKVLZZ, 0) + XCTAssertEqual(calculator.VKVSONST, 0) + XCTAssertEqual(calculator.VFRBS1, 0) + XCTAssertEqual(calculator.VFRBS2, 0) + XCTAssertEqual(calculator.WVFRBO, 0) + XCTAssertEqual(calculator.WVFRBM, 0) } } diff --git a/Tests/LStXML2CodeTests/Lohnsteuer2023AbJuliBig.swift b/Tests/LStXML2CodeTests/Lohnsteuer2023AbJuliBig.swift index a9a2b6f..192fe2d 100644 --- a/Tests/LStXML2CodeTests/Lohnsteuer2023AbJuliBig.swift +++ b/Tests/LStXML2CodeTests/Lohnsteuer2023AbJuliBig.swift @@ -1,79 +1,83 @@ -/// Generated with BMF2Code v0.2.1 @2023-12-07 16:10:06 +0000 +/// Generated with BMF2Code v1.0.0 @2023-12-10 12:27:59 +0000 import Foundation +import JavApi + +public typealias BigDecimal = java.math.BigDecimal + public class Lohnsteuer2023AbJuliBig { public init ( - VMT : BigDecimal = BigDecimal(), - ZKF : BigDecimal = BigDecimal(), - PVZ : Int = Int(), - ZMVB : Int = Int(), - VBEZ : BigDecimal = BigDecimal(), - LZZ : Int = Int(), - STKL : Int = Int(), - SONSTENT : BigDecimal = BigDecimal(), + AJAHR : Int = Int(), + ALTER1 : Int = Int(), + ENTSCH : BigDecimal = BigDecimal(), JFREIB : BigDecimal = BigDecimal(), - PKPV : BigDecimal = BigDecimal(), - RE4 : BigDecimal = BigDecimal(), - PKV : Int = Int(), JHINZU : BigDecimal = BigDecimal(), - KVZ : BigDecimal = BigDecimal(), - SONSTB : BigDecimal = BigDecimal(), - ENTSCH : BigDecimal = BigDecimal(), - R : Int = Int(), - JVBEZ : BigDecimal = BigDecimal(), - VBS : BigDecimal = BigDecimal(), JRE4 : BigDecimal = BigDecimal(), - af : Int = Int(), - LZZFREIB : BigDecimal = BigDecimal(), - MBV : BigDecimal = BigDecimal(), JRE4ENT : BigDecimal = BigDecimal(), - AJAHR : Int = Int(), - VKAPA : BigDecimal = BigDecimal(), - VBEZS : BigDecimal = BigDecimal(), - STERBE : BigDecimal = BigDecimal(), - f : Double = Double(), - ALTER1 : Int = Int(), + JVBEZ : BigDecimal = BigDecimal(), KRV : Int = Int(), + KVZ : BigDecimal = BigDecimal(), + LZZ : Int = Int(), + LZZFREIB : BigDecimal = BigDecimal(), LZZHINZU : BigDecimal = BigDecimal(), - VBEZM : BigDecimal = BigDecimal(), + MBV : BigDecimal = BigDecimal(), + PKPV : BigDecimal = BigDecimal(), + PKV : Int = Int(), PVS : Int = Int(), - VJAHR : Int = Int()) { - self.VMT = VMT - self.ZKF = ZKF - self.PVZ = PVZ + PVZ : Int = Int(), + R : Int = Int(), + RE4 : BigDecimal = BigDecimal(), + SONSTB : BigDecimal = BigDecimal(), + SONSTENT : BigDecimal = BigDecimal(), + STERBE : BigDecimal = BigDecimal(), + STKL : Int = Int(), + VBEZ : BigDecimal = BigDecimal(), + VBEZM : BigDecimal = BigDecimal(), + VBEZS : BigDecimal = BigDecimal(), + VBS : BigDecimal = BigDecimal(), + VJAHR : Int = Int(), + VKAPA : BigDecimal = BigDecimal(), + VMT : BigDecimal = BigDecimal(), + ZKF : BigDecimal = BigDecimal(), + ZMVB : Int = Int(), + af : Int = Int(), + f : Double = Double()) { + self.R = R self.ZMVB = ZMVB - self.VBEZ = VBEZ - self.LZZ = LZZ - self.STKL = STKL - self.SONSTENT = SONSTENT - self.JFREIB = JFREIB - self.PKPV = PKPV - self.RE4 = RE4 - self.PKV = PKV + self.LZZHINZU = LZZHINZU + self.PVZ = PVZ self.JHINZU = JHINZU - self.KVZ = KVZ - self.SONSTB = SONSTB + self.LZZ = LZZ self.ENTSCH = ENTSCH - self.R = R - self.JVBEZ = JVBEZ + self.VBEZS = VBEZS self.VBS = VBS - self.JRE4 = JRE4 - self.af = af - self.LZZFREIB = LZZFREIB - self.MBV = MBV self.JRE4ENT = JRE4ENT self.AJAHR = AJAHR - self.VKAPA = VKAPA - self.VBEZS = VBEZS - self.STERBE = STERBE self.f = f + self.af = af + self.PVS = PVS + self.VBEZ = VBEZ self.ALTER1 = ALTER1 - self.KRV = KRV - self.LZZHINZU = LZZHINZU + self.LZZFREIB = LZZFREIB + self.JVBEZ = JVBEZ + self.JRE4 = JRE4 + self.RE4 = RE4 + self.SONSTB = SONSTB + self.STKL = STKL + self.PKV = PKV + self.VMT = VMT + self.STERBE = STERBE self.VBEZM = VBEZM - self.PVS = PVS + self.ZKF = ZKF + self.SONSTENT = SONSTENT self.VJAHR = VJAHR + self.JFREIB = JFREIB + self.MBV = MBV + self.KVZ = KVZ + self.KRV = KRV + self.PKPV = PKPV + self.VKAPA = VKAPA } // MARK: Variables @@ -1214,116 +1218,3 @@ public class Lohnsteuer2023AbJuliBig { ST = ST.multiply (BigDecimal.valueOf (KZTAB)) } // method UPTAB23 } // type Lohnsteuer2023AbJuliBig - -/// BigDecimal implementation in Swift - see JavApi⁴Swift project -public struct BigDecimal : CustomStringConvertible { - public var description: String { - get { - if self.roundingMode == BigDecimal.ROUND_UNSET { - return "\(self.value)" - } - let factor : Int = (pow (10,scale) as NSDecimalNumber).intValue - let quotiend : Double = Double(factor) - - let roundedSelf = Int (Double(Int(self.value * quotiend)) / quotiend) - - return "\(roundedSelf)" - } - } - - - private var scale : Int = Int.max - private var roundingMode : Int = ROUND_UNSET - - public static let ZERO = BigDecimal(0.0) - public static let ONE = BigDecimal(1.0) - public static let ROUND_UP = 0 - public static let ROUND_DOWN = 1 - public static let ROUND_UNSET = -1 - - private var value : Double - public init (_ newValue : Double = 0.0) { - self.value = newValue - } - public init (_ newValue : Int) { - self.value = Double(newValue) - } - public init (_ newValue : Int64) { - self.value = Double(newValue) - } - - public static func valueOf (_ newValue : Int) -> BigDecimal { - return BigDecimal(newValue) - } - public static func valueOf (_ newValue : Int64) -> BigDecimal { - return BigDecimal(newValue) - } - public static func valueOf (_ newValue : Double) -> BigDecimal { - return BigDecimal(newValue) - } - - public func subtract (_ bd : BigDecimal) -> BigDecimal { - let value : Double = self.value - bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - - public func multiply (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value * bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func divide (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value / bd.value - var result = BigDecimal(value) - result.scale = max(self.scale,bd.scale) - result.roundingMode = self.roundingMode - return result - } - public func divide (_ bd : BigDecimal, _ accuracy : Int, _ round : Int) -> BigDecimal{ - let value : Double = self.value / bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func add (_ bd : BigDecimal) -> BigDecimal{ - let value : Double = self.value + bd.value - var result = BigDecimal(value) - result.scale = self.scale - result.roundingMode = self.roundingMode - return result - } - public func setScale (_ newScale : Int, _ roundingMode : Int = BigDecimal.ROUND_UNSET) -> BigDecimal { - var result = BigDecimal(self.value) - result.scale = newScale - result.roundingMode = roundingMode - return result - } - - public func compareTo (_ bg : BigDecimal) -> Int { - if self.roundingMode == BigDecimal.ROUND_UNSET && bg.roundingMode == BigDecimal.ROUND_UNSET { - if self.value == bg.value {return 0} - if self.value > bg.value {return 1} - return -1 - } - let newScale = max (self.scale, bg.scale) - let factor : Int = (pow (10,newScale) as NSDecimalNumber).intValue - let quotiend : Double = Double(factor) - - let roundedSelf = Int (Double(Int(self.value * quotiend)) / quotiend) - let roundedBg = Int (Double(Int(bg.value * quotiend)) / quotiend) - - if roundedSelf == roundedBg {return 0} - if roundedSelf > roundedBg {return 1} - return -1 - } - - public func longValue () -> Int64 { - return Int64(self.value) - } -} diff --git a/Tests/LStXML2CodeTests/xml/Lohnsteuer2023AbJuli.xml b/Tests/LStXML2CodeTests/xml/Lohnsteuer2023AbJuli.xml index fb65f3b..d9ad918 100644 --- a/Tests/LStXML2CodeTests/xml/Lohnsteuer2023AbJuli.xml +++ b/Tests/LStXML2CodeTests/xml/Lohnsteuer2023AbJuli.xml @@ -1,4 +1,4 @@ - + @@ -1617,4 +1617,4 @@ - \ No newline at end of file +