Go · 47 строк
Промокод даёт скидку в процентах, у него есть срок действия и лимит использований (например, 1 000 первых покупателей). Один пользователь может применить код один раз.
Отметьте строки с ошибками.
В работе: Промокоды блогеров: за первые минуты после публикации их пробуют тысячи человек.
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
Источник: на задачах Ozon: промокоды и акции. Условие пересказано своими словами.
Давали на собеседовании?
Ответов пока мало — ваш поможет.
package promoimport ("context""database/sql""errors""fmt""strings""time")type Promo struct {Code stringPercent intMaxUses intUsed intExpiresAt time.Time}var ErrInvalid = errors.New("промокод недействителен")type Service struct {db *sql.DB}func (s *Service) Apply(ctx context.Context, userID int64, code string, cartKop int64) (int64, error) {code = strings.ToUpper(code)var p Promoq := fmt.Sprintf("SELECT code, percent, max_uses, used, expires_at FROM promos WHERE code = '%s'", code)err := s.db.QueryRowContext(ctx, q).Scan(&p.Code, &p.Percent, &p.MaxUses, &p.Used, &p.ExpiresAt)if err != nil {return 0, ErrInvalid}if p.ExpiresAt.Before(time.Now()) {return 0, ErrInvalid}if p.Used > p.MaxUses {return 0, ErrInvalid}discount := cartKop * int64(p.Percent/100)_, err = s.db.ExecContext(ctx, "UPDATE promos SET used = used + 1 WHERE code = $1", code)if err != nil {return 0, err}_, err = s.db.ExecContext(ctx, "INSERT INTO promo_uses(code, user_id) VALUES ($1, $2)", code, userID)return cartKop - discount, err}