def get(self) -> dict: table = self.context.model( subqueryload("amendements_locations").options( load_only("amendement_pk"), joinedload("amendement").options( load_only( "article_pk", "auteur", "groupe", "id_identique", "lecture_pk", "mission_titre", "num", "parent_pk", "position", "rectif", "sort", ), joinedload("user_content").load_only( "avis", "objet", "reponse_hash"), joinedload("location").options( load_only("batch_pk"), subqueryload("batch").joinedload( "amendements_locations").options( load_only("amendement_pk"), joinedload("amendement").load_only( "num", "rectif"), ), ), joinedload("article").load_only("lecture_pk", "type", "num", "mult", "pos"), ), )) return { "lecture": self.lecture, "lecture_resource": self.context.lecture_resource, "dossier_resource": self.context.lecture_resource.dossier_resource, "current_tab": "table", "table": table, "all_amendements": table.amendements, "collapsed_amendements": Batch.collapsed_batches(table.amendements), "is_owner": table.user.email == self.request.user.email, "table_url": self.request.resource_url( self.context.parent[self.request.user.email]), "index_url": self.request.resource_url( self.context.lecture_resource["amendements"]), "check_url": self.request.resource_path(self.context, "check"), }
def lecture_index(context: AmendementCollection, request: Request) -> dict: """ The index lists all amendements for small lectures, only by article for big ones. """ lecture_resource = context.parent lecture = lecture_resource.model(subqueryload("articles").defer("content")) total_count_amendements = lecture.nb_amendements max_amendements_for_full_index = int( request.registry.settings.get( "zam.limits.max_amendements_for_full_index", 1000)) too_many_amendements = total_count_amendements > max_amendements_for_full_index default_param = "article.1.." if too_many_amendements else "all" article_param = request.params.get("article", default_param) if article_param == "all": amendements = (DBSession.query(Amendement).join(Article).filter( Amendement.lecture == lecture, ).options(*AMDTS_OPTIONS)) else: article_type, article_num, article_mult, article_pos = article_param.split( ".") amendements = (DBSession.query(Amendement).join(Article).filter( Article.pk == Amendement.article_pk, Amendement.lecture == lecture, Article.type == article_type, Article.num == article_num, Article.mult == article_mult, Article.pos == article_pos, ).options(*AMDTS_OPTIONS)) amendements = AmendementList(amendements, sort_key=get_sort_key(request)) article_count_amendements = len(amendements) return { "lecture": lecture, "dossier_resource": lecture_resource.dossier_resource, "lecture_resource": lecture_resource, "current_tab": "index", "total_count_amendements": total_count_amendements, "article_count_amendements": article_count_amendements, "amendements": amendements, "collapsed_amendements": Batch.collapsed_batches(amendements), "articles": lecture.articles, "article_param": article_param, "progress_url": request.resource_url(lecture_resource, "progress_status"), "progress_interval": request.registry.settings["zam.progress.lecture_refresh"], "too_many_amendements": too_many_amendements, }
def amendements_an_batch(amendements_an): from zam_repondeur.models import Batch, DBSession with transaction.manager: batch = Batch.create() amendements_an[0].location.batch = batch amendements_an[1].location.batch = batch DBSession.add_all(amendements_an) return amendements_an
def __init__(self, context: AmendementResource, request: Request) -> None: self.context = context self.request = request self.amendement = context.model() self.amendements = list(Batch.expanded_batches([self.amendement])) self.lecture = self.amendement.lecture self.my_table_resource = self.context.lecture_resource["tables"][ self.request.user.email] self.is_on_my_table = (self.amendement.location.user_table and self.amendement.location.user_table.user == self.request.user)
def test_amendement_batches(amendements_an): from zam_repondeur.models import Amendement, Batch, DBSession a, b = DBSession.query(Amendement).all() assert a.location.batch is None assert b.location.batch is None batch = Batch.create() a.location.batch = batch b.location.batch = batch a, b = DBSession.query(Amendement).all() assert a.location.batch == b.location.batch == batch
def export_pdf(context: LectureResource, request: Request) -> Response: lecture = context.model( noload("amendements"), DOSSIER_OPTIONS, subqueryload("articles").options(joinedload("user_content")), ) nums, article_param = parse_params(request, lecture=lecture) if article_param == "all": article_amendements = ( DBSession.query(Amendement) .join(Article) .filter(Amendement.lecture == lecture,) .options(USER_CONTENT_OPTIONS, LOCATION_OPTIONS) ) else: article_type, article_num, article_mult, article_pos = article_param.split(".") article_amendements = ( DBSession.query(Amendement) .filter( Article.pk == Amendement.article_pk, Amendement.lecture == lecture, Article.type == article_type, Article.num == article_num, Article.mult == article_mult, Article.pos == article_pos, ) .options(USER_CONTENT_OPTIONS, LOCATION_OPTIONS,) ) amendements = [ amendement for amendement in article_amendements if amendement.num in nums ] expanded_amendements = list(Batch.expanded_batches(amendements)) with NamedTemporaryFile() as file_: tmp_file_path = os.path.abspath(file_.name) write_pdf_multiple( lecture=lecture, amendements=amendements, article_amendements=AmendementList(article_amendements), filename=tmp_file_path, request=request, ) return write_response( tmp_file_path=tmp_file_path, fmt="pdf", lecture=lecture, article_param=article_param, amendements=expanded_amendements, )
def test_column_filtering_by_value_with_batches( wsgi_server, driver, lecture_an, lecture_an_url, article7bis_an, amendements_an, user_david_table_an, user_david, column_index, selector, input_text, kind, initial, filtered, ): from zam_repondeur.models import Amendement, Batch, DBSession with transaction.manager: DBSession.add(user_david_table_an) DBSession.add_all(amendements_an) batch = Batch.create() amendements_an[0].location.batch = batch amendements_an[1].location.batch = batch user_david_table_an.add_amendement(amendements_an[0]) user_david_table_an.add_amendement(amendements_an[1]) amendement = Amendement.create(lecture=lecture_an, article=article7bis_an, num=777) user_david_table_an.add_amendement(amendement) driver.get(f"{lecture_an_url}/tables/{user_david.email}") trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_item_text(selector, trs) == initial driver.find_element_by_link_text("Filtrer").click() input_field = driver.find_element_by_css_selector( f"thead tr.filters th:nth-child({column_index}) input") input_field.send_keys(input_text) trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_item_text(selector, trs) == filtered assert (driver.current_url == f"{lecture_an_url}/tables/{user_david.email}?{kind}={input_text}") # Restore initial state. input_field.send_keys(Keys.BACKSPACE * len(input_text)) trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_item_text(selector, trs) == initial
def another_amendements_an_batch(lecture_an, article1_an): from zam_repondeur.models import Amendement, Batch, DBSession with transaction.manager: batch = Batch.create() amendements = [ Amendement.create( lecture=lecture_an, article=article1_an, num=num, position=position, batch=batch, ) for position, num in enumerate((555, 888), 3) ] DBSession.add_all(amendements) return amendements
def export_xlsx(context: LectureResource, request: Request) -> Response: lecture = context.model(noload("amendements")) nums, article_param = parse_params(request, lecture=lecture) if article_param == "all": amendements = ( DBSession.query(Amendement) .join(Article) .filter( Amendement.lecture == lecture, Amendement.num.in_(nums), # type: ignore ) .options(USER_CONTENT_OPTIONS, LOCATION_OPTIONS) ) else: article_type, article_num, article_mult, article_pos = article_param.split(".") amendements = ( DBSession.query(Amendement) .filter( Article.pk == Amendement.article_pk, Amendement.lecture == lecture, Article.type == article_type, Article.num == article_num, Article.mult == article_mult, Article.pos == article_pos, Amendement.num.in_(nums), # type: ignore ) .options(USER_CONTENT_OPTIONS, LOCATION_OPTIONS) ) expanded_amendements = list(Batch.expanded_batches(amendements)) with NamedTemporaryFile() as file_: tmp_file_path = os.path.abspath(file_.name) write_xlsx(lecture, tmp_file_path, request, amendements=expanded_amendements) return write_response( tmp_file_path=tmp_file_path, fmt="xlsx", lecture=lecture, article_param=article_param, amendements=expanded_amendements, )
def post(self) -> Response: # Special case: unbatch (TODO: move to a separate route) if len(self.get_nums(self.request.POST)) == 1: amendement = self.get_amendements_from(self.request.POST)[0] BatchUnset.create(amendement=amendement, request=self.request) return HTTPFound(location=self.my_table_url) amendements = list( Batch.expanded_batches(self.get_amendements_from( self.request.POST))) self.check_amendements_are_all_on_my_table(amendements) self.check_amendements_have_all_same_reponse_or_empty(amendements) self.check_amendements_are_all_from_same_article(amendements) batch = Batch.create() shared_reponse: Optional[ReponseTuple] = None to_be_updated: List[Amendement] = [] for amendement in amendements: if amendement.location.batch: BatchUnset.create(amendement=amendement, request=self.request) BatchSet.create( amendement=amendement, batch=batch, amendements_nums=[ amendement.num for amendement in amendements ], request=self.request, ) reponse = amendement.user_content.as_tuple() if not reponse.is_empty: shared_reponse = reponse else: to_be_updated.append(amendement) if shared_reponse is not None and to_be_updated: for amendement in to_be_updated: if (amendement.user_content.avis or "") != shared_reponse.avis: AvisAmendementModifie.create( amendement=amendement, avis=shared_reponse.avis, request=self.request, ) if (amendement.user_content.objet or "") != shared_reponse.objet: ObjetAmendementModifie.create( amendement=amendement, objet=shared_reponse.objet, request=self.request, ) if (amendement.user_content.reponse or "") != shared_reponse.content: ReponseAmendementModifiee.create( amendement=amendement, reponse=shared_reponse.content, request=self.request, ) if (amendement.user_content.comments or "") != shared_reponse.comments: CommentsAmendementModifie.create( amendement=amendement, comments=shared_reponse.comments, request=self.request, ) return HTTPFound(location=self.my_table_url)
def test_column_filtering_by_value_with_batches( wsgi_server, driver, lecture_an, lecture_an_url, article1_an, amendements_an, user_david_table_an, user_ronan_table_an, user_daniel_table_an, column_index, input_text, kind, initial, filtered, ): from zam_repondeur.models import Amendement, Batch, DBSession with transaction.manager: DBSession.add(user_ronan_table_an) DBSession.add(user_david_table_an) DBSession.add(user_daniel_table_an) batch = Batch.create() amendements_an[0].location.batch = batch amendements_an[1].location.batch = batch user_ronan_table_an.add_amendement(amendements_an[0]) user_david_table_an.add_amendement(amendements_an[1]) amendement = Amendement.create(lecture=lecture_an, article=article1_an, num=777, position=3) user_daniel_table_an.add_amendement(amendement) driver.get(f"{lecture_an_url}/amendements/") trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_column_text(column_index, trs) == initial input_field = driver.find_element_by_css_selector( f"thead tr.filters th:nth-child({column_index}) input") input_field.send_keys(input_text) trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_column_text(column_index, trs) == filtered assert driver.current_url == f"{lecture_an_url}/amendements/?{kind}={input_text}" # Restore initial state. input_field.send_keys(Keys.BACKSPACE * len(input_text)) trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_column_text(column_index, trs) == initial assert driver.current_url == f"{lecture_an_url}/amendements/" # Check filters are active on URL (re)load. driver.get(f"{lecture_an_url}/amendements/?{kind}={input_text}") trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_column_text(column_index, trs) == filtered input_field = driver.find_element_by_css_selector( f"thead tr.filters th:nth-child({column_index}) input") input_field.send_keys(Keys.BACKSPACE * len(input_text)) trs = driver.find_elements_by_css_selector(f"tbody tr:not(.hidden-{kind})") assert extract_column_text(column_index, trs) == initial assert driver.current_url == f"{lecture_an_url}/amendements/"
def stop_editing(context: AmendementResource, request: Request) -> dict: for amendement in Batch.expanded_batches([context.model()]): amendement.stop_editing() return {}
def post(self) -> Response: """ Transfer amendement(s) from this table to another one, or back to the index """ nums: List[str] = self.get_nums() if "submit-index" in self.request.POST: target = "" elif "submit-table" in self.request.POST: target = self.request.user.email else: target = self.request.POST.get("target") if not target: self.request.session.flash( Message(cls="warning", text="Veuillez sélectionner un·e destinataire.")) return HTTPFound(location=self.request.resource_url( self.context.lecture_resource, "transfer_amendements", query={"n": nums}, )) target_user_table = self.get_target_user_table(target) target_shared_table = self.get_target_shared_table(target) amendements = DBSession.query(Amendement).filter( Amendement.lecture == self.lecture, Amendement.num.in_(nums) # type: ignore ) for amendement in Batch.expanded_batches(amendements): old = amendement.table_name_with_email if target_shared_table: if target and amendement.location.shared_table is target_shared_table: continue new = target_shared_table.titre amendement.location.shared_table = target_shared_table amendement.location.user_table = None else: if target and amendement.location.user_table is target_user_table: continue new = str(target_user_table.user) if target_user_table else "" amendement.location.user_table = target_user_table amendement.location.shared_table = None amendement.stop_editing() AmendementTransfere.create( amendement=amendement, old_value=old, new_value=new, request=self.request, ) if target != self.request.user.email and self.request.POST.get( "from_index"): amendements_collection = self.context.lecture_resource[ "amendements"] next_location = self.request.resource_url(amendements_collection) else: table = self.context.model() table_resource = self.context.parent[table.user.email] next_location = self.request.resource_url(table_resource) return HTTPFound(location=next_location)