#include "eetv4adapter.h" #include namespace { void setError(QString *error, const QString &message) { if (error != nullptr) { *error = message; } } QDateTime withExplicitOffset(const QDateTime &dateTime) { if (!dateTime.isValid()) { return {}; } return dateTime.timeSpec() == Qt::LocalTime ? dateTime.toOffsetFromUtc(dateTime.offsetFromUtc()) : dateTime; } } bool EetV4ShopConfig::validate(QString *error) const { if (!endpoint.isValid() || endpoint.scheme().compare(QStringLiteral("https"), Qt::CaseInsensitive) != 0) { setError(error, QStringLiteral("EET v4 endpoint must be a valid HTTPS URL.")); return false; } if (taxpayerEic.isEmpty()) { setError(error, QStringLiteral("EET v4 taxpayer EIC must not be empty.")); return false; } if (unitId < 1) { setError(error, QStringLiteral("EET v4 unit ID must be positive.")); return false; } if (cashRegisterId.isEmpty()) { setError(error, QStringLiteral("EET v4 cash-register ID must not be empty.")); return false; } if (timeoutMilliseconds < 1) { setError(error, QStringLiteral("EET v4 timeout must be positive.")); return false; } return true; } bool EetV4ShopAdapter::amountText(const QDecDouble &amount, QString *text, QString *error) { QString value = QString::fromLatin1(amount.toString()); if (value.contains(QRegularExpression(QStringLiteral("[eE]")))) { setError(error, QStringLiteral("Voucher amount must not use exponential notation.")); return false; } if (!value.contains(QLatin1Char('.'))) { value += QStringLiteral(".00"); } else { const int decimals = value.size() - value.indexOf(QLatin1Char('.')) - 1; if (decimals > 2) { setError(error, QStringLiteral("Voucher amount has more than two decimal places.")); return false; } value = value.leftJustified(value.size() + (2 - decimals), QLatin1Char('0')); } EetV4Amount parsed; if (!EetV4Amount::fromString(value, &parsed, error)) { return false; } if (text != nullptr) { *text = parsed.toString(); } return true; } bool EetV4ShopAdapter::createRequest(const Voucher &voucher, const EetV4ShopConfig &config, EetV4SaleRequest *request, QString *error) { if (request == nullptr) { setError(error, QStringLiteral("EET v4 request output must not be null.")); return false; } if (!config.validate(error)) { return false; } const QDateTime saleAt = withExplicitOffset(voucher.payDateTime()); if (!saleAt.isValid()) { setError(error, QStringLiteral("Voucher payment date must be valid.")); return false; } QString totalText; if (!amountText(voucher.totalPrice(), &totalText, error)) { return false; } EetV4Amount total; if (!EetV4Amount::fromString(totalText, &total, error)) { return false; } EetV4SaleRequest result; result.sentAt = withExplicitOffset(QDateTime::currentDateTime()); result.saleAt = saleAt; result.firstSubmission = voucher.eetStatus() == Voucher::EET_FOR_SEND; result.verificationMode = config.verificationMode; result.taxpayerEic = config.taxpayerEic; result.unitId = config.unitId; result.cashRegisterId = config.cashRegisterId; result.receiptNumber = voucher.numSer(); result.totalSale = total; QStringList validationErrors; if (!result.validate(&validationErrors)) { setError(error, validationErrors.join(QStringLiteral("; "))); return false; } *request = result; return true; }