Added the catalogue models and seed to support phase 3 of the POC prototype in the Persistence package.
This commit is contained in:
1 parent
43dcc03da6
commit
b1ceed7790
20 files changed
+2035
-8
No files matched your search
@@ -0,0 +1,87 @@
|
||||
import Foundation
|
||||
|
||||
/// A `Sendable` snapshot of a buyer's offer on a listing.
|
||||
public struct Offer: Sendable, Equatable {
|
||||
|
||||
// MARK: Constants
|
||||
|
||||
/// The share of the asking price under which an offer is declined outright.
|
||||
public static let floorShare = 0.8
|
||||
|
||||
/// How long an offer binds its buyer: 48 hours.
|
||||
public static let lifetime: TimeInterval = 172_800
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The offer's identifier.
|
||||
public let id: UUID
|
||||
/// The identifier of the conversation the offer was made in.
|
||||
public let conversationID: UUID
|
||||
/// The listing offered on.
|
||||
public let listing: Listing
|
||||
/// The account offering.
|
||||
public let buyer: User
|
||||
/// The amount offered, in euro cents.
|
||||
public let amountCents: Int
|
||||
/// Where the offer stands; an open offer past its expiry reads as expired.
|
||||
public let status: Status
|
||||
/// When the offer was made.
|
||||
public let createdAt: Date
|
||||
/// When the offer stops binding its buyer.
|
||||
public let expiresAt: Date
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
conversationID: UUID,
|
||||
listing: Listing,
|
||||
buyer: User,
|
||||
amountCents: Int,
|
||||
status: Status,
|
||||
createdAt: Date,
|
||||
expiresAt: Date
|
||||
) {
|
||||
self.id = id
|
||||
self.conversationID = conversationID
|
||||
self.listing = listing
|
||||
self.buyer = buyer
|
||||
self.amountCents = amountCents
|
||||
self.status = status
|
||||
self.createdAt = createdAt
|
||||
self.expiresAt = expiresAt
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Enumerations
|
||||
|
||||
public extension Offer {
|
||||
/// Where an offer stands.
|
||||
enum Status: String, Sendable {
|
||||
/// Waiting for the seller's answer.
|
||||
case open
|
||||
/// Accepted: a sale record was opened.
|
||||
case accepted
|
||||
/// Declined by the seller.
|
||||
case declined
|
||||
/// Left unanswered past its expiry, or overtaken by a sale of the listing.
|
||||
case expired
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
public extension Offer {
|
||||
|
||||
// MARK: Methods
|
||||
|
||||
/// The lowest offer a listing's seller hears, in euro cents: ``floorShare`` of the asking price, rounded up to a whole euro.
|
||||
/// - Parameter askingCents: the listing's asking price, in euro cents.
|
||||
static func floor(
|
||||
forAsking askingCents: Int
|
||||
) -> Int {
|
||||
Int((Double(askingCents) * floorShare / 100).rounded(.up)) * 100
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user