From fd22c1f4721a750d8bb8058e57deb8a9240bc009 Mon Sep 17 00:00:00 2001 From: William Mead Date: Wed, 1 Jul 2026 09:35:04 +0200 Subject: [PATCH] Updated Dolibarr stock movement and Dolibarr warehouse with copy logic and equality methods. Updated Common business object equality method. --- CHANGELOG.md | 8 +++ .../Core/Common/CommonBusinessObject.swift | 69 ++++++++++--------- .../Product/Stock/DolibarrStockMovement.swift | 67 +++++++++++++++--- .../Product/Stock/DolibarrWarehouse.swift | 41 +++++++++++ 4 files changed, 144 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df50b5a..5b019a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org) using the following scheme: MAJOR.MINOR.PATCH +## [0.54.0] - 2026-07-01 + +### Added +- Copy method and copying init to Dolibarr stock movement and Dolibarr warehouse + +### Changed +- Updated equality to compare all properties for Dolibarr stock movement, common business object and Dolibarr warehouse to align with hashing + ## [0.53.0] - 2026-06-29 ### Changed diff --git a/Sources/SwiftDolibarr/Models/Core/Common/CommonBusinessObject.swift b/Sources/SwiftDolibarr/Models/Core/Common/CommonBusinessObject.swift index 6122845..606cf47 100644 --- a/Sources/SwiftDolibarr/Models/Core/Common/CommonBusinessObject.swift +++ b/Sources/SwiftDolibarr/Models/Core/Common/CommonBusinessObject.swift @@ -38,7 +38,7 @@ import OSLog /// - SeeAlso: ``DolibarrBusinessObject`` /// - SeeAlso: ``CommonCommercialTransactionObject`` public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject { - + // MARK: - Properties /// Business object ID @@ -108,15 +108,15 @@ public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject { public required init(from decoder: any Decoder) throws { do { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logWithoutSignal("\(Self.self).init.decode", category: .api) - #endif +#endif let container = try decoder.container(keyedBy: CodingKeys.self) self.id = try container.decode(String.self, forKey: .id) if let status = try? container.decode(MultiType.self, forKey: .statusCode), !status.stringValue.isEmpty { self.statusCode = status.stringValue } else if let status = try? container.decode(MultiType.self, forKey: .statusCodeLegacy), - !status.stringValue.isEmpty { + !status.stringValue.isEmpty { self.statusCode = status.stringValue } else { self.statusCode = "" @@ -133,41 +133,41 @@ public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject { } self.notePublic = try container.decodeIfPresent(String.self, forKey: .notePublic) self.notePrivate = try container.decodeIfPresent(String.self, forKey: .notePrivate) - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logWithoutSignal("\(Self.self).init.decoded", category: .api) - #endif +#endif } catch let error as DecodingError { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logDecodingError(error, decodeContext: "\(Self.self).init") - #endif +#endif throw error } catch { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logErrorWithSignal(error, context: "\(Self.self).init", category: .api) - #endif +#endif throw error } } - - public init(copying source: CommonBusinessObject) { - self.id = source.id - self.statusCode = source.statusCode - self.entityId = source.entityId - self.arrayOptions = source.arrayOptions - self.notePublic = source.notePublic - self.notePrivate = source.notePrivate - } - - // MARK: - Methods - - public func copy(_ source: CommonBusinessObject) { - self.id = source.id - self.statusCode = source.statusCode - self.entityId = source.entityId - self.arrayOptions = source.arrayOptions - self.notePublic = source.notePublic - self.notePrivate = source.notePrivate - } + + public init(copying source: CommonBusinessObject) { + self.id = source.id + self.statusCode = source.statusCode + self.entityId = source.entityId + self.arrayOptions = source.arrayOptions + self.notePublic = source.notePublic + self.notePrivate = source.notePrivate + } + + // MARK: - Methods + + public func copy(_ source: CommonBusinessObject) { + self.id = source.id + self.statusCode = source.statusCode + self.entityId = source.entityId + self.arrayOptions = source.arrayOptions + self.notePublic = source.notePublic + self.notePrivate = source.notePrivate + } // MARK: - Protocol methods @@ -175,7 +175,7 @@ public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject { hasher.combine(id) hasher.combine(statusCode) hasher.combine(optional: entityId) - hasher.combine(optional: arrayOptions) + hasher.combine(optional: arrayOptions) hasher.combine(optional: notePublic) hasher.combine(optional: notePrivate) } @@ -185,13 +185,18 @@ public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject { try container.encodeIfNotEmpty(id, forKey: .id) try container.encodeIfNotEmpty(statusCode, forKey: .statusCode) try container.encodeIfPresentAndNotEmpty(entityId, forKey: .entityId) - try container.encodeIfPresent(arrayOptions, forKey: .arrayOptions) + try container.encodeIfPresent(arrayOptions, forKey: .arrayOptions) try container.encodeIfPresent(notePublic, forKey: .notePublic) try container.encodeIfPresent(notePrivate, forKey: .notePrivate) } public static func == (lhs: CommonBusinessObject, rhs: CommonBusinessObject) -> Bool { lhs.id == rhs.id + && lhs.statusCode == rhs.statusCode + && lhs.entityId == rhs.entityId + && lhs.arrayOptions == rhs.arrayOptions + && lhs.notePublic == rhs.notePublic + && lhs.notePrivate == rhs.notePrivate } } diff --git a/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrStockMovement.swift b/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrStockMovement.swift index cb82dc7..b991ce4 100644 --- a/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrStockMovement.swift +++ b/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrStockMovement.swift @@ -119,12 +119,12 @@ public final class DolibarrStockMovement: Equatable, Hashable, Codable, Dolibarr self.userAuthorId = userAuthorId self.tms = tms } - + public init(from decoder: any Decoder) throws { do { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logWithoutSignal("\(Self.self).init.decode", category: .api) - #endif +#endif let container = try decoder.container(keyedBy: CodingKeys.self) self.id = try container.decode(String.self, forKey: .id) if let dictArrayOptions = try? container.decode([String: MultiType].self, forKey: .arrayOptions) { @@ -149,22 +149,58 @@ public final class DolibarrStockMovement: Equatable, Hashable, Codable, Dolibarr self.dateModify = try container.decodeIfPresent(Int.self, forKey: .dateModify) self.userAuthorId = try container.decodeIfPresent(String.self, forKey: .userAuthorId) self.tms = try container.decodeIfPresent(Int.self, forKey: .tms) - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logWithoutSignal("\(Self.self).init.decoded", category: .api) - #endif +#endif } catch let error as DecodingError { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logDecodingError(error, decodeContext: "\(Self.self).init") - #endif +#endif throw error } catch { - #if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) +#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) || os(visionOS) Logger.logErrorWithSignal(error, context: "\(Self.self).init", category: .api) - #endif +#endif throw error } } + public init(copying source: DolibarrStockMovement) { + self.id = source.id + self.arrayOptions = source.arrayOptions + self.productId = source.productId + self.warehouseId = source.warehouseId + self.originId = source.originId + self.originType = source.originType + self.quantity = source.quantity + self.typeCode = source.typeCode + self.label = source.label + self.price = source.price + self.inventoryCode = source.inventoryCode + self.dateModify = source.dateModify + self.userAuthorId = source.userAuthorId + self.tms = source.tms + } + + // MARK: - Methods + + public func copy(_ source: DolibarrStockMovement) { + self.id = source.id + self.arrayOptions = source.arrayOptions + self.productId = source.productId + self.warehouseId = source.warehouseId + self.originId = source.originId + self.originType = source.originType + self.quantity = source.quantity + self.typeCode = source.typeCode + self.label = source.label + self.price = source.price + self.inventoryCode = source.inventoryCode + self.dateModify = source.dateModify + self.userAuthorId = source.userAuthorId + self.tms = source.tms + } + // MARK: - Protocol methods public func hash(into hasher: inout Hasher) { @@ -201,6 +237,19 @@ public final class DolibarrStockMovement: Equatable, Hashable, Codable, Dolibarr public static func == (lhs: DolibarrStockMovement, rhs: DolibarrStockMovement) -> Bool { lhs.id == rhs.id + && lhs.productId == rhs.productId + && lhs.warehouseId == rhs.warehouseId + && lhs.arrayOptions == rhs.arrayOptions + && lhs.originId == rhs.originId + && lhs.originType == rhs.originType + && lhs.quantity == rhs.quantity + && lhs.typeCode == rhs.typeCode + && lhs.label == rhs.label + && lhs.price == rhs.price + && lhs.inventoryCode == rhs.inventoryCode + && lhs.dateModify == rhs.dateModify + && lhs.userAuthorId == rhs.userAuthorId + && lhs.tms == rhs.tms } } diff --git a/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrWarehouse.swift b/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrWarehouse.swift index 4aa9bc5..5b9b210 100644 --- a/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrWarehouse.swift +++ b/Sources/SwiftDolibarr/Models/Core/Product/Stock/DolibarrWarehouse.swift @@ -148,6 +148,34 @@ public final class DolibarrWarehouse: CommonBusinessObject, Locatable { } } + public init(copying source: DolibarrWarehouse) { + self.label = source.label + self.parentId = source.parentId + self.description = source.description + self.location = source.location + self.address = source.address + self.zipCode = source.zipCode + self.city = source.city + self.countryId = source.countryId + self.phone = source.phone + super.init(copying: source) + } + + // MARK: - Methods + + public func copy(_ source: DolibarrWarehouse) { + self.label = source.label + self.parentId = source.parentId + self.description = source.description + self.location = source.location + self.address = source.address + self.zipCode = source.zipCode + self.city = source.city + self.countryId = source.countryId + self.phone = source.phone + super.copy(source) + } + // MARK: - Protocol methods override public func hash(into hasher: inout Hasher) { @@ -177,4 +205,17 @@ public final class DolibarrWarehouse: CommonBusinessObject, Locatable { try super.encode(to: encoder) } + public static func == (lhs: DolibarrWarehouse, rhs: DolibarrWarehouse) -> Bool { + lhs.label == rhs.label + && lhs.parentId == rhs.parentId + && lhs.description == rhs.description + && lhs.location == rhs.location + && lhs.address == rhs.address + && lhs.zipCode == rhs.zipCode + && lhs.city == rhs.city + && lhs.countryId == rhs.countryId + && lhs.phone == rhs.phone + && (lhs as CommonBusinessObject) == (rhs as CommonBusinessObject) + } + }