/// =========================================================================
// ⚙ SaaS-ОБРАБОТЧИК РЕГИСТРАЦИИ (ВСТРАИВАЕТСЯ В КОНЕЦ ФАЙЛА BAZA.GS) v50.0
// =========================================================================
function handleSaaSRegistration(data) {
 var MASTER_CONTROL_ID = '15lc3jj5D4eadrrx0amG-rOE0yCPo2D1P51Hu-T-aV0c'; // ID Мастер-Таблицы
 var TEMPLATE_SHEET_ID = '1kDri-evB3XCaRitYY73WwoRa0CaaXshb3URUyEaKOrU'; // ID вашей идеальной таблицы-донора

 var email = String(data.email || '').trim().toLowerCase();
 var password = String(data.password || '').trim();
 var compName = String(data.compName || 'Студия аэродизайна').trim();

 if (!email || !password) {
  return ContentService.createTextOutput(JSON.stringify({ success: false, error: "Заполните Email и Пароль!" })).setMimeType(ContentService.MimeType.JSON);
 }

 var controlSheet = SpreadsheetApp.openById(MASTER_CONTROL_ID).getSheetByName('Пользователи');
 var usersData = controlSheet.getDataRange().getValues();

 // 1. Проверка на дубликаты
 for (var i = 1; i < usersData.length; i++) {
  if (String(usersData[i][0]).toLowerCase().trim() === email) {
   return ContentService.createTextOutput(JSON.stringify({ success: false, error: "Этот Email уже зарегистрирован в CRM!" })).setMimeType(ContentService.MimeType.JSON);
  }
 }

 try {
  // 2. Клонируем ваш автономный шаблон
  var templateFile = DriveApp.getFileById(TEMPLATE_SHEET_ID);
  // 📂 АВТОМАТИЧЕСКАЯ ОРГАНИЗАЦИЯ: Подключаем вашу целевую папку Диска
  var targetFolder = DriveApp.getFolderById('1ascecLnBm0h6lQKLW6bq0OfPffxYtRDZ');

  // Создаем копию шаблона-донора сразу внутри этой конкретной папки
  var newFile = templateFile.makeCopy("Balloon CRM База — " + email, targetFolder);

  var newSheetId = newFile.getId();


   // ✅ НАДЕЖНЫЙ SaaS-ШЕРИНГ ДЛЯ DRIVE API v3 БЕЗ СИСТЕМНЫХ УВЕДОМЛЕНИЙ GOOGLE
  // 1. БЕЗОПАСНЫЙ ШЕРИНГ ТАБЛИЦЫ КЛИЕНТУ
 var fileId = newFile.getId();
 try {
  // Делаем тихий шеринг через Drive API
  Drive.Permissions.create({
   'role': 'editor',
   'type': 'user',
   'value': email,
   'emailAddress': email
  }, fileId, {
   'sendNotificationEmail': false,
   'supportsAllDrives': true
  });
 } catch(eShare) {
  Logger.log("Ошибка Drive API: " + eShare.toString());
  // Если служба упала — открываем тихий доступ по ссылке редактора (БЕЗ СЕРЫХ ПИСЕМ GOOGLE!)
  try {
   newFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);
  } catch(eFallback) {}
 }

 // 2. РАСЧЕТ 7 ДНЕЙ БЕСПЛАТНОГО ТРИАЛА
 var dateRegistered = new Date();
 var dateExpired = new Date();
 dateExpired.setDate(dateRegistered.getDate() + 7);
 var formattedExpDate = Utilities.formatDate(dateExpired, Session.getScriptTimeZone(), "dd.MM.yyyy");

  // 3. ЗАПИСЬ НОВОГО ПОЛЬЗОВАТЕЛЯ В МАСТЕР-ТАБЛИЦУ УПРАВЛЕНИЯ
 controlSheet.appendRow([
  email,
  password,
  fileId,
  compName,
  "owner",
  "SaaS_System",
  formattedExpDate,
  "trial",
  "PENDING" // ◄ Колонка I (индекс 8): Сигнал для триггера, что письмо нужно отправить!
 ]);

  // 🔔 МГНОВЕННОЕ УВЕДОМЛЕНИЕ ДЛЯ ВЛАДЕЛЬЦА CRM v50.0
  try {
   var adminEmail = "vladballoon@mail.ru"; // ◄ ВПИСАЛ ВАШУ РАБОЧУЮ ПОЧТУ!
   var adminSubject = "🚀 Новая регистрация в Balloon CRM: " + compName;
   var adminBody = "🎉 Ура! На платформе зарегистрировался новый пользователь.\n\n" +
           "👤 Email/Логин: " + email + "\n" +
           "🎈 Студия: " + compName + "\n" +
           "📊 Ссылка на созданную базу: https://docs.google.com/spreadsheets/d/" + fileId + "\n\n" +
           "Проверьте Мастер-Таблицу, строка успешно создана со статусом PENDING.";

   GmailApp.sendEmail(adminEmail, adminSubject, adminBody);
  } catch(eAdmin) {
   Logger.log("Ошибка отправки уведомления админу: " + eAdmin.toString());
  }

 return ContentService.createTextOutput(JSON.stringify({ success: true, sheetId: fileId, compName: compName, role: "owner" })).setMimeType(ContentService.MimeType.JSON);

 } catch(errCopy) {
  return ContentService.createTextOutput(JSON.stringify({ success: false, error: "Ошибка генерации базы: " + errCopy.toString() })).setMimeType(ContentService.MimeType.JSON);
 }
}

 function crmBackgroundMailSender() {

 var MASTER_CONTROL_ID = '15lc3jj5D4eadrrx0amG-rOE0yCPo2D1P51Hu-T-aV0c';
 var controlSheet = SpreadsheetApp.openById(MASTER_CONTROL_ID).getSheetByName('Пользователи');

   // ======= 📨 АДМИНИСТРАТИВНЫЙ ШЛЮЗ МАССОВОЙ РАССЫЛКИ (СТОЛБЕЦ L) =======
 try {
  if (typeof controlSheet !== 'undefined' && controlSheet) {
   var lastMasterRow = controlSheet.getLastRow();
   if (lastMasterRow >= 2) {
    // Запрашиваем диапазон до 12 столбца (L) включительно
    var masterRange = controlSheet.getRange(2, 1, lastMasterRow - 1, 12);
    var masterValues = masterRange.getValues();

    for (var m = 0; m < masterValues.length; m++) {
     var masterRowNum = m + 2;

     // Предполагаем, что Email пользователя лежит в столбце B (индекс 1)
     // Если почта в другом столбце — измените индекс 1 ниже на нужный
     var userEmail = String(masterValues[m][0]).trim().toLowerCase();

     // Столбец L — это 12-й столбец (индекс в массиве 11)
     var mailCommand = String(masterValues[m][11]).trim();     

     if (mailCommand === "SEND_NEWS" && userEmail !== "") {
      var emailSubject = "📢 Ваша подписка скоро закончится";
      var mailSentSuccessfully = false;

      try {
       GmailApp.sendEmail(userEmail, emailSubject, "Включите отображение HTML-писем.", {
        htmlBody: getFormattedAdminNewsHtml(),
        name: "Balloon CRM SaaS Platform"
       });
       mailSentSuccessfully = true;
      } catch(eMailObj) {
       console.error("Ошибка отправки рассылки на почту " + userEmail + ": " + eMailObj.toString());
      }

      // После отправки затираем команду прямо в столбце L (12), записывая дату
      if (mailSentSuccessfully) {
       controlSheet.getRange(masterRowNum, 12).setValue("Отправлено: " + Utilities.formatDate(new Date(), "GMT+3", "dd.MM.yyyy HH:mm"));
      } else {
       controlSheet.getRange(masterRowNum, 12).setValue("Ошибка отправки");
      }
     }
    }
   }
  }
 } catch(eGlobalMailGate) {
  console.error("Критическая ошибка шлюза рассылки в столбце L: " + eGlobalMailGate.toString());
 }
 // ===============================================================================


 var data = controlSheet.getDataRange().getValues();

 for (var i = 1; i < data.length; i++) {
  var row = data[i];
  // Если в колонке I (индекс 8) стоит статус PENDING — отправляем письмо!
  if (row && row.length >= 9 && String(row[8]).trim() === "PENDING") {
   var email = row[0];
   var fileId = row[2];
   var password = row[1];
   var compName = row[3];
   var formattedExpDate = row[6];

   try {
    var tableUrl = "https://docs.google.com/spreadsheets/d/" + fileId + "/edit";
       var emailBody =
   '<div style="font-family:Arial,sans-serif;max-width:600px;color:#333;line-height:1.5;">' +
    '<h2 style="color:#1a73e8;">Добро пожаловать в Balloon CRM!</h2>' +
    '<p>Ваша персональная изолированная база данных успешно сгенерирована.</p>' +
    '<p style="margin:20px 0;"><a href="' + tableUrl + '" target="_blank" style="display:inline-block;background:#28a745;color:#fff;padding:12px 24px;text-decoration:none;border-radius:4px;font-weight:bold;">Открыть таблицу данных</a></p>' +
    '<hr style="border:0;border-top:1px solid #eee;margin:20px 0;">' +
    '<p><b>Инструкция по использованию:</b><br>' +
    'Перед началом работы обязательно ознакомьтесь с <a href="https://drive.google.com/drive/folders/1Ka4AVjId-mrEYWvOzuAMjbkOc6d52O53?dmr=1&ec=wgc-drive-%5Bmodule%5D-goto" target="_blank"> инструкцией по ссылке</a>.</p>' +
    // 🔥 ИСПРАВЛЕННЫЙ SaaS-БЛОК КНОПКИ ВХОДА В CRM v50.0
    '<div style="text-align: center; margin: 25px 0;">' +
    '<a href="https://tvoymarketing.ru/kalkulator" target="_blank" style="display: inline-block; background-color: #1a73e8; color: #ffffff; font-family: \'Helvetica Neue\', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 700; text-decoration: none; padding: 12px 28px; border-radius: 6px; box-shadow: 0 2px 4px rgba(26,115,232,0.25); transition: background-color 0.2s;">' +
    'Войти в личный кабинет CRM' +
    '</a>' +
    '</div>' +


    '<div style="background-color:#f8f9fa;padding:15px;border-left:4px solid #1a73e8;margin:15px 0;border-radius:4px;">' +
    '<b>Ваш логин:</b> ' + email + '<br>' +
    '<b>Ваш пароль:</b> ' + password + '<br>' +
    '<b>Пробный период:</b> 7 дней (до ' + formattedExpDate + ')' +
    '</div>' +
    '<p><b>Видеоматериалы:</b><br>' +
    'Прикладываем видеоинструкции по настройке базы данных и обзор СРМ. Все видео доступны в облачной папке:</p>' +
    '<p style="margin:20px 0;"><a href="https://drive.google.com/drive/folders/1Ka4AVjId-mrEYWvOzuAMjbkOc6d52O53?dmr=1&ec=wgc-drive-%5Bmodule%5D-goto" target="_blank" style="display:inline-block;background:#007bff;color:#fff;padding:12px 24px;text-decoration:none;border-radius:4px;font-weight:bold;">Смотреть видеоинструкции</a></p>' +
   '</div>';

    // Отправка под вашими железными правами Владельца
    GmailApp.sendEmail(email, "Доступы и активация базы Balloon CRM", "", {
     htmlBody: emailBody,
     name: "Balloon CRM SaaS Platform"
    });

    // Меняем статус на SENT, чтобы не отправлять письмо повторно
    controlSheet.getRange(i + 1, 9).setValue("SENT");
    SpreadsheetApp.flush();

   } catch(eMailErr) {
    Logger.log("Ошибка отправки триггером для " + email + ": " + eMailErr.toString());
    controlSheet.getRange(i + 1, 9).setValue("ERROR: " + eMailErr.toString());
   }
  }
 }
}

function getFormattedAdminNewsHtml() {
 return '<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333333; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px;">' +
     ' <h2 style="color: #1a73e8; margin-top: 0;">🎈 Balloon CRM: Большое обновление платформы и помощь в настройке!</h2>' +
     ' <p>Здравствуйте!</p>' +
     ' <p>Ваша подписка скоро закончится, для продления напишите создателю СРМ</p>' +
     ' <p>Мы упростили работу в СРМ и обновили инструкции, больше ни каких смежных таблиц, все в одной системе!</p>' +
     ' <div style="background-color: #e8f0fe; padding: 15px; border-radius: 6px; margin: 20px 0; border: 1px solid #b3d7ff;">' +
     '  <h3 style="color: #1a73e8; margin-top: 0; margin-bottom: 8px;">🔥 Главная новость: Полный отказ от таблиц!</h3>' +
     '  <p style="margin: 0; font-size: 14px;">Работать стало проще! <strong>с 16 июня 2026 года</strong>, мы выкатили масштабное обновление нашей первой версии. Вы сможете наслаждаться полноценным взаимодействием без необходимости перехода в таблицы данных — все возможности будут доступны в одном едином, удобном интерфейсе CRM со встроенными пошаговыми инструкциями.</p>' +
     ' </div>' +
     ' <p>Чтобы вы могли быстрее разобраться со всеми фишками и начать экономить время на рутине, мы открыли для вас <strong>прямую линию поддержки</strong>. Вы можете напрямую обратиться к создателю Balloon CRM в Telegram. Мы поможем адаптировать систему под ваши задачи, ответим на любые вопросы или проведем короткую демонстрацию.</p>' +
     ' <p style="background-color: #f8f9fa; padding: 12px; border-left: 4px solid #1a73e8; font-style: italic; font-size: 14px;">Это полностью бесплатно — нам искренне важно, чтобы наш продукт приносил реальную пользу вашей студии!</p>' +
     '<div style="text-align: center; margin: 25px 0;">' +
    '<a href="https://tvoymarketing.ru/kalkulator" target="_blank" style="display: inline-block; background-color: #1a73e8; color: #ffffff; font-family: \'Helvetica Neue\', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 700; text-decoration: none; padding: 12px 28px; border-radius: 6px; box-shadow: 0 2px 4px rgba(26,115,232,0.25); transition: background-color 0.2s;">' +
    'Войти в личный кабинет CRM' +
    '</a>' +
    '</div>' +
     ' <p>Для связи просто нажмите на синюю кнопку ниже:</p>' +
     ' <div style="text-align: center; margin: 25px 0;">' +
     '  <a href="https://t.me/k_andrey_sv" target="_blank" style="background-color: #1a73e8; color: #ffffff; text-decoration: none; padding: 12px 30px; border-radius: 6px; font-weight: bold; display: inline-block; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">💬 Написать создателю в Telegram</a>' +

     ' </div>' +
     ' <p>Мы на связи и готовы помочь вашему бизнесу расти!</p>' +
     ' <hr style="border: 0; border-top: 1px solid #e0e0e0; margin: 20px 0;">' +
     ' <p style="font-size: 12px; color: #777777;">С уважением,<br>Команда облачной платформы Balloon CRM</p>' +
     '</div>';
}

function smartCustomerUpsert(targetSheet, name, rawPhone, isFromOrder) {
 try {
  if (!rawPhone || !targetSheet) return "no_data";

  // Сквозной поиск строго по последним 10 цифрам номера (игнорируем 7/8/+)
  var digits = String(rawPhone).replace(/\D/g, "");
  if (digits.length < 10) return "phone_too_short";
  var cleanInputPhone = digits.substring(digits.length - 10);

  var lastRow = targetSheet.getLastRow();
  if (lastRow > 1) {
   // Считываем только первые 3 колонки (A - ID, B - Телефон, C - Имя)
   var data = targetSheet.getRange(2, 1, lastRow - 1, 3).getValues();

   for (var i = 0; i < data.length; i++) {
    var row = data[i];
    if (!row || row.length < 2) continue;

    var cellPhoneRaw = row[1] ? String(row[1]).replace(/\D/g, "") : "";
    if (cellPhoneRaw.length < 10) continue;
    var cleanBasePhone = cellPhoneRaw.substring(cellPhoneRaw.length - 10);

    // 🔥 ЕСЛИ КЛИЕНТ НАЙДЕН -> МЕРЖИМ БЕЗ ИЗМЕНЕНИЯ ЕГО СОБЫТИЯ/ПРАЗДНИКА
    if (cleanBasePhone === cleanInputPhone) {
     var rowNum = i + 2;

     // Обновляем только имя (Колонка C), если новое имя полнее
     var currentNameInBase = row[2] ? String(row[2]).trim() : "";
     if (name && (!currentNameInBase || String(name).length > currentNameInBase.length)) {
      targetSheet.getRange(rowNum, 3).setValue(name);
     }
          // Обновляем дату отгрузки в формате YYYY-MM-DD при повторном обращении
     var tildaFormattedDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
     targetSheet.getRange(rowNum, 4).setValue(tildaFormattedDate); // Запись в колонку D

     // Текст праздника менеджера в колонке E НЕ ТРОГАЕМ И НЕ СТИРАЕМ!
     return "merged"; // Выходим, дубликат заблокирован!
    }
   }
  }

    // 🔥 СИНХРОНИЗАЦИЯ ID С TILDA: Берем последние 7 цифр номера телефона!
 var phoneTailForId = cleanInputPhone.substring(cleanInputPhone.length - 7);
 var newId = "C-" + phoneTailForId;

 // ИСПРАВЛЕНО: Форматируем дату в понятный для Tilda вид "YYYY-MM-DD"
 var tildaFormattedDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");

 targetSheet.appendRow([
  newId,                         // А: ID Клиента
  "7" + cleanInputPhone,                 // B: Телефон
  name || "Без имени",                  // C: Имя
  tildaFormattedDate,                  // D: Дата взаимодействия (Теперь отобразится!)
  isFromOrder ? "Заказ шаров" : "Контакты",        // E: Событие
  isFromOrder ? "Из заказа" : "Внесено вручную",     // F: Примечание
  "Система"                       // G: Менеджер
 ]);
 return "created";

} catch (internalErr) {
 Logger.log("Ошибка в smartCustomerUpsert: " + internalErr.toString());
 return "error";
}
}


// ✅ МЕЖДУНАРОДНАЯ НОРМАЛИЗАЦИЯ НОМЕРОВ НА СЕРВЕРЕ (E.164)
function normalizeServerPhone(rawPhone) {
 if (rawPhone === null || rawPhone === undefined) return "";

 // Принудительно превращаем любой тип данных в строку и очищаем от пробелов
 var str = String(rawPhone).trim();
 if (!str) return "";

 var hasPlus = str.startsWith("+");
 // Оставляем строго только цифры
 var clean = str.replace(/\D/g, "");
 if (!clean) return "";

 if (hasPlus) return "+" + clean;

 if (clean.length === 11 && (clean.startsWith("7") || clean.startsWith("8"))) {
  return "+7" + clean.substring(1);
 }

 if (clean.length === 10) {
  return "+7" + clean;
 }

 return "+" + clean;
}

/**
 * 💾 СИНХРОНИЗАЦИЯ СТРУКТУРЫ ТОВАРОВ ИЗ CRM v100.0 (ПОЛНАЯ БЕЗОПАСНАЯ СБОРКА)
 * Исключает падение формул ВПР в калькуляторе и блокирует создание фантомных заказов
 */
function coreSavePrices(sheetId, clientCatalog) {
 if (!sheetId || !clientCatalog) return "error_bad_data";

 try {
  var catalogArr = clientCatalog;

  // Декодируем и парсим JSON-строку от Tilda
  if (typeof clientCatalog === "string") {
   var decodedString = clientCatalog;
   try {
    while (decodedString.indexOf('%') !== -1) {
     decodedString = decodeURIComponent(decodedString);
    }
   } catch(eDecode) {}
   catalogArr = JSON.parse(decodedString);
  }

  if (!Array.isArray(catalogArr)) return "error_not_array";

  var ss = SpreadsheetApp.openById(sheetId);
  var goodsSheet = ss.getSheetByName('Товары') || ss.getSheetByName('товары');
  if (!goodsSheet) return "error_no_sheet";

    // 🛡️ ЖЕСТКИЙ ФИКС ДЛЯ ОБХОДА ФАНТОМНЫХ ТРИГГЕРОВ СВЯЗАННЫХ ЛИСТОВ
  // Вместо .clear() стираем только контент первых двух столбцов, сохраняя ячейки живыми.
  // Это гарантирует, что ВПР в калькуляторе таблицы не упадет в секундную ошибку #REF!
  var lastRow = goodsSheet.getLastRow();
  if (lastRow > 0) {
   goodsSheet.getRange(1, 1, lastRow, 2).clearContent();
  }

  var rowsToPush = [["", ""]]; // Фиксированная пустая строка A1 под шапку калькулятора
  var yellowRows = [];    // Индексы строк для желтой подсветки категорий

  catalogArr.forEach(function(item) {
   if (!item || !item.name) return;
   var colA = String(item.name).trim();

     // 1. Сверяем булевый или текстовый флаг группы
   if (item.isGroup === true || item.isGroup === "true") {
    rowsToPush.push([colA, ""]);
    yellowRows.push(rowsToPush.length); // Запоминаем номер строки для покраски
   } else {
    // Парсим чистую единую цену товара (поддержка центов меньше 1)
    var priceNum = parseFloat(String(item.price).replace(/[^0-9.,]/g, '').replace(',', '.')) || 0;
    rowsToPush.push([colA, priceNum]);
   }
  });

  // 2. Записываем плоскую таблицу строго в 2 столбца (A и B) поверх ячеек за один клик
  var targetRange = goodsSheet.getRange(1, 1, rowsToPush.length, 2);
  targetRange.setValues(rowsToPush);

  // 3. Мягко сбрасываем старые стили в белый цвет в пределах 2 столбцов
  if (lastRow > 0) {
   goodsSheet.getRange(1, 1, lastRow, 2).setBackground("#ffffff").setFontWeight("normal");
  }

  // 4. Накладываем красивую желтую подсветку групп заново на 2 столбца
  yellowRows.forEach(function(rowIndex) {
   goodsSheet.getRange(rowIndex, 1, 1, 2).setBackground("#ffff00").setFontWeight("bold");
  });

  SpreadsheetApp.flush(); // Принудительно сбрасываем кэш Google V8 Engine
  return "success";

 } catch(eSavePricesErr) {
  return "error: " + eSavePricesErr.toString();
 }
}

function coreGetPrices(sheetId) {
 var result = [];
 if (!sheetId) return result;

 try {
  // 1. Подключаемся к таблице по её жесткому sheetId
  var ss = SpreadsheetApp.openById(sheetId);
  var goodsSheet = ss.getSheetByName('Товары') || ss.getSheetByName('товары');
  if (!goodsSheet) return result;

  // 2. Считываем ровно 2 столбца (Название и Цена)
  var lastRow = goodsSheet.getLastRow();
  var goods = [];
  if (lastRow > 0) {
   goods = goodsSheet.getRange(1, 1, lastRow, 2).getValues();
  }

  var currentGroup = "Каталог товаров";

  for (var i = 0; i < goods.length; i++) {
   var row = goods[i];
   if (!row) continue;

   var colA = String(row[0] || '').trim();
   var rawPrice = row[1]; // Забираем исходное значение цены напрямую из столбца B

   if (colA === "" && (rawPrice === "" || rawPrice === undefined || rawPrice === null)) continue;

   // 🎯 СЦЕНАРИЙ А: НАЗВАНИЕ ЕСТЬ, ЦЕНЫ НЕТ — ЭТО ЗАГОЛОВОК ГРУППЫ
   if (colA !== "" && (rawPrice === "" || rawPrice === undefined || rawPrice === null)) {
    currentGroup = colA.replace(/[🎈✨🛍️🎁📂📁]/g, '').trim();
    result.push({
     name: colA,
     price: "",
     currentGroup: currentGroup,
     group: currentGroup,
     isGroup: true
    });
    continue;
   }

   // 🎯 СЦЕНАРИЙ Б: ЕСТЬ И НАЗВАНИЕ, И ЦЕНА — ЭТО ТОВАР С ЧЕСТНЫМИ ДРОБЯМИ (0.5)
   if (colA !== "" && rawPrice !== "" && rawPrice !== undefined && rawPrice !== null) {
    var parsedPrice = 0;

    // ЗАЩИТА ТИПОВ ДАННЫХ V8:
    if (typeof rawPrice === 'number') {
     // Если Google Sheets уже хранит число (0.5), забираем его напрямую
     parsedPrice = rawPrice;
    } else {
     // Если пришла строка (например "0,5"), вычищаем пробелы и меняем запятую на точку
     var cleanStr = String(rawPrice).replace(/\s/g, '').replace(/[^0-9.,]/g, '').replace(',', '.');
     parsedPrice = parseFloat(cleanStr) || 0;
    }

    result.push({
     name: colA,
     price: parsedPrice, // Гарантированно передаст 0.5 в Tilda
     currentGroup: currentGroup,
     group: currentGroup,
     isGroup: false
    });
   }
  }
 } catch(ePricesLog) {
  Logger.log("Ошибка выгрузки прайса в coreGetPrices: " + ePricesLog.toString());
 }

 return result;
}

Made on
Tilda