import_payments_from_csv.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # -*- coding: utf-8 -*-
  2. """
  3. Import payments from a CSV file from a bank. The payments will automatically be
  4. parsed, and there'll be an attempt to automatically match payments with members.
  5. The matching is performed using the label of the payment.
  6. - First, try to find a string such as 'ID-42' where 42 is the member's ID
  7. - Second (if no ID found), try to find a member username (with no ambiguity with
  8. respect to other usernames)
  9. - Third (if no username found), try to find a member family name (with no
  10. ambiguity with respect to other family name)
  11. This script will check if a payment has already been registered with same
  12. properies (date, label, price) to avoid creating duplicate payments inside coin.
  13. By default, only a dry-run is perfomed to let you see what will happen ! You
  14. should run this command with --commit if you agree with the dry-run.
  15. """
  16. from __future__ import unicode_literals
  17. # Standard python libs
  18. import json
  19. import os
  20. # Django specific imports
  21. from argparse import RawTextHelpFormatter
  22. from django.core.management.base import BaseCommand, CommandError
  23. # Coin specific imports
  24. from coin.billing.import_payments_from_csv import process, add_new_payments
  25. ################################################################################
  26. class Command(BaseCommand):
  27. help = __doc__
  28. def create_parser(self, *args, **kwargs):
  29. parser = super(Command, self).create_parser(*args, **kwargs)
  30. parser.formatter_class = RawTextHelpFormatter
  31. return parser
  32. def add_arguments(self, parser):
  33. parser.add_argument(
  34. 'filename',
  35. type=str,
  36. help="The CSV filename to be parsed"
  37. )
  38. parser.add_argument(
  39. '--commit',
  40. action='store_true',
  41. dest='commit',
  42. default=False,
  43. help='Agree with the proposed change and commit them'
  44. )
  45. def handle(self, *args, **options):
  46. assert options["filename"] != ""
  47. if not os.path.isfile(options["filename"]):
  48. raise CommandError("This file does not exists.")
  49. f = open(options["filename"], "r")
  50. new_payments = process(f)
  51. number_of_new_payments = len(new_payments)
  52. if (number_of_new_payments > 0):
  53. print("======================================================")
  54. print(" > New payments found")
  55. print(json.dumps(new_payments, indent=4, separators=(',', ': ')))
  56. print("======================================================")
  57. print("Number of new payments found : " + str(number_of_new_payments))
  58. print("Number of new payments matched : " + str(len([p for p in new_payments if p["member_matched"]])))
  59. print("Number of payments not matched : " + str(len([p for p in new_payments if not p["member_matched"]])))
  60. print("======================================================")
  61. if number_of_new_payments == 0:
  62. print("Nothing to do, everything looks up to date !")
  63. return
  64. if not options["commit"]:
  65. print("Please carefully review the matches, then if everything \n"
  66. "looks alright, use --commit to register these new payments.")
  67. else:
  68. add_new_payments(new_payments)