Android. Kotlin. необходимо как-то сбрасывать значение selectedCommentId при любом редактировании в тексте поля комментария, как это сделать? package ru.maxi.mobile.feature.delivery.latestComments.model

/**
 * Бизнес-сущность комментария функционала доставки
 */
data class Comment(
    val id: Long,
    val text: String,
)

/**
 * Данные функционала последних комментариев
 */
data class CommentsData(
    val commentsList: List<Comment>,
    val selectedCommentId: Long?,
)
package ru.maxi.mobile.feature.delivery.model

import ru.maxi.mobile.core.data.Money
import ru.maxi.mobile.entity.delivery.order.InitDataOrder
import ru.maxi.mobile.entity.delivery.order.NoProductAction
import ru.maxi.mobile.entity.delivery.order.OrderWeightData
import ru.maxi.mobile.entity.delivery.order.PaymentTypeBlockViewItem

/**
 * Состояние экрана оформления заказа
 */
sealed interface MakeOrderFieldsData {

    /**
     * Данные при оформлении заказа анонимом
     */
    data object AnonymousUserData : MakeOrderFieldsData

    /**
     * Данные для экрана оформления заказа
     */
    data class Fields(
        val contactsBlock: ContactsBlock,
        val orderInitData: InitDataOrder?,
        val customAddressBlock: CustomAddressBlock,
        val noProductAction: NoProductAction?,
        val commentBlock: CommentBlock,
        val paymentBlock: PaymentBlock,
        val summaryBlock: SummaryBlock,
        val fieldsErrors: Set<FieldError>,
    ) : MakeOrderFieldsData {

        /**
         * Состояние блока контактов клиента
         */
        data class ContactsBlock(
            val name: String,
            val phone: String,
        )

        /**
         * Состояние блока ручного ввода адреса
         */
        data class CustomAddressBlock(
            val apartment: String,
            val entrance: String,
            val floor: String,
        )

        /**
         * Состояние блока комментария
         */
        data class CommentBlock(
            val comment: String,
            val showBtnLatestComments: Boolean,
        )

        /**
         * Состояние блока оплаты заказа
         */
        data class PaymentBlock(
            val paymentTypes: List<PaymentTypeBlockViewItem>,
            val needShowMyCardsBtn: Boolean,
        )

        /**
         * Состояние блока итоговых данных по заказу
         */
        data class SummaryBlock(
            val orderAmount: Money,
            val deliveryAmount: Money,
            val bonusesAmount: Money,
            val promoCodeDiscountAmount: Money,
            val totalAmount: Money,
            val weightData: OrderWeightData,
        )

        /**
         * Ошибки полей при оформлении заказа
         */
        sealed class FieldError {

            /**
             * Ошибка валидации поля email
             */
            data object EmailNotValid : FieldError()

            /**
             * Ошибка незаполненного поля email
             */
            data object EmailNotFilled : FieldError()

            /**
             * Ошибка валидации поля номера телефона
             */
            data object PhoneNotValid : FieldError()

            /**
             * Ошибка незаполненного поля номера телефона
             */
            data object PhoneNotFilled : FieldError()
        }

        companion object {
            val defaultViewState = Fields(
                contactsBlock = ContactsBlock(
                    name = "",
                    phone = "",
                ),
                orderInitData = null,
                noProductAction = null,
                commentBlock = CommentBlock(
                    comment = "",
                    showBtnLatestComments = false,
                ),
                paymentBlock = PaymentBlock(
                    paymentTypes = listOf(),
                    needShowMyCardsBtn = false,
                ),
                customAddressBlock = CustomAddressBlock(
                    apartment = "",
                    entrance = "",
                    floor = "",
                ),
                fieldsErrors = emptySet(),
                summaryBlock = SummaryBlock(
                    orderAmount = Money.ZERO,
                    deliveryAmount = Money.ZERO,
                    bonusesAmount = Money.ZERO,
                    promoCodeDiscountAmount = Money.ZERO,
                    totalAmount = Money.ZERO,
                    weightData = OrderWeightData(
                        totalWeight = 0.0,
                        overWeightData = null,
                    ),
                ),
            )
        }
    }
}
**
 * [ViewModel] для функционала оформления заказа
 */
class MakeOrderViewModel @Inject constructor(
    private val analyticsUseCase: AnalyticsUseCase,
    private val userAuthorizationUseCase: UserAuthorizationUseCase,
    private val orderInteractor: OrderInteractor,
    private val cartInteractor: CartInteractor,
    private val promoCodeInteractor: PromoCodeInteractor,
    private val deepLinkInteractor: DeepLinkInteractor,
    private val deliveryConfigInteractor: DeliveryConfigInteractor,
) : AndroidViewModel(App.INSTANCE), MakeOrderPaymentTypeBlockActions {

    private var promoCode: String? = null
    private var cartProducts: List<CartProduct> = emptyList()
    private var isDataLoaded: Boolean = false

    /** События навигации */
    private val _navigationEvent = Channel<MakeOrderNavigationEvent>(Channel.BUFFERED)
    val navigationEvent = _navigationEvent.receiveAsFlow()

    /** События сообщений */
    private val _messageEvent = Channel<String>(Channel.BUFFERED)
    val messageEvent = _messageEvent.receiveAsFlow()

    private val paymentTypesFlow: StateFlow<List<OrderPaymentType>> by lazy {
        combine(
            flowOf(deliveryConfigInteractor.getPaymentTypeList()),
            orderInteractor.getOnlinePaymentCardListFlow(),
        ) { paymentTypes, cardList ->
            buildList {
                addAll(paymentTypes.map(PaymentType::toOrderPaymentType))

                val newCardOnlineTypeIndex = paymentTypes.indexOf(PaymentType.ONLINE)
                if (newCardOnlineTypeIndex >= 0) {
                    addAll(newCardOnlineTypeIndex, cardList.map(OrderPaymentType::ByCardOnline))
                }
            }
        }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
    }

    private val selectedPaymentTypeFlow = MutableStateFlow<OrderPaymentType?>(null)

    private val loadingState = MutableStateFlow<LoadableData<Nothing?>>(LoadableData.Loading())

    private val dataState = MutableStateFlow<MakeOrderFieldsData>(defaultViewState)
    private val requiredViewState get() = (dataState.value as MakeOrderFieldsData.Fields)

    private var hasLatestComments = false

    private val viewState = combine(
        dataState,
        paymentTypesFlow,
        selectedPaymentTypeFlow,
        orderInteractor.getLatestCommentsDataFlow(),
    ) { state, paymentTypes, selectedPaymentType, commentData ->
        if (state is MakeOrderFieldsData.AnonymousUserData) return@combine MakeOrderFieldsData.AnonymousUserData
        val selectedCommentText = commentData?.let { commentsData ->
            commentsData.commentsList.find { it.id == commentsData.selectedCommentId }?.text
        }

        (state as MakeOrderFieldsData.Fields).copy(
            paymentBlock = MakeOrderFieldsData.Fields.PaymentBlock(
                paymentTypes = paymentTypes.map {
                    PaymentTypeBlockViewItem(
                        paymentType = it,
                        isSelected = it == selectedPaymentType,
                    )
                },
                needShowMyCardsBtn = paymentTypes.any {
                    it is OrderPaymentType.ByCardOnline
                },
            ),
            commentBlock = MakeOrderFieldsData.Fields.CommentBlock(
                comment = selectedCommentText ?: state.commentBlock.comment,
                showBtnLatestComments = hasLatestComments && (commentData == null || commentData.commentsList.isNotEmpty()),
            ),
        )
    }

    /** Состояние полей оформления заказа */
    val fieldsState: Flow<LoadableData<MakeOrderFieldsData>> = viewState
        .combine(
            loadingState,
        ) { data, loadingData ->
            loadingData.mapped { data }
        }
        .onStart {
            loadData()
        }.stateIn(viewModelScope, SharingStarted.Lazily, LoadableData.Loading())

    /** Состояние ошибок полей заказа */
    val fieldsErrorsState: Flow<Set<MakeOrderFieldsData.Fields.FieldError>> = viewState
        .filterIsInstance<MakeOrderFieldsData.Fields>()
        .map { it.fieldsErrors }
        .stateIn(viewModelScope, SharingStarted.Lazily, emptySet())

    /**
     * Загрузить данные
     */
    fun loadData() {
        if (userAuthorizationUseCase.isUserAnonymous()) {
            orderInteractor.saveMakeOrderFields(MakeOrderFieldsData.AnonymousUserData)
            loadingState.emitSuccess(null)
            return
        }

        viewModelScope.launch {
            try {
                if (!isDataLoaded) {
                    initOrderData()
                }
            } catch (exception: Exception) {
                if (exception is BusinessLogicValidException && exception.code == ValidError.CART_MIN_SUM_NOT_REACHED) {
                    _navigationEvent.send(MakeOrderNavigationEvent.ShowErrorMinSaveDialog(exception.message))
                } else {
                    loadingState.emitError(exception)
                }
            }
        }
    }

    private suspend fun initOrderData() {
        if (!orderInteractor.getAddressSelected()) {
            _navigationEvent.trySend(MakeOrderNavigationEvent.OpenMapIntervalsAddresses)
            return
        }
        val cacheOrderData = orderInteractor.makeOrderFieldsData.first() as MakeOrderFieldsData.Fields
        val phone = cacheOrderData.contactsBlock.phone.let {
            it.ifEmpty {
                orderInteractor.getUserPhone()
            }
        }

        if (deliveryConfigInteractor.getPaymentTypeList().contains(PaymentType.ONLINE)) {
            orderInteractor.loadOnlinePaymentCardList()
        }
        val orderInitData = orderInteractor.getInitData()
        hasLatestComments = orderInitData.hasSavedComments
        val email = cacheOrderData.orderInitData?.email ?: orderInitData.email
        promoCode = promoCodeInteractor.getPromoCode()?.data?.text

        val cartProducts = cartInteractor.getProductList()
        analyticsUseCase log AnalyticsDeliveryEvent.BeginCheckout(
            cartProducts = cartProducts,
            orderAmount = orderInitData.orderSum,
            hasClientAddress = orderInitData.clientAddress != null,
            promoCode = promoCode,
            promoCodeDiscount = orderInitData.promoCodeDiscount,
        )

        val bonusesAmount = Money.fromWholePart(orderInitData.bonusesPointsDiscount?.toLong() ?: 0)
        val promoCodeDiscount = orderInitData.promoCodeDiscount ?: Money.ZERO
        val totalAmount = with(orderInitData) {
            (orderSum + deliveryPrice + (weightData.overWeightData?.overWeightAmount ?: Money.ZERO)) -
                (bonusesAmount + promoCodeDiscount)
        }

        val newFieldsData = cacheOrderData.copy(
            contactsBlock = MakeOrderFieldsData.Fields.ContactsBlock(
                cacheOrderData.contactsBlock.name,
                phone,
            ),
            orderInitData = orderInitData.copy(email = email),
            summaryBlock = MakeOrderFieldsData.Fields.SummaryBlock(
                orderAmount = orderInitData.orderSum,
                deliveryAmount = orderInitData.deliveryPrice,
                bonusesAmount = bonusesAmount,
                promoCodeDiscountAmount = promoCodeDiscount,
                totalAmount = totalAmount,
                weightData = orderInitData.weightData,
            ),
        )
        dataState.emit(newFieldsData)
        isDataLoaded = true
        loadingState.emitSuccess(null)
    }

    /**
     * Обработать изменение текста [text] в поле email'а
     */
    fun onEmailTextChanged(text: String) {
        val email = text.trimStart()
        if (requiredViewState.orderInitData?.email == email) return

        dataState.update { _ ->
            requiredViewState.copy(
                orderInitData = requiredViewState.orderInitData?.copy(email = email),
                fieldsErrors = requiredViewState.fieldsErrors - setOf(
                    emailNotValidError,
                    emailNotFilledError,
                ),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле номера телефона
     */
    fun onPhoneTextChanged(text: String) {
        val phone = text.trimStart()
        if (requiredViewState.contactsBlock.phone == phone) return

        dataState.update { _ ->
            requiredViewState.copy(
                contactsBlock = requiredViewState.contactsBlock.copy(phone = phone),
                fieldsErrors = requiredViewState.fieldsErrors - setOf(phoneNotFilledError, phoneNotValidError),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле имени клиента
     */
    fun onNameTextChanged(text: String) {
        val name = text.trimStart()
        if (requiredViewState.contactsBlock.name == name) return

        dataState.update { _ ->
            requiredViewState.copy(
                contactsBlock = requiredViewState.contactsBlock.copy(name = name),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле квартиры клиента
     */
    fun onApartmentTextChanged(text: String) {
        val apartment = text.trimStart()
        if (requiredViewState.customAddressBlock.apartment == apartment) return

        dataState.update { _ ->
            requiredViewState.copy(
                customAddressBlock = requiredViewState.customAddressBlock.copy(apartment = apartment),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле подъезда клиента
     */
    fun onEntranceTextChanged(text: String) {
        val entrance = text.trimStart()
        if (requiredViewState.customAddressBlock.entrance == entrance) return

        dataState.update { _ ->
            requiredViewState.copy(
                customAddressBlock = requiredViewState.customAddressBlock.copy(entrance = entrance),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле этажа клиента
     */
    fun onFloorTextChanged(text: String) {
        val floor = text.trimStart()
        if (requiredViewState.customAddressBlock.floor == floor) return

        dataState.update { _ ->
            requiredViewState.copy(
                customAddressBlock = requiredViewState.customAddressBlock.copy(floor = floor),
            )
        }
    }

    /**
     * Обработать изменение текста [text] в поле комментария к заказу
     */
    fun onCommentTextChanged(text: String) {
        val comment = text.trimStart()
        if (requiredViewState.commentBlock.comment == comment) return

        dataState.update { _ ->
            requiredViewState.copy(
                commentBlock = requiredViewState.commentBlock.copy(
                    comment = comment,
                ),
            )
        }
    }

    /**
     * Обработать клик по кнопке оформления заказа
     */
    fun onMakeOrderButtonClick(allowEmptyAddressFields: Boolean = false) {
        val formData = MakeOrderFormData(
            name = requiredViewState.contactsBlock.name.trim(),
            phone = requiredViewState.contactsBlock.phone.extractPhoneNumber(),
            apartment = requiredViewState.customAddressBlock.apartment,
            entrance = requiredViewState.customAddressBlock.entrance.toIntOrNull(),
            floor = requiredViewState.customAddressBlock.floor.toIntOrNull(),
            comment = requiredViewState.commentBlock.comment,
            email = requiredViewState.orderInitData?.email.toString(),
        )

        if (!validateFormData(formData, allowEmptyAddressFields)) return

        val orderParameters = createOrderParameters(formData)
        viewModelScope.launch {
            try {
                loadingState.emitLoading()

                val createdOrder = orderInteractor.sendOrder(orderParameters)
                val deliveryPrice = requiredViewState.orderInitData?.deliveryPrice?.plus(
                    (requiredViewState.orderInitData?.weightData?.overWeightData?.overWeightAmount ?: Money.ZERO),
                )

                promoCodeInteractor.clearPushPromoCode()
                analyticsUseCase log AnalyticsDeliveryEvent.Purchase(
                    createdOrder.id,
                    cartProducts,
                    orderAmount = requiredViewState.orderInitData?.orderSum ?: Money.ZERO,
                    deliveryAmount = deliveryPrice ?: Money.ZERO,
                    promoCode,
                    requiredViewState.orderInitData?.promoCodeDiscount,
                )

                dataState.emit(defaultViewState)
                if (createdOrder.paymentInfo.status == PaymentStatus.WAITING) {
                    processPayment(createdOrder.id)
                } else {
                    finishAndOpenOrderList(createdOrder.id)
                }
            } catch (exception: Exception) {
                val errorMessage = (exception as? BusinessLogicException)?.message
                    ?: exception.localizedMessage
                _messageEvent.send(errorMessage)
                loadingState.emitSuccess(null)
            }
        }
    }

    private fun createOrderParameters(formData: MakeOrderFormData): OrderParameters {
        val orderAddress = OrderAddressParameters(
            apartment = formData.apartment,
            entrance = formData.entrance,
            floor = formData.floor,
        )
        return OrderParameters(
            orderAddress = orderAddress,
            name = formData.name,
            phone = formData.phone,
            noProductAction = requiredViewState.noProductAction!!,
            comment = formData.comment,
            paymentType = requireNotNull(selectedPaymentTypeFlow.value),
            bonusesCount = requiredViewState.orderInitData?.bonusesPointsDiscount,
            email = formData.email,
        )
    }

    private fun validateFormData(data: MakeOrderFormData, allowEmptyAddressFields: Boolean): Boolean {
        dataState.update { _ ->
            requiredViewState.copy(
                fieldsErrors = when {
                    data.phone.isBlank() -> requiredViewState.fieldsErrors + phoneNotFilledError - phoneNotValidError
                    data.phone.length < 10 -> requiredViewState.fieldsErrors + phoneNotValidError - phoneNotFilledError
                    else -> requiredViewState.fieldsErrors - setOf(phoneNotFilledError, phoneNotValidError)
                },
            )
        }

        if (requiredViewState.fieldsErrors.isNotEmpty()) {
            return false
        }

        if (requiredViewState.orderInitData?.clientAddress == null &&
            !allowEmptyAddressFields &&
            data.apartment.isNullOrBlank() &&
            data.entrance == null &&
            data.floor == null
        ) {
            _navigationEvent.trySend(MakeOrderNavigationEvent.ShowEmptyFieldsErrorDialog)
            return false
        }

        if (requiredViewState.noProductAction == null) {
            _messageEvent.trySend(
                getApplication<Application>().getString(R.string.delivery_makeorder_no_product_action_empty_error),
            )
            return false
        }

        if (selectedPaymentTypeFlow.value == null) {
            _messageEvent.trySend(
                getApplication<Application>().getString(R.string.delivery_makeorder_no_payment_type_selected),
            )
            return false
        }

        val email = requiredViewState.orderInitData?.email ?: return false
        dataState.update { _ ->
            requiredViewState.copy(
                fieldsErrors = when {
                    email.isBlank() -> requiredViewState.fieldsErrors - emailNotValidError + emailNotFilledError
                    !email.isValidEmail() -> requiredViewState.fieldsErrors + emailNotValidError - emailNotFilledError
                    else -> requiredViewState.fieldsErrors - emailNotValidError - emailNotFilledError
                },
            )
        }

        return requiredViewState.fieldsErrors.isEmpty()
    }

    /**
     * Обработать клик по кнопке выбора действия в случае отсутствия заказа
     */
    fun onNoProductActionChange(action: NoProductAction) {
        dataState.tryEmit(
            requiredViewState.copy(
                noProductAction = action,
            ),
        )
    }

    /**
     * Обработать клик по кнопке перехода на условия оферты
     */
    fun onOfferClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenOfferRules)
    }

    /**
     * Обработать клик по кнопке перехода на условия обработки персональных данных
     */
    fun onPersonalDataClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenPersonalDataRules)
    }

    /**
     * Обработать клик на выбор карты для онлайн оплаты
     */
    fun onOnlinePaymentChooseCardClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenOnlinePaymentChooseCard)
    }

    /**
     * Обработать клик по кнопке авторизации
     */
    fun onAuthButtonClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenAuth)
    }

    /**
     * Обработать клик по кнопке перехода на экран помощи
     */
    fun onGoToFaqClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenFaqScreen)
    }

    /**
     * Обработать клик по кнопке изменения адреса и интервала
     */
    fun onChangeAddressIntervalClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.ShowChangeAddressIntervalDialog)
    }

    /**
     * Обработать клик по подтверждению изменения адреса и интервала в диалоге
     */
    fun onConfirmChangeAddressInterval() {
        orderInteractor.saveMakeOrderFields(dataState.value)
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenMapIntervalsAddresses)
    }

    /**
     * Обработать изменение адреса и интервала
     */
    fun onChangeAddressInterval() {
        if (isDataLoaded) {
            loadOnlineClientAddress()
        } else {
            loadData()
        }
    }

    /**
     * Обработать клик по кнопке "Подробные условия"
     */
    fun onOverWeightConditionsClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenOverWeightConditions)
    }

    /**
     * Обработать клик по кнопке "Последние комментарии"
     */
    fun onLatestCommentsButtonClick() {
        _navigationEvent.trySend(MakeOrderNavigationEvent.OpenLatestCommentsChooserScreen)
    }

    override fun onPaymentTypeClick(position: Int) {
        val paymentType = paymentTypesFlow.value[position]
        viewModelScope.launch {
            try {
                when (paymentType) {
                    OrderPaymentType.ByNewCardOnline -> {
                        selectedPaymentTypeFlow.update { null }
                        val addCardData = orderInteractor.addOnlinePaymentCard()
                        val paymentData = addCardData.copy(
                            formType = OnlinePaymentFormType.AddNewCard(),
                        )
                        _navigationEvent.send(
                            MakeOrderNavigationEvent.OpenOnlinePaymentForm(
                                paymentData,
                                OnlinePaymentFormType.AddNewCard.ADD_NEW_CARD_REQUEST_KEY,
                            ),
                        )
                    }

                    else -> selectedPaymentTypeFlow.update { paymentType }
                }
            } catch (exception: Exception) {
                val errorMessage = (exception as? BusinessLogicException)?.message
                    ?: exception.localizedMessage
                _messageEvent.send(errorMessage)
            }
        }
    }

    private suspend fun processPayment(orderId: Long) {
        try {
            val onlinePaymentType = checkNotNull(selectedPaymentTypeFlow.value)
            val paymentFormType = OnlinePaymentFormType.OrderPayment(orderId)
            val paymentData = orderInteractor.startOrderOnlinePayment(orderId)
                .copy(formType = paymentFormType)
            when (onlinePaymentType) {
                OrderPaymentType.ViaSbp -> {
                    parseSbpQrContent(
                        paymentData.formUrl,
                        paymentFormType.resultRequestKey,
                        orderId,
                        requireNotNull(paymentData.merchantName),
                    )
                }

                is OrderPaymentType.ByCardOnline -> {
                    _navigationEvent.send(
                        MakeOrderNavigationEvent.OpenOnlinePaymentForm(
                            paymentData,
                            paymentFormType.resultRequestKey,
                        ),
                    )
                }

                else -> throw BusinessLogicException("Invalid payment type")
            }
        } catch (ignored: Exception) {
            finishAndOpenOrderList(orderId)
        }
    }

    private fun parseSbpQrContent(qrContent: String, resultKey: String, orderId: Long, merchantName: String) {
        try {
            val uri = Uri.parse(qrContent)
            check(uri.isHierarchical && uri.host == "qr.nspk.ru")
            _navigationEvent.trySend(
                MakeOrderNavigationEvent.OpenBankChooserScreen(
                    paymentUri = uri,
                    sbpSourceType = SbpSourceType.QR,
                    resultKey = resultKey,
                    onBankChooserResult = { finishAndOpenOrderList(orderId) },
                    merchantName = merchantName,
                ),
            )
        } catch (ignored: Exception) {
            finishAndOpenOrderList(orderId)
        }
    }

    /**
     * Закрыть текущий экран и перейти на список заказов
     */
    fun finishAndOpenOrderList(newOrderId: Long) {
        deepLinkInteractor.saveDeepLink(DeepLinkType.OpenOrderList(newOrderId = newOrderId))
        _navigationEvent.trySend(MakeOrderNavigationEvent.Exit)
    }

    /**
     * Обновить информацию об оплате заказа
     */
    fun loadOnlinePaymentCardList() {
        viewModelScope.launch {
            try {
                loadingState.emitLoading()
                if (deliveryConfigInteractor.getPaymentTypeList().contains(PaymentType.ONLINE)) {
                    orderInteractor.loadOnlinePaymentCardList()
                }
                loadingState.emitSuccess(null)
            } catch (exception: Exception) {
                _messageEvent.send(exception.localizedMessage!!)
            }
        }
    }

    private fun loadOnlineClientAddress() {
        viewModelScope.launch {
            try {
                loadingState.emitLoading()
                val cacheOrderData = orderInteractor.makeOrderFieldsData.first() as MakeOrderFieldsData.Fields
                val orderInitData = orderInteractor.getInitData()
                hasLatestComments = orderInitData.hasSavedComments
                val email = cacheOrderData.orderInitData?.email ?: orderInitData.email
                promoCode = promoCodeInteractor.getPromoCode()?.data?.text

                val bonusesAmount = Money.fromWholePart(orderInitData.bonusesPointsDiscount?.toLong() ?: 0)
                val promoCodeDiscount = orderInitData.promoCodeDiscount ?: Money.ZERO
                val totalAmount = with(orderInitData) {
                    (orderSum + deliveryPrice + (weightData.overWeightData?.overWeightAmount ?: Money.ZERO)) -
                        (bonusesAmount + promoCodeDiscount)
                }

                dataState.emit(
                    requiredViewState.copy(
                        customAddressBlock = cacheOrderData.customAddressBlock,
                        orderInitData = orderInitData.copy(email = email),
                        summaryBlock = MakeOrderFieldsData.Fields.SummaryBlock(
                            orderAmount = orderInitData.orderSum,
                            deliveryAmount = orderInitData.deliveryPrice,
                            bonusesAmount = bonusesAmount,
                            promoCodeDiscountAmount = promoCodeDiscount,
                            totalAmount = totalAmount,
                            weightData = orderInitData.weightData,
                        ),
                    ),
                )

                loadingState.emitSuccess(null)
            } catch (exception: Exception) {
                loadingState.emitError(exception)
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        orderInteractor.saveMakeOrderFields(dataState.value)
    }

    private companion object {

        val emailNotValidError = MakeOrderFieldsData.Fields.FieldError.EmailNotValid
        val emailNotFilledError = MakeOrderFieldsData.Fields.FieldError.EmailNotFilled

        val phoneNotValidError = MakeOrderFieldsData.Fields.FieldError.PhoneNotValid
        val phoneNotFilledError = MakeOrderFieldsData.Fields.FieldError.PhoneNotFilled
    }
}

private fun PaymentType.toOrderPaymentType(): OrderPaymentType {
    return when (this) {
        PaymentType.CASH -> OrderPaymentType.Cash
        PaymentType.CARD -> OrderPaymentType.ByCard
        PaymentType.ONLINE -> OrderPaymentType.ByNewCardOnline
        PaymentType.SBP -> OrderPaymentType.ViaSbp
    }
}