1
0
forked from BRT/arc
arc/scripts/ozon/get_profile_info.js

167 lines
7.9 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ozon/get_profile_info.js
//
// JS-порт Ozon::GetProfileInfoScript. Логика 1:1 с C++ (см.
// android/ozon/GetProfileInfoScript.cpp). Все ADB/DAO/парсер-вызовы идут
// через host.*-мост, состояние парсера общее с host.helpers.
//
// Контракт:
// params.deviceId — серийный или android_id
// params.appCode — "ozon"
// Возвращает:
// "" / null / undefined → success
// строка → бизнес-ошибка (попадёт в EventInfo.error
// и в BankSetupWizard.humanReadableError)
// При throw runtime сделает fallback на C++.
//
// Сообщения об ошибках в этом файле ДОЛЖНЫ совпадать с подстроками из
// views/bank/BankSetupWizard.cpp:659 (humanReadableError), иначе мастер
// покажет "Произошла непредвиденная ошибка" вместо конкретной диагностики.
function run(host) {
var deviceId = host.params.deviceId;
var appCode = host.params.appCode;
var counter = 0;
// 1. Резолвим device (id может быть как android_id, так и adb serial).
var device = host.dao.deviceGetById(deviceId);
if (!device || !device.id) {
device = host.dao.deviceFindByAdbSerial(deviceId);
}
if (device && device.adbSerial) {
deviceId = device.adbSerial;
}
var app = host.dao.bankProfileGet(device.id, appCode);
if (!device || !device.id || !app || app.id < 0) {
var msg = "Device or app not found: " + deviceId + " " + appCode;
host.log.error(msg);
return msg;
}
host.dump.beginScope("ozon", "FETCH_PROFILE_INFO", deviceId, {});
try {
// 2. Читаем текущий экран
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
// 3. Закрываем рекламный bottom sheet, если открыт (home_ad_1)
var adNode = host.parser.tryToFindAdBanner();
if (!adNode.isEmpty) {
host.log.debug("Ad banner detected, closing...");
host.adb.makeTap(deviceId, adNode.x, adNode.y);
host.timer.sleep(1000);
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
}
// 4. Свежий дамп перед проверкой домашнего экрана
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
// 5. Если не на домашнем экране — перезапускаем приложение и вводим пин-код
if (!host.parser.isHomeScreen()) {
host.log.debug("Not on home screen, restarting app...");
if (!host.helpers.runAppAndGoToHomeScreen(deviceId, app.package, app.pinCode,
device.screenWidth, device.screenHeight)) {
var err = "Cannot reach home screen: " + device.name + " (" + deviceId + ") " + appCode;
host.log.warn(err);
host.adb.tryToKillApplication(deviceId, app.package);
return err;
}
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
}
// 6. Закрываем баннеры на главной, если есть
host.helpers.tryToCloseAllBannersOnHomePage(deviceId, device.screenWidth, device.screenHeight);
host.timer.sleep(500);
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
// 7. Парсим баланс с домашнего экрана
var parsedCards = host.parser.parseCardsOnHomeScreen();
var parsedBalance = parsedCards.length > 0 ? parsedCards[0].amount : 0.0;
host.log.debug("parseCardsOnHomeScreen returned " + parsedCards.length
+ " cards, balance: " + parsedBalance);
// 8. Fallback: если парсинг не нашёл баланс, берём из materials
if (parsedBalance <= 0.0) {
var accounts = host.dao.materialGetAccounts(device.id, appCode);
for (var i = 0; i < accounts.length; ++i) {
if (accounts[i].amount > 0.0) {
parsedBalance = accounts[i].amount;
break;
}
}
host.log.debug("Fallback balance from materials: " + parsedBalance);
}
if (parsedBalance > 0.0) {
host.dao.bankProfileUpdateAmount(app.id, parsedBalance);
}
// 9. Находим имя пользователя в верхней части и тапаем по нему
var userNameNode = host.parser.findUserNameOnHomeScreen(device.screenHeight);
if (userNameNode.isEmpty) {
var err2 = "Cannot find user name on home screen: " + deviceId;
host.log.warn(err2);
host.adb.tryToKillApplication(deviceId, app.package);
return err2;
}
host.log.debug("Tapping on user name: " + userNameNode.text
+ " at " + userNameNode.x + " " + userNameNode.y);
host.adb.makeTap(deviceId, userNameNode.x, userNameNode.y);
// 10. Ждём загрузки страницы профиля
host.timer.sleep(2500);
// 11. Проверяем что мы действительно на экране профиля (с retry)
var profileFound = false;
for (var j = 0; j < 5; ++j) {
host.parser.parseAndSaveXml(host.adb.getScreenDumpAsXml(deviceId, ++counter));
host.helpers.closeGooglePlayBannerIfVisible(deviceId, device.screenWidth, device.screenHeight);
if (host.parser.isProfileScreen()) {
profileFound = true;
break;
}
host.timer.sleep(1000);
}
if (!profileFound) {
var err3 = "Profile screen not detected after tap: " + deviceId;
host.log.warn(err3);
host.adb.tryToKillApplication(deviceId, app.package);
return err3;
}
// 12. Извлекаем полное имя и телефон. Telephone из Ozon XML может
// содержать неразрывные пробелы (U+00A0) и обычные — чистим оба.
var fullName = host.parser.parseProfileFullName();
var phone = host.parser.parseProfilePhone().replace(/[\s ]/g, '');
host.log.debug("fullName: " + fullName + " phone: " + phone);
// 13. Сохраняем профиль (email Ozon не отдаёт — передаём пустую строку)
if (!host.dao.bankProfileUpdateProfileInfo(app.id, fullName, phone, "")) {
host.log.warn("Failed to save profile info to DB: " + deviceId);
}
// 14. Регистрируем/обновляем bank profile на сервере. Хелпер сам
// перечитывает свежий профиль из БД и шлёт POST/PATCH по наличию bankProfileId.
host.helpers.createBankProfileIfNeeded(deviceId, appCode, parsedBalance);
// 15. Отправляем аккаунты без material_id на сервер
var allAccounts = host.dao.materialGetAccounts(device.id, appCode);
var accountsToPost = [];
for (var k = 0; k < allAccounts.length; ++k) {
if (!allAccounts[k].materialId) accountsToPost.push(allAccounts[k]);
}
if (accountsToPost.length > 0) {
host.helpers.postAccountsData(accountsToPost);
}
// 16. Возвращаемся на домашний экран
host.adb.goBack(deviceId);
host.timer.sleep(1000);
host.dump.endScope("");
return ""; // success
} catch (e) {
host.dump.endScope(String(e));
throw e;
}
}