Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
69 changes: 37 additions & 32 deletions Sources/SwiftDolibarr/Models/Core/Common/CommonBusinessObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import OSLog
/// - SeeAlso: ``DolibarrBusinessObject``
/// - SeeAlso: ``CommonCommercialTransactionObject``
public class CommonBusinessObject: Equatable, Codable, DolibarrBusinessObject {

// MARK: - Properties

/// Business object ID
Expand Down Expand Up @@ -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 = ""
Expand All @@ -133,49 +133,49 @@ 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

public func hash(into hasher: inout Hasher) {
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)
}
Expand All @@ -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
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
}

}
Loading