Skip to content
This repository has been archived by the owner on Sep 5, 2022. It is now read-only.

Commit

Permalink
Add 'matching' method to class 'Volksbank'
Browse files Browse the repository at this point in the history
  • Loading branch information
S1SYPHOS authored May 23, 2021
1 parent cc7bb2b commit 795b94f
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 30 deletions.
20 changes: 19 additions & 1 deletion knv_cli/gateways/payments.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from abc import abstractmethod
from datetime import datetime, timedelta
from operator import itemgetter

from ..base import BaseClass
Expand Down Expand Up @@ -36,4 +37,21 @@ def payments(self):


def blocked_payments(self):
return sorted(self.blocked_payments, key=itemgetter('Datum'))
return sorted(self._blocked_payments, key=itemgetter('Datum'))


def matched_payments(self):
# Sort payments by date
return sorted(self._matched_payments, key=itemgetter('Datum'))


# MATCHING HELPER methods

def match_dates(self, base_date, test_date, days=1) -> bool:
date_objects = [datetime.strptime(date, '%Y-%m-%d') for date in [base_date, test_date]]
date_range = timedelta(days=days)

if date_objects[0] <= date_objects[1] <= date_objects[0] + date_range:
return True

return False
25 changes: 5 additions & 20 deletions knv_cli/gateways/paypal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# See https://www.paypal.com/de/smarthelp/article/FAQ1007


from datetime import datetime, timedelta
from operator import itemgetter
from os.path import join

Expand Down Expand Up @@ -79,18 +78,18 @@ def match_payments(self, orders: list, infos: list) -> None:
results.append(payment)
continue

matching_infos = self.match_infos(matching_order, infos)
matching_invoices = self.match_invoices(matching_order, infos)

# Skip if no matching invoice numbers
if not matching_infos:
if not matching_invoices:
results.append(payment)
continue

# Store data
# (1) Apply matching order number
# (2) Add invoice number(s) to payment data
payment['ID'] = matching_order['ID']
payment['Vorgang'] = matching_infos
payment['Vorgang'] = matching_invoices
payment['Versand'] = matching_order['Versand']
# (3) Add total order cost & purchased items
payment['Summe'] = matching_order['Bestellung']['Summe']
Expand Down Expand Up @@ -160,28 +159,14 @@ def match_orders(self, payment, orders) -> dict:
return {}


def match_infos(self, order, infos) -> list:
info = []

def match_invoices(self, order, infos) -> list:
for info in infos:
if info['ID'] == order['ID']:
return info['Rechnungen']
return info['Rechnungen'].keys()

return []


# MATCHING HELPER methods

def match_dates(self, base_date, test_date, days=1) -> bool:
date_objects = [datetime.strptime(date, '%Y-%m-%d') for date in [base_date, test_date]]
date_range = timedelta(days=days)

if date_objects[0] <= date_objects[1] <= date_objects[0] + date_range:
return True

return False


# MATCHING OUTPUT methods

def matched_payments(self, csv_compatible: bool = False) -> list:
Expand Down
88 changes: 79 additions & 9 deletions knv_cli/gateways/volksbank.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from string import punctuation

from .payments import Payments
from ..utils import dedupe


class Volksbank(Payments):
Expand Down Expand Up @@ -81,14 +82,14 @@ def process_payments(self, data) -> list:
continue

# Match strings preceeded by VKN & hypen (definite hit)
if line.split('-')[0] == self.VKN:
if self.VKN + '-' in line:
order_candidates.append(line)

# Otherwise, try matching 6 random digits ..
else:
order_candidate = fullmatch(r"\d{6}", line)

# .. so unless it's the VKN by itself ..
# .. and unless it's the VKN by itself ..
if order_candidate and order_candidate[0] != self.VKN:
# .. we got a hit
order_candidates.append(self.VKN + '-' + order_candidate[0])
Expand All @@ -102,25 +103,94 @@ def process_payments(self, data) -> list:
# Extract invoice numbers, matching ..
# (1) .. '20' + 9 random digits
# (2) .. '9' + 11 random digits
pattern = r"(R?[2][0]\d{9}|[9]\d{11})"
pattern = r"([2][0]\d{9}|[9]\d{11})"
invoice_candidates = findall(pattern, reference)

# If this yields no invoices as result ..
if not invoice_candidates:
# Remove whitespace & try again
# .. remove whitespace & try again
reference = reference.replace(' ', '')
invoice_candidates = findall(pattern, reference)

if invoice_candidates:
payment['Vorgang'] = invoice_candidates
payment['Vorgang'] = []

if payment['ID'] == 'nicht zugeordnet' and payment['Vorgang'] == 'nicht zugeordnet':
self._blocked_payments.append(payment)
continue
for invoice in invoice_candidates:
if invoice[:1] == '2':
invoice = 'R' + invoice

payment['Vorgang'].append(invoice)

payments.append(payment)

return payments


# MATCHING methods

# TODO: Check if payment equals order total
def match_payments(self, orders: list, infos: list) -> None:
pass
results = []

for payment in self.data:
# Assign payment to order number(s) & invoices
# (1) Find matching order(s) for current payment
matching_orders = self.match_orders(payment, orders)

# (2) Find matching invoices for each identified order
matching_invoices = self.match_invoices(matching_orders, infos)

if isinstance(payment['Vorgang'], list):
matching_invoices += payment['Vorgang']

# Store data
# (1) Add invoice number(s) to payment data
if matching_invoices:
payment['Vorgang'] = matching_invoices

# Reverse-lookup orders if no matching order number(s) yet
if not matching_orders:
matching_orders = self.lookup_orders(matching_invoices, infos)

# (2) Apply matching order number(s)
if matching_orders:
payment['ID'] = matching_orders

# (3) Save matched payment
results.append(payment)

self._matched_payments = results


def match_orders(self, payment: dict, orders: list) -> list:
matches = []

for order in orders:
if order['ID'] in payment['ID']:
matches.append(order['ID'])

return dedupe(matches)


def match_invoices(self, orders: list, infos: list) -> list:
matches = []

for order in orders:
for info in infos:
if order == info['ID']:
matches += info['Rechnungen']
break

return dedupe(matches)


def lookup_orders(self, invoices: list, infos: list) -> list:
matches = []

for invoice in invoices:
for info in infos:
if invoice in info['Rechnungen']:
matches.append(info['ID'])
break

return dedupe(matches)

0 comments on commit 795b94f

Please sign in to comment.