scripts: script to generate regularisation files and modify db.
This commit is contained in:
parent
8bc46b58a8
commit
2cc55ddace
|
@ -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()
|
Reference in New Issue