|
@@ -81,27 +81,27 @@ class Command(BaseCommand):
|
|
|
if not os.path.isfile(options["filename"]):
|
|
|
raise CommandError("This file does not exists.")
|
|
|
|
|
|
- payments = self.convertCSVToDicts(self.cleanCSV(self.loadCSV(options["filename"])))
|
|
|
+ payments = self.convert_csv_to_dicts(self.clean_csv(self.load_csv(options["filename"])))
|
|
|
|
|
|
- payments = self.tryToMatchPaymentWithMembers(payments)
|
|
|
- newPayments = self.filterAlreadyKnownPayments(payments)
|
|
|
- newPayments = self.unmatchPaymentWithKeywords(newPayments)
|
|
|
+ payments = self.try_to_match_payment_with_members(payments)
|
|
|
+ new_payments = self.filter_already_known_payments(payments)
|
|
|
+ new_payments = self.unmatch_payment_with_keywords(new_payments)
|
|
|
|
|
|
- numberOfAlreadyKnownPayments = len(payments)-len(newPayments)
|
|
|
- numberOfNewPayments = len(newPayments)
|
|
|
+ number_of_already_known_payments = len(payments)-len(new_payments)
|
|
|
+ number_of_new_payments = len(new_payments)
|
|
|
|
|
|
- if (numberOfNewPayments > 0) :
|
|
|
+ if (number_of_new_payments > 0) :
|
|
|
print "======================================================"
|
|
|
print " > New payments found"
|
|
|
- print json.dumps(newPayments, indent=4, separators=(',', ': '))
|
|
|
+ print json.dumps(new_payments, indent=4, separators=(',', ': '))
|
|
|
print "======================================================"
|
|
|
- print "Number of already known payments found : " + str(numberOfAlreadyKnownPayments)
|
|
|
- print "Number of new payments found : " + str(numberOfNewPayments)
|
|
|
- print "Number of new payments matched : " + str(len([p for p in newPayments if p["memberMatched"]]))
|
|
|
- print "Number of payments not matched : " + str(len([p for p in newPayments if not p["memberMatched"]]))
|
|
|
+ print "Number of already known payments found : " + str(number_of_already_known_payments)
|
|
|
+ print "Number of new payments found : " + str(number_of_new_payments)
|
|
|
+ print "Number of new payments matched : " + str(len([p for p in new_payments if p["member_matched"]]))
|
|
|
+ print "Number of payments not matched : " + str(len([p for p in new_payments if not p["member_matched"]]))
|
|
|
print "======================================================"
|
|
|
|
|
|
- if numberOfNewPayments == 0:
|
|
|
+ if number_of_new_payments == 0:
|
|
|
print "Nothing to do, everything looks up to date !"
|
|
|
return
|
|
|
|
|
@@ -109,10 +109,10 @@ class Command(BaseCommand):
|
|
|
print "Please carefully review the matches, then if everything \n" \
|
|
|
"looks alright, use --commit to register these new payments."
|
|
|
else:
|
|
|
- self.addNewPayments(newPayments)
|
|
|
+ self.add_new_payments(new_payments)
|
|
|
|
|
|
|
|
|
- def isDate(self, text):
|
|
|
+ def is_date(self, text):
|
|
|
try:
|
|
|
datetime.datetime.strptime(text, DATE_FORMAT)
|
|
|
return True
|
|
@@ -120,7 +120,7 @@ class Command(BaseCommand):
|
|
|
return False
|
|
|
|
|
|
|
|
|
- def isMoneyAmount(self, text):
|
|
|
+ def is_money_amount(self, text):
|
|
|
try:
|
|
|
float(text.replace(",","."))
|
|
|
return True
|
|
@@ -128,12 +128,12 @@ class Command(BaseCommand):
|
|
|
return False
|
|
|
|
|
|
|
|
|
- def loadCSV(self, filename):
|
|
|
+ def load_csv(self, filename):
|
|
|
with open(filename, "r") as f:
|
|
|
return list(csv.reader(f, delimiter=DELIMITER))
|
|
|
|
|
|
|
|
|
- def cleanCSV(self, data):
|
|
|
+ def clean_csv(self, data):
|
|
|
|
|
|
output = []
|
|
|
|
|
@@ -145,17 +145,17 @@ class Command(BaseCommand):
|
|
|
if len(row) < 4:
|
|
|
continue
|
|
|
|
|
|
- if not self.isDate(row[0]):
|
|
|
+ if not self.is_date(row[0]):
|
|
|
logging.warning("Ignoring the following row (bad format for date in the first column) :")
|
|
|
logging.warning(str(row))
|
|
|
continue
|
|
|
|
|
|
- if self.isMoneyAmount(row[2]):
|
|
|
+ if self.is_money_amount(row[2]):
|
|
|
logging.warning("Ignoring row %s (not a payment)" % str(i))
|
|
|
logging.warning(str(row))
|
|
|
continue
|
|
|
|
|
|
- if not self.isMoneyAmount(row[3]):
|
|
|
+ if not self.is_money_amount(row[3]):
|
|
|
logging.warning("Ignoring the following row (bad format for money amount in colun three) :")
|
|
|
logging.warning(str(row))
|
|
|
continue
|
|
@@ -172,7 +172,7 @@ class Command(BaseCommand):
|
|
|
return output
|
|
|
|
|
|
|
|
|
- def convertCSVToDicts(self, data):
|
|
|
+ def convert_csv_to_dicts(self, data):
|
|
|
|
|
|
output = []
|
|
|
|
|
@@ -188,7 +188,7 @@ class Command(BaseCommand):
|
|
|
return output
|
|
|
|
|
|
|
|
|
- def tryToMatchPaymentWithMembers(self, payments):
|
|
|
+ def try_to_match_payment_with_members(self, payments):
|
|
|
|
|
|
members = Member.objects.filter(status="member")
|
|
|
|
|
@@ -196,16 +196,16 @@ class Command(BaseCommand):
|
|
|
|
|
|
for payment in payments:
|
|
|
|
|
|
- paymentLabel = payment["label"]
|
|
|
+ payment_label = payment["label"]
|
|
|
|
|
|
# First, attempt to match the member ID
|
|
|
- idmatches = idregex.findall(paymentLabel)
|
|
|
+ idmatches = idregex.findall(payment_label)
|
|
|
if len(idmatches) == 1:
|
|
|
i = int(idmatches[0][1])
|
|
|
- memberMatches = [ member.username for member in members if member.pk==i ]
|
|
|
- if len(memberMatches) == 1:
|
|
|
- payment["memberMatched"] = memberMatches[0]
|
|
|
- #print "Matched by ID to "+memberMatches[0]
|
|
|
+ member_matches = [ member.username for member in members if member.pk==i ]
|
|
|
+ if len(member_matches) == 1:
|
|
|
+ payment["member_matched"] = member_matches[0]
|
|
|
+ #print "Matched by ID to "+member_matches[0]
|
|
|
continue
|
|
|
|
|
|
|
|
@@ -213,7 +213,7 @@ class Command(BaseCommand):
|
|
|
usernamematch = None
|
|
|
for member in members:
|
|
|
matches = re.compile(r"(?i)(\b|_)"+re.escape(member.username)+r"(\b|_)") \
|
|
|
- .findall(paymentLabel)
|
|
|
+ .findall(payment_label)
|
|
|
# If not found, try next
|
|
|
if len(matches) == 0:
|
|
|
continue
|
|
@@ -226,7 +226,7 @@ class Command(BaseCommand):
|
|
|
usernamematch = member.username
|
|
|
|
|
|
if usernamematch != None:
|
|
|
- payment["memberMatched"] = usernamematch
|
|
|
+ payment["member_matched"] = usernamematch
|
|
|
#print "Matched by username to "+usernamematch
|
|
|
continue
|
|
|
|
|
@@ -235,7 +235,7 @@ class Command(BaseCommand):
|
|
|
familynamematch = None
|
|
|
for member in members:
|
|
|
matches = re.compile(r"(?i)(\b|_)"+re.escape(str(member.last_name))+r"(\b|_)") \
|
|
|
- .findall(paymentLabel)
|
|
|
+ .findall(payment_label)
|
|
|
# If not found, try next
|
|
|
if len(matches) == 0:
|
|
|
continue
|
|
@@ -252,17 +252,17 @@ class Command(BaseCommand):
|
|
|
familynamematch = str(member.last_name)
|
|
|
|
|
|
if familynamematch != None:
|
|
|
- payment["memberMatched"] = familynamematch
|
|
|
+ payment["member_matched"] = familynamematch
|
|
|
#print "Matched by familyname to "+familynamematch
|
|
|
continue
|
|
|
|
|
|
#print "Could not match"
|
|
|
- payment["memberMatched"] = None
|
|
|
+ payment["member_matched"] = None
|
|
|
|
|
|
return payments
|
|
|
|
|
|
|
|
|
- def unmatchPaymentWithKeywords(self, payments):
|
|
|
+ def unmatch_payment_with_keywords(self, payments):
|
|
|
|
|
|
matchers = {}
|
|
|
for keyword in KEYWORDS_TO_NOTMATCH:
|
|
@@ -271,7 +271,7 @@ class Command(BaseCommand):
|
|
|
for i, payment in enumerate(payments):
|
|
|
|
|
|
# If no match found, don't filter anyway
|
|
|
- if payment["memberMatched"] == None:
|
|
|
+ if payment["member_matched"] == None:
|
|
|
continue
|
|
|
|
|
|
for keyword, matcher in matchers.items():
|
|
@@ -284,51 +284,51 @@ class Command(BaseCommand):
|
|
|
print "Ignoring possible match for payment '%s' because " \
|
|
|
"it contains the keyword %s" \
|
|
|
% (payment["label"], keyword)
|
|
|
- payments[i]["memberMatched"] = None
|
|
|
+ payments[i]["member_matched"] = None
|
|
|
|
|
|
break
|
|
|
|
|
|
return payments
|
|
|
|
|
|
- def filterAlreadyKnownPayments(self, payments):
|
|
|
+ def filter_already_known_payments(self, payments):
|
|
|
|
|
|
- newPayments = []
|
|
|
+ new_payments = []
|
|
|
|
|
|
- knownPayments = Payment.objects.all()
|
|
|
+ known_payments = Payment.objects.all()
|
|
|
|
|
|
for payment in payments:
|
|
|
|
|
|
- foundMatch = False
|
|
|
- for knownPayment in knownPayments:
|
|
|
+ found_match = False
|
|
|
+ for known_payment in known_payments:
|
|
|
|
|
|
- if (str(knownPayment.date) == payment["date"].encode('utf-8')) \
|
|
|
- and (knownPayment.label == payment["label"]) \
|
|
|
- and (float(knownPayment.amount) == float(payment["amount"])):
|
|
|
- foundMatch = True
|
|
|
+ if (str(known_payment.date) == payment["date"].encode('utf-8')) \
|
|
|
+ and (known_payment.label == payment["label"]) \
|
|
|
+ and (float(known_payment.amount) == float(payment["amount"])):
|
|
|
+ found_match = True
|
|
|
break
|
|
|
|
|
|
- if not foundMatch:
|
|
|
- newPayments.append(payment)
|
|
|
+ if not found_match:
|
|
|
+ new_payments.append(payment)
|
|
|
|
|
|
- return newPayments
|
|
|
+ return new_payments
|
|
|
|
|
|
|
|
|
- def addNewPayments(self, newPayments):
|
|
|
+ def add_new_payments(self, new_payments):
|
|
|
|
|
|
- for newPayment in newPayments:
|
|
|
+ for new_payment in new_payments:
|
|
|
|
|
|
# Get the member if there's a member matched
|
|
|
member = None
|
|
|
- if newPayment["memberMatched"]:
|
|
|
- member = Member.objects.filter(username=newPayment["memberMatched"])
|
|
|
+ if new_payment["member_matched"]:
|
|
|
+ member = Member.objects.filter(username=new_payment["member_matched"])
|
|
|
assert len(member) == 1
|
|
|
member = member[0]
|
|
|
|
|
|
print "Adding new payment : "
|
|
|
- print newPayment
|
|
|
+ print new_payment
|
|
|
# Create the payment
|
|
|
- payment = Payment.objects.create(amount=float(newPayment["amount"]),
|
|
|
- label=newPayment["label"].encode('utf-8'),
|
|
|
- date=newPayment["date"].encode('utf-8'),
|
|
|
+ payment = Payment.objects.create(amount=float(new_payment["amount"]),
|
|
|
+ label=new_payment["label"].encode('utf-8'),
|
|
|
+ date=new_payment["date"].encode('utf-8'),
|
|
|
member=member)
|
|
|
|