Каталог

Большие мягкие игрушки «Кот»

По вашему запросу ничего не найдено

Большие мягкие игрушки: Профессиональный подход к выбору и покупке

В современном мире большие мягкие игрушки занимают особое место в жизни детей и взрослых. Они не только служат предметом для игры, но и становятся верными спутниками, мини-психологами и источниками уюта. В нашем интернет-магазине вы можете купить огромные плюшевые игрушки по низкой цене, а также заказать их с доставкой в любом уголке Москвы и по всей России.

Почему стоит выбрать большие мягкие игрушки?

Большие мягкие игрушки привлекают внимание своей мягкостью и размером. Они создают атмосферу тепла и комфорта, и именно поэтому идеально подходят для праздника, будь то день рождения, Новый год или любой другой важный момент из жизни. Каждая игрушка предоставляет уникальную возможность для проявления заботы и любви. В нашем ассортименте вы найдете разнообразные модели: котов, капибар, собак, рыб и медведей. Эти игрушки не только радуют глаз, но и становятся идеальным подарком для детей и взрослых.

Разнообразие моделей

  • Большие мягкие коты — это не просто игрушки, а настоящие компаньоны. Их мягкие тела и дружелюбные лица способны поднять настроение в любой ситуации. Коты подарят вашему ребенку радость и уют.
  • Капибары — забавные и милые создания, которые завоевали популярность благодаря своей уникальной внешности и добродушному характеру. Большие мягкие игрушки в виде капибар идеально подойдут для создания уютной атмосферы в доме.
  • Собаки — верные спутники, символ преданности и любви. Большие мягкие собаки способны стать не только игрушками, но и настоящими друзьями для вашего ребенка.
  • Рыбы — яркие и необычные, они привносят в дом атмосферу подводного мира. Большие мягкие игрушки в виде рыб станут отличным дополнением к детской комнате и добавят ей оригинальности.
  • Медведи — классика жанра. Большие плюшевые медведи всегда были и будут популярными. Они символизируют защиту и заботу, а также станут не только игрушкой, но и элементом декора.

Почему стоит покупать у нас?

Мы предлагаем большие мягкие игрушки недорого, с возможностью закупить их оптом. У нас есть оптовый склад, где вы всегда сможете найти самые выгодные предложения. Мы гарантируем низкие цены и высокое качество нашей продукции.

  • С доставкой по всей России: Мы обеспечим вам быструю и надежную доставку, чтобы вы могли получить свои любимые товары в кратчайшие сроки.
  • Разнообразие выбора: В нашем магазине вы найдете не только большие мягкие игрушки, но и различные аксессуары, такие как брелки, которые можно использовать для дополнения подарка.
  • Качественные материалы: Все наши игрушки изготовлены из безопасных для детей материалов, что делает их идеальными для игры.

Как оформить заказ?

Чтобы заказать большие мягкие игрушки, достаточно выбрать понравившуюся модель на нашем сайте, добавить в корзину и оформить заказ. Мы доставим ваш заказ с доставкой по всей России, включая Москву. Не упустите возможность получить качественные игрушки по низкой цене!

Большие мягкие игрушки — это не просто предметы для игры, это настоящие друзья, которые приносят радость и комфорт в каждый дом. Мы предлагаем широкий выбор моделей, качественные материалы и выгодные условия покупки. Не откладывайте на потом — купите большие мягкие игрушки в нашем магазине уже сегодня! Обеспечьте своему ребенку яркие эмоции и счастье, которые подарят эти милые создания.

Обратный звонок
Запрос успешно отправлен!
Имя *
Телефон *
Предзаказ
Предзаказ успешно отправлен!
Имя *
Телефон *
Добавить в корзину
Название товара
100 ₽
1 шт.
Перейти в корзину
Заявка

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.

Заявка

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.

`; } /** * Показ модального окна ошибки оформления заказа */ showOrderErrorModal(result) { // Скрываем успешное окно и показываем ошибку $('.order-success-content').hide(); $('.order-error-content').show(); // Заполняем сообщение об ошибке $('#error-message').text(result.details || result.error || 'Произошла ошибка при оформлении заказа'); this.showModal('Ошибка оформления заказа', '', 'error'); } /** * Создание содержимого модального окна успеха */ createSuccessModalContent(result) { const { orderNumber, paymentMethod, clientType, paymentButton } = result; // Получаем HTML ответ для поиска ключа заказа const $html = $(result.htmlResponse || ''); // Извлекаем информацию о заказе из HTML const orderInfo = this.extractOrderInfo($html); const orderItems = this.extractOrderItems($html); let content = `

Заказ №${orderNumber}

Товары в заказе
${this.createOrderItemsHTML(orderItems)}
${this.createOrderTotalHTML(orderItems)}
Информация о заказе
${this.createOrderInfoHTML(orderInfo, paymentMethod, clientType)} ${paymentMethod === 'Юкасса' && paymentButton ? this.createPaymentSectionHTML(paymentButton, $html) : ''}
`; return content; } /** * Извлечение информации о заказе из HTML */ extractOrderInfo($html) { const info = { orderDate: new Date().toLocaleDateString('ru-RU'), deliveryMethod: 'Доставка курьером', deliveryAddress: '', recipient: '', phone: '', email: '' }; // Извлекаем адрес доставки const addressSelectors = [ '.delivery-address', '.shipping-address', '[class*="address"]' ]; for (const selector of addressSelectors) { const $address = $html.find(selector); if ($address.length > 0) { info.deliveryAddress = $address.text().trim(); break; } } // Извлекаем получателя const recipientSelectors = [ '.recipient-name', '.client-name', '[class*="recipient"]' ]; for (const selector of recipientSelectors) { const $recipient = $html.find(selector); if ($recipient.length > 0) { info.recipient = $recipient.text().trim(); break; } } // Извлекаем телефон и email из формы info.phone = $('#phone').val() || ''; info.email = $('#email').val() || ''; // Если не нашли получателя, используем данные из формы if (!info.recipient) { const firstName = $('#contact_name').val() || ''; const lastName = $('#surname').val() || ''; const middleName = $('#middlename').val() || ''; info.recipient = `${lastName} ${firstName} ${middleName}`.trim(); } // Если не нашли адрес, используем данные из формы if (!info.deliveryAddress) { const city = $('#shipping_address_full_locality_name').val() || ''; const street = $('#shipping_address_street').val() || ''; const house = $('#shipping_address_house').val() || ''; const flat = $('#shipping_address_flat').val() || ''; info.deliveryAddress = `${city}, ${street}, д.${house}${flat ? ', кв.' + flat : ''}`.trim(); } return info; } /** * Извлечение товаров заказа из HTML */ extractOrderItems($html) { const items = []; // Сначала пытаемся получить товары из текущей корзины const $cartItems = $('.cart-item'); const self = this; // Сохраняем контекст if ($cartItems.length > 0) { $cartItems.each(function() { const $item = $(this); const imageSrc = $item.find('img').attr('src') || ''; const item = { name: $item.find('.item-title').text().trim() || 'Товар', sku: $item.find('.item-sku').text().trim() || '', quantity: $item.find('input[name*="quantity"]').val() || '1', price: $item.find('.item-total').text().trim() || '0 ₽', image: self.isValidImageUrl(imageSrc) ? imageSrc : '' }; if (item.name && item.name !== 'Товар') { items.push(item); } }); } // Если не нашли в корзине, ищем в HTML ответе if (items.length === 0) { const itemSelectors = [ '.order-item', '.cart-item', '.product-item', '[class*="item"]' ]; for (const selector of itemSelectors) { const $items = $html.find(selector); if ($items.length > 0) { $items.each(function() { const $item = $(this); const imageSrc = $item.find('img').attr('src') || ''; const item = { name: $item.find('.item-name, .product-name, [class*="name"]').text().trim() || 'Товар', sku: $item.find('.item-sku, .product-sku, [class*="sku"]').text().trim() || '', quantity: $item.find('.item-quantity, .product-quantity, [class*="quantity"]').text().trim() || '1', price: $item.find('.item-price, .product-price, [class*="price"]').text().trim() || '0 ₽', image: self.isValidImageUrl(imageSrc) ? imageSrc : '' }; if (item.name && item.name !== 'Товар') { items.push(item); } }); break; } } } // Если все еще не нашли товары, создаем заглушку if (items.length === 0) { items.push({ name: 'Товары в заказе', sku: '', quantity: '1', price: '0 ₽', image: '' }); } return items; } /** * Создание HTML для товаров заказа */ createOrderItemsHTML(items) { return items.map(item => { const imageHTML = (item.image && this.isValidImageUrl(item.image)) ? `
${item.name || ''}
` : ''; return `
${imageHTML}
${item.name || ''}
${item.sku ? `
Артикул: ${item.sku}
` : ''}
Количество: ${item.quantity || 1}
${item.price || 0}
`; }).join(''); } /** * Создание HTML для итоговой суммы */ createOrderTotalHTML(items) { // Получаем данные из корзины const $cartTotal = $('[data-cart-total-price]'); const $cartDiscount = $('.discount .insales-ui-discounts-errors'); let totalPrice = '0 ₽'; let discountPrice = '0 ₽'; if ($cartTotal.length > 0) { totalPrice = $cartTotal.text().trim() || '0 ₽'; } if ($cartDiscount.length > 0) { const discountText = $cartDiscount.text().trim(); const discountMatch = discountText.match(/(\d+[\s,]*\d*)\s*₽/); if (discountMatch) { discountPrice = discountMatch[0]; } } return `
Скидка: ${discountPrice}
Итого: ${totalPrice}
`; } /** * Создание HTML для информации о заказе */ createOrderInfoHTML(orderInfo, paymentMethod, clientType) { return `
Дата оформления:
${orderInfo.orderDate}
Способ оплаты:
${paymentMethod}
Способ доставки:
${orderInfo.deliveryMethod}
Адрес доставки:
${orderInfo.deliveryAddress || 'Не указан'}
Получатель:
${orderInfo.recipient || 'Не указан'}
Телефон:
${orderInfo.phone || 'Не указан'}
Email:
${orderInfo.email || 'Не указан'}
`; } /** * Создание HTML для секции оплаты */ createPaymentSectionHTML(paymentButton, $html) { // Проверяем, что ссылка корректная let paymentUrl = paymentButton.href; if (!paymentUrl || paymentUrl === 'https://канцопт24.рф/page/payment') { // Если ссылка неправильная, создаем правильную const orderKey = this.extractOrderKey($html); if (orderKey) { paymentUrl = `/payments/external/6146185/create?key=${orderKey}`; } } return `

Для завершения заказа необходимо произвести оплату:

${paymentButton.text || 'Перейти к оплате'}
`; } /** * Создание содержимого модального окна ошибки */ createErrorModalContent(result) { const { error, details } = result; return `

${error}

${details ? `

${details}

` : ''}
`; } /** * Показ модального окна */ showModal(title, content, type = 'info') { const $modal = $('#order-result-modal'); if ($modal.length === 0) { return; } const $modalTitle = $modal.find('.modal-title'); // Устанавливаем заголовок $modalTitle.text(title); // Показываем нужный контент в зависимости от типа if (type === 'success') { $('.order-success-content').show(); $('.order-error-content').hide(); } else if (type === 'error') { $('.order-success-content').hide(); $('.order-error-content').show(); } // Блокируем прокрутку фона (как в CU0.14) const scrollY = window.scrollY; $('body').addClass('modal-open').css({ 'position': 'fixed', 'top': `-${scrollY}px`, 'width': '100%', 'overflow': 'hidden' }); // Принудительно показываем модальное окно $modal.attr('style', ` position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background: rgba(0, 0, 0, 0.6) !important; backdrop-filter: blur(4px) !important; z-index: 10000 !important; display: flex !important; align-items: center !important; justify-content: center !important; opacity: 1 !important; pointer-events: auto !important; overflow-y: auto !important; padding: 20px !important; `); // Обработчик закрытия по клику на overlay const self = this; $modal.off('click.modal').on('click.modal', function(e) { // Проверяем, что клик был именно по overlay (не по содержимому) if (e.target === this || $(e.target).hasClass('modal-overlay')) { self.closeModal(); } }); // Обработчик закрытия по клавише Escape $(document).off('keydown.modal').on('keydown.modal', function(e) { if (e.key === 'Escape' || e.keyCode === 27) { self.closeModal(); } }); } /** * Закрытие модального окна */ closeModal() { const $modal = $('#order-result-modal'); if ($modal.length) { // Скрываем модальное окно и отключаем pointer-events $modal.attr('style', 'display: none !important; pointer-events: none !important;'); } // Очищаем обработчики событий $modal.off('click.modal'); $(document).off('keydown.modal'); // Разблокируем прокрутку фона $('body').removeClass('modal-open'); $('body').removeAttr('style'); $('html').removeAttr('style'); // Принудительная перезагрузка с обходом кеша // Используем несколько методов для максимальной надежности на мобильных const currentUrl = window.location.href.split('?')[0].split('#')[0]; const timestamp = new Date().getTime(); const newUrl = currentUrl + '?nocache=' + timestamp; // Используем replace вместо reload для более агрессивной очистки window.location.replace(newUrl); } /** * Сброс виджета */ resetWidget() { // Проверяем, нужно ли сбрасывать состояние // Сбрасываем только для авторизованных + незарегистрированных // Для авторизованных + зарегистрированных НЕ сбрасываем if (this.clientState.isAuthorized && this.clientState.isRegistered) { // Не сбрасываем состояние для авторизованных и зарегистрированных return; } this.clientState = { isAuthorized: false, isRegistered: false, email: null, clientType: 'individual', clientData: null, authCodeSent: false, codeTimer: null }; localStorage.removeItem('client_auth'); $('#order-form')[0].reset(); $('#auth-email-form')[0].reset(); $('#auth-code-form')[0].reset(); $('#order-success-step').removeClass('active'); $('#order-form-step').removeClass('active'); $('#auth-code-step').removeClass('active'); $('#auth-email-step').addClass('active'); this.updateUI(); } /** * Обновление UI */ updateUI() { if (this.clientState.isAuthorized) { this.showAuthSuccess(this.clientState.email); // Скрываем заголовок авторизации для авторизованного клиента $('.auth-header').hide(); // Заполняем email для авторизованного клиента if (this.clientState.email) { $('#email').val(this.clientState.email); $('#email').prop('disabled', true); $('#email').addClass('disabled-field'); } // Проверяем наличие данных клиента (id ИЛИ email + name) const hasValidClientData = this.clientState.clientData && (this.clientState.clientData.id || (this.clientState.clientData.email && this.clientState.clientData.name)); if (this.clientState.isRegistered && hasValidClientData) { this.fillFormWithClientData(); this.showClientStatus(); // Сворачиваем блок организации для авторизованных юр.лиц if (this.clientState.clientType === 'juridical') { this.collapseOrgSectionForAuthUser(); } } } else { // Показываем заголовок авторизации для неавторизованного клиента $('.auth-header').show(); // Разблокируем поле email для неавторизованного клиента $('#email').prop('disabled', false); $('#email').removeClass('disabled-field'); $('#email').val(''); // Очищаем поле // Очищаем статус организации this.setStatusOrgName(null); // Показываем селектор типа клиента this.showClientTypeSelector(); $('#auth-email-step').addClass('active'); $('#auth-code-step').removeClass('active'); $('#auth-success-step').removeClass('active'); } } /** * Таймер для повторной отправки кода */ startCodeTimer() { // Сначала останавливаем предыдущий таймер, если он был запущен this.stopCodeTimer(); // Блокируем кнопку и показываем таймер $('#resend-code-btn').prop('disabled', true).text('Отправить повторно'); $('.code-timer').show(); this.timerSeconds = 60; this.updateTimerDisplay(); // Показываем начальное значение this.codeTimer = setInterval(() => { this.timerSeconds--; if (this.timerSeconds <= 0) { // Разблокируем кнопку повторной отправки и скрываем таймер $('#resend-code-btn').prop('disabled', false).text('Отправить повторно'); $('.code-timer').hide(); this.stopCodeTimer(); } else { this.updateTimerDisplay(); } }, 1000); } /** * Остановка таймера кода */ stopCodeTimer() { if (this.codeTimer) { clearInterval(this.codeTimer); this.codeTimer = null; } } /** * Обновление отображения таймера */ updateTimerDisplay() { const minutes = Math.floor(this.timerSeconds / 60); const seconds = this.timerSeconds % 60; $('#code-timer-text').html(`Повторная отправка через: ${minutes}:${seconds.toString().padStart(2, '0')} сек`); } /** * Показ поля ввода email */ showEmailInput() { $('#auth-code-step').removeClass('active'); $('#auth-email-step').addClass('active'); this.clientState.authCodeSent = false; } /** * Обработка повторной отправки кода */ async handleResendCode() { const email = $('#auth-email').val().trim(); if (!email) { this.showNotification('Нет сохраненного email для повторной отправки', 'error'); return; } // Блокируем кнопку (текст остаётся "Отправить повторно") $('#resend-code-btn').prop('disabled', true); try { const result = await this.sendAuthCode(email); if (result.success) { this.showNotification('Код отправлен повторно', 'success'); // Запускаем таймер (он сам покажет таймер и заблокирует кнопку) this.startCodeTimer(); } else { this.showNotification(result.errors || result.error, 'error'); // При ошибке разблокируем кнопку $('#resend-code-btn').prop('disabled', false); } } catch (error) { this.showNotification('Ошибка повторной отправки кода', 'error'); // При ошибке разблокируем кнопку $('#resend-code-btn').prop('disabled', false); } } /** * Обработка смены email */ handleChangeEmail() { // Останавливаем таймер this.stopCodeTimer(); // Очищаем поля $('#auth-email').val(''); $('#auth-code').val(''); // Возвращаемся к форме ввода email this.showEmailInput(); // Фокусируемся на поле email setTimeout(() => { $('#auth-email').focus(); }, 100); } /** * Показ состояния загрузки */ showLoading(selector) { $(selector).addClass('loading'); } /** * Скрытие состояния загрузки */ hideLoading(selector) { $(selector).removeClass('loading'); } /** * Показ ошибки */ showError(elementId, message) { $(`#${elementId}`).text(message).addClass('show'); } /** * Скрытие ошибки */ hideError(elementId) { $(`#${elementId}`).removeClass('show').text(''); } /** * Отключение стандартной валидации браузера */ disableBrowserValidation() { // Принудительно убираем красную обводку с необязательных полей при загрузке $('#kpp, #okpo').css({ 'border-color': '#d1d5db', 'box-shadow': 'none', 'outline': 'none' }); // Отключаем стандартную валидацию для необязательных полей $('#kpp, #okpo').on('invalid', function(e) { e.preventDefault(); $(this).removeClass('error'); $(this).css({ 'border-color': '#d1d5db', 'box-shadow': 'none', 'outline': 'none' }); }); // Принудительно убираем красную обводку с необязательных полей при любом событии $('#kpp, #okpo').on('blur focus input change', function() { $(this).removeClass('error'); $(this).css({ 'border-color': '#d1d5db', 'box-shadow': 'none', 'outline': 'none' }); }); // Периодически проверяем и убираем красную обводку setInterval(() => { $('#kpp, #okpo').css({ 'border-color': '#d1d5db', 'box-shadow': 'none', 'outline': 'none' }); }, 100); } /** * Обработчики для скрытия ошибок при вводе */ initErrorHandlers() { // Список всех полей с их error ID const fieldErrorMap = { 'contact_name': 'contact_name-error', 'surname': 'surname-error', 'phone': 'phone-error', 'email': 'email-error', 'organization_name': 'organization_name-error', 'legal_address': 'legal_address-error', 'inn': 'inn-error', 'kpp': 'kpp-error', 'ogrn': 'ogrn-error', 'okpo': 'okpo-error', 'bik': 'bik-error', 'bank_name': 'bank_name-error', 'correspondent_account': 'correspondent_account-error', 'settlement_account': 'settlement_account-error', 'delivery_city': 'delivery_city-error', 'delivery_street': 'delivery_street-error', 'delivery_house': 'delivery_house-error' }; // Добавляем обработчики для каждого поля Object.keys(fieldErrorMap).forEach(fieldId => { $(`#${fieldId}`).on('input focus', () => { this.hideError(fieldErrorMap[fieldId]); }); }); } /** * Инициализация обработчиков сворачивания блока организации */ initOrgCollapseHandlers() { // Обработчик клика на заголовок блока организации $(document).on('click', '.org-section-header', () => { this.toggleOrgSection(); }); } /** * Переключение сворачивания/разворачивания блока организации */ toggleOrgSection() { const $orgSection = $('#organization-section'); const $orgContent = $('#org-section-content'); if ($orgSection.hasClass('collapsed')) { // Разворачиваем $orgSection.removeClass('collapsed'); $orgContent.slideDown(300); } else { // Сворачиваем $orgSection.addClass('collapsed'); $orgContent.slideUp(300); } } /** * Установка названия организации в заголовок блока */ setOrgSectionName(orgName) { const $orgName = $('#org-section-name'); const $orgTitle = $('.org-section-title'); if (orgName) { $orgName.text(` - ${orgName}`).show(); $orgTitle.text('Данные организации'); } else { $orgName.hide(); $orgTitle.text('Данные организации'); } } /** * Установка названия организации в статус клиента */ setStatusOrgName(orgName) { const $statusOrgName = $('#status-org-name'); if (orgName) { $statusOrgName.text(` "${orgName}"`).show(); } else { $statusOrgName.hide(); } } /** * Сворачивание блока организации для зарегистрированных юр.лиц */ collapseOrgSectionForAuthUser() { if (this.clientState.clientType === 'juridical') { const $orgSection = $('#organization-section'); $orgSection.addClass('collapsed'); $('#org-section-content').hide(); } } /** * Показ уведомления */ showNotification(message, type = 'info') { const notification = $(`
${message}
`); $('#widget-notifications').append(notification); // Автоматически скрываем через 5 секунд setTimeout(() => { notification.fadeOut(() => notification.remove()); }, 5000); } /** * Проверка заполненности обязательных полей организации и разворачивание блока */ checkOrgFieldsAndExpand() { const requiredFields = [ 'organization_name', 'legal_address', 'inn', 'ogrn', 'bik', 'bank_name', 'correspondent_account', 'settlement_account' ]; // Проверяем, есть ли пустые обязательные поля let hasEmptyFields = false; for (const fieldId of requiredFields) { const value = $(`#${fieldId}`).val(); if (!value || value.trim() === '') { hasEmptyFields = true; break; } } // Если есть пустые поля, разворачиваем блок организации if (hasEmptyFields) { const $orgSection = $('#organization-section'); $orgSection.removeClass('collapsed'); $('#org-section-content').show(); // Показываем уведомление this.showNotification('Заполните недостающие данные организации для оформления заказа', 'info'); } } /** * Получение данных организации по ИНН через DaData API * * ИНСТРУКЦИЯ ПО НАСТРОЙКЕ: * 1. Зарегистрируйтесь на https://dadata.ru * 2. Получите API ключ в личном кабинете * 3. Замените 'YOUR_DADATA_API_KEY' на ваш реальный ключ * 4. Бесплатный тариф: 100 запросов в сутки */ async fetchCompanyDataByINN(inn) { try { // Очищаем ИНН от лишних символов const cleanINN = inn.replace(/\D/g, ''); if (cleanINN.length !== 10 && cleanINN.length !== 12) { throw new Error('ИНН должен содержать 10 или 12 цифр'); } // Показываем индикатор загрузки this.showFieldLoading('inn', true); // Запрос к DaData API const response = await fetch('https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Token da92b4f24405aa61c91ead2726c34a99f965376a', 'Accept': 'application/json' }, body: JSON.stringify({ query: cleanINN }) }); if (!response.ok) { throw new Error('Ошибка при запросе к DaData API'); } const data = await response.json(); if (data.suggestions && data.suggestions.length > 0) { const company = data.suggestions[0].data; // Заполняем поля организации (используем краткое название) $('#organization_name').val(company.name?.short_with_opf || company.name?.full_with_opf || ''); // Полный юридический адрес - собираем из всех доступных частей let fullAddress = ''; // Сначала пробуем получить полный адрес с индексом if (company.address?.unrestricted_value) { fullAddress = company.address.unrestricted_value; } else if (company.address?.data?.source) { fullAddress = company.address.data.source; } else if (company.address?.value) { fullAddress = company.address.value; } else { // Собираем адрес из частей const parts = []; if (company.address?.data?.postal_code) parts.push(company.address.data.postal_code); if (company.address?.data?.region) parts.push(company.address.data.region); if (company.address?.data?.city) parts.push(company.address.data.city); if (company.address?.data?.street) parts.push(company.address.data.street); if (company.address?.data?.house) parts.push(company.address.data.house); if (company.address?.data?.flat) parts.push('кв. ' + company.address.data.flat); fullAddress = parts.join(', '); } // Для ИП адрес может быть только город - это нормально $('#legal_address').val(fullAddress); $('#ogrn').val(company.ogrn || ''); $('#okpo').val(company.okpo || ''); // КПП всегда заполняем, если есть if (company.kpp) { $('#kpp').val(company.kpp); } else { // Если КПП нет в данных, оставляем поле пустым $('#kpp').val(''); // Для ИП добавляем подсказку, что КПП не нужен if (company.type === 'INDIVIDUAL') { $('#kpp').attr('placeholder', 'КПП не требуется для ИП'); } } // Делаем поля readonly после автозаполнения this.setFieldsReadonly(['organization_name', 'legal_address', 'ogrn', 'okpo', 'kpp'], true); // Принудительно сбрасываем стили для проблемных полей setTimeout(() => { $('#kpp, #okpo').css({ 'border': '2px solid #e1e5e9', 'box-shadow': 'none', 'outline': 'none' }); }, 100); this.showNotification('Данные организации загружены автоматически', 'success'); } else { throw new Error('Организация с таким ИНН не найдена'); } } catch (error) { this.showNotification(`Ошибка загрузки данных: ${error.message}`, 'error'); } finally { this.showFieldLoading('inn', false); } } /** * Получение банковских данных по БИК через DaData API * * ИНСТРУКЦИЯ ПО НАСТРОЙКЕ: * 1. Используйте тот же API ключ, что и для организаций * 2. Замените 'YOUR_DADATA_API_KEY' на ваш реальный ключ * 3. Бесплатный тариф: 100 запросов в сутки */ async fetchBankDataByBIK(bik) { try { // Очищаем БИК от лишних символов const cleanBIK = bik.replace(/\D/g, ''); if (cleanBIK.length !== 9) { throw new Error('БИК должен содержать 9 цифр'); } // Показываем индикатор загрузки this.showFieldLoading('bik', true); // Запрос к DaData API для банков const response = await fetch('https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/bank', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Token da92b4f24405aa61c91ead2726c34a99f965376a', 'Accept': 'application/json' }, body: JSON.stringify({ query: cleanBIK }) }); if (!response.ok) { throw new Error('Ошибка при запросе к DaData API'); } const data = await response.json(); if (data.suggestions && data.suggestions.length > 0) { const bank = data.suggestions[0].data; // Заполняем банковские поля $('#bank_name').val(bank.name?.payment || bank.name?.full || ''); if (bank.correspondent_account) { $('#correspondent_account').val(bank.correspondent_account); } // Делаем поля readonly после автозаполнения this.setFieldsReadonly(['bank_name', 'correspondent_account'], true); this.showNotification('Банковские данные загружены автоматически', 'success'); } else { throw new Error('Банк с таким БИК не найден'); } } catch (error) { this.showNotification(`Ошибка загрузки банковских данных: ${error.message}`, 'error'); } finally { this.showFieldLoading('bik', false); } } /** * Показать/скрыть индикатор загрузки для поля */ showFieldLoading(fieldId, show) { const $field = $(`#${fieldId}`); const $loading = $field.siblings('.field-loading'); if (show) { if ($loading.length === 0) { $field.after('
⏳ Загрузка...
'); } $field.prop('disabled', true); } else { $loading.remove(); $field.prop('disabled', false); } } /** * Установить поля в режим readonly */ setFieldsReadonly(fieldIds, readonly) { fieldIds.forEach(fieldId => { const $field = $(`#${fieldId}`); $field.prop('readonly', readonly); if (readonly) { $field.addClass('auto-filled'); } else { $field.removeClass('auto-filled'); } }); } /** * Инициализация обработчика сообщений о промокодах */ initCouponMessageHandler() { // Флаг для предотвращения повторной обработки let isProcessing = false; // Следим только за изменениями в DOM const observer = new MutationObserver((mutations) => { if (isProcessing) return; mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // Element node const $node = $(node); // Проверяем только точное сообщение о регистрации const text = $node.text().trim(); if (text === 'Для использования купона необходимо зарегистрироваться') { isProcessing = true; const isUnauthorized = !this.clientState.isAuthorized; const isAuthorizedButUnregistered = this.clientState.isAuthorized && !this.clientState.isRegistered; if (isUnauthorized || isAuthorizedButUnregistered) { $node.replaceWith(this.createCouponSuccessMessage()); } setTimeout(() => { isProcessing = false; }, 100); } // Проверяем вложенные элементы $node.find('*').each((index, element) => { const $element = $(element); const text = $element.text().trim(); if (text === 'Для использования купона необходимо зарегистрироваться') { isProcessing = true; const isUnauthorized = !this.clientState.isAuthorized; const isAuthorizedButUnregistered = this.clientState.isAuthorized && !this.clientState.isRegistered; if (isUnauthorized || isAuthorizedButUnregistered) { $element.replaceWith(this.createCouponSuccessMessage()); } setTimeout(() => { isProcessing = false; }, 100); } }); } }); } }); }); // Начинаем наблюдение за изменениями в DOM observer.observe(document.body, { childList: true, subtree: true }); // Перехватываем через наш метод showNotification const originalShowNotification = this.showNotification; this.showNotification = (message, type) => { if (message === 'Для использования купона необходимо зарегистрироваться') { const isUnauthorized = !this.clientState.isAuthorized; const isAuthorizedButUnregistered = this.clientState.isAuthorized && !this.clientState.isRegistered; if (isUnauthorized || isAuthorizedButUnregistered) { this.showCouponSuccessMessage(); return; } } originalShowNotification.call(this, message, type); }; } /** * Создать элемент сообщения об успешном применении промокода */ createCouponSuccessMessage() { return $(`
Промокод будет применен при оформлении заказа
`); } /** * Скрыть предупреждения InSales в консоли */ hideConsoleWarnings() { // Перехватываем console.warn для скрытия предупреждений о купонах const originalWarn = console.warn; console.warn = function(...args) { const message = args.join(' '); // Скрываем предупреждения о купонах if (message.includes('Вы отключили атвоматическое обновление страницы корзины после применения купона') || message.includes('set_coupon:insales:cart')) { return; // Не выводим это сообщение } // Для всех остальных сообщений используем оригинальный warn originalWarn.apply(console, args); }; } /** * Показать сообщение об успешном применении промокода */ showCouponSuccessMessage() { // Удаляем предыдущие сообщения о промокоде $('.coupon-success-message').remove(); // Создаем новое сообщение const $message = this.createCouponSuccessMessage(); // Ищем поле промокода и добавляем сообщение после него const $couponField = $('input[name="coupon_code"], input[name="coupon"], input[placeholder*="промокод"], input[placeholder*="Промокод"]'); if ($couponField.length > 0) { $couponField.after($message); } else { // Если поле не найдено, добавляем в конец формы $('.widget-main').append($message); } // Автоматически скрываем сообщение через 5 секунд setTimeout(() => { $message.fadeOut(300, function() { $(this).remove(); }); }, 5000); } } // Глобальная обработка ошибок для предотвращения поломки сайта window.addEventListener('error', function(event) { console.error('UNIFIED_WIDGET_V3: Глобальная ошибка JavaScript:', event.error); // Предотвращаем поломку сайта из-за внешних ошибок event.preventDefault(); }); // Обработка неправильных ссылок на изображения $(document).ready(function() { // Исправляем неправильные ссылки на изображения $('img[src*="${item.image}"]').each(function() { $(this).attr('src', '').hide(); console.warn('UNIFIED_WIDGET_V3: Исправлена неправильная ссылка на изображение'); }); }); // Инициализация виджета при загрузке DOM $(document).ready(function() { try { window.unifiedWidget = new UnifiedWidgetV3(); } catch (error) { console.error('UNIFIED_WIDGET_V3: Ошибка инициализации виджета:', error); } }); } catch(error) { console.error('Widget "widget-type_CART_ONLY"', error) } } catch(error) { console.error('Widget "widget-type_CART_ONLY"', error) }