82 lines
1.9 KiB
Swift
82 lines
1.9 KiB
Swift
import FluentKit
|
|||
|
|
import Foundation
|
||
|
|
|
||
|
|
/// A FluentKit model of a single `offers` row.
|
||
|
|
final class OfferRecord: Model, @unchecked Sendable {
|
||
|
|
|
||
|
|
// MARK: Properties
|
||
|
|
|
||
|
|
static let schema = "offers"
|
||
|
|
|
||
|
|
@ID(key: .id)
|
||
|
|
var id: UUID?
|
||
|
|
|
||
|
|
@Parent(key: "conversation_id")
|
||
|
|
var conversation: ConversationRecord
|
||
|
|
|
||
|
|
@Parent(key: "listing_id")
|
||
|
|
var listing: ListingRecord
|
||
|
|
|
||
|
|
@Parent(key: "buyer_id")
|
||
|
|
var buyer: UserRecord
|
||
|
|
|
||
|
|
@Field(key: "amount_cents")
|
||
|
|
var amountCents: Int
|
||
|
|
|
||
|
|
@Field(key: "status")
|
||
|
|
var status: String
|
||
|
|
|
||
|
|
@Field(key: "created_at")
|
||
|
|
var createdAt: Date
|
||
|
|
|
||
|
|
@Field(key: "expires_at")
|
||
|
|
var expiresAt: Date
|
||
|
|
|
||
|
|
// MARK: Initializers
|
||
|
|
|
||
|
|
init() {}
|
||
|
|
|
||
|
|
init(
|
||
|
|
conversationID: UUID,
|
||
|
|
listingID: UUID,
|
||
|
|
buyerID: UUID,
|
||
|
|
amountCents: Int,
|
||
|
|
at date: Date
|
||
|
|
) {
|
||
|
|
self.$conversation.id = conversationID
|
||
|
|
self.$listing.id = listingID
|
||
|
|
self.$buyer.id = buyerID
|
||
|
|
self.amountCents = amountCents
|
||
|
|
self.status = Offer.Status.open.rawValue
|
||
|
|
self.createdAt = date
|
||
|
|
self.expiresAt = date.addingTimeInterval(Offer.lifetime)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Extensions
|
||
|
|
|
||
|
|
extension OfferRecord {
|
||
|
|
|
||
|
|
// MARK: Methods
|
||
|
|
|
||
|
|
/// The `Sendable` snapshot of the saved record; its buyer, and its listing with its shop, must be eager-loaded.
|
||
|
|
/// - Parameter now: the moment an open offer's expiry is judged at.
|
||
|
|
func snapshot(
|
||
|
|
at now: Date
|
||
|
|
) throws -> Offer {
|
||
|
|
let stored = Offer.Status(rawValue: status) ?? .declined
|
||
|
|
|
||
|
|
return .init(
|
||
|
|
id: try requireID(),
|
||
|
|
conversationID: $conversation.id,
|
||
|
|
listing: listing.snapshot,
|
||
|
|
buyer: try buyer.snapshot,
|
||
|
|
amountCents: amountCents,
|
||
|
|
status: stored == .open && expiresAt <= now ? .expired : stored,
|
||
|
|
createdAt: createdAt,
|
||
|
|
expiresAt: expiresAt
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|