App: Zweiteinheit erfassen und anzeigen
Eigener Abschnitt im Artikel mit "Menge [Stk] entspricht [Gramm] das sind
[250]" und der ausgerechneten Kontrolle in der Fusszeile. Nur Charge-Artikel,
und nur die anderen Arten stehen zur Wahl - eine Bruecke auf die eigene Art
haette nichts umzurechnen.
ProductUpdateRequest bekommt sendSecondary nach dem Vorbild von sendMinStock:
ein PATCH aus einer anderen Maske soll die Bruecke nicht unbeabsichtigt
loeschen. Die Einheitenauswahl beim Ein- und Auslagern nimmt bei hinterlegter
Bruecke die Gegenart mit auf, der Bestand steht in beiden Lesarten
("6 Stueck · 500 g").
Alle neuen Product-Felder sind Optionals, damit die App auch gegen einen
aelteren Server laeuft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,14 @@ struct Product: Codable, Identifiable, Hashable {
|
||||
let baseUnit: String
|
||||
let packageSize: Double?
|
||||
let packageLabel: String?
|
||||
/// Zweiteinheit: „secondaryCount Basiseinheiten ≙ secondaryAmount
|
||||
/// secondaryBase". Bruecke zwischen den sonst strikt getrennten Arten.
|
||||
/// Optionals, damit die App auch gegen einen aelteren Server laeuft.
|
||||
let secondaryBase: String?
|
||||
let secondaryCount: Double?
|
||||
let secondaryAmount: Double?
|
||||
/// Vom Server ausgerechnet: Zweit-Basiseinheiten je EINER Basiseinheit.
|
||||
let secondaryFactor: Double?
|
||||
let groupId: Int?
|
||||
let minStock: Double?
|
||||
let stock: Double
|
||||
@@ -98,6 +106,10 @@ struct Product: Codable, Identifiable, Hashable {
|
||||
case baseUnit = "base_unit"
|
||||
case packageSize = "package_size"
|
||||
case packageLabel = "package_label"
|
||||
case secondaryBase = "secondary_base"
|
||||
case secondaryCount = "secondary_count"
|
||||
case secondaryAmount = "secondary_amount"
|
||||
case secondaryFactor = "secondary_factor"
|
||||
case groupId = "group_id"
|
||||
case minStock = "min_stock"
|
||||
case expiredCount = "expired_count"
|
||||
@@ -134,6 +146,38 @@ struct Product: Codable, Identifiable, Hashable {
|
||||
|
||||
var stockInArticleUnits: Double { stock / articleUnitFactor }
|
||||
|
||||
/// Zweit-Basiseinheiten je EINER Basiseinheit – nil ohne Bruecke.
|
||||
var zweitFaktor: Double? {
|
||||
guard let basis = secondaryBase, !basis.isEmpty, basis != baseUnit else { return nil }
|
||||
if let f = secondaryFactor, f > 0 { return f }
|
||||
// Rueckfall, falls das abgeleitete Feld fehlt (aelterer Server).
|
||||
guard let n = secondaryCount, let m = secondaryAmount, n > 0, m > 0 else { return nil }
|
||||
return m / n
|
||||
}
|
||||
|
||||
/// Art der Zweiteinheit ("count"/"weight"/"volume") – fuer die Einheitenwahl.
|
||||
var zweitKind: String? {
|
||||
switch secondaryBase {
|
||||
case "piece": return "count"
|
||||
case "gram": return "weight"
|
||||
case "milliliter": return "volume"
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
/// Kuerzel der Zweit-Basiseinheit fuer die Anzeige.
|
||||
var zweitKurz: String {
|
||||
switch secondaryBase {
|
||||
case "gram": return "g"
|
||||
case "milliliter": return "ml"
|
||||
case "piece": return "Stück"
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
|
||||
/// Bestand in der Zweiteinheit, z.B. 500 g bei 6 Stueck.
|
||||
var stockInZweit: Double? { zweitFaktor.map { stock * $0 } }
|
||||
|
||||
/// Wie es um den Mindestbestand steht. Beides in Basiseinheiten verglichen.
|
||||
enum StockLevel { case none, ok, close, below }
|
||||
|
||||
@@ -585,6 +629,12 @@ struct ProductUpdateRequest: Encodable {
|
||||
var individual: Bool? = nil
|
||||
var bulk: Bool? = nil
|
||||
var sendMode = false
|
||||
// Zweiteinheit ebenfalls nur auf Wunsch – ein PATCH aus einer anderen Maske
|
||||
// soll die Bruecke nicht unbeabsichtigt loeschen.
|
||||
var secondaryBase: String? = nil
|
||||
var secondaryCount: Double? = nil
|
||||
var secondaryAmount: Double? = nil
|
||||
var sendSecondary = false
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name, brand, individual, bulk
|
||||
@@ -600,6 +650,9 @@ struct ProductUpdateRequest: Encodable {
|
||||
case minStockInPackages = "min_stock_in_packages"
|
||||
case minStockUnitId = "min_stock_unit_id"
|
||||
case baseUnit = "base_unit"
|
||||
case secondaryBase = "secondary_base"
|
||||
case secondaryCount = "secondary_count"
|
||||
case secondaryAmount = "secondary_amount"
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
@@ -625,6 +678,11 @@ struct ProductUpdateRequest: Encodable {
|
||||
try container.encode(bulk, forKey: .bulk)
|
||||
if let baseUnit { try container.encode(baseUnit, forKey: .baseUnit) }
|
||||
}
|
||||
if sendSecondary {
|
||||
try container.encode(secondaryBase, forKey: .secondaryBase)
|
||||
try container.encode(secondaryCount, forKey: .secondaryCount)
|
||||
try container.encode(secondaryAmount, forKey: .secondaryAmount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user