def post(self) -> Response: dossier = self._get_dossier() lecture = self._get_lecture(dossier) chambre = lecture.chambre.value num_texte = lecture.texte.numero titre = lecture.titre organe = lecture.organe # FIXME: use date_depot to find the right session? if lecture.chambre == Chambre.AN: session = "15" else: session = "2017-2018" if LectureModel.exists(chambre, session, num_texte, organe): self.request.session.flash( ("warning", "Cette lecture existe déjà...")) else: LectureModel.create(chambre, session, num_texte, titre, organe, dossier.titre) self.request.session.flash( ("success", "Lecture créée avec succès.")) resource = self.context[f"{chambre}.{session}.{num_texte}.{organe}"] return HTTPFound(location=self.request.resource_url(resource))
def test_derouleur_urls_plf2019_2e_partie(texte_senat, dossier_plf): from zam_repondeur.fetch.senat.derouleur import derouleur_urls from zam_repondeur.models import Lecture texte_senat.numero = 146 lecture = Lecture.create( chambre="senat", session="2018-2019", texte=texte_senat, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf, ) urls = list(derouleur_urls(lecture)) assert len(urls) > 1 assert ( urls[0] == "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103427.json" ) assert ( urls[-1] == "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103394.json" )
def test_derouleur_urls_and_mission_refs_plf2019_2e_partie( dossier_plf_2019, texte_plf_2019): from zam_repondeur.models import Lecture, Phase from zam_repondeur.services.fetch.missions import MissionRef from zam_repondeur.services.fetch.senat.derouleur import ( derouleur_urls_and_mission_refs, ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2019, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf_2019, ) urls = list(derouleur_urls_and_mission_refs(lecture)) assert len(urls) == 52 assert urls[0] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103414.json", MissionRef( titre="Mission Action et transformation publiques", titre_court="Action transfo.", ), ) assert urls[1] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103415.json", MissionRef(titre="Mission Action extérieure de l'État", titre_court="Action ext."), ) assert urls[-1] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103394.json", MissionRef(titre="", titre_court=""), )
def test_derouleur_urls_and_mission_refs_plf2020_2e_partie( dossier_plf_2020, texte_plf_2020): from zam_repondeur.models import Lecture, Phase from zam_repondeur.services.fetch.missions import MissionRef from zam_repondeur.services.fetch.senat.derouleur import ( derouleur_urls_and_mission_refs, ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2020, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf_2020, ) urls = list(derouleur_urls_and_mission_refs(lecture)) assert len(urls) == 50 assert urls[0] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103930.json", MissionRef(titre="", titre_court=""), ) assert urls[1] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103931.json", MissionRef( titre="Budget annexe - Contrôle et exploitation aériens", titre_court="Contrôle et exploitation aériens", ), ) assert urls[-1] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103979.json", MissionRef(titre="Mission Travail et emploi", titre_court="Trav. emploi"), )
def fetch_amendements_for_dossier( dossier_ref: DossierRef, chambre: Optional[str], num: Optional[int], settings: Dict[str, Any], ) -> None: dossier, _ = get_one_or_create( Dossier, an_id=dossier_ref.uid, create_kwargs=dict(titre=dossier_ref.titre, slug=dossier_ref.slug), ) for lecture_ref in dossier_ref.lectures: texte_ref = lecture_ref.texte if chambre is not None and texte_ref.chambre.name.lower() != chambre: continue if num is not None and texte_ref.numero != num: continue texte, _ = get_one_or_create( Texte, type_=texte_ref.type_, chambre=texte_ref.chambre, legislature=texte_ref.legislature, session=texte_ref.session, numero=texte_ref.numero, date_depot=texte_ref.date_depot, ) lecture = Lecture.create( phase=lecture_ref.phase, dossier=dossier, texte=texte, partie=lecture_ref.partie, organe=lecture_ref.organe, titre=lecture_ref.titre, ) fetch_amendements_for_lecture(lecture, settings)
def test_fetch_all_commission(db): from zam_repondeur.models import Chambre, Dossier, Lecture, Phase, Texte, TypeTexte from zam_repondeur.services.fetch.senat.amendements import _fetch_all with transaction.manager: dossier = Dossier.create( senat_id="pjl17-583", titre="Liberté de choisir son avenir professionnel", slug="liberte-choisir-avenir-professionnel", ) texte = Texte.create( type_=TypeTexte.PROJET, chambre=Chambre.SENAT, session=2017, numero=583, date_depot=date(2018, 6, 20), ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte, titre="Première lecture – Commissions", organe=None, dossier=dossier, ) sample_data = read_sample_data("jeu_complet_commission_2017-2018_583.csv") responses.add( responses.GET, "https://www.senat.fr/amendements/commissions/2017-2018/583/jeu_complet_commission_2017-2018_583.csv", # noqa body=sample_data, status=200, ) items = _fetch_all(lecture) assert len(items) == 434 assert items[0] == { "Nature ": "Amt", "Numéro ": "COM-1", "Subdivision ": "Article 40", "Alinéa": "36", "Auteur ": "M. FORISSIER, rapporteur", "Au nom de ": "", "Date de dépôt ": "2018-06-21", "Dispositif ": "<body><p>Alinéa 36</p><p>Après le mot :</p><p>services</p><p>Insérer les mots :</p><p>ou à des partenariats</p><p></p></body> ", # noqa "Objet ": "<body><p>Cet amendement vise à inclure parmi les dépenses pouvant être déduites de la contribution financière annuelle, en plus des contrats de sous-traitance et de prestations, les <b>dépenses afférentes à des partenariats</b> avec les entreprises adaptées, les Esat et les travailleurs handicapés indépendants.</p><p>En effet, le nouveau mode de déduction des montants de ces contrats de la contribution annuelle risque de moins inciter les employeurs à leur conclusion. D'où l'intérêt d'élargir cette déduction aux autres actions qu'ils sont susceptibles de mener auprès des EA et des Esat notamment.</p></body> ", # noqa "Sort ": "Adopté", "Url amendement ": "//www.senat.fr/amendements/commissions/2017-2018/583/Amdt_COM-1.html", # noqa "Fiche Sénateur": "//www.senat.fr/senfic/forissier_michel14087w.html", }
def lecture_plf_2e_partie(dossier_plf_2019, texte_plf_2019): from zam_repondeur.models import Lecture, Phase with transaction.manager: return Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2019, partie=2, titre="Numéro lecture – Titre lecture sénat", organe="PO78718", dossier=dossier_plf_2019, )
def lecture_an(db, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plfss2018_an_premiere_lecture, titre="Numéro lecture – Titre lecture", organe="PO717460", dossier=dossier_plfss2018, ) return lecture
def test_aspire_senat_plf2019_1re_partie(app, texte_senat, dossier_plf): from zam_repondeur.fetch.senat.amendements import Senat from zam_repondeur.models import DBSession, Lecture with transaction.manager: texte_senat.numero = 146 lecture = Lecture.create( chambre="senat", session="2018-2019", texte=texte_senat, partie=1, titre="Numéro lecture – Titre lecture sénat", organe="PO78718", dossier=dossier_plf, ) sample_data = read_sample_data("jeu_complet_2018-2019_146.csv") responses.add( responses.GET, "https://www.senat.fr/amendements/2018-2019/146/jeu_complet_2018-2019_146.csv", body=sample_data, status=200, ) odsen_data = read_sample_data("ODSEN_GENERAL.csv") responses.add( responses.GET, "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv", body=odsen_data, status=200, ) json_data = json.loads(read_sample_data("liste_discussion_103393.json")) responses.add( responses.GET, "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103393.json", json=json_data, status=200, ) DBSession.add(lecture) source = Senat() amendements, created, errored = source.fetch(lecture) # All amendements from part 1 are fetched assert len(amendements) == 1005
def test_sous_amendements(self, app, source, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import DBSession, Lecture with transaction.manager: texte_plfss2018_an_premiere_lecture.numero = 911 lecture = Lecture.create( chambre="an", session="15", texte=texte_plfss2018_an_premiere_lecture, titre="Titre lecture", organe="PO717460", dossier=dossier_plfss2018, ) DBSession.add(lecture) with setup_mock_responses( lecture=lecture, liste=read_sample_data("an/911/liste.xml"), amendements=( ("1", read_sample_data("an/911/1.xml")), ("2", read_sample_data("an/911/2.xml")), ("3", read_sample_data("an/911/3.xml")), ), ): amendements, created, errored = source.fetch(lecture=lecture) assert len(amendements) == 3 assert amendements[0].num == 1 assert amendements[0].position == 1 assert amendements[0].id_discussion_commune == 3448 assert amendements[0].id_identique == 8496 assert amendements[1].num == 2 assert amendements[1].position == 2 assert amendements[1].id_discussion_commune is None assert amendements[1].id_identique is None assert amendements[2].num == 3 assert amendements[2].position == 3 assert amendements[2].id_discussion_commune is None assert amendements[1].id_identique is None for amendement in amendements[1:]: assert amendement.parent is amendements[0] assert amendement.parent_pk == amendements[0].pk assert created == 3 assert errored == []
def test_import_liasse_second_part( app, dossier_essoc2018, texte_essoc2018_an_nouvelle_lecture_commission_fond): from zam_repondeur.models import DBSession, Lecture, Phase from zam_repondeur.services.import_export.liasse_xml import ( LectureDoesNotMatch, import_liasse_xml, ) with transaction.manager: part1 = Lecture.create( phase=Phase.NOUVELLE_LECTURE, texte=texte_essoc2018_an_nouvelle_lecture_commission_fond, partie=1, titre="Nouvelle lecture – Titre lecture", organe="PO744107", dossier=dossier_essoc2018, ) part2 = Lecture.create( phase=Phase.NOUVELLE_LECTURE, texte=texte_essoc2018_an_nouvelle_lecture_commission_fond, partie=2, titre="Nouvelle lecture – Titre lecture", organe="PO744107", dossier=dossier_essoc2018, ) DBSession.add(part2) with pytest.raises(LectureDoesNotMatch): import_liasse_xml(open_liasse("liasse_second_part.xml"), part1) amendements, errors = import_liasse_xml( open_liasse("liasse_second_part.xml"), part2) assert (len(amendements), len(errors)) == (3, 0) for amendement in amendements: assert amendement.lecture == part2
def lecture_plfss2018_an_premiere_lecture_commission_avis( db, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plfss2018_an_premiere_lecture, titre="Première lecture – Commission saisie pour avis", organe="PO59048", dossier=dossier_plfss2018, ) return lecture
def dummy_lecture(app): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", num_texte=269, titre="Titre lecture", organe="PO717460", dossier_legislatif="Titre dossier legislatif", ) return lecture
def lecture_plfss2018_senat_nouvelle_lecture_seance_publique( db, dossier_plfss2018, texte_plfss2018_senat_nouvelle_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.NOUVELLE_LECTURE, texte=texte_plfss2018_senat_nouvelle_lecture, titre="Nouvelle lecture – Séance publique", organe="PO78718", dossier=dossier_plfss2018, ) return lecture
def lecture_plfss2018_an_lecture_definitive_commission_fond( db, dossier_plfss2018, texte_plfss2018_an_lecture_definitive): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.LECTURE_DÉFINITIVE, texte=texte_plfss2018_an_lecture_definitive, titre="Lecture définitive – Commission saisie au fond", organe="PO420120", dossier=dossier_plfss2018, ) return lecture
def lecture_an(db, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", texte=texte_plfss2018_an_premiere_lecture, titre="Numéro lecture – Titre lecture", organe="PO717460", dossier=dossier_plfss2018, ) return lecture
def lecture_plfss2018_senat_nouvelle_lecture_commission_fond( db, dossier_plfss2018, texte_plfss2018_senat_nouvelle_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.NOUVELLE_LECTURE, texte=texte_plfss2018_senat_nouvelle_lecture, titre="Nouvelle lecture – Commission saisie au fond", organe="PO211493", dossier=dossier_plfss2018, ) return lecture
def lecture_plfss2018_an_lecture_definitive_seance_publique( db, dossier_plfss2018, texte_plfss2018_an_lecture_definitive): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.LECTURE_DÉFINITIVE, texte=texte_plfss2018_an_lecture_definitive, titre="Lecture définitive – Séance publique", organe="PO717460", dossier=dossier_plfss2018, ) return lecture
def lecture_senat(db, dossier_plfss2018, texte_plfss2018_senat_premiere_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="senat", session="2017-2018", texte=texte_plfss2018_senat_premiere_lecture, titre="Numéro lecture – Titre lecture sénat", organe="PO78718", dossier=dossier_plfss2018, ) return lecture
def lecture_plf2018_senat_premiere_lecture_seance_publique_2( db, dossier_plf2018, texte_plf2018_senat_premiere_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, partie=2, texte=texte_plf2018_senat_premiere_lecture, titre="Première lecture – Séance publique", organe="PO78718", dossier=dossier_plf2018, ) return lecture
def lecture_plfss2018_an_lecture_definitive_seance_publique( db, dossier_plfss2018, texte_plfss2018_an_lecture_definitive): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", texte=texte_plfss2018_an_lecture_definitive, titre="Lecture définitive – Séance publique", organe="PO717460", dossier=dossier_plfss2018, ) return lecture
def lecture_plf2018_an_nouvelle_lecture_commission_fond( db, dossier_plf2018, texte_plf2018_an_nouvelle_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", texte=texte_plf2018_an_nouvelle_lecture, titre="Nouvelle lecture – Commission saisie au fond", organe="PO59048", dossier=dossier_plf2018, ) return lecture
def lecture_plfss2018_senat_nouvelle_lecture_commission_fond( db, dossier_plfss2018, texte_plfss2018_senat_nouvelle_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="senat", session="2017-2018", texte=texte_plfss2018_senat_nouvelle_lecture, titre="Nouvelle lecture – Commission saisie au fond", organe="PO211493", dossier=dossier_plfss2018, ) return lecture
def lecture_plfss2018_senat_nouvelle_lecture_seance_publique( db, dossier_plfss2018, texte_plfss2018_senat_nouvelle_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="senat", session="2017-2018", texte=texte_plfss2018_senat_nouvelle_lecture, titre="Nouvelle lecture – Séance publique", organe="PO78718", dossier=dossier_plfss2018, ) return lecture
def lecture_plfss2018_an_lecture_definitive_commission_fond( db, dossier_plfss2018, texte_plfss2018_an_lecture_definitive): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", texte=texte_plfss2018_an_lecture_definitive, titre="Lecture définitive – Commission saisie au fond", organe="PO420120", dossier=dossier_plfss2018, ) return lecture
def lecture_essoc2018_an_premiere_lecture_seance_publique( db, texte_essoc2018_an_premiere_lecture_seance_publique, dossier_essoc2018): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_essoc2018_an_premiere_lecture_seance_publique, titre="Première lecture – Séance publique", organe="PO717460", dossier=dossier_essoc2018, ) return lecture
def lecture_plf2018_senat_premiere_lecture_commission_fond_2( db, dossier_plf2018, texte_plf2018_senat_premiere_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, partie=2, texte=texte_plf2018_senat_premiere_lecture, titre="Première lecture – Commission saisie au fond", organe="PO211494", dossier=dossier_plf2018, ) return lecture
def dummy_lecture_essoc(app): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", num_texte=806, titre="Nouvelle lecture", organe="PO744107", dossier_legislatif= "Fonction publique : un Etat au service d'une société de confiance", # noqa ) return lecture
def lecture_essoc2018_an_premier_lecture_commission_fond( db, texte_essoc2018_an_premier_lecture_commission_fond, dossier_essoc2018): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_essoc2018_an_premier_lecture_commission_fond, titre="Première lecture – Commission saisie au fond", organe="PO744107", dossier=dossier_essoc2018, ) return lecture
def lecture_plfss2018_an_premiere_lecture_commission_avis( db, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import Lecture with transaction.manager: lecture = Lecture.create( chambre="an", session="15", texte=texte_plfss2018_an_premiere_lecture, titre="Première lecture – Commission saisie pour avis", organe="PO59048", dossier=dossier_plfss2018, ) return lecture