/// A `Sendable` snapshot of a seller's shop. public struct Shop: Sendable, Equatable { // MARK: Properties /// The shop's URL slug. public let slug: String /// The shop's name. public let name: String /// The city the shop ships from. public let city: String /// The ISO 3166-1 alpha-2 code of the country the shop ships from. public let country: String /// The year the shop started selling on the site. public let sinceYear: Int /// Whether the shop's identity has been verified. public let isVerified: Bool /// The shop's average rating, out of five. public let rating: Double /// The number of rated sales behind ``rating``. public let ratedSales: Int /// The number of items the shop has sold. public let soldCount: Int /// The shop's handling time, in business days. public let handlingDays: Int /// Where and how the shop ships. public let shipsNote: String /// The shop's returns policy, in a few words. public let returnsNote: String /// The shop's description of itself. public let about: String /// Whether the seller sells as a private collector or as a business. public let kind: Kind /// The business's Chamber of Commerce (KvK) number, shown on its shop page. public let kvkNumber: String? /// The business's VAT (BTW) identifier. public let vatID: String? /// The business's registered name. public let legalName: String? // MARK: Initializers public init( slug: String, name: String, city: String, country: String, sinceYear: Int, isVerified: Bool, rating: Double, ratedSales: Int, soldCount: Int, handlingDays: Int, shipsNote: String, returnsNote: String, about: String, kind: Kind = .business, kvkNumber: String? = nil, vatID: String? = nil, legalName: String? = nil ) { self.slug = slug self.name = name self.city = city self.country = country self.sinceYear = sinceYear self.isVerified = isVerified self.rating = rating self.ratedSales = ratedSales self.soldCount = soldCount self.handlingDays = handlingDays self.shipsNote = shipsNote self.returnsNote = returnsNote self.about = about self.kind = kind self.kvkNumber = kvkNumber self.vatID = vatID self.legalName = legalName } } // MARK: - Extensions public extension Shop { // MARK: Computed /// Whether the shop ships from a member state of the European Union, so a delivery within it crosses no customs border. var shipsFromEU: Bool { ListingFilter.euCountries.contains(country) } } // MARK: - Enumerations public extension Shop { /// How a seller sells, which decides what consumer law asks of them. enum Kind: String, CaseIterable, Sendable { /// A business: its KvK number shows on its shop page, and consumers get the 14-day right of withdrawal. case business /// A private collector selling their own books: no statutory right of withdrawal. case privateSeller = "private" } }