Войти Регистрация
Код-ревью

43. Загрузка зарплатного реестра в Альфа-Банке

Средняя

Python · 39 строк

Бухгалтер компании выгружает из 1С реестр на зарплату: CSV в cp1251 с заголовком «ФИО;Счёт;Сумма», суммы вида 45 000,50. Функция проверяет баланс компании, зачисляет деньги сотрудникам на счета в банке и списывает сумму с компании.

В реестре до 3 000 строк. credit_account сразу переводит деньги на счёт, get_connection — psycopg2. Если импорт упал, бухгалтер загружает тот же файл ещё раз. Отметьте строки с ошибками.

В работе: Альфа-Бизнес Онлайн: «Зарплатный проект» → «Загрузить реестр» 5-го и 20-го числа.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
CSVкодировкиDecimalидемпотентностьблокировкидоступ

Источник: наша задача на данных Альфа-Банка: зарплатный проект для бизнеса. Условие пересказано своими словами.

  1. import csv
  2. import logging
  3. from .bank import credit_account
  4. from .db import get_connection
  5. log = logging.getLogger(__name__)
  6. def import_payroll(path, company_id):
  7. """Зарплатный реестр от бухгалтерии клиента: ФИО;счёт;сумма."""
  8. total = 0
  9. rows = []
  10. f = open(path)
  11. for line in csv.reader(f, delimiter=";"):
  12. name, account, amount = line
  13. rows.append((name, account, float(amount)))
  14. total += float(amount)
  15. conn = get_connection()
  16. cur = conn.cursor()
  17. cur.execute("SELECT balance FROM companies WHERE id = %s", (company_id,))
  18. balance = cur.fetchone()[0]
  19. if total > balance:
  20. raise ValueError("Недостаточно средств на счёте компании")
  21. for name, account, amount in rows:
  22. cur.execute("SELECT id FROM employees WHERE account = %s", (account,))
  23. emp = cur.fetchone()
  24. if emp is None:
  25. log.warning("Сотрудник не найден: %s", line)
  26. continue
  27. credit_account(account, amount)
  28. cur.execute(
  29. "UPDATE companies SET balance = balance - %s WHERE id = %s", (amount, company_id)
  30. )
  31. conn.commit()
  32. log.info("Реестр %s: %d строк, %s ₽", path, len(rows), total)
  33. return total