New accounting rules
This commit is contained in:
parent
42c55f5521
commit
261ed1e99b
3 changed files with 97 additions and 53 deletions
|
|
@ -135,44 +135,45 @@ class Teacher(models.Model):
|
|||
'report': self.next_report,
|
||||
}
|
||||
|
||||
def calc_imputations(self):
|
||||
def calc_imputations(self, ratios):
|
||||
"""
|
||||
Return a tuple for accountings charges
|
||||
"""
|
||||
activities = self.calc_activity()
|
||||
imputations = OrderedDict(
|
||||
[('ASA', 0), ('ASSC', 0), ('ASE', 0), ('MP', 0), ('EDEpe', 0), ('EDEps', 0),
|
||||
('EDS', 0), ('CAS_FPP', 0), ('Direction', 0)]
|
||||
[('ASAFE', 0), ('ASSCFE', 0), ('ASEFE', 0), ('MPTS', 0), ('MPS', 0), ('EDEpe', 0), ('EDEps', 0),
|
||||
('EDS', 0), ('CAS_FPP', 0)]
|
||||
)
|
||||
courses = self.course_set.all()
|
||||
|
||||
for key in imputations:
|
||||
imputations[key] = courses.filter(imputation__contains=key).aggregate(models.Sum('period'))['period__sum'] or 0
|
||||
|
||||
# Split EDE periods in EDEpe and EDEps columns, in proportion
|
||||
# Spliting imputations for EDE, ASE and ASSC
|
||||
ede = courses.filter(imputation='EDE').aggregate(models.Sum('period'))['period__sum'] or 0
|
||||
if ede > 0:
|
||||
pe = imputations['EDEpe']
|
||||
ps = imputations['EDEps']
|
||||
pe_percent = (pe / (pe + ps)) if (pe + ps) > 0 else 0.5
|
||||
pe_plus = round(ede * pe_percent)
|
||||
imputations['EDEpe'] += pe_plus
|
||||
imputations['EDEps'] += ede - pe_plus
|
||||
pe = int(round(ede * ratios['edepe'], 0))
|
||||
imputations['EDEpe'] += pe
|
||||
imputations['EDEps'] += ede - pe
|
||||
|
||||
ase = courses.filter(imputation='ASE').aggregate(models.Sum('period'))['period__sum'] or 0
|
||||
if ase > 0:
|
||||
asefe = int(round(ase * ratios['asefe'], 0))
|
||||
imputations['ASEFE'] += asefe
|
||||
imputations['MPTS'] += ase - asefe
|
||||
|
||||
assc = courses.filter(imputation='ASSC').aggregate(models.Sum('period'))['period__sum'] or 0
|
||||
if assc > 0:
|
||||
asscfe = int(round(assc * ratios['asscfe'], 0))
|
||||
imputations['ASSCFE'] += asscfe
|
||||
imputations['MPS'] += assc - asscfe
|
||||
|
||||
# Split formation periods in proportions
|
||||
tot = sum(imputations.values())
|
||||
if tot > 0:
|
||||
for key in imputations:
|
||||
imputations[key] += round(imputations[key] / tot * activities['tot_formation'])
|
||||
imputations[key] += round(imputations[key] / tot * activities['tot_formation'],0)
|
||||
|
||||
# Correct for rounding errors changing the first imputations value
|
||||
tot = sum(imputations.values()) + self.previous_report - (self.next_report)
|
||||
dif = tot - activities['tot_paye']
|
||||
if dif in [-1, 1]:
|
||||
for k, v in imputations.items():
|
||||
if v > 0:
|
||||
imputations[k] += 1 if dif == -1 else -1
|
||||
break
|
||||
return (activities, imputations)
|
||||
|
||||
def total_logbook(self):
|
||||
|
|
@ -555,13 +556,20 @@ IMPUTATION_CHOICES = (
|
|||
('ASAFE', 'ASAFE'),
|
||||
('ASEFE', 'ASEFE'),
|
||||
('ASSCFE', 'ASSCFE'),
|
||||
('MP', 'MP'),
|
||||
|
||||
('MPTS', 'MPTS'),
|
||||
('MPS', 'MPS'),
|
||||
|
||||
('EDEpe', 'EDEpe'),
|
||||
('EDEps', 'EDEps'),
|
||||
('EDE', 'EDE'),
|
||||
('EDS', 'EDS'),
|
||||
('CAS_FPP', 'CAS_FPP'),
|
||||
('Direction', 'Direction'),
|
||||
|
||||
# To split afterwards
|
||||
('EDE', 'EDE'),
|
||||
('#Mandat_ASA', 'ASA'),
|
||||
('#Mandat_ASE', 'ASE'),
|
||||
('#Mandat_ASSC', 'ASSC'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -382,32 +382,41 @@ class TeacherTests(TestCase):
|
|||
self.assertEqual(self.teacher.next_report, -2)
|
||||
|
||||
def test_calc_imputations(self):
|
||||
result = self.teacher.calc_imputations()
|
||||
self.assertEqual(result[1]['ASSC'], 9)
|
||||
ratio = {'edepe': 0.45, 'asefe': 0.45, 'asscfe': 0.55}
|
||||
result = self.teacher.calc_imputations(ratio)
|
||||
self.assertEqual(result[1]['ASSCFE'], 9)
|
||||
self.assertEqual(result[1]['EDEpe'], 5)
|
||||
|
||||
# Test with only EDE data
|
||||
# Test with only ASSC data
|
||||
t2 = Teacher.objects.create(
|
||||
first_name='Isidore', last_name='Gluck', birth_date='1986-01-01'
|
||||
)
|
||||
Course.objects.create(
|
||||
teacher=t2, period=13, subject='#ASE Colloque', imputation='ASSCFE',
|
||||
teacher=t2, period=24, subject='#ASSCE Colloque', imputation='ASSC',
|
||||
)
|
||||
Course.objects.create(
|
||||
teacher=t2, period=5, subject='Cours EDE', imputation='EDE',
|
||||
teacher=t2, period=130, subject='#Coaching', imputation='ASSC',
|
||||
)
|
||||
Course.objects.create(
|
||||
teacher=t2, period=17, subject='Sém. enfance 2', imputation='ASE',
|
||||
teacher=t2, period=275, subject='Cours MP ASSC', imputation='MPS',
|
||||
)
|
||||
Course.objects.create(
|
||||
teacher=t2, period=450, subject='Cours ASSCFE', imputation='ASSCFE',
|
||||
)
|
||||
|
||||
result = t2.calc_imputations()
|
||||
self.assertEqual(result[1]['ASE'], 19)
|
||||
self.assertEqual(result[1]['ASSC'], 16) # rounding correction (first col > 0)
|
||||
self.assertEqual(result[1]['EDEpe'], 2)
|
||||
self.assertEqual(result[1]['EDEps'], 3)
|
||||
self.assertEqual(result[0]['tot_paye'], result[0]['tot_trav'])
|
||||
self.assertEqual(result[0]['tot_paye'], 40)
|
||||
self.assertEqual(result[0]['report'], 0)
|
||||
t2.previous_report = 10
|
||||
|
||||
ratio = {'edepe': 0.45, 'asefe': 0.45, 'asscfe': 0.55}
|
||||
|
||||
result = t2.calc_imputations(ratio)
|
||||
|
||||
self.assertEqual(result[0]['tot_paye'], 1005)
|
||||
self.assertEqual(result[0]['tot_formation'], 116)
|
||||
self.assertEqual(result[0]['tot_mandats'], 154)
|
||||
self.assertEqual(result[1]['ASSCFE'], 606)
|
||||
self.assertEqual(result[1]['MPS'], 389)
|
||||
|
||||
|
||||
|
||||
def test_export_imputations(self):
|
||||
self.client.login(username='me', password='mepassword')
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from django.contrib import messages
|
|||
from django.core.files import File
|
||||
from django.core.mail import EmailMessage
|
||||
from django.db import transaction
|
||||
from django.db.models import Case, Count, Value, When, Q
|
||||
from django.db.models import Case, Count, Value, When, Q, Sum
|
||||
from django.db.models.functions import Concat
|
||||
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
|
|
@ -32,7 +32,7 @@ from .exports import OpenXMLExport
|
|||
from .forms import EmailBaseForm, PeriodForm, StudentImportForm, UploadHPFileForm, UploadReportForm
|
||||
from .models import (
|
||||
Klass, Section, Option, Student, Teacher, Corporation, CorpContact, Course, Period,
|
||||
Training, Availability,
|
||||
Training, Availability
|
||||
)
|
||||
from .pdf import ExpertEdeLetterPdf, UpdateDataFormPDF, MentorCompensationPdfForm
|
||||
from .utils import is_int
|
||||
|
|
@ -402,17 +402,23 @@ class HPImportView(ImportViewBase):
|
|||
('ASAFE', 'ASAFE'),
|
||||
('ASEFE', 'ASEFE'),
|
||||
('ASSCFE', 'ASSCFE'),
|
||||
('MP', 'MP'),
|
||||
('CMS', 'MP'),
|
||||
|
||||
('#Mandat_ASA', 'ASAFE'),
|
||||
|
||||
('MPTS', 'MPTS'),
|
||||
('MPS', 'MPS'),
|
||||
('CMS ASE', 'MPTS'),
|
||||
('CMS ASSC', 'MPS'),
|
||||
|
||||
('EDEpe', 'EDEpe'),
|
||||
('EDEps', 'EDEps'),
|
||||
('EDE', 'EDE'),
|
||||
('EDS', 'EDS'),
|
||||
('CAS_FPP', 'CAS_FPP'),
|
||||
('#Mandat_ASA', 'ASAFE'),
|
||||
('#Mandat_ASE', 'ASEFE'),
|
||||
('#Mandat_ASSC', 'ASSCFE'),
|
||||
('Direction', 'Direction'),
|
||||
|
||||
# To split afterwards
|
||||
('EDE', 'EDE'),
|
||||
('#Mandat_ASE', 'ASE'),
|
||||
('#Mandat_ASSC', 'ASSC'),
|
||||
])
|
||||
|
||||
def import_data(self, up_file):
|
||||
|
|
@ -878,18 +884,37 @@ def stages_export(request, scope=None):
|
|||
return export.get_http_response('stages_export')
|
||||
|
||||
|
||||
def _ratio_Ede_Ase_Assc():
|
||||
# Spliting for unattribued periods
|
||||
tot_edeps = Course.objects.filter(imputation='EDEps').aggregate(Sum('period'))['period__sum'] or 0
|
||||
tot_edepe = Course.objects.filter(imputation='EDEpe').aggregate(Sum('period'))['period__sum'] or 0
|
||||
edepe_ratio = 1 if tot_edepe + tot_edeps == 0 else tot_edepe / (tot_edepe + tot_edeps)
|
||||
|
||||
tot_asefe = Course.objects.filter(imputation='ASEFE').aggregate(Sum('period'))['period__sum'] or 0
|
||||
tot_mpts = Course.objects.filter(imputation='MPTS').aggregate(Sum('period'))['period__sum'] or 0
|
||||
asefe_ratio = 1 if tot_asefe + tot_mpts == 0 else tot_asefe / (tot_asefe + tot_mpts)
|
||||
|
||||
tot_asscfe = Course.objects.filter(imputation='ASSCFE').aggregate(Sum('period'))['period__sum'] or 0
|
||||
tot_mps = Course.objects.filter(imputation='MPS').aggregate(Sum('period'))['period__sum'] or 0
|
||||
asscfe_ratio = 1 if tot_asscfe + tot_mps == 0 else tot_asscfe / (tot_asscfe + tot_mps)
|
||||
|
||||
return {'edepe':edepe_ratio, 'asefe':asefe_ratio, 'asscfe': asscfe_ratio}
|
||||
|
||||
|
||||
def imputations_export(request):
|
||||
IMPUTATIONS_EXPORT_FIELDS = [
|
||||
'Nom', 'Prénom', 'Report passé', 'Ens', 'Discipline',
|
||||
'Accomp.', 'Discipline', 'Total payé', 'Indice', 'Taux', 'Report futur',
|
||||
'ASA', 'ASSC', 'ASE', 'MP', 'EDEpe', 'EDEps', 'EDS', 'CAS_FPP', 'Direction'
|
||||
'ASA', 'ASSC', 'ASE', 'MPTS', 'MPS', 'EDEpe', 'EDEps', 'EDS', 'CAS_FPP'
|
||||
]
|
||||
|
||||
ratios = _ratio_Ede_Ase_Assc()
|
||||
|
||||
export = OpenXMLExport('Imputations')
|
||||
export.write_line(IMPUTATIONS_EXPORT_FIELDS, bold=True) # Headers
|
||||
|
||||
for teacher in Teacher.objects.filter(archived=False):
|
||||
activities, imputations = teacher.calc_imputations()
|
||||
activities, imputations = teacher.calc_imputations(ratios)
|
||||
values = [
|
||||
teacher.last_name, teacher.first_name, teacher.previous_report,
|
||||
activities['tot_ens'], 'Ens. prof.', activities['tot_mandats'] + activities['tot_formation'],
|
||||
|
|
@ -909,17 +934,19 @@ def export_sap(request):
|
|||
'ZACT', 'ZBRA', 'ZOTP', 'ZCCO', 'ZORD', 'ZTAUX',
|
||||
]
|
||||
MAPPING_OTP = {
|
||||
'ASA': 'CIFO01.03.02.03.01.02 - ASA EE',
|
||||
'ASE': 'CIFO01.03.02.04.01.02 - CFC ASE EE',
|
||||
'ASSC': 'CIFO01.03.02.04.02.02 - CFC ASSC EE',
|
||||
'ASAFE': 'CIFO01.03.02.03.01.02 - ASA EE',
|
||||
'ASEFE': 'CIFO01.03.02.04.01.02 - CFC ASE EE',
|
||||
'ASSCFE': 'CIFO01.03.02.04.02.02 - CFC ASSC EE',
|
||||
'EDEpe': 'CIFO01.03.02.07.01.01 - EDE prat. prof. PT',
|
||||
'EDEps': 'CIFO01.03.02.07.02.01 - EDE stages PT',
|
||||
'EDS': 'CIFO01.03.02.07.03.02 - EDS EE',
|
||||
'CAS_FPP': 'CIFO01.03.02.01.03 - Mandats divers (CAS FPP)',
|
||||
'MP' : 'Matu. Santé + Travail social',
|
||||
'Direction': 'Direction',
|
||||
'MPTS' : 'CIFO01.04.03.06.02.01 - MPTS ASE',
|
||||
'MPS': 'CIFO01.04.03.06.03.01 - MPS Santé',
|
||||
}
|
||||
|
||||
ratios = _ratio_Ede_Ase_Assc()
|
||||
|
||||
export = OpenXMLExport('Imputations')
|
||||
export.write_line(EXPORT_SAP_HEADERS, bold=True) # Headers
|
||||
start_date = '20.08.2018'
|
||||
|
|
@ -931,7 +958,7 @@ def export_sap(request):
|
|||
stat = ''
|
||||
|
||||
for teacher in Teacher.objects.filter(archived=False):
|
||||
activities, imputations = teacher.calc_imputations()
|
||||
activities, imputations = teacher.calc_imputations(ratios)
|
||||
for key in imputations:
|
||||
if imputations[key] > 0:
|
||||
values = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue