scripts: script to generate regularisation files and modify db.

This commit is contained in:
Mikaël Ates 2014-01-13 16:25:24 +01:00
parent 8bc46b58a8
commit 2cc55ddace
1 changed files with 356 additions and 0 deletions

356
scripts/regul_fact_ppa.py Normal file
View File

@ -0,0 +1,356 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python
"""
Procédure
0 - Vérifier que les lots concernées ont bien été payés et les rejets pointés.
1- Créer les fichiers de télétransmission et à imprimer sur une machine de dev :
$ python scripts/regul_fact_ppa.py -pw
2 - Copier les fichiers de TT sur la prod et les mailer:
$ scp ./file.b2-mail \
user@prod:/path
$ ssh prod
$ sudo chown run_user.run_user ./file.b2-mail
$ python manage.py shell
>>> %cpaste
from calebasse.facturation.b2 import sendmail_raw
from smtplib import SMTP, SMTPException
mail = open("file.b2-mail").read()
try:
to, via = sendmail_raw(mail)
except SMTPException as e:
print str(e)
else:
print 'OK'
3 - Diffuser les pdf à imprimer.
4 - Modifier le plan de facturation (ajout de la facturation de
regularisation) sur la production pour que l'incrémentation des
numéros de lots se fasse bien à la suite dans les prochianes
facturations :
$ python scripts/regul_fact_ppa.py -e
5 - Faire l'export comptable à partir de l'interface graphique sur la
page de détail de la facturation de régularisation sur la production.
6 - Corriger sur la production le prix dans le passé.
"""
import django.core.management
import calebasse.settings
django.core.management.setup_environ(calebasse.settings)
import sys, getopt
from datetime import datetime
from decimal import Decimal
from django.db.models import Max, Q
from calebasse.facturation.models import Invoicing, Invoice
from calebasse.facturation.b2 import b2
from calebasse.facturation.batches import Batch
from calebasse.facturation.invoice_header import render_invoicing
from calebasse.ressources.models import HealthCenter, Service
OLD_PPA = 13965
NEW_PPA = 16159
LIMIT_DATE = datetime(2013, 8, 1)
if __name__ == "__main__":
print "### START: %s" % datetime.now()
try:
opts, args = getopt.getopt(sys.argv[1:], "btdwpec:n:")
except getopt.GetoptError:
print 'regul_fact_ppa.py -b -t -p -d -w -e -c <hc_id> -n <nb_invoice>'
sys.exit(2)
build = False
transmission = False
one_hc = None
number = 0
detail = False
pdf = False
write = False
export = False
for opt, arg in opts:
if opt == '-h':
print 'regul_fact_ppa.py -b -t -p -d -w -e -c <hc_id> -n <nb_invoice>'
sys.exit()
elif opt in ("-d", "--detail"):
detail = True
elif opt in ("-b", "--build"):
build = True
elif opt in ("-w", "--write"):
write = True
if not build:
build = True
elif opt in ("-t", "--transmission"):
transmission = True
if not build:
build = True
elif opt in ("-p", "--pdf"):
pdf = True
if not build:
build = True
elif opt in ("-e", "--export"):
export = True
if not build:
build = True
elif opt in ("-c", "--center"):
# 163 is CPAM42
one_hc = HealthCenter.objects.get(id=int(arg))
elif opt in ("-n", "--number"):
if one_hc:
number = int(arg)
print "Option: Build batches is %s." %str(build)
print "Option: Transmit batches is %s." %str(transmission)
if one_hc:
print "Option: Health center %s found." % one_hc
else:
print "Option: All health centers."
if number:
print "Option: With %d invoices." % number
else:
print "Option: All invoices."
print "Option: Detail is %s." %str(detail)
print
print "### ----> Recherche des factures à régulariser"
invoices_bad_price = Invoice.objects.filter(ppa=OLD_PPA, rejected = False).distinct()
# invoices_bad_price = Invoice.objects.filter(ppa=OLD_PPA, acts__date__gte=LIMIT_DATE.date(), rejected = False).distinct()
if one_hc:
print "\tRecherche restreinte à : %s" % one_hc
# invoices_bad_price = invoices_bad_price.filter(policy_holder_healthcenter=one_hc)
invoices_bad_price = invoices_bad_price.filter(
Q(patient_healthcenter=one_hc,
policy_holder_healthcenter__isnull=True)|
Q(policy_holder_healthcenter=one_hc))
invoices_bad_price_l = list()
for i in invoices_bad_price:
found = False
for date in i.list_dates.split('$'):
date_o = datetime.strptime(date, '%d/%m/%Y')
if date_o >= LIMIT_DATE:
found = True
break
if found:
invoices_bad_price_l.append(i)
if one_hc and number:
print "\tNombre de factures réduit à : %d" % number
if number > len(invoices_bad_price_l):
print "\t\tLa limite du nombre de factures est plus grand que le nombre de factures trouvées : %d" % len(invoices_bad_price_l)
number = len(invoices_bad_price_l)
invoices_bad_price_l = invoices_bad_price_l[:number]
invoicings = dict()
for i in invoices_bad_price_l:
invoicings.setdefault(i.invoicing, dict())
if not i.health_center:
print "Invoice %d has no healthcenter!!!" % i.id
sys.exit(0)
invoicings[i.invoicing].setdefault((i.batch, i.health_center), list()).append(i)
print "Nombre de factures à régulariser %d" % len(invoices_bad_price_l)
print "Nombre de facturations touchées %d (%s)" % (len(invoicings), ' '.join([str(i.seq_id) for i in invoicings.keys()]))
print
print "### ----> Analyse par lot"
invoices_per_healthcenter = dict()
regul_total = 0
for invoicing, batch in invoicings.items():
real_batches = invoicing.get_batches()
billed_batches = {}
for hc, b, amount_rejected, versement in real_batches:
billed_batches[(b.number, hc)] = (b, amount_rejected, versement)
# print "%d %d %s" % (invoicing.seq_id, b.number, hc)
print "\tFacturation : %d" % invoicing.seq_id
regul_invoicing = 0
for (batch_nb, health_center), invoices in batch.items():
invoices_per_healthcenter.setdefault(health_center, list()).extend(invoices)
print "\t\tCentre : %s" % health_center
print "\t\tLot : %d" % batch_nb
print "\t\t\tNb factures à régulariser : %d" % len(invoices)
init_price_batch = 0
regul_batch = 0
for i in invoices:
regul = 0
for date in i.list_dates.split('$'):
init_price_batch += OLD_PPA
date_o = datetime.strptime(date, '%d/%m/%Y')
if date_o >= LIMIT_DATE:
regul = regul + NEW_PPA - OLD_PPA
regul_batch += regul
regul_invoicing += regul_batch
try:
hc = health_center.hc_invoice if health_center.hc_invoice else health_center
print "\t\t\tMontant total facturé : %.2f" % billed_batches[(batch_nb, hc)][0].total
print "\t\t\tMontant des rejets : %.2f" % billed_batches[(batch_nb, hc)][1]
print "\t\t\tVersement : %.2f" % billed_batches[(batch_nb, hc)][2]
if (billed_batches[(batch_nb, hc)][0].total - billed_batches[(batch_nb, hc)][1]) != (Decimal(init_price_batch) / Decimal(100)):
b = billed_batches[(batch_nb, hc)][0]
amount = 0
nb_f = 0
for i in b.invoices:
if not i.rejected:
found = False
for date in i.list_dates.split('$'):
date_o = datetime.strptime(date, '%d/%m/%Y')
if date_o >= LIMIT_DATE:
found = True
if not found:
amount += i.decimal_amount
nb_f += 1
if amount:
if (billed_batches[(batch_nb, hc)][0].total - billed_batches[(batch_nb, hc)][1] - amount) != (Decimal(init_price_batch) / Decimal(100)):
print "\t\t\t!!! problème 1 : Montant : %.2f €, calcul : %.2f €, trouvé: %.2f" % (amount, (billed_batches[(batch_nb, hc)][0].total - billed_batches[(batch_nb, hc)][1] - amount), (Decimal(init_price_batch) / Decimal(100)))
print "\t\t\t!!! Nombre de factures dans le lot : %d" % len(b.invoices)
print "\t\t\t!!! Nombre de factures payées et avec seulement des actes antérieurs au 01/08/2013 : %d" % nb_f
rej = 0
for tmp in b.invoices:
if tmp.rejected:
rej += 1
print "\t\t\t!!! Nombre de factures rejetée : %d" % rej
else:
print "\t\t\tMontant des factures payées et avec seulement des actes antérieurs au 01/08/2013 : %.2f" % amount
else:
print "\t\t\t!!! problème 2 !!!"
except Exception, e:
print "\t\t\t!!! Centres %s et %s, lot %d ne correspond pas" % (health_center, hc, batch_nb)
print e
print "\t\t\t\tMontant facturé sur mauvaises factures: %.2f" % (Decimal(init_price_batch) / Decimal(100))
print "\t\t\t\tMontant regularisation : %.2f" % (Decimal(regul_batch) / Decimal(100))
print
regul_total += regul_invoicing
print "\tMontant regularisation de la facturation : %.2f" % (Decimal(regul_invoicing) / Decimal(100))
print "Montant regularisation total : %.2f" % (Decimal(regul_total) / Decimal(100))
print
b2_fns = dict()
if one_hc:
invoices = invoices_per_healthcenter[one_hc]
invoices_per_healthcenter = {one_hc: invoices}
for hc, invoices in invoices_per_healthcenter.items():
old_amount = 0
regul_total = 0
print '### ----> Centre : %s (ID: %d)' % (str(hc), hc.id)
for i in invoices:
regul = 0
for date in i.list_dates.split('$'):
date_o = datetime.strptime(date, '%d/%m/%Y')
if date_o >= LIMIT_DATE:
regul = regul + NEW_PPA - OLD_PPA
old_amount += i.amount
regul_total += regul
if detail:
print '\t\tFacture ancien n°: %d (ID : %d)' % (i.number, i.id)
print '\t\tAncien montant : %.2f' % (Decimal(i.amount) / Decimal(100))
print '\t\tNouveau montant : %.2f' % (Decimal(i.amount + regul) / Decimal(100))
print '\t\tRégularisation : %.2f' % (Decimal(regul) / Decimal(100))
print
new_amount = regul_total + old_amount
print '\tAncien montant total : %.2f' % (Decimal(old_amount) / Decimal(100))
print '\tNouveau montant total : %.2f' % (Decimal(new_amount) / Decimal(100))
print '\tRégularisation totale : %.2f' % (Decimal(regul_total) / Decimal(100))
print
last_seq_id = Invoicing.objects.filter(service=Service.objects.get(name='CMPP'), status=Invoicing.STATUS.validated).aggregate(Max('seq_id'))['seq_id__max']
position_seq_id = last_seq_id + 1
batches_per_healthcenter = dict()
batches_amount_per_healthcenter = dict()
if build:
print '### ----> Construction des lots'
j = 1
for hc, invoices in invoices_per_healthcenter.items():
print 'Lots pour le centre : %s (ID: %d)' % (str(hc), hc.id)
print "\tNombre de factures à régulariser : %d" % len(invoices)
for i in invoices:
i.number = position_seq_id * 1000000 + j
j += 2
if not hc.dest_organism[0:3]:
print "HC has no dest org, no need to build because no transmission possible !!!!"
continue
agg = Invoice.objects.filter(
Q(patient_healthcenter=hc,
policy_holder_healthcenter__isnull=True)|
Q(policy_holder_healthcenter=hc)) \
.aggregate(Max('batch'))
max_bn = agg['batch__max']
last_batch_id = max_bn + 1
batches = []
nb_batches = len(invoices)/80 + 1
reste = len(invoices)%80
if not reste:
nb_batches = nb_batches - 1
for i in range(nb_batches):
end = (i + 1) * 80
if (i+1) == nb_batches and reste:
end = i * 80 + reste
batch = Batch(number=last_batch_id + i, invoices=invoices[i*80:end])
batch.number_of_invoices = len(batch.invoices) * 2
nb_acts = 0
for i in batch.invoices:
nb_acts += (len(i.list_dates.split('$'))*2)
batch.number_of_acts = nb_acts
batches.append(batch)
print "\tNombre de lots construits : %d" % len(batches)
total = 0
batches_amount = []
for batch in batches:
print "\t\tLot %d" % batch.number
amount = 0
for i in batch.invoices:
for date in i.list_dates.split('$'):
date_o = datetime.strptime(date, '%d/%m/%Y')
if date_o >= LIMIT_DATE:
amount = amount + NEW_PPA - OLD_PPA
total += amount
batch.total = Decimal((batch.number_of_acts * OLD_PPA + amount) / Decimal(100))
batches_amount.append((batch, amount))
print "\t\tNombre d'actes : %d" % batch.number_of_acts
print "\t\tNombre de factures : %d " % batch.number_of_invoices
print "\t\tMontant total B2 : %.2f" % batch.total
print "\t\tMontant de la regularisation : %.2f" % (Decimal(amount) / Decimal(100))
batches_per_healthcenter[hc] = batches
batches_amount_per_healthcenter[hc] = batches_amount
print "\tMontant de la regularisation pour le centre : %.2f" % (Decimal(total) / Decimal(100))
if write:
print '\tBuilding B2 file...'
for batch in batches:
b2_fns[hc] = b2(seq_id=position_seq_id, hc=hc, batches=[batch], adj_date=LIMIT_DATE, adj_price=NEW_PPA)
print '\tBatch file written : %s' % b2_fns[hc]
print
if transmission:
print "### ----> Transmission sending emails not implemented"
print
if pdf:
print "### ----> Generate pdf files"
path = render_invoicing(delete=False, batches_by_health_center=batches_per_healthcenter, adj_date=LIMIT_DATE, adj_price=NEW_PPA, seq_id=position_seq_id)
print "file generated : %s" % path
print
if export:
start_date = datetime.today()
last_seq_id = Invoicing.objects.filter(service=Service.objects.get(name='CMPP'), status=Invoicing.STATUS.validated).aggregate(Max('seq_id'))['seq_id__max']
position_seq_id = last_seq_id + 1
for invoicing in Invoicing.objects.filter(service=Service.objects.get(name='CMPP'), seq_id__gte=position_seq_id).order_by('-seq_id'):
invoicing.seq_id += 1
invoicing.save()
invoicing = Invoicing(service=Service.objects.get(name='CMPP'),
start_date=start_date, end_date=start_date,
status=Invoicing.STATUS.validated, seq_id=position_seq_id)
invoicing.save()
n = 0
for hc, batches_amount in batches_amount_per_healthcenter.items():
for batch, amount in batches_amount:
i_id = invoicing.seq_id * 1000000 + 1 + n
invoice = Invoice(batch=batch.number, number=i_id, invoicing=invoicing, ppa=0, amount=amount, policy_holder_healthcenter=hc,
list_dates = start_date.date().strftime('%d/%m/%Y'))
invoice.save()
n += 1
print "### END: %s" % datetime.now()