pax_global_header 0000666 0000000 0000000 00000000064 14575653726 0014536 g ustar 00root root 0000000 0000000 52 comment=5f3d558793b537a74480241ac6981479f5938cd3
woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/ 0000775 0000000 0000000 00000000000 14575653726 0023001 5 ustar 00root root 0000000 0000000 woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/modules/ 0000775 0000000 0000000 00000000000 14575653726 0024451 5 ustar 00root root 0000000 0000000 woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/modules/cesu/ 0000775 0000000 0000000 00000000000 14575653726 0025410 5 ustar 00root root 0000000 0000000 woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/modules/cesu/__init__.py 0000664 0000000 0000000 00000001474 14575653726 0027527 0 ustar 00root root 0000000 0000000 # flake8: compatible
# Copyright(C) 2020 Ludovic LANGE
#
# This file is part of a woob module.
#
# This woob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This woob module is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this woob module. If not, see .
from .module import CesuModule
__all__ = ["CesuModule"]
woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/modules/cesu/browser.py 0000664 0000000 0000000 00000017504 14575653726 0027454 0 ustar 00root root 0000000 0000000 # flake8: compatible
# Copyright(C) 2020 Ludovic LANGE
#
# This file is part of a woob module.
#
# This woob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This woob module is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this woob module. If not, see .
import calendar
from datetime import datetime
from dateutil.relativedelta import relativedelta
from woob.browser import LoginBrowser, URL, need_login
from woob.browser.exceptions import ClientError
from woob.capabilities.bill import Subscription
from woob.exceptions import BrowserIncorrectPassword
from .pages import (
LoginPage,
HomePage,
StatusPage,
EmployerPage,
EmployeesPage,
RegistrationPage,
RegistrationDashboardPage,
DirectDebitSummaryPage,
EmployeesDashboardPage,
CurrentFiscalAdvantagePage,
LastDayMonthPage,
DirectDebitsHeaderPage,
DirectDebitsDetailPage,
PayslipDownloadPage,
DirectDebitDownloadPage,
TaxCertificateDownloadPage,
TaxCertificatesPage,
)
class CesuBrowser(LoginBrowser):
BASEURL = 'https://www.cesu.urssaf.fr'
login = URL(r'/cesuwebdec/authentication$', LoginPage)
homepage = URL(r'/info/accueil\.login\.do$', HomePage)
logout = URL(r'/cesuwebdec/deconnexion$')
status = URL(r'/cesuwebdec/status', StatusPage)
employer = URL(r'/cesuwebdec/employeursIdentite/(?P.*)', EmployerPage)
employees = URL(r'/cesuwebdec/employeurs/(?P.*)/salaries', EmployeesPage)
employees_dashboard = URL(
r'/cesuwebdec/salariesTdb?pseudoSiret=(?P.*)&maxResult=8',
EmployeesDashboardPage
)
registrations = URL(r'/cesuwebdec/employeurs/(?P.*)/declarationsby\?.*', RegistrationPage)
registrations_dashboard = URL(
r'/cesuwebdec/employeurs/(?P.*)/declarationsTdBby\?.*',
RegistrationDashboardPage
)
direct_debits_summary = URL(r'/cesuwebdec/employeurs/(?P.*)/recapprelevements', DirectDebitSummaryPage)
direct_debits_header = URL(
r'/cesuwebdec/employeurs/(?P.*)/entetePrelevements\?.*',
DirectDebitsHeaderPage
)
direct_debits_detail = URL(
r'/cesuwebdec/employeurs/(?P.*)/detailPrelevements\?periode=202001&type=IPVT&reference=0634675&idPrelevement=0',
DirectDebitsDetailPage
)
direct_debit_download = URL(
r'/cesuwebdec/employeurs/(?P.*)/editions/avisPrelevement\?reference=(?P.*)&periode=(?P.*)&type=(?P.*)',
DirectDebitDownloadPage
)
current_fiscal_advantage = URL(
r'/cesuwebdec/employeurs/(?P.*)/avantagefiscalencours',
CurrentFiscalAdvantagePage
)
last_day_month = URL(r'/cesuwebdec/employeurs/(?P.*)/dernierJourOuvreMois', LastDayMonthPage)
payslip_download = URL(
r'/cesuwebdec/employeurs/(?P.*)/editions/bulletinSalairePE\?refDoc=(?P.*)',
PayslipDownloadPage
)
tax_certificates = URL(r'/cesuwebdec/employeurs/(?P.*)/attestationsfiscales', TaxCertificatesPage)
tax_certificate_download = URL(
r'/cesuwebdec/employeurs/(?P.*)/editions/attestation_fiscale_annee\?periode=(?P.*)',
TaxCertificateDownloadPage
)
employer = None
compteur = 0
def do_login(self):
self.session.cookies.clear()
self.session.headers.update({
"Accept": "*/*",
"Content-Type": "application/json; charset=utf-8",
"X-Requested-With": "XMLHttpRequest",
})
try:
self.login.go(json={
'username': self.username,
'password': self.password,
})
except ClientError as error:
response = error.response.json()
error_messages_list = response.get('listeMessages', [])
for error_message in error_messages_list:
if error_message.get('contenu', '') == 'Identifiant / mot de passe non reconnus':
raise BrowserIncorrectPassword(error_message['contenu'])
raise
self.status.go()
self.employer = self.page.get_object().get("numero")
def do_logout(self):
self.logout.go()
self.session.cookies.clear()
@need_login
def iter_subscription(self):
self.employees.go(employer=self.employer)
for sub in self.page.iter_subscriptions():
yield sub
s = Subscription()
s.label = "Prélèvements"
s.id = "prelevements"
s._type = s.id
yield s
s = Subscription()
s.label = "Attestations fiscales"
s.id = "taxcertificates"
s._type = s.id
yield s
def _search_registrations(
self, subscription, begin_date, end_date, num_start, step
):
self.registrations.go(
employer=self.employer,
params={
"numInterneSalarie": subscription.id,
"dtDebutRecherche": begin_date.strftime("%Y%m%d"),
"dtFinRecherche": end_date.strftime("%Y%m%d"),
"numStart": num_start,
"nbAffiche": step,
"numeroOrdre": self.compteur,
},
)
self.compteur += 1
def _search_direct_debits(self, begin_date, end_date):
self.direct_debits_header.go(
employer=self.employer,
params={
"dtDebut": begin_date.strftime("%Y%m%d"),
"dtFin": end_date.strftime("%Y%m%d"),
"numeroOrdre": self.compteur,
"nature": "",
},
)
self.compteur += 1
@need_login
def iter_documents(self, subscription):
self.compteur = 0
if subscription._type == "employee":
end_date = datetime.today()
# 5 years maximum
begin_date = end_date - relativedelta(years=+5)
has_results = True
num_start = 0
step = 24
while has_results:
self._search_registrations(
subscription, begin_date, end_date, num_start, step
)
num_start += step
has_results = len(self.page.get_objects()) > 0
for doc in self.page.iter_documents(
subscription=subscription.id, employer=self.employer
):
yield doc
elif subscription._type == "prelevements":
# Start end of month
end_date = datetime.today()
end_date += relativedelta(
day=calendar.monthrange(end_date.year, end_date.month)[1],
hour=0,
minute=0,
second=0,
microsecond=0,
)
# 1 year maximum ; beginning of month
begin_date = end_date - relativedelta(years=+1, day=1)
self._search_direct_debits(begin_date, end_date)
has_results = len(self.page.get_objects()) > 0
for doc in self.page.iter_documents(
subscription=subscription.id, employer=self.employer
):
yield doc
elif subscription._type == "taxcertificates":
self.tax_certificates.go(employer=self.employer)
for doc in self.page.iter_documents(
subscription=subscription.id, employer=self.employer
):
yield doc
woob-master-5f3d558793b537a74480241ac6981479f5938cd3-modules-cesu/modules/cesu/favicon.png 0000664 0000000 0000000 00000010364 14575653726 0027547 0 ustar 00root root 0000000 0000000 PNG
IHDR @ @ iq iCCPkCGColorSpaceGenericRGB 8U]hU>sg#$Sl4t?
%
V46nI6"dΘ83OEP|1Ŀ (>/
% (>P苦;3ie|{g蹪X-2s=+WQ+]L6Ow[C{_F qbUvz?Zb1@/zcs>~if,ӈUSjF1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK7KRDrYQO-Q||6
(0
MXd(@h2_f<:_δ*d>e\c?~,7?& ك^2Iq2"y