V_Login static method

Future<bool> V_Login(
  1. BuildContext contex, {
  2. String userName = "",
  3. String password = "",
  4. String maDvcs = "",
  5. bool isShowMsg = true,
  6. bool isShowloading = true,
})

Implementation

static Future<bool> V_Login(
  BuildContext contex, {
  String userName = "",
  String password = "",
  String maDvcs = "",
  bool isShowMsg = true,
  bool isShowloading = true,
}) async {
  // ✅ Get certificate và token
  // ignore: unused_local_variable, no_leading_underscores_for_local_identifiers
  String _certificate = await DeviceInfo.cetificate;
  // ignore: no_leading_underscores_for_local_identifiers
  String _strTokenId = await strTokenId;
  // ignore: no_leading_underscores_for_local_identifiers
  String _pass = MD5(password);
  // ✅ Call API
  // ignore: use_build_context_synchronously
  ReturnData returnDatalogin = await contex.callApi(
    functionName: "CP_APPNBSysLogin",
    parameter: "$_strTokenId#$_certificate#$userName#$_pass#$maDvcs",
    showError: isShowMsg,
    showLoading: isShowloading,
  );

  // ✅ Check response validity
  if (!returnDatalogin.isValid()) {
    return false;
  }

  // ✅ Safe null checks
  CyberDataset? dslogin = returnDatalogin.toCyberDataset();
  if (dslogin == null) {
    return false;
  }
  // ignore: use_build_context_synchronously
  if (!dslogin.checkStatus(contex, isShowMsg: isShowMsg)) return false;
  CyberDataTable? dtlogin = dslogin[0];
  if (dtlogin == null || dtlogin.rowCount == 0) {
    return false;
  }

  // ✅ Get first row safely
  final loginRow = dtlogin[0];

  // ✅ Save token
  final tokenKey = loginRow["tokenkey"]?.toString();
  if (tokenKey != null && tokenKey.isNotEmpty) {
    await setstrTokenId(tokenKey);
  }

  // ✅ Safe field extraction với null handling
  user_name = loginRow["User_name"]?.toString() ?? "";
  comment = loginRow["Comment"]?.toString() ?? "";
  ma_dvcs = loginRow["ma_dvcs"]?.toString() ?? "";

  // ✅ Handle isOTP với nhiều format khác nhau
  if (dtlogin.containerColumn("isOTP")) {
    final otpValue = loginRow["isOTP"];
    if (otpValue is bool) {
      isOTP = otpValue ? "1" : "0";
    } else if (otpValue is String) {
      isOTP = otpValue;
    } else if (otpValue is int) {
      isOTP = otpValue.toString();
    } else {
      isOTP = "0";
    }
  } else if (dtlogin.containerColumn("isotp")) {
    // ✅ Fallback cho lowercase field
    final otpValue = loginRow["isotp"];
    if (otpValue is bool) {
      isOTP = otpValue ? "1" : "0";
    } else if (otpValue is String) {
      isOTP = otpValue;
    } else if (otpValue is int) {
      isOTP = otpValue.toString();
    } else {
      isOTP = "0";
    }
  } else {
    isOTP = "0";
  }

  // ✅ Handle id_otp
  if (dtlogin.containerColumn("id_otp")) {
    id_otp = loginRow["id_otp"]?.toString() ?? "";
  } else if (dtlogin.containerColumn("idotp")) {
    // ✅ Fallback cho lowercase
    id_otp = loginRow["idotp"]?.toString() ?? "";
  } else {
    id_otp = "";
  }
  // ✅ Cập nhật Language theo biến M_Lan từ server
  if (dtlogin.containerColumn("M_Lan")) {
    String languageCode = loginRow["M_Lan"]?.toString() ?? "";
    if (languageCode.isNotEmpty) {
      try {
        final language = CyberLanguage.fromCode(languageCode);
        // Cập nhật language (không pass context để không gọi API lại)
        await cyberLanguage.setLanguage(language);
      } catch (e) {
        //debugPrint('⚠️ Error updating language from server: $e');
      }
    }
  }
  dtPhanHe = dslogin[2];
  dtCommand = dslogin[3];

  return true;
}