예제 #1
0
 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"),
     }
예제 #2
0
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,
    }
예제 #3
0
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
예제 #4
0
파일: amendements.py 프로젝트: betagouv/zam
 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)
예제 #5
0
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
예제 #6
0
파일: download.py 프로젝트: betagouv/zam
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,
        )
예제 #7
0
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
예제 #8
0
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
예제 #9
0
파일: download.py 프로젝트: betagouv/zam
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,
        )
예제 #10
0
    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)
예제 #11
0
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/"
예제 #12
0
파일: amendements.py 프로젝트: betagouv/zam
def stop_editing(context: AmendementResource, request: Request) -> dict:
    for amendement in Batch.expanded_batches([context.model()]):
        amendement.stop_editing()
    return {}
예제 #13
0
    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)