Kotlin · 42 строк
Каждую ночь в 00:10 по Москве джоба списывает абонентскую плату за подписку: цена тарифа минус персональная скидка (discountPercent — целое, 0–50). После четырёх неудачных списаний подряд подписка приостанавливается, до этого её пробуют списать снова на следующую ночь.
Активных подписок 6,2 млн. JVM на серверах запущена в UTC, monthlyPrice — Double. Отметьте строки с ошибками.
В работе: Подписка с кино, музыкой и кешбэком: списание в ночь даты продления и SMS абоненту.
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
Источник: наша задача на данных МТС: подписки и списания со счёта. Условие пересказано своими словами.
Давали на собеседовании?
@Serviceclass SubscriptionRenewalJob(private val subscriptions: SubscriptionRepository,private val billing: BillingClient,private val sms: SmsGateway,) {private val log = LoggerFactory.getLogger(javaClass)@Scheduled(cron = "0 10 0 * * *", zone = "Europe/Moscow")fun renewAll() {val today = LocalDate.now()val due = subscriptions.findAll().filter { it.nextChargeDate == today && it.status == Status.ACTIVE }for (sub in due) {renew(sub)}}fun renew(sub: Subscription) {if (sub.trialEndsAt != null && sub.trialEndsAt!!.isAfter(LocalDate.now())) {sub.nextChargeDate = sub.trialEndsAt!!subscriptions.save(sub)return}val discount = sub.discountPercent / 100val price = sub.tariff.monthlyPrice * (1 - discount)try {val result = billing.charge(sub.msisdn, price)if (result.status == "OK") {sub.nextChargeDate = sub.nextChargeDate.plusDays(30)sub.failedAttempts = 0} else {sub.failedAttempts++if (sub.failedAttempts > 3) sub.status = Status.SUSPENDED}} catch (e: Exception) {log.warn("charge failed for ${sub.msisdn}, auth=${billing.token}", e)}subscriptions.save(sub)sms.send(sub.msisdn, "Подписка ${sub.tariff.name} продлена, списано $price ₽")}}