altocompta/dev/csv-tools/verif.py
Dany De Bontridder 110335b08c Merged revisions 3264-3278 via svnmerge from
file:///home/developper/svn/phpcompta/branches/rel510

........
  r3268 | danydb | 2010-06-03 00:41:59 +0200 (Thu, 03 Jun 2010) | 1 line
  
  Add script for creating class based on a table
........
  r3269 | danydb | 2010-06-03 00:42:51 +0200 (Thu, 03 Jun 2010) | 1 line
  
  Add script for creating class based on a table
........
  r3271 | danydb | 2010-06-03 22:01:05 +0200 (Thu, 03 Jun 2010) | 10 lines
  
  remove obsolete comment
  =======================
  include/class_lettering.php 
  
  Improve generation of PHP Class for a table
  ===========================================
  dev/create_phpclass.py   
  dev/create_file_table.sql
........
  r3272 | danydb | 2010-06-03 22:30:59 +0200 (Thu, 03 Jun 2010) | 2 lines
  
  remove obsolete
........
  r3273 | danydb | 2010-06-03 22:38:28 +0200 (Thu, 03 Jun 2010) | 1 line
  
  create_phpclass.php improve it
........
  r3274 | danydb | 2010-06-04 01:06:20 +0200 (Fri, 04 Jun 2010) | 2 lines
  
  create_phpclass : add insert, new comment, fix load function
........
  r3275 | danydb | 2010-06-04 14:02:59 +0200 (Fri, 04 Jun 2010) | 1 line
  
  add doc
........
  r3276 | danydb | 2010-06-04 14:44:55 +0200 (Fri, 04 Jun 2010) | 1 line
  
  Generate child object
........
  r3277 | danydb | 2010-06-09 15:57:54 +0200 (Wed, 09 Jun 2010) | 1 line
  
  Remove useless transform.py
........
  r3278 | danydb | 2010-06-09 15:58:26 +0200 (Wed, 09 Jun 2010) | 1 line
  
  Housekeeping : create subfolders
........
2010-06-09 13:58:58 +00:00

110 lines
3.4 KiB
Python

# -*- coding: latin-1 -*-
#simple python script to check bank vs. accounts.
import sys
import csv
import time
from datetime import date
#bank account input file sample line:
#"Code interne";"Date";"Description";"Débit";"Crédit"
#"OD-01-00001";"18.12.2003";"versement initial capital";6200.0000; 0.0000
DATE_OUT_FORMAT = "%d/%m/%Y"
def toDateString(date):
return time.strftime(DATE_OUT_FORMAT, date)
class Extract:
def __repr__(self):
return "[%s]: %s %s" % (self.code, toDateString(self.date), self.amount)
class Operation:
def __repr__(self):
return "[%s]: %s D: %s C: %s" % (self.code, toDateString(self.date), self.debit, self.credit)
accountFile = sys.argv[1]
reader = csv.reader(open(accountFile, "rb"), delimiter=";")
operations = []
reader.next()
for row in reader:
op = Operation()
#print row
if len(row) == 5:
op.code, op.date, op.desc, op.debit, op.credit = row
op.date = time.strptime(op.date, "%d.%m.%Y")
op.debit = float(op.debit)
op.credit = float(op.credit)
operations.append(op)
print "loaded %s bank operations from %s" % (len(operations), accountFile)
bankExtractsFile = sys.argv[2]
reader = csv.reader(open(bankExtractsFile, "rb"), delimiter=";")
extracts = []
reader.next()
for row in reader:
ex = Extract()
#print row
ex.code, ex.date, ex.desc, ex.amount, ex.currency, ex.val_date, ex.from_account, ex.from_name, ex.com1, ex.com2, ex.ref = row
ex.com = "%s %s" % (ex.com1, ex.com2)
#transform 6.200,00 EUR in 6200.00 EUR
ex.amount = float(ex.amount.replace(".", "").replace(",", "."))
ex.date = time.strptime(ex.date, "%d/%m/%Y")
extracts.append(ex)
print "loaded %s bank extracts from %s" % (len(extracts), bankExtractsFile)
#now match the two sets:
#1: we want to find one operation in financial ledger per bank extract. Amount must match.
verbose = False
if len(sys.argv) > 3:
operationToCheck = int(sys.argv[3])
extracts = extracts[operationToCheck:operationToCheck+1]
verbose = True
def matchAmount(extract, operation):
if extract.amount > 0:
return operation.debit == extract.amount
else:
return operation.credit == -extract.amount
def checkExtract(extract, operations, verbose):
#1: get all fin. ledger operations at that date.
if verbose:
print "extract: %s" % extract
candidates = filter(lambda x: x.date == extract.date, operations)
errorMessage = None
if candidates == []:
#it may have been posted later on in the accounting.
candidates = filter(lambda x: x.date > extract.date and matchAmount(extract,x), operations)
if verbose:
print "candidates: %s " % candidates
if candidates == []:
errorMessage = "Found no ledger operations for extract: %s" % extract
else:
#2: find the one.
matches = filter(lambda x: matchAmount(extract, x) and x.code != "ANNULE", candidates)
if len(matches) != 1:
if len(matches) == 0:
errorMessage = "Problem: no candidates for extract %s" % extract
else:
errorMessage = "Problem. Multiple candidates: %s for extract %s" % (matches, extract)
else:
#remove the matched from the operations list.
operations.remove(matches[0])
return errorMessage
errorCount = 0
for extract in extracts:
error = checkExtract(extract, operations, verbose)
if error:
errorCount = errorCount + 1
print "%s \n" % error
print "Error count: %s" % errorCount