[{{mminutes}}:{{sseconds}}] X
Пользователь приглашает вас присоединиться к открытой игре игре с друзьями .
RestaurantRepository
(0)       Используют 5 человек

Комментарии

Ни одного комментария.
Написать тут
Описание:
code from RestaurantRepository
Автор:
majorpein
Создан:
26 октября 2020 в 10:57 (текущая версия от 26 октября 2020 в 11:02)
Публичный:
Нет
Тип словаря:
Слова
Текст для игры будет составляться из слов, перемешанных в случайном порядке.
Содержание:
import UIKit
import Delivery_Club_Models
import Delivery_Club_Managers
import Delivery_Club_Remote_Config
import Delivery_Club_Storages
final class RestaurantRepository {
enum DataError: Swift.Error {
case mapingData
case requestError(Swift.Error)
case noVendor
case requestedMenuForBooking
}
enum CartAddProductError: Error {
case request(Error)
case needClearCart
case bonusNoAuthBefore
case bonusNoAuthAfter
case bonusProductAlreadyInCart
case bonusNeedPoints(Int)
case bonusNeedReplacement
}
private let dataMapper: RestaurantDataMapperProtocol
private let infoMapper: RestaurantInfoMapperProtocol
private let serviceManager: ServiceManagerProtocol
private let accountManager: AccountManagerProtocol
private let addressManager: AddressManagerProtocol
private let cartManager: CartManagersProtocol
private let favoritesManager: FavoritesManagerProtocol
private let restaurauntDataStorage: RestaurauntDataStorageProtocol
private let vendorContainerRepository: VendorContainerRepositoryProtocol
private var observers: [Weak<RestaurantRepositoryObserver>] = []
init(dataMapper: RestaurantDataMapperProtocol,
infoMapper: RestaurantInfoMapperProtocol,
serviceManager: ServiceManagerProtocol,
accountManager: AccountManagerProtocol,
cartManager: CartManagersProtocol,
addressManager: AddressManagerProtocol,
favoritesManager: FavoritesManagerProtocol,
restaurauntDataStorage: RestaurauntDataStorageProtocol,
vendorContainerRepository: VendorContainerRepositoryProtocol) {
self.serviceManager = serviceManager
self.accountManager = accountManager
self.cartManager = cartManager
self.addressManager = addressManager
self.dataMapper = dataMapper
self.infoMapper = infoMapper
self.favoritesManager = favoritesManager
self.restaurauntDataStorage = restaurauntDataStorage
self.vendorContainerRepository = vendorContainerRepository
setup()
}
private func setup() {
favoritesManager.addObserver(self)
}
private func cleanReleasedObservers() {
observers.removeAll(where: { $0.isReleased })
}
private func notifyObserversFavoriteDidUpdate() {
cleanReleasedObservers()
observers.forEach({ $0.object?.didUpdateFavorites() })
}
private func notifyObserversFavoriteDidAdd(serviceId: Int) {
cleanReleasedObservers()
observers.forEach({ $0.object?.didAddFavorite(serviceId: serviceId) })
}
private func notifyObserversFavoriteDidRemove(serviceId: Int) {
cleanReleasedObservers()
observers.forEach({ $0.object?.didRemoveFavorite(serviceId: serviceId) })
}
}
extension RestaurantRepository: RestaurantRepositoryProtocol {
func saveResaurauntData(_ data: AnalyticsRestaurantData) {
restaurauntDataStorage.saveAnalyticsRestaurantData(data)
}
func addObserver(_ observer: RestaurantRepositoryObserver) {
cleanReleasedObservers()
observers.append(Weak(observer))
}
func requestRestaurantInfo(serviceId: Int, vendorId: Int, completion: @escaping RestaurantInfoCompletion) {
vendorContainerRepository.requestVendorContainer(withServiceId: serviceId, vendorId: vendorId) { result in
completion(.init(catching: {
try result.get()
}))
}
}
func requestData(serviceId: Int, vendorId: Int, containerTab: RestaurantContainerTab, completion: @escaping RestuarantDataCompletion) {
vendorContainerRepository.requestVendorContainer(withServiceId: serviceId, vendorId: vendorId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
completion(.failure(error))
case .success(let vendorContainer):
let deliveryType: DCDeliveryType
var correctVendorId = vendorId
switch containerTab {
case .delivery:
guard let service = vendorContainer.deliveryVendor else {
completion(.failure(DataError.noVendor))
return
}
deliveryType = service.mostAccurateDeliveryType
correctVendorId = service.identifier
case .takeaway:
deliveryType = .takeAway
case .booking:
completion(.failure(DataError.requestedMenuForBooking))
return
}
self.requestMenuAndPromo(
vendorContainer: vendorContainer,
vendorId: correctVendorId,
deliveryType: deliveryType,
isFavorite: self.isServiceInFavorite(serviceId: serviceId),
isTakeaway: containerTab == .takeaway,
completion: completion
)
}
}
}
func addProduct(_ product: DCFullProductObject,
service: RestaurantServiceProtocol,
deliveryType: DCDeliveryType,
isFavorite: Bool,
completion: @escaping CartAddProductCompletion) {
switch product.classId {
case .default:
addDefaultProductToCart(product, service: service, deliveryType: deliveryType, isFavorite: isFavorite, completion: completion)
case .points:
addPointProductToCart(product, service: service, isFavorite: isFavorite, completion: completion)
case .variantsIngredients:
completion(.success(.variantsIngredients))
@unknown default:
return
}
}
func deleteProduct(_ product: DCFullProductObject) {
cartManager.requestDeleteProduct?(
product,
quantity: 1,
completion: nil,
failure: nil)
}
func removeProduct(_ product: DCFullProductObject, service: DCServiceObject) {
guard let cartProductModel = obtainCartProductModels([product], service: service).first?.1 else { return }
cartManager.requestRemoveProduct?(cartProductModel, completion: nil)
}
func clearCart() {
cartManager.clearCart()
}
func obtainCartProductModels(_ products: [DCFullProductObject], service: RestaurantServiceProtocol?) -> [ProductIdentifier: CartProductModel] {
guard let service = service else { return [:] }
return products.reduce(into: [ProductIdentifier: CartProductModel]()) { result, product in
let baseService = DCBaseServiceObject.baseService(from: service)
guard let productModel = cartManager.getProductModel?(product, service: baseService)
else { return }
result[product.identifier] = productModel
}
}
func getCartData() -> RestaurantCartData {
return RestaurantCartData(
totalQuantity: cartManager.totalQuantity,
totalPrice: cartManager.totalPrice,
hint: cartManager.getCartModel().getRestriction()?.hint,
state: cartManager.state
)
}
func deletePointsProduct() {
guard let pointProduct = cartManager.getPointsProduct?() else { return }
cartManager.requestRemoveProduct?(pointProduct, completion: nil)
}
func isCartModelServiceEqualService(_ service: RestaurantServiceProtocol) -> Bool {
return cartManager.getService()?.serviceId == service.serviceId
}
func getRestriction() -> DCRestrictionsObject? {
return cartManager.getCartModel().getRestriction()
}
func isServiceInFavorite(serviceId: Int) -> Bool {
return favoritesManager.isFavorite(identifier: serviceId)
}
func toggleFavorites(serviceId: Int, completion: @escaping RestuarantFavoriteCompletion) {
guard isServiceInFavorite(serviceId: serviceId) else {
addFavorite(serviceId: serviceId, completion: completion)
return
}
removeFavorite(serviceId: serviceId, completion: completion)
}
}
private extension RestaurantRepository {
func requestAddFavorite(serviceId: Int, completion: @escaping RestuarantFavoriteCompletion) {
serviceManager.requestAddFavorites(serviceId: serviceId, completion: completion)
}
func requestRemoveFavorite(serviceId: Int, completion: @escaping RestuarantFavoriteCompletion) {
serviceManager.requestRemoveFromFavorites(serviceId: serviceId, completion: completion)
}
func removeFavorite(serviceId: Int, completion: @escaping RestuarantFavoriteCompletion) {
favoritesManager.removeFavorite(identifier: serviceId)
requestRemoveFavorite(serviceId: serviceId) { [weak self] result in
guard let self = self else { return }
switch result {
case .success: break
case .failure: self.favoritesManager.addFavorite(identifier: serviceId)
}
completion(result)
}
}
func addFavorite(serviceId: Int, completion: @escaping RestuarantFavoriteCompletion) {
favoritesManager.addFavorite(identifier: serviceId)
requestAddFavorite(serviceId: serviceId) { [weak self] result in
guard let self = self else { return }
switch result {
case .success: break
case .failure: self.favoritesManager.removeFavorite(identifier: serviceId)
}
completion(result)
}
}
func requestMenuAndPromo(vendorContainer: VendorContainer?,
vendorId: Int,
deliveryType: DCDeliveryType,
isFavorite: Bool,
isTakeaway: Bool,
completion: @escaping RestuarantDataCompletion) {
serviceManager.requestMenuAndPromoactions(
serviceIdentifier: vendorId,
supportedRewards: [.productDiscount, .freeProduct],
deliveryType: deliveryType) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let response):
let data = self.dataMapper.mapRestaurantData(
vendorContainer: vendorContainer,
deliveryType: deliveryType,
menu: response.0,
promoActions: response.1,
isFavorite: isFavorite,
isTakeaway: isTakeaway
)
completion(.success(data))
case .failure(let error):
completion(.failure(DataError.requestError(error)))
}
}
}
func addDefaultProductToCart(_ product: DCFullProductObject,
service: RestaurantServiceProtocol,
deliveryType: DCDeliveryType,
isFavorite: Bool,
completion: @escaping CartAddProductCompletion) {
guard cartManager.canAddProductFromRestaurant(withServiceId: service.serviceId, vendorId: service.identifier) else {
completion(.failure(.needClearCart))
return
}
saveAddressIfNeeded { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
completion(.failure(error))
case .success:
self.addProductToCart(product, service: service, isFavorite: isFavorite)
completion(.success(.default))
}
}
}
func addPointProductToCart(_ product: DCFullProductObject,
service: RestaurantServiceProtocol,
isFavorite: Bool,
completion: @escaping CartAddProductCompletion) {
guard accountManager.isAuthorized else {
completion(.failure(.bonusNoAuthBefore))
return
}
accountManager.requestUser(withProgress: true) { [weak self] (result) in
guard let self = self else { return }
switch result {
case .failure(let error):
completion(.failure(.request(error)))
case .success:
let mediumService = DCMediumServiceObject.mediumService(from: service)
let isAlreadyInCart = self.cartManager.getCountInCartForProduct?(product, service: mediumService) ?? .zero > .zero
let isNeedPoints = self.accountManager.scorePoints < product.points
let hasPointsProducts = self.cartManager.hasPointsProducts ?? false
switch product.classId {
case .points:
if !self.accountManager.isAuthorized {
completion(.failure(.bonusNoAuthAfter))
} else if isAlreadyInCart {
completion(.failure(.bonusProductAlreadyInCart))
} else if isNeedPoints {
completion(.failure(.bonusNeedPoints(product.points - self.accountManager.scorePoints)))
}
case .default, .variantsIngredients: break
@unknown default: break
}
guard !hasPointsProducts else {
completion(.failure(.bonusNeedReplacement))
return
}
self.addProductToCart(product, service: service, isFavorite: isFavorite)
completion(.success(.points))
}
}
}
func addProductToCart(_ product: DCFullProductObject, service: RestaurantServiceProtocol, isFavorite: Bool) {
//TODO Siri?
//[DCSiriHelper registerService:self.service.title serviceId:self.service.serviceId viewController:(UIViewController *)self.view];
let mediumService = DCMediumServiceObject.mediumService(from: service)
cartManager.requestAddProduct?(
product,
service: mediumService,
ingredients: product.ingredients,
variantItems: nil,
quantity: 1,
recommendationId: nil,
isFromFavorites: isFavorite,
completion: nil,
failure: nil
)
}
func saveAddressIfNeeded(_ completion: @escaping (Result<Void, CartAddProductError>) -> Void) {
guard let address = accountManager.lastAddress,
let city = address.city,
address.identifier == .zero && accountManager.isAuthorized else {
completion(.success(Void()))
return
}
addressManager.requestAddAddress(address, cityTitle: city) { [weak self] (result) in
guard let self = self else { return }
switch result {
case .failure(let error):
completion(.failure(.request(error)))
case .success(let responseAddress):
self.accountManager.setLastAddress(responseAddress)
completion(.success(Void()))
}
}
}
}
extension RestaurantRepository: FavoritesManagerObserver {
func didUpdateFavorites() {
notifyObserversFavoriteDidUpdate()
}
func didAddFavorite(identifier: Int) {
notifyObserversFavoriteDidAdd(serviceId: identifier)
}
func didRemoveFavorite(identifier: Int) {
notifyObserversFavoriteDidRemove(serviceId: identifier)
}
}
//MARK: - Error localization
extension RestaurantRepository.DataError: LocalizedError {
public var errorDescription: String? {
switch self {
case .mapingData: return Localized("SOMETHING_GOES_WRONG")
case .requestError(let error): return error.localizedDescription
case .noVendor, .requestedMenuForBooking: return nil
}
}
}
extension RestaurantRepository.CartAddProductError: LocalizedError {
public var errorDescription: String? {
switch self {
case .bonusNoAuthAfter: return Localized("BONUS_NO_AUTH_MESSAGE")
case .bonusProductAlreadyInCart: return Localized("PRODUCT_IS_ALREADY_IN_THE_CART")
case .bonusNeedPoints(let points): return String(format: Localized("MORE_POINTS_NEEDED_PATTERN"), points)
case .request(let error): return error.localizedDescription
case .needClearCart, .bonusNeedReplacement, .bonusNoAuthBefore: return nil
}
}
}

Связаться
Выделить
Выделите фрагменты страницы, относящиеся к вашему сообщению
Скрыть сведения
Скрыть всю личную информацию
Отмена