diff --git a/Dockerfile.base b/Dockerfile.base index 497cfeb8d6..001b855274 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -20,7 +20,7 @@ FROM python:3.9-slim-bullseye # require debian packages RUN apt-get update -y && apt-get upgrade -y RUN apt-get install --no-install-recommends -y git vim-tiny curl gcc gnupg libc6-dev procps imagemagick && rm -rf /var/lib/apt/lists/* -RUN pip install --upgrade setuptools wheel pip poetry +RUN pip install --upgrade setuptools wheel pip poetry && poetry self add poetry-plugin-shell # # uwsgi uwsgitop uwsgi-tools diff --git a/INSTALL.rst b/INSTALL.rst index d9c900f1b4..106657af01 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -58,7 +58,10 @@ among other things. $ pyenv install 3.9.7 $ cd rero-ils $ pyenv local 3.9.7 - $ sudo pip install poetry + $ curl -sSL https://install.python-poetry.org | python3 - + $ optional: poetry self add poetry-plugin-shell + +See: https://python-poetry.org/docs#installation for more detail. Next, ``cd`` into the project directory and bootstrap the instance (this will install all Python dependencies and build all static assets): diff --git a/data/acq_invoices.json b/data/acq_invoices.json deleted file mode 100644 index da07a8bb4d..0000000000 --- a/data/acq_invoices.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "pid": "1", - "invoice_number": "INV_0001", - "invoice_price": 500, - "invoice_status": "approved", - "invoice_date": "2022-12-31", - "invoice_items": [ - { - "acq_order_line": { - "$ref": "https://bib.rero.ch/api/acq_order_lines/1" - }, - "acq_account": { - "$ref": "https://bib.rero.ch/api/acq_accounts/2" - }, - "document": { - "$ref": "https://bib.rero.ch/api/documents/15" - }, - "order_number": "AOSTE-CANT1-POL-1", - "quantity": 3, - "price": 75 - } - ], - "library": { - "$ref": "https://bib.rero.ch/api/libraries/1" - }, - "organisation": { - "$ref": "https://bib.rero.ch/api/organisations/1" - }, - "vendor": { - "$ref": "https://bib.rero.ch/api/vendors/7" - } - } -] \ No newline at end of file diff --git a/data/acq_order_lines.json b/data/acq_order_lines.json index d27ee003e6..cb6c8dcf4b 100644 --- a/data/acq_order_lines.json +++ b/data/acq_order_lines.json @@ -4,7 +4,6 @@ "priority": 0, "quantity": 3, "amount": 25, - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -23,15 +22,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/1" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "2", "priority": 0, "quantity": 15, "amount": 5, - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -50,15 +47,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/1" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "3", "priority": 0, "quantity": 2, "amount": 100, - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -77,15 +72,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/1" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "4", "priority": 0, "quantity": 5, "amount": 10, - "exchange_rate": 1, "acq_account": { "$ref": "https://bib.rero.ch/api/acq_accounts/7" }, @@ -98,15 +91,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/2" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "5", "priority": 5, "quantity": 1, "amount": 100, - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -125,15 +116,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/2" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "6", "priority": 1, "quantity": 5, "amount": 7, - "exchange_rate": 1, "acq_account": { "$ref": "https://bib.rero.ch/api/acq_accounts/14" }, @@ -146,15 +135,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/3" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "7", "priority": 1, "quantity": 15, "amount": 12, - "exchange_rate": 1, "acq_account": { "$ref": "https://bib.rero.ch/api/acq_accounts/20" }, @@ -167,15 +154,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/4" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "8", "priority": 1, "quantity": 10, "amount": 20, - "exchange_rate": 1, "acq_account": { "$ref": "https://bib.rero.ch/api/acq_accounts/4" }, @@ -188,15 +173,13 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/1" }, - "is_cancelled": false, - "send_now": true + "is_cancelled": false }, { "pid": "9", "priority": 0, "quantity": 3, "amount": 22, - "exchange_rate": 1, "acq_account": { "$ref": "https://bib.rero.ch/api/acq_accounts/2" }, @@ -216,7 +199,6 @@ "priority": 0, "quantity": 3, "amount": 25, - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -235,7 +217,6 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/1" }, - "is_cancelled": false, - "order_date": "2021-07-20" + "is_cancelled": false } ] diff --git a/data/acq_orders.json b/data/acq_orders.json index a5ed434031..31ab0fc203 100644 --- a/data/acq_orders.json +++ b/data/acq_orders.json @@ -2,7 +2,6 @@ { "pid": "1", "reference": "AOSTE-CANT1-POL-1", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -18,12 +17,12 @@ }, "organisation": { "$ref": "https://bib.rero.ch/api/organisations/1" - } + }, + "send_now": true }, { "pid": "2", "reference": "AOSTE-CANT1-POL-2", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -39,12 +38,12 @@ }, "organisation": { "$ref": "https://bib.rero.ch/api/organisations/1" - } + }, + "send_now": true }, { "pid": "3", "reference": "AOSTE-CANT2-POL-1", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -65,7 +64,6 @@ { "pid": "4", "reference": "AOSTE-AVISE-POL-1", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -86,7 +84,6 @@ { "pid": "5", "reference": "AOSTE-LYCEE-POL-1", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -107,7 +104,6 @@ { "pid": "6", "reference": "AOSTE-CANT1-POL-6", - "type": "monograph", "currency": "EUR", "library": { "$ref": "https://bib.rero.ch/api/libraries/1" @@ -122,7 +118,6 @@ { "pid": "7", "reference": "AOSTE-CANT1-POL-2021-1", - "type": "monograph", "currency": "EUR", "notes": [ { @@ -138,6 +133,7 @@ }, "organisation": { "$ref": "https://bib.rero.ch/api/organisations/1" - } + }, + "send_now": true } ] diff --git a/data/acq_receipts.json b/data/acq_receipts.json index acb05df625..b984947fda 100644 --- a/data/acq_receipts.json +++ b/data/acq_receipts.json @@ -5,7 +5,6 @@ "$ref": "https://bib.rero.ch/api/acq_orders/1" }, "reference": "AOSTE-CANT1-POL-1", - "exchange_rate": 1, "notes": [ { "type": "staff_note", @@ -25,7 +24,6 @@ "$ref": "https://bib.rero.ch/api/acq_orders/7" }, "reference": "AOSTE-CANT1-POL-2021-1", - "exchange_rate": 1, "notes": [ { "type": "staff_note", diff --git a/data/role_policies.json b/data/role_policies.json index 89f5c9fe16..e6a3104fcc 100644 --- a/data/role_policies.json +++ b/data/role_policies.json @@ -36,38 +36,6 @@ "pro_acquisition_manager", "pro_library_administrator" ], - "acin-access": [ - "pro_full_permissions", - "pro_acquisition_manager", - "pro_library_administrator" - ], - "acin-search": [ - "pro_full_permissions", - "pro_read_only", - "pro_acquisition_manager", - "pro_library_administrator" - ], - "acin-read": [ - "pro_full_permissions", - "pro_read_only", - "pro_acquisition_manager", - "pro_library_administrator" - ], - "acin-create": [ - "pro_full_permissions", - "pro_acquisition_manager", - "pro_library_administrator" - ], - "acin-update": [ - "pro_full_permissions", - "pro_acquisition_manager", - "pro_library_administrator" - ], - "acin-delete": [ - "pro_full_permissions", - "pro_acquisition_manager", - "pro_library_administrator" - ], "acol-access": [ "pro_full_permissions", "pro_acquisition_manager", diff --git a/pyproject.toml b/pyproject.toml index f90518cce1..7bc302d1eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -252,7 +252,6 @@ rero_ils = "rero_ils:alembic" [project.entry-points."invenio_db.models"] acq_accounts = "rero_ils.modules.acquisition.acq_accounts.models" -acq_invoices = "rero_ils.modules.acquisition.acq_invoices.models" acq_order_lines = "rero_ils.modules.acquisition.acq_order_lines.models" acq_orders = "rero_ils.modules.acquisition.acq_orders.models" acq_receipt_lines = "rero_ils.modules.acquisition.acq_receipt_lines.models" @@ -289,7 +288,6 @@ messages_wiki = "flask_wiki" [project.entry-points."invenio_jsonschemas.schemas"] acq_accounts = "rero_ils.modules.acquisition.acq_accounts.jsonschemas" -acq_invoices = "rero_ils.modules.acquisition.acq_invoices.jsonschemas" acq_order_lines = "rero_ils.modules.acquisition.acq_order_lines.jsonschemas" acq_orders = "rero_ils.modules.acquisition.acq_orders.jsonschemas" acq_receipt_lines = "rero_ils.modules.acquisition.acq_receipt_lines.jsonschemas" @@ -334,7 +332,6 @@ patron_types = "rero_ils.oauth.scopes:patron_types" [project.entry-points."invenio_pidstore.fetchers"] acq_account_id = "rero_ils.modules.acquisition.acq_accounts.api:acq_account_id_fetcher" -acq_invoice_id = "rero_ils.modules.acquisition.acq_invoices.api:acq_invoice_id_fetcher" acq_order_id = "rero_ils.modules.acquisition.acq_orders.api:acq_order_id_fetcher" acq_order_line_id = "rero_ils.modules.acquisition.acq_order_lines.api:acq_order_line_id_fetcher" acq_receipt_id = "rero_ils.modules.acquisition.acq_receipts.api:acq_receipt_id_fetcher" @@ -367,7 +364,6 @@ vendor_id = "rero_ils.modules.vendors.api:vendor_id_fetcher" [project.entry-points."invenio_pidstore.minters"] acq_account_id = "rero_ils.modules.acquisition.acq_accounts.api:acq_account_id_minter" -acq_invoice_id = "rero_ils.modules.acquisition.acq_invoices.api:acq_invoice_id_minter" acq_order_id = "rero_ils.modules.acquisition.acq_orders.api:acq_order_id_minter" acq_order_line_id = "rero_ils.modules.acquisition.acq_order_lines.api:acq_order_line_id_minter" acq_receipt_id = "rero_ils.modules.acquisition.acq_receipts.api:acq_receipt_id_minter" @@ -399,7 +395,6 @@ vendor_id = "rero_ils.modules.vendors.api:vendor_id_minter" [project.entry-points."invenio_records.jsonresolver"] acq_accounts = "rero_ils.modules.acquisition.acq_accounts.jsonresolver" -acq_invoices = "rero_ils.modules.acquisition.acq_invoices.jsonresolver" acq_order_lines = "rero_ils.modules.acquisition.acq_order_lines.jsonresolver" acq_orders = "rero_ils.modules.acquisition.acq_orders.jsonresolver" acq_receipt_lines = "rero_ils.modules.acquisition.acq_receipt_lines.jsonresolver" @@ -428,7 +423,6 @@ vendors = "rero_ils.modules.vendors.jsonresolver" [project.entry-points."invenio_search.mappings"] acq_accounts = "rero_ils.modules.acquisition.acq_accounts.mappings" -acq_invoices = "rero_ils.modules.acquisition.acq_invoices.mappings" acq_order_lines = "rero_ils.modules.acquisition.acq_order_lines.mappings" acq_orders = "rero_ils.modules.acquisition.acq_orders.mappings" acq_receipt_lines = "rero_ils.modules.acquisition.acq_receipt_lines.mappings" diff --git a/rero_ils/config.py b/rero_ils/config.py index 02dacabede..8435cfb81c 100644 --- a/rero_ils/config.py +++ b/rero_ils/config.py @@ -55,10 +55,6 @@ from rero_ils.modules.acquisition.acq_accounts.permissions import ( AcqAccountPermissionPolicy, ) -from rero_ils.modules.acquisition.acq_invoices.api import AcquisitionInvoice -from rero_ils.modules.acquisition.acq_invoices.permissions import ( - AcqInvoicePermissionPolicy, -) from rero_ils.modules.acquisition.acq_order_lines.api import AcqOrderLine from rero_ils.modules.acquisition.acq_order_lines.permissions import ( AcqOrderLinePermissionPolicy, @@ -1905,51 +1901,6 @@ def _(x): "delete", record=record ), ), - acin=dict( - pid_type="acin", - pid_minter="acq_invoice_id", - pid_fetcher="acq_invoice_id", - search_class="rero_ils.modules.acquisition.acq_invoices.api:AcquisitionInvoicesSearch", - search_index="acq_invoices", - indexer_class="rero_ils.modules.acquisition.acq_invoices.api:AcquisitionInvoicesIndexer", - record_serializers={ - "application/json": "rero_ils.modules.serializers:json_v1_response", - "application/rero+json": "rero_ils.modules.acquisition.acq_invoices.serializers:json_acq_invoice_record", - }, - record_serializers_aliases={ - "json": "application/json", - }, - search_serializers={ - "application/json": "rero_ils.modules.serializers:json_v1_search", - "application/rero+json": "rero_ils.modules.acquisition.acq_invoices.serializers:json_acq_invoice_search", - }, - record_loaders={ - "application/json": lambda: AcquisitionInvoice(request.get_json()), - }, - record_class="rero_ils.modules.acquisition.acq_invoices.api:AcquisitionInvoice", - list_route="/acq_invoices/", - item_route=( - "/acq_invoices/" - ), - default_media_type="application/json", - max_result_window=MAX_RESULT_WINDOW, - search_factory_imp="rero_ils.query:organisation_search_factory", - list_permission_factory_imp=lambda record: AcqInvoicePermissionPolicy( - "search", record=record - ), - read_permission_factory_imp=lambda record: AcqInvoicePermissionPolicy( - "read", record=record - ), - create_permission_factory_imp=lambda record: AcqInvoicePermissionPolicy( - "create", record=record - ), - update_permission_factory_imp=lambda record: AcqInvoicePermissionPolicy( - "update", record=record - ), - delete_permission_factory_imp=lambda record: AcqInvoicePermissionPolicy( - "delete", record=record - ), - ), tmpl=dict( pid_type="tmpl", pid_minter="template_id", @@ -2483,30 +2434,6 @@ def _(x): _("budget"): and_term_filter("budget"), }, ), - acq_invoices=dict( - aggs=dict( - library=dict( - terms=dict( - field="library.pid", - size=RERO_ILS_AGGREGATION_SIZE.get( - "acq_invoices", RERO_ILS_DEFAULT_AGGREGATION_SIZE - ), - ) - ), - status=dict( - terms=dict( - field="invoice_status", - size=RERO_ILS_AGGREGATION_SIZE.get( - "acq_invoices", RERO_ILS_DEFAULT_AGGREGATION_SIZE - ), - ) - ), - ), - filters={ - _("library"): and_term_filter("library.pid"), - _("status"): and_term_filter("invoice_status"), - }, - ), acq_orders=dict( aggs=dict( library=dict( @@ -3169,12 +3096,6 @@ def _(x): "rero_ils.modules.acquisition.acq_accounts.permissions:create_action", "rero_ils.modules.acquisition.acq_accounts.permissions:update_action", "rero_ils.modules.acquisition.acq_accounts.permissions:delete_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:access_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:search_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:read_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:create_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:update_action", - "rero_ils.modules.acquisition.acq_invoices.permissions:delete_action", "rero_ils.modules.acquisition.acq_order_lines.permissions:access_action", "rero_ils.modules.acquisition.acq_order_lines.permissions:search_action", "rero_ils.modules.acquisition.acq_order_lines.permissions:read_action", @@ -3414,7 +3335,6 @@ def _(x): "acor": "/acq_orders/acq_order-v0.0.1.json", "acre": "/acq_receipts/acq_receipt-v0.0.1.json", "acrl": "/acq_receipt_lines/acq_receipt_line-v0.0.1.json", - "acin": "/acq_invoices/acq_invoice-v0.0.1.json", "budg": "/budgets/budget-v0.0.1.json", "cipo": "/circ_policies/circ_policy-v0.0.1.json", "coll": "/collections/collection-v0.0.1.json", diff --git a/rero_ils/es_templates/v7/record.json b/rero_ils/es_templates/v7/record.json index 265fc45dc8..9527cb33a4 100644 --- a/rero_ils/es_templates/v7/record.json +++ b/rero_ils/es_templates/v7/record.json @@ -1,7 +1,6 @@ { "index_patterns": [ "acq_accounts-*", - "acq_invoices-*", "acq_order_lines-*", "acq_orders-*", "acq_receipt_lines-*", diff --git a/rero_ils/jsonschemas/common/cantons-v0.0.1.json b/rero_ils/jsonschemas/common/cantons-v0.0.1.json index 285f87872d..20e71d632a 100644 --- a/rero_ils/jsonschemas/common/cantons-v0.0.1.json +++ b/rero_ils/jsonschemas/common/cantons-v0.0.1.json @@ -37,7 +37,6 @@ }, "props": { "sort": true, - "placeholder": "Select an option…", "sortOrder": "asc", "filter": true, "options": [ diff --git a/rero_ils/jsonschemas/common/countries-v0.0.1.json b/rero_ils/jsonschemas/common/countries-v0.0.1.json index 0167a0c4e2..76e7328d5e 100644 --- a/rero_ils/jsonschemas/common/countries-v0.0.1.json +++ b/rero_ils/jsonschemas/common/countries-v0.0.1.json @@ -382,7 +382,6 @@ "formlyConfig": { "props": { "sort": true, - "placeholder": "Select an option…", "sortOrder": "asc", "filter": true, "options": [ diff --git a/rero_ils/jsonschemas/common/identifier-v0.0.1.json b/rero_ils/jsonschemas/common/identifier-v0.0.1.json index 1324076d8b..232ad87547 100644 --- a/rero_ils/jsonschemas/common/identifier-v0.0.1.json +++ b/rero_ils/jsonschemas/common/identifier-v0.0.1.json @@ -26,8 +26,8 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row", - "itemCssClass": "col-lg-12", + "containerCssClass": "grid grid-nogutter-y", + "itemCssClass": "col-12", "hide": true } } @@ -46,7 +46,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "value": "bf:Local", @@ -76,7 +76,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -93,7 +93,7 @@ "hide": "field?.parent?.model?.type !== 'bf:Local'" }, "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } diff --git a/rero_ils/jsonschemas/common/languages-v0.0.1.json b/rero_ils/jsonschemas/common/languages-v0.0.1.json index ee35b81d5e..aa930dc65d 100644 --- a/rero_ils/jsonschemas/common/languages-v0.0.1.json +++ b/rero_ils/jsonschemas/common/languages-v0.0.1.json @@ -494,7 +494,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "lang_aar", @@ -2550,7 +2550,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "hide": true } } @@ -2574,7 +2574,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -2586,7 +2586,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -2610,7 +2610,7 @@ "formlyConfig": { "focus": true, "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -2622,7 +2622,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/jsonschemas/common/ui-languages-v0.0.1.json b/rero_ils/jsonschemas/common/ui-languages-v0.0.1.json index 8f76183c47..175ec177ac 100644 --- a/rero_ils/jsonschemas/common/ui-languages-v0.0.1.json +++ b/rero_ils/jsonschemas/common/ui-languages-v0.0.1.json @@ -13,7 +13,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-2", + "itemCssClass": "col-12 md:col-2", "options": [ { "label": "lang_fre", diff --git a/rero_ils/modules/acquisition/acq_accounts/api.py b/rero_ils/modules/acquisition/acq_accounts/api.py index b71eaf0cbe..9f5c1074e9 100644 --- a/rero_ils/modules/acquisition/acq_accounts/api.py +++ b/rero_ils/modules/acquisition/acq_accounts/api.py @@ -23,7 +23,6 @@ from elasticsearch_dsl import Q from flask_babel import gettext as _ -from rero_ils.modules.acquisition.acq_invoices.api import AcquisitionInvoicesSearch from rero_ils.modules.acquisition.acq_order_lines.api import AcqOrderLinesSearch from rero_ils.modules.acquisition.acq_order_lines.models import AcqOrderLineStatus from rero_ils.modules.acquisition.acq_receipt_lines.api import AcqReceiptLinesSearch @@ -410,9 +409,6 @@ def get_links_to_me(self, get_pids=False): "term", acq_account__pid=self.pid ) children_query = AcqAccountsSearch().filter("term", parent__pid=self.pid) - invoices_query = AcquisitionInvoicesSearch().filter( - "term", invoice_items__acq_account__pid=self.pid - ) receipts_query = AcqReceiptsSearch().filter( "nested", path="amount_adjustments", @@ -424,20 +420,16 @@ def get_links_to_me(self, get_pids=False): if get_pids: order_lines = sorted_pids(order_lines_query) children = sorted_pids(children_query) - invoices = sorted_pids(invoices_query) receipts = sorted_pids(receipts_query) else: order_lines = order_lines_query.count() children = children_query.count() - invoices = invoices_query.count() receipts = receipts_query.count() if order_lines: links["acq_order_lines"] = order_lines if children: links["acq_accounts"] = children - if invoices: - links["acq_invoices"] = invoices if receipts: links["acq_receipts"] = receipts return links diff --git a/rero_ils/modules/acquisition/acq_accounts/jsonschemas/acq_accounts/acq_account-v0.0.1.json b/rero_ils/modules/acquisition/acq_accounts/jsonschemas/acq_accounts/acq_account-v0.0.1.json index 6cd37c5a12..dc3b8e0911 100644 --- a/rero_ils/modules/acquisition/acq_accounts/jsonschemas/acq_accounts/acq_account-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_accounts/jsonschemas/acq_accounts/acq_account-v0.0.1.json @@ -108,10 +108,7 @@ "widget": { "formlyConfig": { "hideLabel": true, - "type": "account-select", - "props": { - "placeholder": "Choose a parent account" - } + "type": "account-select" } } } diff --git a/rero_ils/modules/acquisition/acq_accounts/serializers/json.py b/rero_ils/modules/acquisition/acq_accounts/serializers/json.py index ad63d2c1b8..c48afcd1eb 100644 --- a/rero_ils/modules/acquisition/acq_accounts/serializers/json.py +++ b/rero_ils/modules/acquisition/acq_accounts/serializers/json.py @@ -26,6 +26,15 @@ class AcqAccountJSONSerializer(ACQJSONSerializer): """Serializer for RERO-ILS `AcqAccount` records as JSON.""" + def _postprocess_search_hit(self, hit: dict) -> None: + """Post-process each hit of a search result.""" + hit["metadata"]["number_of_children"] = ( + AcqAccountsSearch() + .filter("term", parent__pid=hit["metadata"]["pid"]) + .count() + ) + super()._postprocess_search_hit(hit) + def preprocess_record(self, pid, record, links_factory=None, **kwargs): """Prepare a record and persistent identifier for serialization.""" # Add some ES stored keys into response diff --git a/rero_ils/modules/acquisition/acq_invoices/__init__.py b/rero_ils/modules/acquisition/acq_invoices/__init__.py deleted file mode 100644 index 88770c148e..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Acquisition Invoice Records.""" diff --git a/rero_ils/modules/acquisition/acq_invoices/api.py b/rero_ils/modules/acquisition/acq_invoices/api.py deleted file mode 100644 index abd1878841..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/api.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# Copyright (C) 2019-2022 UCLouvain -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""API for manipulating acq_invoices.""" - -from functools import partial - -from rero_ils.modules.acquisition.api import AcquisitionIlsRecord -from rero_ils.modules.api import IlsRecordsIndexer, IlsRecordsSearch -from rero_ils.modules.fetchers import id_fetcher -from rero_ils.modules.libraries.api import Library -from rero_ils.modules.minters import id_minter -from rero_ils.modules.providers import Provider -from rero_ils.modules.utils import extracted_data_from_ref, get_base_url - -from .models import AcquisitionInvoiceIdentifier, AcquisitionInvoiceMetadata - -# provider -AcquisitionInvoiceProvider = type( - "AcqInvoiceProvider", - (Provider,), - dict(identifier=AcquisitionInvoiceIdentifier, pid_type="acin"), -) -# minter -acq_invoice_id_minter = partial(id_minter, provider=AcquisitionInvoiceProvider) -# fetcher -acq_invoice_id_fetcher = partial(id_fetcher, provider=AcquisitionInvoiceProvider) - - -class AcquisitionInvoicesSearch(IlsRecordsSearch): - """AcquisitionInvoicesSearch.""" - - class Meta: - """Search only on acq_invoice index.""" - - index = "acq_invoices" - doc_types = None - fields = ("*",) - facets = {} - - default_filter = None - - -class AcquisitionInvoice(AcquisitionIlsRecord): - """AcquisitionInvoice class.""" - - minter = acq_invoice_id_minter - fetcher = acq_invoice_id_fetcher - provider = AcquisitionInvoiceProvider - model_cls = AcquisitionInvoiceMetadata - pids_exist_check = { - "required": {"lib": "library", "vndr": "vendor"}, - "not_required": {"org": "organisation"}, - } - - @classmethod - def create( - cls, data, id_=None, delete_pid=False, dbcommit=False, reindex=False, **kwargs - ): - """Create acquisition invoice record.""" - cls._acquisition_invoice_build_org_ref(data) - cls._build_total_amount_of_invoice(data) - return super().create(data, id_, delete_pid, dbcommit, reindex, **kwargs) - - def update(self, data, commit=True, dbcommit=True, reindex=True): - """Update Acquisition Invoice record.""" - self._build_total_amount_of_invoice(data) - super().update(data, commit, dbcommit, reindex) - return self - - @classmethod - def _build_total_amount_of_invoice(cls, data): - """Build total amount for invoice.""" - invoice_price = 0 - for idx, item in enumerate(data.get("invoice_items")): - # build total price for each invoice line item - invoiceLine = InvoiceLine(item) - data["invoice_items"][idx]["total_price"] = invoiceLine.total_price - invoice_price += data["invoice_items"][idx]["total_price"] - - # check if discount percentage - if data.get("discount", {}).get("percentage"): - invoice_price -= cls._calculate_percentage_discount( - invoice_price, data.get("discount").get("percentage") - ) - # check if discount amount - if data.get("discount", {}).get("amount"): - invoice_price -= data.get("discount").get("amount") - # set invoice price - data["invoice_price"] = invoice_price - - @classmethod - def _calculate_percentage_discount(cls, amount, percentage): - """Calculate discount percentage of invoice.""" - return amount * percentage / 100 - - @classmethod - def _acquisition_invoice_build_org_ref(cls, data): - """Build $ref for the organisation of the acquisition invoice.""" - library_pid = ( - data.get("library", {}).get("pid") - or data.get("library").get("$ref").split("libraries/")[1] - ) - org_pid = ( - Library.get_record_by_pid(library_pid).organisation_pid - or cls.organisation_pid - ) - data["organisation"] = {"$ref": f"{get_base_url()}/api/organisations/{org_pid}"} - - @property - def library_pid(self): - """Shortcut for acquisition order library pid.""" - return extracted_data_from_ref(self.get("library")) - - @property - def vendor_pid(self): - """Shortcut for acquisition order vendor pid.""" - return extracted_data_from_ref(self.get("vendor")) - - @property - def is_active(self): - """Check if the invoice should be considered as active.""" - # TODO: implement this when introducing the invoicing module - return True - - -class AcquisitionInvoicesIndexer(IlsRecordsIndexer): - """Indexing invoices in Elasticsearch.""" - - record_cls = AcquisitionInvoice - - def bulk_index(self, record_id_iterator): - """Bulk index records. - - :param record_id_iterator: Iterator yielding record UUIDs. - """ - super().bulk_index(record_id_iterator, doc_type="acin") - - -class InvoiceLine(object): - """Acquisition Invoice line class.""" - - def __init__(self, data): - """Initialize instance with dictionary data.""" - self.data = data - - @property - def total_price(self): - """Build total price for invoice line.""" - total_price = self.data["price"] * self.data["quantity"] - total_price -= self.data.get("discount", 0) - return total_price diff --git a/rero_ils/modules/acquisition/acq_invoices/jsonresolver.py b/rero_ils/modules/acquisition/acq_invoices/jsonresolver.py deleted file mode 100644 index 9b529f56ca..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/jsonresolver.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Acquisition Invoice resolver.""" - -import jsonresolver -from flask import current_app -from invenio_pidstore.models import PersistentIdentifier, PIDStatus - - -@jsonresolver.route("/api/acq_invoices/", host="bib.rero.ch") -def acquisition_invoice_resolver(pid): - """Resolver for acq_invoice record.""" - persistent_id = PersistentIdentifier.get("acin", pid) - if persistent_id.status == PIDStatus.REGISTERED: - return dict(pid=persistent_id.pid_value) - current_app.logger.error( - "Acquisition invoice resolver error: /api/acq_invoices/" - f"{pid} {persistent_id}" - ) - raise Exception("unable to resolve") diff --git a/rero_ils/modules/acquisition/acq_invoices/jsonschemas/__init__.py b/rero_ils/modules/acquisition/acq_invoices/jsonschemas/__init__.py deleted file mode 100644 index 571456e317..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/jsonschemas/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""JSON schemas.""" - -from __future__ import absolute_import, print_function diff --git a/rero_ils/modules/acquisition/acq_invoices/jsonschemas/acq_invoices/acq_invoice-v0.0.1.json b/rero_ils/modules/acquisition/acq_invoices/jsonschemas/acq_invoices/acq_invoice-v0.0.1.json deleted file mode 100644 index d381790aab..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/jsonschemas/acq_invoices/acq_invoice-v0.0.1.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "title": "Acquisition invoice", - "description": "JSON schema for Acquisition Invoice resource.", - "additionalProperties": false, - "required": [ - "$schema", - "pid", - "invoice_date", - "invoice_status", - "invoice_items", - "vendor", - "library" - ], - "definitions": { - "invoice_item": { - "type": "object", - "required": [ - "acq_order_line", - "acq_account", - "document", - "order_number", - "quantity", - "price" - ], - "additionalProperties": false, - "properties": { - "acq_order_line": { - "title": "Acquisition order line", - "type": "object", - "properties": { - "$ref": { - "title": "Acquisition order line URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/acq_order_lines/.*?$" - } - } - }, - "acq_account": { - "title": "Acquisition account", - "type": "object", - "properties": { - "$ref": { - "title": "Acquisition account URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/acq_accounts/.*?$" - } - } - }, - "document": { - "title": "Document", - "type": "object", - "properties": { - "$ref": { - "title": "Document URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/documents/.*?$" - } - } - }, - "order_number": { - "title": "Order number", - "type": "string", - "minLength": 3 - }, - "quantity": { - "title": "Number of units", - "type": "integer", - "minimum": 1 - }, - "price": { - "title": "Price per unit", - "type": "number", - "minimum": 0 - }, - "discount": { - "title": "Discount amount", - "type": "number", - "minimum": 0 - }, - "total_price": { - "title": "Total price", - "type": "number", - "minimum": 0 - } - } - } - }, - "properties": { - "$schema": { - "title": "Schema", - "description": "Schema to validate Acquisition Invoice records against.", - "type": "string", - "minLength": 9, - "default": "https://bib.rero.ch/schemas/acq_invoices/acq_invoice-v0.0.1.json", - "pattern": "^https://bib.rero.ch/schemas/acq_invoices/acq_invoice-v([0-9]+?\\.){3}json$" - }, - "pid": { - "title": "Acquisition invoice ID", - "type": "string", - "minLength": 1 - }, - "invoice_number": { - "title": "Invoice number", - "type": "string", - "minLength": 1, - "widget": { - "formlyConfig": { - "props": { - "validation": { - "validators": { - "valueAlreadyExists": { - "term": "invoice_number" - } - }, - "messages": { - "alreadyTakenMessage": "The invoice number is already taken." - } - } - } - } - } - }, - "invoice_price": { - "title": "Invoice price", - "type": "number" - }, - "invoice_status": { - "title": "Invoice status", - "type": "string", - "enum": [ - "in_progress", - "approved", - "deleted" - ], - "default": "in progress", - "widget": { - "formlyConfig": { - "type": "select", - "props": { - "sort": true, - "options": [ - { - "value": "in_progress", - "label": "in_progress" - }, - { - "value": "approved", - "label": "approved" - }, - { - "value": "deleted", - "label": "deleted" - } - ] - } - } - } - }, - "invoice_date": { - "title": "Date", - "type": "string", - "format": "date", - "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", - "widget": { - "formlyConfig": { - "type": "datePicker", - "props": { - "validation": { - "messages": { - "patternMessage": "Should be in the following format: 2022-12-31 (YYYY-MM-DD)." - } - }, - "placeholder": "Select a date" - } - } - } - }, - "notes": { - "title": "Notes", - "type": "array", - "minItems": 1, - "items": { - "type": "string", - "minLength": 1 - } - }, - "taxes": { - "title": "Taxes", - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "title": "Type of taxe", - "type": "string", - "enum": [ - "shipping_and_handling", - "state_taxes", - "miscellaneous" - ], - "widget": { - "formlyConfig": { - "type": "select", - "props": { - "sort": true, - "options": [ - { - "value": "shipping_and_handling", - "label": "shipping_and_handling" - }, - { - "value": "state_taxes", - "label": "state_taxes" - }, - { - "value": "miscellaneous", - "label": "miscellaneous" - } - ] - } - } - } - }, - "amount": { - "title": "Amount", - "type": "number", - "minimum": 0 - } - } - } - }, - "discount": { - "type": "object", - "title": "Discount", - "oneOf": [ - { - "title": "Percentage", - "additionalProperties": false, - "properties": { - "percentage": { - "title": "Discount percentage.", - "type": "number", - "minimum": 0, - "maximum": 100 - } - } - }, - { - "title": "Amount", - "additionalProperties": false, - "properties": { - "amount": { - "title": "Discount amount", - "type": "number", - "minimum": 0 - } - } - } - ] - }, - "invoice_items": { - "items": { - "$ref": "#/definitions/invoice_item" - }, - "minItems": 1, - "title": "List of invoice lines", - "type": "array", - "uniqueItems": true - }, - "vendor": { - "title": "Vendor", - "type": "object", - "required": [ - "$ref" - ], - "properties": { - "$ref": { - "title": "Vendor URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/vendors/.*?$", - "widget": { - "formlyConfig": { - "focus": true, - "props": { - "hideLabel": true, - "placeholder": "Choose a vendor", - "remoteOptions": { - "type": "vendors" - } - } - } - } - } - } - }, - "library": { - "title": "Library", - "type": "object", - "properties": { - "$ref": { - "title": "Library URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/libraries/.*?$" - } - } - }, - "organisation": { - "title": "Organisation", - "type": "object", - "additionalProperties": false, - "required": [ - "$ref" - ], - "properties": { - "$ref": { - "title": "Organisation URI", - "type": "string", - "pattern": "^https://bib.rero.ch/api/organisations/.*?$" - } - } - } - } -} diff --git a/rero_ils/modules/acquisition/acq_invoices/mappings/__init__.py b/rero_ils/modules/acquisition/acq_invoices/mappings/__init__.py deleted file mode 100644 index 942bc64b23..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/mappings/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Elasticsearch mappings.""" - -from __future__ import absolute_import, print_function diff --git a/rero_ils/modules/acquisition/acq_invoices/mappings/v7/__init__.py b/rero_ils/modules/acquisition/acq_invoices/mappings/v7/__init__.py deleted file mode 100644 index 942bc64b23..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/mappings/v7/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Elasticsearch mappings.""" - -from __future__ import absolute_import, print_function diff --git a/rero_ils/modules/acquisition/acq_invoices/mappings/v7/acq_invoices/acq_invoice-v0.0.1.json b/rero_ils/modules/acquisition/acq_invoices/mappings/v7/acq_invoices/acq_invoice-v0.0.1.json deleted file mode 100644 index 080a3cd2e0..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/mappings/v7/acq_invoices/acq_invoice-v0.0.1.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "mappings": { - "date_detection": false, - "numeric_detection": false, - "properties": { - "$schema": { - "type": "keyword" - }, - "pid": { - "type": "keyword" - }, - "vendor": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "library": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "organisation": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "invoice_number": { - "type": "keyword" - }, - "invoice_status": { - "type": "keyword" - }, - "invoice_date": { - "type": "date" - }, - "invoice_price": { - "type": "float" - }, - "discount": { - "properties": { - "percentage": { - "type": "float" - }, - "amount": { - "type": "float" - } - } - }, - "taxes": { - "properties": { - "type": { - "type": "keyword" - }, - "amount": { - "type": "float" - } - } - }, - "notes": { - "type": "text" - }, - "invoice_items": { - "type": "object", - "properties": { - "acq_order_line": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "acq_account": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "document": { - "properties": { - "pid": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "order_number": { - "type": "keyword" - }, - "quantity": { - "type": "integer" - }, - "price": { - "type": "float" - }, - "discount": { - "type": "float" - }, - "total_price": { - "type": "float" - } - } - }, - "_created": { - "type": "date" - }, - "_updated": { - "type": "date" - } - } - } -} diff --git a/rero_ils/modules/acquisition/acq_invoices/models.py b/rero_ils/modules/acquisition/acq_invoices/models.py deleted file mode 100644 index a138d84a9e..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/models.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Define relation between records and buckets.""" - -from __future__ import absolute_import - -from invenio_db import db -from invenio_pidstore.models import RecordIdentifier -from invenio_records.models import RecordMetadataBase - - -class AcquisitionInvoiceIdentifier(RecordIdentifier): - """Sequence generator for Acquisition Invoice identifiers.""" - - __tablename__ = "acq_invoice_id" - __mapper_args__ = {"concrete": True} - - recid = db.Column( - db.BigInteger().with_variant(db.Integer, "sqlite"), - primary_key=True, - autoincrement=True, - ) - - -class AcquisitionInvoiceMetadata(db.Model, RecordMetadataBase): - """AcquisitionInvoice record metadata.""" - - __tablename__ = "acq_invoice_metadata" diff --git a/rero_ils/modules/acquisition/acq_invoices/permissions.py b/rero_ils/modules/acquisition/acq_invoices/permissions.py deleted file mode 100644 index b6c9e54eae..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/permissions.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# Copyright (C) 2019-2022 UCLouvain -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Permissions for Acquisition invoice.""" - -from invenio_access import action_factory - -from rero_ils.modules.permissions import ( - AllowedByAction, - AllowedByActionRestrictByManageableLibrary, - DisallowedIfRollovered, - RecordPermissionPolicy, -) - -from .api import AcquisitionInvoice - -# Actions to control acquisition invoices resource policies -search_action = action_factory("acin-search") -read_action = action_factory("acin-read") -create_action = action_factory("acin-create") -update_action = action_factory("acin-update") -delete_action = action_factory("acin-delete") -access_action = action_factory("acin-access") - - -class AcqInvoicePermissionPolicy(RecordPermissionPolicy): - """Acquisition invoice Permission Policy used by the CRUD operations.""" - - can_search = [AllowedByAction(search_action)] - can_read = [AllowedByActionRestrictByManageableLibrary(read_action)] - can_create = [ - AllowedByActionRestrictByManageableLibrary(create_action), - DisallowedIfRollovered(AcquisitionInvoice), - ] - can_update = [ - AllowedByActionRestrictByManageableLibrary(update_action), - DisallowedIfRollovered(AcquisitionInvoice), - ] - can_delete = [ - AllowedByActionRestrictByManageableLibrary(delete_action), - DisallowedIfRollovered(AcquisitionInvoice), - ] diff --git a/rero_ils/modules/acquisition/acq_invoices/serializers.py b/rero_ils/modules/acquisition/acq_invoices/serializers.py deleted file mode 100644 index 161d65f36a..0000000000 --- a/rero_ils/modules/acquisition/acq_invoices/serializers.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2022 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Acquisition invoice serialization.""" - -from invenio_records_rest.serializers.response import record_responsify - -from rero_ils.modules.libraries.api import LibrariesSearch -from rero_ils.modules.serializers import ( - ACQJSONSerializer, - JSONSerializer, - RecordSchemaJSONV1, - search_responsify, -) - - -class AcquisitionInvoiceJSONSerializer(ACQJSONSerializer): - """Serializer for RERO-ILS `AcqInvoice` records as JSON.""" - - def _postprocess_search_aggregations(self, aggregations: dict) -> None: - """Post-process aggregations from a search result.""" - JSONSerializer.enrich_bucket_with_data( - aggregations.get("library", {}).get("buckets", []), LibrariesSearch, "name" - ) - super()._postprocess_search_aggregations(aggregations) - - -_json = AcquisitionInvoiceJSONSerializer(RecordSchemaJSONV1) -json_acq_invoice_search = search_responsify(_json, "application/rero+json") -json_acq_invoice_record = record_responsify(_json, "application/rero+json") diff --git a/rero_ils/modules/acquisition/acq_order_lines/api.py b/rero_ils/modules/acquisition/acq_order_lines/api.py index 5f43a809c7..8761b4dbd7 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/api.py +++ b/rero_ils/modules/acquisition/acq_order_lines/api.py @@ -19,11 +19,9 @@ """API for manipulating Acquisition Order Line.""" from copy import deepcopy -from datetime import datetime from functools import partial from flask_babel import gettext as _ -from werkzeug.utils import cached_property from rero_ils.modules.acquisition.api import AcquisitionIlsRecord from rero_ils.modules.api import IlsRecordsIndexer, IlsRecordsSearch @@ -89,7 +87,23 @@ def extended_validation(self, **kwargs): note_types = [note.get("type") for note in self.get("notes", [])] if len(note_types) != len(set(note_types)): return _("Can not have multiple notes of the same type.") + from rero_ils.modules.acquisition.acq_orders.api import AcqOrder + from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus + order_status = AcqOrder.get_status_by_pid(self.order_pid) + valid_statuses = [ + AcqOrderStatus.CANCELLED, + AcqOrderStatus.PENDING, + ] + if self.updated: + valid_statuses += [ + AcqOrderStatus.ORDERED, + AcqOrderStatus.PARTIALLY_RECEIVED, + ] + if order_status not in valid_statuses: + return _( + f"Can not create an order line with an order with a wrong status {order_status}." + ) return True @classmethod @@ -149,11 +163,6 @@ def order(self): """Shortcut to the order of the order line.""" return extracted_data_from_ref(self.get("acq_order"), data="record") - @property - def order_date(self): - """Shortcut for acquisition order send date.""" - return self.get("order_date") - @property def is_cancelled(self): """Shortcut for acquisition order is_cancelled falg.""" @@ -223,19 +232,6 @@ def unreceived_quantity(self): """Get quantity of unreceived ordered_items for a line order.""" return self.quantity - self.received_quantity - @cached_property - def receipt_date(self): - """Get the first reception date for one item of this order line.""" - from rero_ils.modules.acquisition.acq_receipt_lines.api import ( - AcqReceiptLinesSearch, - ) - - search = AcqReceiptLinesSearch().filter("term", acq_order_line__pid=self.pid) - search.aggs.metric("min_receipt_date", "min", field="receipt_date") - results = search.execute() - epoch = results.aggregations.min_receipt_date.value / 1000 - return datetime.fromtimestamp(epoch) - @property def status(self): """Calculate the order line status. @@ -252,7 +248,7 @@ def status(self): return AcqOrderLineStatus.CANCELLED status = ( AcqOrderLineStatus.ORDERED - if self.order_date + if self.order.get("order_date") else AcqOrderLineStatus.APPROVED ) diff --git a/rero_ils/modules/acquisition/acq_order_lines/dumpers.py b/rero_ils/modules/acquisition/acq_order_lines/dumpers.py index d9fc056c51..32b7b2b867 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/dumpers.py +++ b/rero_ils/modules/acquisition/acq_order_lines/dumpers.py @@ -42,7 +42,7 @@ def dump(self, record, data): :param data: The initial dump data passed in by ``record.dumps()``. """ # Keep only some attributes from AcqOrderLine object initial dump. - for attr in ["pid", "status", "order_date", "quantity"]: + for attr in ["pid", "status", "quantity"]: if value := record.get(attr): data.update({attr: value}) diff --git a/rero_ils/modules/acquisition/acq_order_lines/jsonschemas/acq_order_lines/acq_order_line-v0.0.1.json b/rero_ils/modules/acquisition/acq_order_lines/jsonschemas/acq_order_lines/acq_order_line-v0.0.1.json index bc00fb95f4..016cfaece1 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/jsonschemas/acq_order_lines/acq_order_line-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_order_lines/jsonschemas/acq_order_lines/acq_order_line-v0.0.1.json @@ -8,11 +8,8 @@ "acq_account", "document", "priority", - "order_date", - "receipt_date", "quantity", "amount", - "exchange_rate", "notes", "is_cancelled" ], @@ -44,14 +41,10 @@ "type": "integer", "minimum": 0, "maximum": 5, - "default": 0, "widget": { "formlyConfig": { "props": { - "hide": true, - "navigation": { - "essential": true - } + "itemCssClass": "col-12 md:col-3 md:col-offset-right-9" } } } @@ -60,7 +53,14 @@ "title": "Quantity", "type": "integer", "default": 1, - "minimum": 1 + "minimum": 1, + "widget": { + "formlyConfig": { + "props": { + "itemCssClass": "col-12 md:col-6" + } + } + } }, "amount": { "title": "Amount", @@ -70,8 +70,8 @@ "widget": { "formlyConfig": { "props": { - "hideLabel": true, - "fieldMap": "amount" + "fieldMap": "amount", + "itemCssClass": "col-12 md:col-6" } } } @@ -82,26 +82,10 @@ "default": 0, "minimum": 0 }, - "exchange_rate": { - "title": "Exchange rate", - "type": "number", - "minimum": 0, - "widget": { - "formlyConfig": { - "props": { - "hideLabel": true, - "hide": true, - "navigation": { - "essential": true - } - } - } - } - }, "notes": { "title": "Notes", "type": "array", - "minItems": 1, + "minItems": 0, "maxItems": 2, "items": { "type": "object", @@ -161,10 +145,8 @@ }, "widget": { "formlyConfig": { - "wrappers": [ - "card" - ], "props": { + "itemCssClass": "col-12", "validation": { "validators": { "uniqueValueKeysInObject": { @@ -176,61 +158,11 @@ "messages": { "uniqueValueKeysInObjectMessage": "Only one note per type is allowed" } - }, - "hide": true, - "navigation": { - "essential": true } } } } }, - "order_date": { - "title": "Order date", - "type": "string", - "format": "date", - "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", - "widget": { - "formlyConfig": { - "type": "datePicker", - "expressions": { - "props.required": "field?.parent?.model?.status === 'ordered' || field?.parent?.model?.status === 'received'", - "hide": "field?.parent?.model?.status !== 'ordered' && field?.parent?.model?.status !== 'received'" - }, - "props": { - "validation": { - "messages": { - "patternMessage": "Should be in the following format: 2022-12-31 (YYYY-MM-DD)." - } - }, - "placeholder": "Select a date" - } - } - } - }, - "receipt_date": { - "title": "Receipt date", - "type": "string", - "format": "date", - "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", - "widget": { - "formlyConfig": { - "type": "datePicker", - "expressions": { - "props.required": "field?.parent?.model?.status === 'received'", - "hide": "field?.parent?.model?.status !== 'received'" - }, - "props": { - "validation": { - "messages": { - "patternMessage": "Should be in the following format: 2022-12-31 (YYYY-MM-DD)." - } - }, - "placeholder": "Select a date" - } - } - } - }, "acq_account": { "title": "Acquisition account", "type": "object", @@ -246,13 +178,17 @@ "formlyConfig": { "hideLabel": true, "type": "account-select", - "focus": true, - "props": { - "placeholder": "Select an account" - } + "focus": true } } } + }, + "widget": { + "formlyConfig": { + "props": { + "itemCssClass": "col-12" + } + } } }, "acq_order": { @@ -264,6 +200,13 @@ "type": "string", "pattern": "^https://bib.rero.ch/api/acq_orders/.*?$" } + }, + "widget": { + "formlyConfig": { + "props": { + "itemCssClass": "col-12" + } + } } }, "document": { @@ -280,6 +223,7 @@ "widget": { "formlyConfig": { "type": "remoteAutoComplete", + "hideLabel": true, "props": { "validation": { "messages": { @@ -294,6 +238,13 @@ } } } + }, + "widget": { + "formlyConfig": { + "props": { + "itemCssClass": "col-12" + } + } } }, "organisation": { @@ -330,7 +281,21 @@ "title": "Cancelled", "description": "If checked this order line should be considered as cancelled.", "type": "boolean", - "default": false + "default": false, + "widget": { + "formlyConfig": { + "props": { + "itemCssClass": "col-12" + } + } + } + } + }, + "widget": { + "formlyConfig": { + "props": { + "containerCssClass": "grid grid-nogutter-y" + } } } } diff --git a/rero_ils/modules/acquisition/acq_order_lines/mappings/v7/acq_order_lines/acq_order_line-v0.0.1.json b/rero_ils/modules/acquisition/acq_order_lines/mappings/v7/acq_order_lines/acq_order_line-v0.0.1.json index d9b5167049..78a7eed3bd 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/mappings/v7/acq_order_lines/acq_order_line-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_order_lines/mappings/v7/acq_order_lines/acq_order_line-v0.0.1.json @@ -90,9 +90,6 @@ "total_unreceived_amount": { "type": "float" }, - "exchange_rate": { - "type": "float" - }, "notes": { "properties": { "type": { @@ -103,12 +100,6 @@ } } }, - "order_date": { - "type": "date" - }, - "receipt_date": { - "type": "date" - }, "is_cancelled": { "type": "boolean" }, diff --git a/rero_ils/modules/acquisition/acq_order_lines/models.py b/rero_ils/modules/acquisition/acq_order_lines/models.py index 8ff340004b..6871d42d8b 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/models.py +++ b/rero_ils/modules/acquisition/acq_order_lines/models.py @@ -51,7 +51,6 @@ class AcqOrderLineStatus: ORDERED = "ordered" RECEIVED = "received" PARTIALLY_RECEIVED = "partially_received" - RECEIVED_STATUSES = [RECEIVED, PARTIALLY_RECEIVED] diff --git a/rero_ils/modules/acquisition/acq_order_lines/permissions.py b/rero_ils/modules/acquisition/acq_order_lines/permissions.py index 83f95fe760..fd7b74c87a 100644 --- a/rero_ils/modules/acquisition/acq_order_lines/permissions.py +++ b/rero_ils/modules/acquisition/acq_order_lines/permissions.py @@ -19,9 +19,11 @@ """Permissions for Acquisition order line.""" from invenio_access import action_factory +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus from rero_ils.modules.permissions import ( AllowedByAction, AllowedByActionRestrictByManageableLibrary, + DisallowedByOrderStatus, DisallowedIfRollovered, RecordPermissionPolicy, ) @@ -49,8 +51,20 @@ class AcqOrderLinePermissionPolicy(RecordPermissionPolicy): can_update = [ AllowedByActionRestrictByManageableLibrary(update_action), DisallowedIfRollovered(AcqOrderLine), + DisallowedByOrderStatus( + AcqOrderLine, + [ + AcqOrderStatus.CANCELLED, + AcqOrderStatus.PENDING, + AcqOrderStatus.ORDERED, + AcqOrderStatus.PARTIALLY_RECEIVED, + ], + ), ] can_delete = [ AllowedByActionRestrictByManageableLibrary(delete_action), DisallowedIfRollovered(AcqOrderLine), + DisallowedByOrderStatus( + AcqOrderLine, [AcqOrderStatus.CANCELLED, AcqOrderStatus.PENDING] + ), ] diff --git a/rero_ils/modules/acquisition/acq_orders/api.py b/rero_ils/modules/acquisition/acq_orders/api.py index 1dd3192115..9ab7a54456 100644 --- a/rero_ils/modules/acquisition/acq_orders/api.py +++ b/rero_ils/modules/acquisition/acq_orders/api.py @@ -155,8 +155,13 @@ def status(self): is PARTIALLY_RECEIVED or RECEIVED. RECEIVED: if all related order lines has RECEIVED status. """ + return self.get_status_by_pid(self.pid) + + @classmethod + def get_status_by_pid(cls, pid): + """.""" status = AcqOrderStatus.PENDING - search = AcqOrderLinesSearch().filter("term", acq_order__pid=self.pid) + search = AcqOrderLinesSearch().filter("term", acq_order__pid=pid) search.aggs.bucket("status", "terms", field="status") results = search.execute() statuses = [hit.key for hit in results.aggregations.status.buckets] @@ -185,19 +190,6 @@ def status(self): return status - @property - def order_date(self): - """Get the order date of this order.""" - result = ( - AcqOrderLinesSearch() - .filter("term", acq_order__pid=self.pid) - .filter("exists", field="order_date") - .source(["order_date"]) - .scan() - ) - dates = [hit.order_date for hit in result] - return next(iter(dates or []), None) - @property def item_quantity(self): """Get the total of item quantity for this order.""" @@ -485,11 +477,13 @@ def send_order(self, emails=None): # notification metadata (status, process_date, ...) if dispatcher_result.get("sent", 0): order_date = datetime.now().strftime("%Y-%m-%d") + self["order_date"] = order_date + record = self.update(self, dbcommit=True, reindex=False) order_lines = self.get_order_lines(includes=[AcqOrderLineStatus.APPROVED]) for order_line in order_lines: - order_line["order_date"] = order_date - order_line.update(order_line, dbcommit=True, reindex=True) - self.reindex() + order_line.reindex() + record.reindex() + notif = Notification.get_record(notif.id) return notif diff --git a/rero_ils/modules/acquisition/acq_orders/dumpers.py b/rero_ils/modules/acquisition/acq_orders/dumpers.py index 57dd3f63d0..0be187e165 100644 --- a/rero_ils/modules/acquisition/acq_orders/dumpers.py +++ b/rero_ils/modules/acquisition/acq_orders/dumpers.py @@ -46,7 +46,7 @@ def dump(self, record, data): data.update( { "reference": record.get("reference"), - "order_date": record.order_date or today, + "order_date": record.get("order_date", today), "note": record.get_note(AcqOrderNoteType.VENDOR), } ) diff --git a/rero_ils/modules/acquisition/acq_orders/extensions.py b/rero_ils/modules/acquisition/acq_orders/extensions.py index c2a418a8b8..08a247fb41 100644 --- a/rero_ils/modules/acquisition/acq_orders/extensions.py +++ b/rero_ils/modules/acquisition/acq_orders/extensions.py @@ -31,8 +31,6 @@ def pre_dump(self, record, dumper=None): :param record: the record metadata. :param dumper: the record dumper. """ - if record.order_date: - record["order_date"] = record.order_date record["account_statement"] = record.get_account_statement() record["status"] = record.status @@ -44,7 +42,6 @@ def pre_load(self, data, loader=None): """ data.pop("account_statement", None) data.pop("status", None) - data.pop("order_date", None) def pre_delete(self, record, force=False): """Called before a record is deleted. diff --git a/rero_ils/modules/acquisition/acq_orders/jsonschemas/acq_orders/acq_order-v0.0.1.json b/rero_ils/modules/acquisition/acq_orders/jsonschemas/acq_orders/acq_order-v0.0.1.json index 96b21fd5d3..380884535e 100644 --- a/rero_ils/modules/acquisition/acq_orders/jsonschemas/acq_orders/acq_order-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_orders/jsonschemas/acq_orders/acq_order-v0.0.1.json @@ -7,15 +7,14 @@ "propertiesOrder": [ "vendor", "reference", - "type", + "order_date", "notes" ], "required": [ "$schema", "pid", "vendor", - "library", - "type" + "library" ], "properties": { "$schema": { @@ -35,56 +34,22 @@ "type": "string", "minLength": 3 }, - "type": { - "title": "Type", + "currency": { + "$ref": "https://bib.rero.ch/schemas/common/currency-v0.0.1.json#/currency" + }, + "order_date": { + "title": "Order date", "type": "string", - "enum": [ - "serial", - "monograph", - "standing_order", - "monographic_set", - "planned_order", - "multi_volume" - ], - "default": "monograph", + "format": "date", + "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", "widget": { "formlyConfig": { - "type": "select", - "props": { - "sort": true, - "options": [ - { - "value": "monograph", - "label": "monograph" - }, - { - "value": "serial", - "label": "serial" - }, - { - "value": "standing_order", - "label": "standing_order" - }, - { - "value": "monographic_set", - "label": "monographic_set" - }, - { - "value": "planned_order", - "label": "planned_order" - }, - { - "value": "multi_volume", - "label": "multi_volume" - } - ] + "expressions": { + "hide": "true" } } } }, - "currency": { - "$ref": "https://bib.rero.ch/schemas/common/currency-v0.0.1.json#/currency" - }, "notes": { "title": "Notes", "type": "array", @@ -185,7 +150,6 @@ "focus": true, "props": { "hideLabel": true, - "placeholder": "Choose a vendor", "remoteOptions": { "type": "vendors" } diff --git a/rero_ils/modules/acquisition/acq_orders/mappings/v7/acq_orders/acq_order-v0.0.1.json b/rero_ils/modules/acquisition/acq_orders/mappings/v7/acq_orders/acq_order-v0.0.1.json index 881556a802..647346c2ee 100644 --- a/rero_ils/modules/acquisition/acq_orders/mappings/v7/acq_orders/acq_order-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_orders/mappings/v7/acq_orders/acq_order-v0.0.1.json @@ -73,9 +73,6 @@ } } }, - "type": { - "type": "keyword" - }, "status": { "type": "keyword" }, @@ -123,9 +120,6 @@ "pid": { "type": "keyword" }, - "order_date": { - "type": "date" - }, "quantity": { "type": "integer" }, diff --git a/rero_ils/modules/acquisition/acq_orders/serializers/__init__.py b/rero_ils/modules/acquisition/acq_orders/serializers/__init__.py index 17a8870f07..b8899420dc 100644 --- a/rero_ils/modules/acquisition/acq_orders/serializers/__init__.py +++ b/rero_ils/modules/acquisition/acq_orders/serializers/__init__.py @@ -44,7 +44,6 @@ "order_date", "order_staff_note", "order_vendor_note", - "order_type", "order_status", "vendor_name", "document_pid", diff --git a/rero_ils/modules/acquisition/acq_orders/serializers/csv.py b/rero_ils/modules/acquisition/acq_orders/serializers/csv.py index 9ae121e43f..9d41b181cc 100644 --- a/rero_ils/modules/acquisition/acq_orders/serializers/csv.py +++ b/rero_ils/modules/acquisition/acq_orders/serializers/csv.py @@ -84,7 +84,6 @@ def serialize_search( "order_pid": "pid", "order_reference": "reference", "order_date": "order_date", - "order_type": "type", "order_status": "status", } diff --git a/rero_ils/modules/acquisition/acq_receipt_lines/api.py b/rero_ils/modules/acquisition/acq_receipt_lines/api.py index 0de0522986..4d8e9cdcaa 100644 --- a/rero_ils/modules/acquisition/acq_receipt_lines/api.py +++ b/rero_ils/modules/acquisition/acq_receipt_lines/api.py @@ -21,6 +21,7 @@ from copy import deepcopy from functools import partial +from flask_babel import gettext as _ from werkzeug.utils import cached_property from rero_ils.modules.acquisition.api import AcquisitionIlsRecord @@ -85,6 +86,24 @@ def create( cls._build_additional_refs(data) return super().create(data, id_, delete_pid, dbcommit, reindex, **kwargs) + def extended_validation(self, **kwargs): + """Add additional record validation. + + :return: False if + """ + from rero_ils.modules.acquisition.acq_orders.api import AcqOrder + from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus + + order_status = AcqOrder.get_status_by_pid(self.order_pid) + if order_status not in [ + AcqOrderStatus.ORDERED, + AcqOrderStatus.PARTIALLY_RECEIVED, + ]: + return _( + f"Can not create a receipt with an order with a wrong status {order_status}." + ) + return True + def update(self, data, commit=True, dbcommit=True, reindex=True): """Update Acquisition Receipt Line record.""" # TODO :: try to find a better way to load original record. @@ -129,6 +148,11 @@ def order_line(self): """Shortcut for related acquisition order line record.""" return extracted_data_from_ref(self.get("acq_order_line"), data="record") + @property + def order_pid(self): + """Shortcut for related acquisition order pid.""" + return self.receipt.order_pid + @property def is_active(self): """Check if the receipt line should be considered as active. @@ -157,7 +181,7 @@ def amount(self): def total_amount(self): """Shortcut for related acquisition total_amount.""" vat_factor = (100 + self.get("vat_rate", 0)) / 100 - total = self.amount * self.receipt.exchange_rate * self.quantity * vat_factor + total = self.amount * self.quantity * vat_factor return round(total, 2) @property diff --git a/rero_ils/modules/acquisition/acq_receipt_lines/jsonschemas/acq_receipt_lines/acq_receipt_line-v0.0.1.json b/rero_ils/modules/acquisition/acq_receipt_lines/jsonschemas/acq_receipt_lines/acq_receipt_line-v0.0.1.json index e9680f2691..62b08ca99c 100644 --- a/rero_ils/modules/acquisition/acq_receipt_lines/jsonschemas/acq_receipt_lines/acq_receipt_line-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_receipt_lines/jsonschemas/acq_receipt_lines/acq_receipt_line-v0.0.1.json @@ -128,8 +128,7 @@ }, "navigation": { "essential": true - }, - "placeholder": "Select a date" + } } } } diff --git a/rero_ils/modules/acquisition/acq_receipt_lines/permissions.py b/rero_ils/modules/acquisition/acq_receipt_lines/permissions.py index c0a4989041..e1f5598963 100644 --- a/rero_ils/modules/acquisition/acq_receipt_lines/permissions.py +++ b/rero_ils/modules/acquisition/acq_receipt_lines/permissions.py @@ -19,9 +19,11 @@ """Permissions for Acquisition receipt line.""" from invenio_access import action_factory +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus from rero_ils.modules.permissions import ( AllowedByAction, AllowedByActionRestrictByManageableLibrary, + DisallowedByOrderStatus, DisallowedIfRollovered, RecordPermissionPolicy, ) @@ -49,8 +51,12 @@ class AcqReceiptLinePermissionPolicy(RecordPermissionPolicy): can_update = [ AllowedByActionRestrictByManageableLibrary(update_action), DisallowedIfRollovered(AcqReceiptLine), + DisallowedByOrderStatus(AcqReceiptLine, [AcqOrderStatus.PARTIALLY_RECEIVED]), ] can_delete = [ AllowedByActionRestrictByManageableLibrary(delete_action), DisallowedIfRollovered(AcqReceiptLine), + DisallowedByOrderStatus( + AcqReceiptLine, [AcqOrderStatus.PARTIALLY_RECEIVED, AcqOrderStatus.RECEIVED] + ), ] diff --git a/rero_ils/modules/acquisition/acq_receipts/api.py b/rero_ils/modules/acquisition/acq_receipts/api.py index 08db28b7eb..78f2a2fae3 100644 --- a/rero_ils/modules/acquisition/acq_receipts/api.py +++ b/rero_ils/modules/acquisition/acq_receipts/api.py @@ -21,6 +21,8 @@ from copy import deepcopy from functools import partial +from flask_babel import gettext as _ + from rero_ils.modules.acquisition.acq_receipt_lines.api import ( AcqReceiptLine, AcqReceiptLinesSearch, @@ -140,6 +142,24 @@ def update(self, data, commit=True, dbcommit=True, reindex=True): account.reindex() return self + def extended_validation(self, **kwargs): + """Add additional record validation. + + :return: False if + """ + from rero_ils.modules.acquisition.acq_orders.api import AcqOrder + from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus + + order_status = AcqOrder.get_status_by_pid(self.order_pid) + if order_status not in [ + AcqOrderStatus.ORDERED, + AcqOrderStatus.PARTIALLY_RECEIVED, + ]: + return _( + f"Can not create a receipt with an order with a wrong status {order_status}." + ) + return True + @classmethod def _build_additional_refs(cls, data): """Build $ref for the organisation of the acquisition receipt.""" @@ -242,11 +262,6 @@ def amount_adjustments(self): """Shortcut to get receipt amount adjustments.""" return self.get("amount_adjustments", []) - @property - def exchange_rate(self): - """Shortcut to get receipt exchange_rate.""" - return self.get("exchange_rate") - @property def total_amount(self): """Get this acquisition receipt total amount. diff --git a/rero_ils/modules/acquisition/acq_receipts/jsonschemas/acq_receipts/acq_receipt-v0.0.1.json b/rero_ils/modules/acquisition/acq_receipts/jsonschemas/acq_receipts/acq_receipt-v0.0.1.json index 2731a3ab60..364659909f 100644 --- a/rero_ils/modules/acquisition/acq_receipts/jsonschemas/acq_receipts/acq_receipt-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_receipts/jsonschemas/acq_receipts/acq_receipt-v0.0.1.json @@ -6,15 +6,13 @@ "additionalProperties": false, "propertiesOrder": [ "reference", - "exchange_rate", "amount_adjustments", "notes" ], "required": [ "$schema", "pid", - "acq_order", - "exchange_rate" + "acq_order" ], "properties": { "$schema": { @@ -47,32 +45,7 @@ "reference": { "title": "Reference", "type": "string", - "minLength": 3, - "widget": { - "formlyConfig": { - "props": { - "navigation": { - "essential": true - } - } - } - } - }, - "exchange_rate": { - "title": "Exchange rate", - "type": "number", - "exclusiveMinimum": 0, - "default": 1, - "widget": { - "formlyConfig": { - "props": { - "hide": true, - "navigation": { - "essential": true - } - } - } - } + "minLength": 3 }, "amount_adjustments": { "title": "Additional fees, discount and credit", @@ -117,26 +90,13 @@ "formlyConfig": { "type": "account-select", "hideLabel": true, - "focus": true, - "props": { - "placeholder": "Select an account" - } + "focus": true } } } } } } - }, - "widget": { - "formlyConfig": { - "props": { - "hide": true, - "navigation": { - "essential": true - } - } - } } }, "notes": { @@ -197,9 +157,6 @@ }, "widget": { "formlyConfig": { - "wrappers": [ - "card" - ], "props": { "validation": { "validators": { @@ -212,10 +169,6 @@ "messages": { "uniqueValueKeysInObjectMessage": "Only one note per type is allowed" } - }, - "hide": true, - "navigation": { - "essential": true } } } diff --git a/rero_ils/modules/acquisition/acq_receipts/mappings/v7/acq_receipts/acq_receipt-v0.0.1.json b/rero_ils/modules/acquisition/acq_receipts/mappings/v7/acq_receipts/acq_receipt-v0.0.1.json index 256fdeddd3..4d93ebe01b 100644 --- a/rero_ils/modules/acquisition/acq_receipts/mappings/v7/acq_receipts/acq_receipt-v0.0.1.json +++ b/rero_ils/modules/acquisition/acq_receipts/mappings/v7/acq_receipts/acq_receipt-v0.0.1.json @@ -42,9 +42,6 @@ } } }, - "exchange_rate": { - "type": "float" - }, "quantity": { "type": "integer" }, diff --git a/rero_ils/modules/acquisition/acq_receipts/permissions.py b/rero_ils/modules/acquisition/acq_receipts/permissions.py index 0eebba1d1a..c267bc48e9 100644 --- a/rero_ils/modules/acquisition/acq_receipts/permissions.py +++ b/rero_ils/modules/acquisition/acq_receipts/permissions.py @@ -19,9 +19,11 @@ """Permissions for Acquisition receipt.""" from invenio_access import action_factory +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus from rero_ils.modules.permissions import ( AllowedByAction, AllowedByActionRestrictByManageableLibrary, + DisallowedByOrderStatus, DisallowedIfRollovered, RecordPermissionPolicy, ) @@ -49,8 +51,12 @@ class AcqReceiptPermissionPolicy(RecordPermissionPolicy): can_update = [ AllowedByActionRestrictByManageableLibrary(update_action), DisallowedIfRollovered(AcqReceipt), + DisallowedByOrderStatus(AcqReceipt, [AcqOrderStatus.PARTIALLY_RECEIVED]), ] can_delete = [ AllowedByActionRestrictByManageableLibrary(delete_action), DisallowedIfRollovered(AcqReceipt), + DisallowedByOrderStatus( + AcqReceipt, [AcqOrderStatus.PARTIALLY_RECEIVED, AcqOrderStatus.RECEIVED] + ), ] diff --git a/rero_ils/modules/circ_policies/jsonschemas/circ_policies/circ_policy-v0.0.1.json b/rero_ils/modules/circ_policies/jsonschemas/circ_policies/circ_policy-v0.0.1.json index ec2abaeffb..490a3bb513 100644 --- a/rero_ils/modules/circ_policies/jsonschemas/circ_policies/circ_policy-v0.0.1.json +++ b/rero_ils/modules/circ_policies/jsonschemas/circ_policies/circ_policy-v0.0.1.json @@ -281,7 +281,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-3" + "itemCssClass": "col-12 md:col-3" } } } @@ -293,7 +293,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-3" + "itemCssClass": "col-12 md:col-3" } } } @@ -306,7 +306,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4", + "itemCssClass": "col-12 md:col-4", "hideLabel": true, "fieldMap": "fee_amount" } @@ -317,7 +317,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/cli/fixtures.py b/rero_ils/modules/cli/fixtures.py index f2b8a96539..6f81060c3e 100644 --- a/rero_ils/modules/cli/fixtures.py +++ b/rero_ils/modules/cli/fixtures.py @@ -212,7 +212,7 @@ def create( record["name"] = year record["start_date"] = f"{year}-01-01" record["end_date"] = f"{year}-12-31" - elif pid_type == "acol" and record.pop("send_now", None): + elif pid_type == "acor" and record.pop("send_now", None): # ensure all orders are sent record["order_date"] = f"{order_date}" elif pid_type == "acrl" and record.pop("receive_now", None): diff --git a/rero_ils/modules/collections/templates/rero_ils/detailed_view_collections.html b/rero_ils/modules/collections/templates/rero_ils/detailed_view_collections.html index 22815afc91..3ac9f5c983 100644 --- a/rero_ils/modules/collections/templates/rero_ils/detailed_view_collections.html +++ b/rero_ils/modules/collections/templates/rero_ils/detailed_view_collections.html @@ -21,7 +21,7 @@ {% from 'rero_ils/macros/macro.html' import div, dict_values, div_list, dl, dl_row, dl_dict, dl_list, div_json %} {%- block body %} -
+

{{ record.title }}

{%- for subject in record.subjects %} diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_admin_metadata-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_admin_metadata-v0.0.1.json index dded8f6b27..1d91f0d7de 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_admin_metadata-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_admin_metadata-v0.0.1.json @@ -27,7 +27,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -53,7 +53,7 @@ "formlyConfig": { "type": "select", "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "sort": true, "options": [ { @@ -109,7 +109,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } @@ -127,7 +127,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } @@ -145,7 +145,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } @@ -165,11 +165,18 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } } + }, + "widget": { + "formlyConfig": { + "props": { + "containerCssClass": "grid grid-nogutter-y" + } + } } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_content_media_carrier-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_content_media_carrier-v0.0.1.json index 4f08698787..a5cc64c4e1 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_content_media_carrier-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_content_media_carrier-v0.0.1.json @@ -812,7 +812,7 @@ ], "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": true, "options": [ diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_entity_link-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_entity_link-v0.0.1.json index 3725a46a71..8f3453d8b1 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_entity_link-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_entity_link-v0.0.1.json @@ -50,7 +50,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_local-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_local-v0.0.1.json index 1604fc5fa4..ef637c8faf 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_local-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_local-v0.0.1.json @@ -48,7 +48,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: Musset, Alfred de, 1810-1857" } } @@ -61,7 +61,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_organisation-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_organisation-v0.0.1.json index bf3cd56d47..423e704c45 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_organisation-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_organisation-v0.0.1.json @@ -40,7 +40,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: Miller, John" } } @@ -65,7 +65,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -78,7 +78,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -90,7 +90,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: Lausanne" } } @@ -103,7 +103,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: 4" } } @@ -117,7 +117,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: 1989" } } @@ -143,7 +143,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_person-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_person-v0.0.1.json index 2822d419cd..1e467ecf8d 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_person-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_person-v0.0.1.json @@ -39,7 +39,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: Miller, John" } } @@ -53,7 +53,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: 1955" } } @@ -67,7 +67,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: 2012" } } @@ -80,7 +80,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: physicist" } } @@ -94,7 +94,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: XXIII" } } @@ -108,7 +108,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -120,7 +120,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_role-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_role-v0.0.1.json index 6d0251fbe7..6f83425265 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_contribution_role-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_contribution_role-v0.0.1.json @@ -162,11 +162,11 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "filter": true, "sort": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "value": "aut", diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_electronic_locator-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_electronic_locator-v0.0.1.json index 5d8b16bba9..1f8383ee0f 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_electronic_locator-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_electronic_locator-v0.0.1.json @@ -28,7 +28,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "validation": { "messages": { "patternMessage": "Should be a valid URL format." @@ -55,7 +55,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "resource", @@ -122,7 +122,7 @@ "props": { "sort": true, "filter": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "poster", @@ -261,7 +261,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -270,7 +270,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_entity_local-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_entity_local-v0.0.1.json index a9d1bc89e5..df55cd4e7c 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_entity_local-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_entity_local-v0.0.1.json @@ -33,7 +33,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "bf:Person", @@ -71,7 +71,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -87,7 +87,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -149,7 +149,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -159,7 +159,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "hide": true } } @@ -181,7 +181,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "bf:Topic", @@ -204,7 +204,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_genre_form_local-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_genre_form_local-v0.0.1.json index bde88034a0..f48adc2ce6 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_genre_form_local-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_genre_form_local-v0.0.1.json @@ -34,7 +34,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: Electronic serials" } } @@ -53,7 +53,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_identified_by-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_identified_by-v0.0.1.json index 9095997766..5ec280b49e 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_identified_by-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_identified_by-v0.0.1.json @@ -54,7 +54,7 @@ "props": { "sort": true, "filter": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "bf:AudioIssueNumber", @@ -159,7 +159,7 @@ "identifiedby-value" ], "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "doNotSubmitOnEnter": true } } @@ -172,7 +172,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "hide": true } } @@ -186,7 +186,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "hide": true, "placeholder": "Example: volume 1" } @@ -205,7 +205,7 @@ "hide": "field?.parent?.model?.type !== 'bf:Local'" }, "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Examples: LCCN, PMID, DNB" } } @@ -222,7 +222,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "hide": true } } @@ -232,7 +232,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_intended_audience-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_intended_audience-v0.0.1.json index 6b7e834aba..8811ddfefa 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_intended_audience-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_intended_audience-v0.0.1.json @@ -69,11 +69,11 @@ ], "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": true, "filter": true, - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "target_understanding_children", diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_issuance-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_issuance-v0.0.1.json index a0bd70fd6a..27af4b709f 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_issuance-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_issuance-v0.0.1.json @@ -29,7 +29,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "article", @@ -70,7 +70,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -100,7 +100,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "Set", @@ -137,7 +137,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -167,7 +167,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "serialInSerial", @@ -204,7 +204,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -233,7 +233,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "updatingWebsite", @@ -266,7 +266,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_language-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_language-v0.0.1.json index c3824242af..14970f553e 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_language-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_language-v0.0.1.json @@ -51,7 +51,7 @@ "formlyConfig": { "type": "textarea", "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "rows": 3, "hide": true } @@ -62,10 +62,10 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } } } -} \ No newline at end of file +} diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_note-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_note-v0.0.1.json index 51d0df1e7f..3499fbaea0 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_note-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_note-v0.0.1.json @@ -31,7 +31,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "options": [ { "label": "accompanyingMaterial", @@ -61,7 +61,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -70,7 +70,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_part_of-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_part_of-v0.0.1.json index d341782697..ebbeb6e665 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_part_of-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_part_of-v0.0.1.json @@ -73,7 +73,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "validation": { "messages": { "patternMessage": "Should be in the following format: AAAA (2020)." @@ -90,7 +90,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -102,7 +102,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -114,7 +114,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "validation": { "messages": { "patternMessage": "Should be in the following format: 135 or 5-27." @@ -129,7 +129,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_provision_activity-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_provision_activity-v0.0.1.json index f700fd44fe..df6edc07aa 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_provision_activity-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_provision_activity-v0.0.1.json @@ -86,7 +86,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -105,7 +105,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -123,7 +123,7 @@ "props.required": "field?.parent?.model && field.parent.model.type === 'bf:Publication'" }, "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -158,7 +158,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-4", + "itemCssClass": "col-12 md:col-4", "options": [ { "label": "bf:Place", @@ -188,7 +188,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-8" + "itemCssClass": "col-12 md:col-8" } } } @@ -197,7 +197,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -205,7 +205,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12" + "itemCssClass": "col-12" } } } @@ -217,7 +217,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "hide": true } } @@ -235,7 +235,7 @@ "props.required": "model.type === 'bf:Publication'" }, "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } @@ -249,7 +249,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4", + "itemCssClass": "col-12 md:col-4", "hide": true } } @@ -264,7 +264,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4", + "itemCssClass": "col-12 md:col-4", "hide": true } } @@ -274,7 +274,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_series-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_series-v0.0.1.json index 3712cc4f24..42386e0d2c 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_series-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_series-v0.0.1.json @@ -129,7 +129,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "placeholder": "Example: vol.3" } } @@ -149,7 +149,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_types-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_types-v0.0.1.json index ebb6d95b9e..58ae2f94b8 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_types-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_types-v0.0.1.json @@ -42,7 +42,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -76,7 +76,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -121,7 +121,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_music", @@ -148,7 +148,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -197,7 +197,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_other_book", @@ -240,7 +240,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -274,7 +274,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -317,7 +317,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_comic", @@ -336,7 +336,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -397,7 +397,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -442,7 +442,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_other_game", @@ -469,7 +469,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -517,7 +517,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_poster", @@ -556,7 +556,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -590,7 +590,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -624,7 +624,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -685,7 +685,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -729,7 +729,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_movie", @@ -752,7 +752,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -796,7 +796,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_kamishibai", @@ -819,7 +819,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -853,7 +853,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -897,7 +897,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_printed_score", @@ -920,7 +920,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -954,7 +954,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -988,7 +988,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -1034,7 +1034,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "label": "docsubtype_reading_kit", @@ -1065,7 +1065,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_usage_and_access_policy-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_usage_and_access_policy-v0.0.1.json index 00209f6581..730ee72310 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_usage_and_access_policy-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_usage_and_access_policy-v0.0.1.json @@ -37,7 +37,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "placeholder": "Example: Copy not allowed" } } @@ -47,7 +47,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/documents/templates/rero_ils/_other_edition.html b/rero_ils/modules/documents/templates/rero_ils/_other_edition.html index 3dba1e9e6e..936f28cdd1 100644 --- a/rero_ils/modules/documents/templates/rero_ils/_other_edition.html +++ b/rero_ils/modules/documents/templates/rero_ils/_other_edition.html @@ -32,7 +32,7 @@ {% endfor %}
{% else %} -
+
{{ fieldLabel }}
    diff --git a/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html b/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html index 4a62bed4d6..659f4418c3 100644 --- a/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html +++ b/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html @@ -33,7 +33,7 @@
    {{ _('Back') }}
    -
    +
    {%- set icon_name = record | document_main_type(false) %} {%- set covert_art = record | get_cover_art %}
    @@ -106,12 +106,12 @@

    {% if record.partOf %} {% for partOf in record.partOf %} {% set data = partOf|part_of_format %} -
    +
    {{ data.label }}
    -
    +
    {{ data.title }} {% if data.numbering|length > 0 %} ; diff --git a/rero_ils/modules/entities/local_entities/jsonschemas/local_entities/local_entity_person-v0.0.1.json b/rero_ils/modules/entities/local_entities/jsonschemas/local_entities/local_entity_person-v0.0.1.json index ad84eb0880..18a9767b95 100644 --- a/rero_ils/modules/entities/local_entities/jsonschemas/local_entities/local_entity_person-v0.0.1.json +++ b/rero_ils/modules/entities/local_entities/jsonschemas/local_entities/local_entity_person-v0.0.1.json @@ -166,7 +166,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6", + "itemCssClass": "col-12 md:col-6", "options": [ { "value": "M", diff --git a/rero_ils/modules/entities/remote_entities/jsonschemas/remote_entities/remote_entity-v0.0.1.json b/rero_ils/modules/entities/remote_entities/jsonschemas/remote_entities/remote_entity-v0.0.1.json index 62b23f9647..7bfc9bca3c 100644 --- a/rero_ils/modules/entities/remote_entities/jsonschemas/remote_entities/remote_entity-v0.0.1.json +++ b/rero_ils/modules/entities/remote_entities/jsonschemas/remote_entities/remote_entity-v0.0.1.json @@ -55,7 +55,7 @@ ], "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": true, "options": [ diff --git a/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html b/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html index e11561c534..ef09769211 100644 --- a/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html +++ b/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html @@ -28,8 +28,8 @@ {% endif %} {% if data.broader %} -
    {{ _('Broader') }}
    -
    +
    {{ _('Broader') }}
    +
      {% for broader in data.broader %}
    • {{ broader.authorized_access_point }}
    • @@ -39,8 +39,8 @@ {% endif %} {% if data.related %} -
      {{ _('Related') }}
      -
      +
      {{ _('Related') }}
      +
        {% for related in data.related %}
      • {{ related.authorized_access_point }}
      • @@ -50,8 +50,8 @@ {% endif %} {% if data.classification %} -
        {{ _('Classification(s)') }}
        -
        +
        {{ _('Classification(s)') }}
        +
          {% for classification in data.classification %}
        • diff --git a/rero_ils/modules/entities/templates/rero_ils/entity_local.html b/rero_ils/modules/entities/templates/rero_ils/entity_local.html index 23b73a6e9e..94390f6252 100644 --- a/rero_ils/modules/entities/templates/rero_ils/entity_local.html +++ b/rero_ils/modules/entities/templates/rero_ils/entity_local.html @@ -24,7 +24,7 @@ {% set pid = record.pid %} {%- block body %} -
          +

          @@ -54,8 +54,8 @@

          {{ dl(_('Source catalog'), record.source_catalog) }} {% if record.identifier %} -
          {{ _('Identifier') }}
          -
          +
          {{ _('Identifier') }}
          +
          {{ _(record.identifier.type) }} - {{ record.identifier.value }} {% if record.identifier.source %}({{ record.identifier.source }}){% endif %}
          diff --git a/rero_ils/modules/entities/templates/rero_ils/entity_remote.html b/rero_ils/modules/entities/templates/rero_ils/entity_remote.html index 820bbca984..fe334aaa52 100644 --- a/rero_ils/modules/entities/templates/rero_ils/entity_remote.html +++ b/rero_ils/modules/entities/templates/rero_ils/entity_remote.html @@ -25,7 +25,7 @@ {% set pid = record.pid %} {%- block body %} -
          +

          @@ -48,8 +48,8 @@

          {% set links = record|sources_link %} {% if links != {} %} -
          {{ _('Source(s)') }}
          -
          +
          {{ _('Source(s)') }}
          +
            {% for source, link in links.items() %}
          • diff --git a/rero_ils/modules/entities/templates/rero_ils/macros/entity.html b/rero_ils/modules/entities/templates/rero_ils/macros/entity.html index 8dd8572b9e..14a36b6d0f 100644 --- a/rero_ils/modules/entities/templates/rero_ils/macros/entity.html +++ b/rero_ils/modules/entities/templates/rero_ils/macros/entity.html @@ -20,10 +20,10 @@ {% macro dl(name, value, prefix) %} {% if value %} -
            +
            {{ name }}:
            -
            +
            {% if value is string %} {% if prefix %} {{ _(prefix.format(v=value)) }} @@ -52,10 +52,10 @@ {% macro dl_bool(name, value) %} {% if value %} -
            +
            {{ name }}:
            -
            +
            {% endif %} @@ -63,10 +63,10 @@ {% macro dl_permalink_by_source(name, data, source) %} {% if data.pid %} -
            +
            {{ _(name) }}:
            -
            +
            {% if source != 'rero' %} {{ data.pid }} {% else %} diff --git a/rero_ils/modules/ill_requests/jsonschemas/ill_requests/ill_request-v0.0.1.json b/rero_ils/modules/ill_requests/jsonschemas/ill_requests/ill_request-v0.0.1.json index 8cc361fda5..accd6ddbe2 100644 --- a/rero_ils/modules/ill_requests/jsonschemas/ill_requests/ill_request-v0.0.1.json +++ b/rero_ils/modules/ill_requests/jsonschemas/ill_requests/ill_request-v0.0.1.json @@ -144,8 +144,7 @@ "value": "CANCELLED", "label": "CANCELLED" } - ], - "placeholder": "Choose a status" + ] } } } @@ -242,7 +241,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-md-3 p-0" + "itemCssClass": "col-12 md:col-3" } } } diff --git a/rero_ils/modules/item_types/jsonschemas/item_types/item_type-v0.0.1.json b/rero_ils/modules/item_types/jsonschemas/item_types/item_type-v0.0.1.json index f3e03020c5..2049165d03 100644 --- a/rero_ils/modules/item_types/jsonschemas/item_types/item_type-v0.0.1.json +++ b/rero_ils/modules/item_types/jsonschemas/item_types/item_type-v0.0.1.json @@ -138,7 +138,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-10" + "itemCssClass": "col-12 md:col-10" } } } @@ -147,7 +147,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -204,7 +204,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-10" + "itemCssClass": "col-12 md:col-10" } } } @@ -213,7 +213,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/modules/locations/jsonschemas/locations/location-v0.0.1.json b/rero_ils/modules/locations/jsonschemas/locations/location-v0.0.1.json index 7cc7b1ed88..6151034792 100644 --- a/rero_ils/modules/locations/jsonschemas/locations/location-v0.0.1.json +++ b/rero_ils/modules/locations/jsonschemas/locations/location-v0.0.1.json @@ -236,16 +236,6 @@ "formlyConfig": { "expressions": { "hide": "field?.parent?.model?.allow_request === false" - }, - "wrappers": [ - "toggle-switch" - ], - "props": { - "hideLabel": true, - "toggle-switch": { - "label": "Restrict pickup to", - "description": "If enabled, restrict pickup to specific pickup locations." - } } } } diff --git a/rero_ils/modules/patron_types/jsonschemas/patron_types/patron_type-v0.0.1.json b/rero_ils/modules/patron_types/jsonschemas/patron_types/patron_type-v0.0.1.json index 732f08ac47..cacb506bf5 100644 --- a/rero_ils/modules/patron_types/jsonschemas/patron_types/patron_type-v0.0.1.json +++ b/rero_ils/modules/patron_types/jsonschemas/patron_types/patron_type-v0.0.1.json @@ -80,24 +80,10 @@ } }, "subscription_amount": { - "title": "Amount", + "title": "Yearly subscription", "description": "Yearly amount due by patrons linked to this patron type.", "type": "number", - "exclusiveMinimum": 0, - "widget": { - "formlyConfig": { - "wrappers": [ - "toggle-switch", - "form-field" - ], - "props": { - "toggle-switch": { - "label": "Yearly subscription", - "description": "Activation of subscription fees for patrons linked to this type." - } - } - } - } + "exclusiveMinimum": 0 }, "limits": { "title": "Limits", @@ -110,6 +96,7 @@ ], "properties": { "checkout_limits": { + "title": "Limit by checkouts", "type": "object", "additionalProperties": false, "required": [ @@ -186,27 +173,12 @@ } } } - }, - "widget": { - "formlyConfig": { - "wrappers": [ - "toggle-switch", - "form-field" - ], - "props": { - "toggle-switch": { - "label": "Limit by checkouts" - } - } - } } }, "fee_amount_limits": { + "title": "Limit by overdue fee amount", "type": "object", "additionalProperties": false, - "required": [ - "default_value" - ], "properties": { "default_value": { "title": "Fee amount", @@ -214,27 +186,12 @@ "type": "number", "minimum": 0 } - }, - "widget": { - "formlyConfig": { - "wrappers": [ - "toggle-switch", - "form-field" - ], - "props": { - "toggle-switch": { - "label": "Limit by overdue fee amount" - } - } - } } }, "overdue_items_limits": { + "title": "Limit by overdue items", "type": "object", "additionalProperties": false, - "required": [ - "default_value" - ], "properties": { "default_value": { "title": "Number of overdue items", @@ -242,19 +199,6 @@ "type": "number", "minimum": 1 } - }, - "widget": { - "formlyConfig": { - "wrappers": [ - "toggle-switch", - "form-field" - ], - "props": { - "toggle-switch": { - "label": "Limit by overdue items" - } - } - } } }, "unpaid_subscription": { diff --git a/rero_ils/modules/patrons/jsonschemas/patrons/patron-v0.0.1.json b/rero_ils/modules/patrons/jsonschemas/patrons/patron-v0.0.1.json index 30c91798a4..7d8103f1b9 100644 --- a/rero_ils/modules/patrons/jsonschemas/patrons/patron-v0.0.1.json +++ b/rero_ils/modules/patrons/jsonschemas/patrons/patron-v0.0.1.json @@ -89,7 +89,7 @@ "formlyConfig": { "type": "textarea", "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "rows": 2 } } @@ -102,7 +102,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -114,7 +114,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-6" + "itemCssClass": "col-12 md:col-6" } } } @@ -142,7 +142,7 @@ "card" ], "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } @@ -264,8 +264,7 @@ "messages": { "patternMessage": "Should be in the following format: 2022-12-31 (YYYY-MM-DD)." } - }, - "placeholder": "Select a date" + } } } } diff --git a/rero_ils/modules/permissions.py b/rero_ils/modules/permissions.py index c2e189ca4e..f1c2770047 100644 --- a/rero_ils/modules/permissions.py +++ b/rero_ils/modules/permissions.py @@ -42,6 +42,8 @@ from rero_ils.modules.patrons.api import current_librarian, current_patrons from rero_ils.modules.utils import get_record_class_and_permissions_from_route +from .acquisition.acq_orders.api import AcqOrder + # SPECIFIC ACTIONS ============================================================ # Some actions are not related to a specific resource. For this case, we # can create a specific action in this root permission module. @@ -481,3 +483,35 @@ def excludes(self, record=None, **kwargs): if self.is_rollovered(record): return [any_user] return [] + + +class DisallowedByOrderStatus(Generator): + """Disallow if the record is considerate roll-overed.""" + + def __init__(self, record_cls, allowed_statuses): + """Constructor. + + :param record_cls: the record class to build a resource if record is + received is only dict/data. + :param callback: the function to use to know if the resource is + rollovered. This function should return a boolean value. By default + the ``is_active`` record property will be returned if exists ; + otherwise True. + """ + self.record_cls = record_cls + self.allowed_statuses = allowed_statuses + + def excludes(self, record=None, **kwargs): + """Disallow operation check. + + :param record; the record to check. + :param kwargs: extra named arguments. + :returns: a list of Needs to disable access. + """ + if record: + if not isinstance(record, self.record_cls): + record = self.record_cls(record) + if order_status := AcqOrder.get_status_by_pid(record.order_pid): + if not order_status in self.allowed_statuses: + return [any_user] + return [] diff --git a/rero_ils/modules/stats/templates/rero_ils/detailed_view_stats.html b/rero_ils/modules/stats/templates/rero_ils/detailed_view_stats.html index 9770847241..369cee3fc1 100644 --- a/rero_ils/modules/stats/templates/rero_ils/detailed_view_stats.html +++ b/rero_ils/modules/stats/templates/rero_ils/detailed_view_stats.html @@ -52,13 +52,13 @@

            {{record.created | string | format_date}}

            {%- for val in value[1] %} {% if val is mapping %} - + {%- for k in val %}
          • {{k}}: {{val[k]}}
          • {%- endfor%} {%- else %} - {{val}} + {{val}} {%- endif %} {%- endfor%} @@ -105,13 +105,13 @@

            {{record.created | string | format_date}}

            {%- for head in val.keys() %} {% if val[head] is mapping %} - + {%- for k, v in val[head].items() %}
          • {{k}}: {{v}}
          • {%- endfor%} {%- else %} - {{val[head]}} + {{val[head]}} {%- endif %} {%- endfor%} diff --git a/rero_ils/modules/stats_cfg/jsonschemas/stats_cfg/stat_cfg-v0.0.1.json b/rero_ils/modules/stats_cfg/jsonschemas/stats_cfg/stat_cfg-v0.0.1.json index 5405588a5e..5c835dd2ec 100644 --- a/rero_ils/modules/stats_cfg/jsonschemas/stats_cfg/stat_cfg-v0.0.1.json +++ b/rero_ils/modules/stats_cfg/jsonschemas/stats_cfg/stat_cfg-v0.0.1.json @@ -205,7 +205,6 @@ }, { "items": { - "additionalProperties": false, "title": "distributions", "type": "string", "enum": [ @@ -217,7 +216,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -277,7 +276,6 @@ }, { "items": { - "additionalProperties": false, "title": "distributions", "type": "string", "enum": [ @@ -288,7 +286,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -344,7 +342,6 @@ }, { "items": { - "additionalProperties": false, "title": "distributions", "type": "string", "enum": [ @@ -359,7 +356,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -432,7 +429,6 @@ }, { "items": { - "additionalProperties": false, "title": "distributions", "type": "string", "enum": [ @@ -444,7 +440,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -551,7 +547,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -907,7 +903,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -982,7 +978,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ @@ -1054,7 +1050,7 @@ }, "widget": { "formlyConfig": { - "type": "select", + "type": "multi-select", "props": { "sort": false, "options": [ diff --git a/rero_ils/modules/users/jsonschemas/users/user-v0.0.1.json b/rero_ils/modules/users/jsonschemas/users/user-v0.0.1.json index d841a9808c..777002337a 100644 --- a/rero_ils/modules/users/jsonschemas/users/user-v0.0.1.json +++ b/rero_ils/modules/users/jsonschemas/users/user-v0.0.1.json @@ -64,6 +64,7 @@ "pattern": "^(19|2[0-9])[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", "widget": { "formlyConfig": { + "type": "datePicker", "validation": { "messages": { "patternMessage": "Should be in the following format: 2022-12-31 (YYYY-MM-DD)." @@ -87,7 +88,6 @@ "widget": { "formlyConfig": { "props": { - "placeholder": "Select an option\u2026", "options": [ { "label": "female", @@ -114,7 +114,7 @@ "title": "Username", "description": "Login username for the web interface.", "type": "string", - "pattern": "^[a-zA-Z0-9-_]{2,255}$", + "pattern": "^[a-zA-Z0-9\\-_]{2,255}$", "minLength": 3, "maxLength": 255, "widget": { @@ -283,7 +283,8 @@ "formlyConfig": { "type": "passwordGenerator", "props": { - "api": "/api/user/password/generate" + "api": "/api/user/password/generate", + "class": "surface-100" } } } @@ -296,4 +297,4 @@ } } } -} \ No newline at end of file +} diff --git a/rero_ils/modules/vendors/api.py b/rero_ils/modules/vendors/api.py index 98c49a5b4b..7abad49faf 100644 --- a/rero_ils/modules/vendors/api.py +++ b/rero_ils/modules/vendors/api.py @@ -22,7 +22,6 @@ from flask_babel import gettext as _ -from rero_ils.modules.acquisition.acq_invoices.api import AcquisitionInvoicesSearch from rero_ils.modules.api import IlsRecord, IlsRecordsIndexer, IlsRecordsSearch from rero_ils.modules.fetchers import id_fetcher from rero_ils.modules.minters import id_minter @@ -147,23 +146,16 @@ def get_links_to_me(self, get_pids=False): from rero_ils.modules.holdings.api import HoldingsSearch acq_orders_query = AcqOrdersSearch().filter("term", vendor__pid=self.pid) - acq_invoices_query = AcquisitionInvoicesSearch().filter( - "term", vendor__pid=self.pid - ) hold_query = HoldingsSearch().filter("term", vendor__pid=self.pid) links = {} if get_pids: acq_orders = sorted_pids(acq_orders_query) - acq_invoices = sorted_pids(acq_invoices_query) holdings = sorted_pids(hold_query) else: acq_orders = acq_orders_query.count() - acq_invoices = acq_invoices_query.count() holdings = hold_query.count() if acq_orders: links["acq_orders"] = acq_orders - if acq_invoices: - links["acq_invoices"] = acq_invoices if holdings: links["holdings"] = holdings return links diff --git a/rero_ils/modules/vendors/jsonschemas/vendors/vendor-v0.0.1.json b/rero_ils/modules/vendors/jsonschemas/vendors/vendor-v0.0.1.json index df10eb3a9d..7f788a5479 100644 --- a/rero_ils/modules/vendors/jsonschemas/vendors/vendor-v0.0.1.json +++ b/rero_ils/modules/vendors/jsonschemas/vendors/vendor-v0.0.1.json @@ -268,7 +268,7 @@ "type": "select", "props": { "sort": true, - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "options": [ { "value": "default", @@ -295,7 +295,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "addonLeft": [ "" ] @@ -312,7 +312,7 @@ "formlyConfig": { "type": "textarea", "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "rows": 2 } } @@ -325,7 +325,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-4" + "itemCssClass": "col-12 md:col-4" } } } @@ -337,7 +337,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-8" + "itemCssClass": "col-12 md:col-8" } } } @@ -349,7 +349,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "addonLeft": [ "" ] @@ -364,7 +364,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "addonLeft": [ "" ] @@ -379,7 +379,7 @@ "widget": { "formlyConfig": { "props": { - "itemCssClass": "col-lg-12", + "itemCssClass": "col-12", "addonLeft": [ "" ] @@ -391,7 +391,7 @@ "widget": { "formlyConfig": { "props": { - "containerCssClass": "row" + "containerCssClass": "grid grid-nogutter-y" } } } diff --git a/rero_ils/theme/templates/rero_ils/macros/macro.html b/rero_ils/theme/templates/rero_ils/macros/macro.html index 319000b985..511a7257a1 100644 --- a/rero_ils/theme/templates/rero_ils/macros/macro.html +++ b/rero_ils/theme/templates/rero_ils/macros/macro.html @@ -65,7 +65,7 @@ {% endmacro %} {% macro dl_row(title, content) %} -
            +
            {{ title }}
            @@ -133,7 +133,7 @@ {% endmacro %} {% macro div_row(title, content) %} -
            +
            {{ title }}:
            @@ -144,7 +144,7 @@ {% endmacro %} {% macro div_row_xs3_xs9(title, content) %} -
            +
            {{ title }}:
            diff --git a/tests/api/acq_invoices/test_acq_invoices_permissions.py b/tests/api/acq_invoices/test_acq_invoices_permissions.py deleted file mode 100644 index f2cb66bd52..0000000000 --- a/tests/api/acq_invoices/test_acq_invoices_permissions.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2022 RERO -# Copyright (C) 2022 UCLouvain -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import mock -from flask import current_app -from flask_principal import AnonymousIdentity, identity_changed -from flask_security import login_user -from utils import check_permission - -from rero_ils.modules.acquisition.acq_invoices.permissions import ( - AcqInvoicePermissionPolicy, -) - - -def test_invoice_permissions( - patron_martigny, - librarian_martigny, - librarian2_martigny, - system_librarian_martigny, - document, - org_martigny, - acq_invoice_fiction_sion, - acq_invoice_fiction_saxon, - acq_invoice_fiction_martigny, -): - """Test invoices permissions class.""" - - # Anonymous user & Patron :: None action allowed - identity_changed.send( - current_app._get_current_object(), identity=AnonymousIdentity() - ) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": False, - "read": False, - "create": False, - "update": False, - "delete": False, - }, - {}, - ) - login_user(patron_martigny.user) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": False, - "read": False, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_martigny, - ) - - # As staff member without any specific access : - # - None action allowed - # - except read record of its own library (pro_read_only) - login_user(librarian2_martigny.user) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": True, - "read": True, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_martigny, - ) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": True, - "read": False, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_sion, - ) - - # As staff member with "library-administration" role : - # - Search :: everything - # - Read :: record of its own library - # - Create/Update/Delete :: record of its own library - login_user(librarian_martigny.user) - check_permission( - AcqInvoicePermissionPolicy, - {"search": True, "read": True, "create": True, "update": True, "delete": True}, - acq_invoice_fiction_martigny, - ) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": True, - "read": False, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_saxon, - ) - - # As staff member with "full_permissions" role : - # - Search :: everything - # - Read :: record of its own organisation - # - Create/Update/Delete :: record of its own organisation - login_user(system_librarian_martigny.user) - check_permission( - AcqInvoicePermissionPolicy, - {"search": True, "read": True, "create": True, "update": True, "delete": True}, - acq_invoice_fiction_saxon, - ) - check_permission( - AcqInvoicePermissionPolicy, - { - "search": True, - "read": False, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_sion, - ) - - # Special case !!! An acquisition invoice linked to a closed budget - # should be considerate as roll-overed and can't be updated. - with mock.patch( - "rero_ils.modules.acquisition.acq_invoices.api.AcquisitionInvoice." "is_active", - False, - ): - check_permission( - AcqInvoicePermissionPolicy, - { - "search": True, - "read": True, - "create": False, - "update": False, - "delete": False, - }, - acq_invoice_fiction_martigny, - ) diff --git a/tests/api/acq_invoices/test_acq_invoices_rest.py b/tests/api/acq_invoices/test_acq_invoices_rest.py deleted file mode 100644 index a2219d74c1..0000000000 --- a/tests/api/acq_invoices/test_acq_invoices_rest.py +++ /dev/null @@ -1,195 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Tests REST API acquisition invoices.""" - -import json - -import mock -from flask import url_for -from invenio_accounts.testutils import login_user_via_session -from utils import VerifyRecordPermissionPatch, get_json, postdata, to_relative_url - - -@mock.patch( - "invenio_records_rest.views.verify_record_permission", - mock.MagicMock(return_value=VerifyRecordPermissionPatch), -) -def test_acquisition_invoices_library_facets( - client, org_martigny, acq_invoice_fiction_martigny, rero_json_header -): - """Test record retrieval.""" - list_url = url_for("invenio_records_rest.acin_list", view="org1") - - res = client.get(list_url, headers=rero_json_header) - data = get_json(res) - aggs = data["aggregations"] - assert "library" in aggs - - -@mock.patch( - "invenio_records_rest.views.verify_record_permission", - mock.MagicMock(return_value=VerifyRecordPermissionPatch), -) -def test_acquisition_invoice_total_amount(client, acq_invoice_fiction_martigny): - """Test calculate total amonut of invoice.""" - item_url = url_for("invenio_records_rest.acin_item", pid_value="acin1") - acq_invoice = acq_invoice_fiction_martigny - res = client.get(item_url) - assert res.status_code == 200 - - data = get_json(res) - assert data["metadata"]["invoice_price"] == 1500 - - -@mock.patch( - "invenio_records_rest.views.verify_record_permission", - mock.MagicMock(return_value=VerifyRecordPermissionPatch), -) -def test_acquisition_invoice_get(client, acq_invoice_fiction_martigny): - """Test record retrieval.""" - item_url = url_for("invenio_records_rest.acin_item", pid_value="acin1") - acq_invoice = acq_invoice_fiction_martigny - res = client.get(item_url) - assert res.status_code == 200 - - assert res.headers["ETag"] == f'"{acq_invoice.revision_id}"' - - data = get_json(res) - assert acq_invoice.dumps() == data["metadata"] - - # Check metadata - for k in ["created", "updated", "metadata", "links"]: - assert k in data - - # Check self links - res = client.get(to_relative_url(data["links"]["self"])) - assert res.status_code == 200 - assert data == get_json(res) - assert acq_invoice.dumps() == data["metadata"] - - list_url = url_for("invenio_records_rest.acin_list", pid="acin1") - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) - - assert data["hits"]["hits"][0]["metadata"] == acq_invoice.replace_refs() - - -@mock.patch( - "invenio_records_rest.views.verify_record_permission", - mock.MagicMock(return_value=VerifyRecordPermissionPatch), -) -def test_acquisition_invoices_post_put_delete( - client, org_martigny, vendor2_martigny, acq_invoice_fiction_saxon, json_header -): - """Test record retrieval.""" - # Create record / POST - item_url = url_for("invenio_records_rest.acin_item", pid_value="1") - list_url = url_for("invenio_records_rest.acin_list", q="pid:1") - - acq_invoice_fiction_saxon["pid"] = "1" - res, data = postdata( - client, "invenio_records_rest.acin_list", acq_invoice_fiction_saxon - ) - assert res.status_code == 201 - - # Check that the returned record matches the given data - assert data["metadata"] == acq_invoice_fiction_saxon - - res = client.get(item_url) - assert res.status_code == 200 - data = get_json(res) - assert acq_invoice_fiction_saxon == data["metadata"] - - # Update record/PUT - data = acq_invoice_fiction_saxon - data["invoice_number"] = "IN-TEST-2" - res = client.put(item_url, data=json.dumps(data), headers=json_header) - assert res.status_code == 200 - - # Check that the returned record matches the given data - data = get_json(res) - assert data["metadata"]["invoice_number"] == "IN-TEST-2" - - res = client.get(item_url) - assert res.status_code == 200 - - data = get_json(res) - assert data["metadata"]["invoice_number"] == "IN-TEST-2" - - res = client.get(list_url) - assert res.status_code == 200 - - data = get_json(res)["hits"]["hits"][0] - assert data["metadata"]["invoice_number"] == "IN-TEST-2" - - # Delete record/DELETE - res = client.delete(item_url) - assert res.status_code == 204 - - res = client.get(item_url) - assert res.status_code == 410 - - -def test_acquisition_invoices_can_delete(client, acq_invoice_fiction_martigny): - """Test can delete an acquisition invoice.""" - can, reasons = acq_invoice_fiction_martigny.can_delete - assert can - assert reasons == {} - - -def test_filtered_acquisition_invoices_get( - client, - librarian_martigny, - acq_invoice_fiction_martigny, - acq_invoice_fiction_saxon, - librarian_sion, - acq_invoice_fiction_sion, -): - """Test acquisition invoices filter by organisation.""" - list_url = url_for("invenio_records_rest.acin_list") - - res = client.get(list_url) - assert res.status_code == 401 - - # Martigny - login_user_via_session(client, librarian_martigny.user) - list_url = url_for("invenio_records_rest.acin_list") - - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) - assert data["hits"]["total"]["value"] == 2 - - # Sion - login_user_via_session(client, librarian_sion.user) - list_url = url_for("invenio_records_rest.acin_list") - - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) - assert data["hits"]["total"]["value"] == 1 - - -def test_acquisition_invoice_properties( - org_sion, vendor_sion, document, lib_sion, acq_invoice_fiction_sion -): - """Test acquisition invoice properties.""" - assert acq_invoice_fiction_sion.vendor_pid == vendor_sion.pid - assert acq_invoice_fiction_sion.library_pid == lib_sion.pid - assert acq_invoice_fiction_sion.organisation_pid == org_sion.pid diff --git a/tests/api/acq_order_lines/test_acq_order_lines_permissions.py b/tests/api/acq_order_lines/test_acq_order_lines_permissions.py index de02e03098..92e8beafd1 100644 --- a/tests/api/acq_order_lines/test_acq_order_lines_permissions.py +++ b/tests/api/acq_order_lines/test_acq_order_lines_permissions.py @@ -25,6 +25,7 @@ from rero_ils.modules.acquisition.acq_order_lines.permissions import ( AcqOrderLinePermissionPolicy, ) +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus def test_order_lines_permissions( @@ -158,3 +159,82 @@ def test_order_lines_permissions( }, acq_order_line_fiction_martigny, ) + + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.CANCELLED), + ): + check_permission( + AcqOrderLinePermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": True, + "delete": True, + }, + acq_order_line_fiction_martigny, + ) + + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.PENDING), + ): + check_permission( + AcqOrderLinePermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": True, + "delete": True, + }, + acq_order_line_fiction_martigny, + ) + + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.ORDERED), + ): + check_permission( + AcqOrderLinePermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": True, + "delete": False, + }, + acq_order_line_fiction_martigny, + ) + + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.PARTIALLY_RECEIVED), + ): + check_permission( + AcqOrderLinePermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": True, + "delete": False, + }, + acq_order_line_fiction_martigny, + ) + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.RECEIVED), + ): + check_permission( + AcqOrderLinePermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": False, + "delete": False, + }, + acq_order_line_fiction_martigny, + ) diff --git a/tests/api/acq_orders/test_acq_orders_rest.py b/tests/api/acq_orders/test_acq_orders_rest.py index ec2b84e1cd..9b37ccecf2 100644 --- a/tests/api/acq_orders/test_acq_orders_rest.py +++ b/tests/api/acq_orders/test_acq_orders_rest.py @@ -112,7 +112,6 @@ def test_acq_orders_post_put_delete( } assert data["metadata"].pop("status") == AcqOrderStatus.PENDING - assert not data["metadata"].pop("order_date", None) acq_order_fiction_saxon_data["pid"] = data["metadata"]["pid"] assert data["metadata"] == acq_order_fiction_saxon_data @@ -128,7 +127,6 @@ def test_acq_orders_post_put_delete( "expenditure": {"total_amount": 0, "quantity": 0}, } assert data["metadata"].pop("status") == AcqOrderStatus.PENDING - assert not data["metadata"].pop("order_date", None) assert acq_order_fiction_saxon_data == data["metadata"] # Update record/PUT @@ -221,7 +219,6 @@ def test_acq_order_history_api( data = { "vendor": {"$ref": get_ref_for_pid("vndr", vendor_martigny.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, - "type": "monograph", } acor1 = _make_resource(client, "acor", data) data["previousVersion"] = {"$ref": get_ref_for_pid("acor", acor1.pid)} diff --git a/tests/api/acq_orders/test_acq_orders_serializers.py b/tests/api/acq_orders/test_acq_orders_serializers.py index 3a56cd3a85..8cc0dac2bf 100644 --- a/tests/api/acq_orders/test_acq_orders_serializers.py +++ b/tests/api/acq_orders/test_acq_orders_serializers.py @@ -47,7 +47,7 @@ def test_csv_serializer( assert data assert ( '"order_pid","order_reference","order_date","order_staff_note",' - '"order_vendor_note","order_type","order_status","vendor_name",' + '"order_vendor_note","order_status","vendor_name",' '"document_pid","document_creator","document_title",' '"document_publisher","document_publication_year",' '"document_edition_statement","document_series_statement",' diff --git a/tests/api/acq_orders/test_acq_orders_views.py b/tests/api/acq_orders/test_acq_orders_views.py index 48484b1ee5..b27d5070dd 100644 --- a/tests/api/acq_orders/test_acq_orders_views.py +++ b/tests/api/acq_orders/test_acq_orders_views.py @@ -152,12 +152,10 @@ def test_send_order( l2 = AcqOrderLine.get_record_by_pid(acq_order_line2_fiction_martigny.pid) l3 = AcqOrderLine.get_record_by_pid(acq_order_line3_fiction_martigny.pid) assert l1.status == AcqOrderLineStatus.ORDERED - assert l1.order_date assert l2.status == AcqOrderLineStatus.ORDERED - assert l2.order_date assert l3.status == AcqOrderLineStatus.CANCELLED - assert not l3.order_date assert acor.status == AcqOrderStatus.ORDERED + assert acor.get("order_date") # ensure that created notification is well constructed from the associated # order and vendor diff --git a/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest.py b/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest.py index 804b195f78..675145063a 100644 --- a/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest.py +++ b/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest.py @@ -19,57 +19,55 @@ """Tests REST API acquisition receipt lines.""" import json -from copy import deepcopy import mock from flask import url_for -from invenio_accounts.testutils import login_user_via_session from utils import VerifyRecordPermissionPatch, get_json, postdata, to_relative_url from rero_ils.modules.acquisition.acq_receipt_lines.models import AcqReceiptLineNoteType -@mock.patch( - "invenio_records_rest.views.verify_record_permission", - mock.MagicMock(return_value=VerifyRecordPermissionPatch), -) def test_acq_receipt_lines_get(client, acq_receipt_line_1_fiction_martigny): """Test record retrieval.""" - item_url = url_for("invenio_records_rest.acrl_item", pid_value="acrl1") - acq_receipt_line = deepcopy(acq_receipt_line_1_fiction_martigny) - res = client.get(item_url) - assert res.status_code == 200 + with mock.patch( + "invenio_records_rest.views.verify_record_permission", + mock.MagicMock(return_value=VerifyRecordPermissionPatch), + ): + item_url = url_for("invenio_records_rest.acrl_item", pid_value="acrl1") + acq_receipt_line = acq_receipt_line_1_fiction_martigny + res = client.get(item_url) + assert res.status_code == 200 - assert res.headers["ETag"] == f'"{acq_receipt_line.revision_id}"' + assert res.headers["ETag"] == f'"{acq_receipt_line.revision_id}"' - data = get_json(res) - assert acq_receipt_line.dumps() == data["metadata"] + data = get_json(res) + assert acq_receipt_line.dumps() == data["metadata"] - # Check metadata - for k in ["created", "updated", "metadata", "links"]: - assert k in data + # Check metadata + for k in ["created", "updated", "metadata", "links"]: + assert k in data - # Check self links - res = client.get(to_relative_url(data["links"]["self"])) - assert res.status_code == 200 - assert data == get_json(res) - assert acq_receipt_line.dumps() == data["metadata"] + # Check self links + res = client.get(to_relative_url(data["links"]["self"])) + assert res.status_code == 200 + assert data == get_json(res) + assert acq_receipt_line.dumps() == data["metadata"] - list_url = url_for("invenio_records_rest.acrl_list", pid="acrl1") - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) + list_url = url_for("invenio_records_rest.acrl_list", pid="acrl1") + res = client.get(list_url) + assert res.status_code == 200 + data = get_json(res) - metadata = data["hits"]["hits"][0]["metadata"] + metadata = data["hits"]["hits"][0]["metadata"] - total_amount = metadata["total_amount"] - assert total_amount == 1000.0 + total_amount = metadata["total_amount"] + assert total_amount == 1000.0 - # remove dynamically added fields - del metadata["acq_account"] - del metadata["total_amount"] - del metadata["document"] - assert data["hits"]["hits"][0]["metadata"] == acq_receipt_line.replace_refs() + # remove dynamically added fields + del metadata["acq_account"] + del metadata["total_amount"] + del metadata["document"] + assert data["hits"]["hits"][0]["metadata"] == acq_receipt_line.replace_refs() @mock.patch( @@ -142,36 +140,3 @@ def test_acq_receipt_lines_can_delete( can, reasons = acq_receipt_line_1_fiction_martigny.can_delete assert can assert "links" not in reasons - - -def test_filtered_acq_receipt_lines_get( - client, - librarian_martigny, - acq_receipt_line_1_fiction_martigny, - acq_receipt_line_2_fiction_martigny, - librarian_sion, - acq_receipt_line_fiction_sion, -): - """Test acq receipt lines filter by organisation.""" - list_url = url_for("invenio_records_rest.acrl_list") - - res = client.get(list_url) - assert res.status_code == 401 - - # Martigny - login_user_via_session(client, librarian_martigny.user) - list_url = url_for("invenio_records_rest.acrl_list") - - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) - assert data["hits"]["total"]["value"] == 3 - - # Sion - login_user_via_session(client, librarian_sion.user) - list_url = url_for("invenio_records_rest.acrl_list") - - res = client.get(list_url) - assert res.status_code == 200 - data = get_json(res) - assert data["hits"]["total"]["value"] == 1 diff --git a/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest_filtered.py b/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest_filtered.py new file mode 100644 index 0000000000..4b3d634aba --- /dev/null +++ b/tests/api/acq_receipt_lines/test_acq_receipt_lines_rest_filtered.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# +# RERO ILS +# Copyright (C) 2021 RERO +# Copyright (C) 2021 UCLouvain +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +"""Tests REST API acquisition receipt lines.""" + + +from flask import url_for +from invenio_accounts.testutils import login_user_via_session +from utils import get_json + + +def test_filtered_acq_receipt_lines_get( + client, + librarian_martigny, + acq_order_line_fiction_martigny, + acq_order_line2_fiction_martigny, + acq_receipt_line_1_fiction_martigny, + acq_receipt_line_2_fiction_martigny, + librarian_sion, + acq_receipt_line_fiction_sion, +): + """Test acq receipt lines filter by organisation.""" + list_url = url_for("invenio_records_rest.acrl_list") + + res = client.get(list_url) + assert res.status_code == 401 + + # Martigny + login_user_via_session(client, librarian_martigny.user) + list_url = url_for("invenio_records_rest.acrl_list") + + res = client.get(list_url) + assert res.status_code == 200 + data = get_json(res) + assert data["hits"]["total"]["value"] == 2 + + # Sion + login_user_via_session(client, librarian_sion.user) + list_url = url_for("invenio_records_rest.acrl_list") + + res = client.get(list_url) + assert res.status_code == 200 + data = get_json(res) + assert data["hits"]["total"]["value"] == 1 diff --git a/tests/api/acq_receipts/test_acq_receipts_permissions.py b/tests/api/acq_receipts/test_acq_receipts_permissions.py index d1831fc316..8fd90bc9cd 100644 --- a/tests/api/acq_receipts/test_acq_receipts_permissions.py +++ b/tests/api/acq_receipts/test_acq_receipts_permissions.py @@ -22,6 +22,7 @@ from flask_security import login_user from utils import check_permission +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus from rero_ils.modules.acquisition.acq_receipts.permissions import ( AcqReceiptPermissionPolicy, ) @@ -37,6 +38,8 @@ def test_receipts_permissions( acq_receipt_fiction_sion, acq_receipt_fiction_saxon, acq_receipt_fiction_martigny, + acq_receipt_line_1_fiction_martigny, + acq_receipt_line_fiction_saxon, ): """Test receipt permissions class.""" @@ -155,3 +158,79 @@ def test_receipts_permissions( }, acq_receipt_fiction_martigny, ) + + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.CANCELLED), + ): + check_permission( + AcqReceiptPermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": False, + "delete": False, + }, + acq_receipt_fiction_martigny, + ) + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.PENDING), + ): + check_permission( + AcqReceiptPermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": False, + "delete": False, + }, + acq_receipt_fiction_martigny, + ) + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.ORDERED), + ): + check_permission( + AcqReceiptPermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": False, + "delete": False, + }, + acq_receipt_fiction_martigny, + ) + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.PARTIALLY_RECEIVED), + ): + check_permission( + AcqReceiptPermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": True, + "delete": True, + }, + acq_receipt_fiction_martigny, + ) + with mock.patch( + "rero_ils.modules.acquisition.acq_orders.api.AcqOrder.get_status_by_pid", + mock.MagicMock(return_value=AcqOrderStatus.RECEIVED), + ): + check_permission( + AcqReceiptPermissionPolicy, + { + "search": True, + "read": True, + "create": True, + "update": False, + "delete": True, + }, + acq_receipt_fiction_martigny, + ) diff --git a/tests/api/acq_receipts/test_acq_receipts_rest.py b/tests/api/acq_receipts/test_acq_receipts_rest.py index ada66126a8..06977282f1 100644 --- a/tests/api/acq_receipts/test_acq_receipts_rest.py +++ b/tests/api/acq_receipts/test_acq_receipts_rest.py @@ -96,26 +96,18 @@ def test_acq_receipts_post_put_delete( # Update record/PUT data = acq_receipt_fiction_saxon - data["exchange_rate"] = 1.01 res = client.put(item_url, data=json.dumps(data), headers=json_header) assert res.status_code == 200 # Check that the returned record matches the given data data = get_json(res) - assert data["metadata"]["exchange_rate"] == 1.01 res = client.get(item_url) assert res.status_code == 200 - data = get_json(res) - assert data["metadata"]["exchange_rate"] == 1.01 - res = client.get(list_url) assert res.status_code == 200 - data = get_json(res)["hits"]["hits"][0] - assert data["metadata"]["exchange_rate"] == 1.01 - # Delete record/DELETE res = client.delete(item_url) assert res.status_code == 204 diff --git a/tests/api/acquisition/test_acquisition_reception_workflow.py b/tests/api/acquisition/test_acquisition_reception_workflow.py index ee032a910c..004f5770e7 100644 --- a/tests/api/acquisition/test_acquisition_reception_workflow.py +++ b/tests/api/acquisition/test_acquisition_reception_workflow.py @@ -163,7 +163,6 @@ def assert_account_data(accounts): data = { "vendor": {"$ref": get_ref_for_pid("vndr", vendor_martigny.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, - "type": "monograph", } order = _make_resource(client, "acor", data) assert order["reference"] == f"ORDER-{order.pid}" @@ -272,7 +271,7 @@ def assert_account_data(accounts): assert order.status == AcqOrderStatus.PENDING # TODO: fix links to me for the order resource, this should fail assert order.can_delete - assert not order.order_date + assert not order.get("order_date") assert order.item_quantity == 24 assert order.item_received_quantity == 0 @@ -391,10 +390,6 @@ def assert_account_data(accounts): ]: line = AcqOrderLine.get_record_by_pid(order_line.get("line").pid) assert line.status == order_line.get("status") - if line.status == AcqOrderLineStatus.CANCELLED: - assert not line.order_date - else: - assert line.order_date # check order order = AcqOrder.get_record_by_pid(order.pid) assert order.status == AcqOrderStatus.ORDERED @@ -419,7 +414,6 @@ def assert_account_data(accounts): ref_acc_serial = get_ref_for_pid("acac", m_serials_acc.pid) data = { "acq_order": {"$ref": get_ref_for_pid("acor", order.pid)}, - "exchange_rate": 1, "amount_adjustments": [ { "label": "handling fees", @@ -533,7 +527,6 @@ def assert_account_data(accounts): # except `order_line_5` should have the RECEIVED STATUS # * complete the order reception to receive the `order_line_5` data = { - "exchange_rate": 1, "acq_order": {"$ref": get_ref_for_pid("acor", order.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, "organisation": {"$ref": get_ref_for_pid("org", org_martigny.pid)}, diff --git a/tests/api/acquisition/test_acquisition_scenarios.py b/tests/api/acquisition/test_acquisition_scenarios.py index 9af71e7847..85aee10ca9 100644 --- a/tests/api/acquisition/test_acquisition_scenarios.py +++ b/tests/api/acquisition/test_acquisition_scenarios.py @@ -452,7 +452,6 @@ def test_acquisition_order( order_data = { "vendor": {"$ref": get_ref_for_pid("vndr", vendor_martigny.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, - "type": "monograph", } order = _make_resource(client, "acor", order_data) assert order["reference"] == f"ORDER-{order.pid}" @@ -622,7 +621,6 @@ def test_acquisition_order_line_account_changes( { "vendor": {"$ref": get_ref_for_pid("vndr", vendor_martigny.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, - "type": "monograph", }, ) order_line = _make_resource( diff --git a/tests/api/acquisition/test_acquisition_serializers.py b/tests/api/acquisition/test_acquisition_serializers.py index eda0d049b3..09b9d5a79b 100644 --- a/tests/api/acquisition/test_acquisition_serializers.py +++ b/tests/api/acquisition/test_acquisition_serializers.py @@ -50,7 +50,6 @@ def test_acquisition_orders_serializers( "vendor": {"$ref": get_ref_for_pid("vndr", vendor_martigny.pid)}, "library": {"$ref": get_ref_for_pid("lib", lib_martigny.pid)}, "reference": "ORDER#1", - "type": "monograph", } order = _make_resource(client, "acor", order_data) order.reindex() diff --git a/tests/api/test_monitoring_rest.py b/tests/api/test_monitoring_rest.py index c0bffc0862..3f741c5d9a 100644 --- a/tests/api/test_monitoring_rest.py +++ b/tests/api/test_monitoring_rest.py @@ -41,7 +41,6 @@ def test_monitoring_es_db_counts(client): assert get_json(res) == { "data": { "acac": {"db": 0, "db-es": 0, "es": 0, "index": "acq_accounts"}, - "acin": {"db": 0, "db-es": 0, "es": 0, "index": "acq_invoices"}, "acol": {"db": 0, "db-es": 0, "es": 0, "index": "acq_order_lines"}, "acor": {"db": 0, "db-es": 0, "es": 0, "index": "acq_orders"}, "acre": {"db": 0, "db-es": 0, "es": 0, "index": "acq_receipts"}, diff --git a/tests/api/test_serializers.py b/tests/api/test_serializers.py index c7cbabd95e..1f5b10a403 100644 --- a/tests/api/test_serializers.py +++ b/tests/api/test_serializers.py @@ -307,8 +307,10 @@ def test_acq_orders_serializers( def test_acq_receipts_serializers( client, rero_json_header, - acq_order_fiction_martigny, acq_account_fiction_martigny, + acq_order_fiction_martigny, + acq_order_line_fiction_martigny, + acq_order_line2_fiction_martigny, acq_receipt_fiction_martigny, acq_receipt_line_1_fiction_martigny, acq_receipt_line_2_fiction_martigny, diff --git a/tests/api/vendors/test_vendors.py b/tests/api/vendors/test_vendors.py index ee21e418e1..3542ba149d 100644 --- a/tests/api/vendors/test_vendors.py +++ b/tests/api/vendors/test_vendors.py @@ -84,7 +84,6 @@ def test_vendors_can_delete( can, reasons = vendor_martigny.can_delete assert not can assert reasons["links"]["acq_orders"] - assert reasons["links"]["acq_invoices"] assert reasons["links"]["holdings"] diff --git a/tests/data/acquisition.json b/tests/data/acquisition.json index 0c6c790f7d..b7633b1d8d 100644 --- a/tests/data/acquisition.json +++ b/tests/data/acquisition.json @@ -262,8 +262,7 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/lib1" }, - "reference": "OR-1", - "type": "monograph" + "reference": "OR-1" }, "acor2": { "$schema": "https://bib.rero.ch/schemas/acq_orders/acq_order-v0.0.1.json", @@ -274,8 +273,7 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/lib2" }, - "reference": "OR-2", - "type": "monograph" + "reference": "OR-2" }, "acor3": { "$schema": "https://bib.rero.ch/schemas/acq_orders/acq_order-v0.0.1.json", @@ -286,8 +284,7 @@ "library": { "$ref": "https://bib.rero.ch/api/libraries/lib4" }, - "reference": "OR-3", - "type": "monograph" + "reference": "OR-3" }, "acol1": { "$schema": "https://bib.rero.ch/schemas/acq_order_lines/acq_order_line-v0.0.1.json", @@ -383,7 +380,6 @@ "acq_order": { "$ref": "https://bib.rero.ch/api/acq_orders/acor1" }, - "exchange_rate": 1, "amount_adjustments": [ { "label": "handling fees", @@ -455,7 +451,6 @@ "acq_order": { "$ref": "https://bib.rero.ch/api/acq_orders/acor2" }, - "exchange_rate": 1, "amount_adjustments": [ { "label": "handling fees", @@ -509,7 +504,6 @@ "acq_order": { "$ref": "https://bib.rero.ch/api/acq_orders/acor3" }, - "exchange_rate": 1, "amount_adjustments": [ { "label": "handling fees", @@ -556,121 +550,5 @@ "content": "well received too" } ] - }, - "acin1": { - "$schema": "https://bib.rero.ch/schemas/acq_invoices/acq_invoice-v0.0.1.json", - "pid": "acin1", - "vendor": { - "$ref": "https://bib.rero.ch/api/vendors/vndr1" - }, - "library": { - "$ref": "https://bib.rero.ch/api/libraries/lib1" - }, - "organisation": { - "$ref": "https://bib.rero.ch/api/organisations/org1" - }, - "invoice_number": "IN-1", - "invoice_status": "in_progress", - "invoice_date": "2020-01-06", - "invoice_items": [ - { - "acq_account": { - "$ref": "https://bib.rero.ch/api/acq_accounts/acac1" - }, - "acq_order_line": { - "$ref": "https://bib.rero.ch/api/acq_order_lines/acol1" - }, - "document": { - "$ref": "https://bib.rero.ch/api/documents/doc1" - }, - "order_number": "OR-1", - "price": 1000, - "quantity": 1 - }, - { - "acq_account": { - "$ref": "https://bib.rero.ch/api/acq_accounts/acac1" - }, - "acq_order_line": { - "$ref": "https://bib.rero.ch/api/acq_order_lines/acol2" - }, - "document": { - "$ref": "https://bib.rero.ch/api/documents/doc2" - }, - "order_number": "OR-1", - "price": 500, - "quantity": 1 - } - ] - }, - "acin2": { - "$schema": "https://bib.rero.ch/schemas/acq_invoices/acq_invoice-v0.0.1.json", - "pid": "acin2", - "vendor": { - "$ref": "https://bib.rero.ch/api/vendors/vndr2" - }, - "library": { - "$ref": "https://bib.rero.ch/api/libraries/lib2" - }, - "organisation": { - "$ref": "https://bib.rero.ch/api/organisations/org1" - }, - "invoice_number": "IN-2", - "invoice_status": "in_progress", - "invoice_date": "2020-01-06", - "discount": { - "amount": 100 - }, - "invoice_items": [ - { - "acq_account": { - "$ref": "https://bib.rero.ch/api/acq_accounts/acac2" - }, - "acq_order_line": { - "$ref": "https://bib.rero.ch/api/acq_order_lines/acol3" - }, - "document": { - "$ref": "https://bib.rero.ch/api/documents/doc1" - }, - "order_number": "OR-2", - "price": 1000, - "quantity": 1 - } - ] - }, - "acin3": { - "$schema": "https://bib.rero.ch/schemas/acq_invoices/acq_invoice-v0.0.1.json", - "pid": "acin3", - "vendor": { - "$ref": "https://bib.rero.ch/api/vendors/vndr4" - }, - "library": { - "$ref": "https://bib.rero.ch/api/libraries/lib4" - }, - "organisation": { - "$ref": "https://bib.rero.ch/api/organisations/org2" - }, - "invoice_number": "IN-3", - "invoice_status": "in_progress", - "invoice_date": "2020-01-06", - "discount": { - "percentage": 10 - }, - "invoice_items": [ - { - "acq_account": { - "$ref": "https://bib.rero.ch/api/acq_accounts/acac4" - }, - "acq_order_line": { - "$ref": "https://bib.rero.ch/api/acq_order_lines/acol4" - }, - "document": { - "$ref": "https://bib.rero.ch/api/documents/doc1" - }, - "order_number": "OR-3", - "price": 1000, - "quantity": 1 - } - ] } } diff --git a/tests/data/data.json b/tests/data/data.json index 22f9258f61..06c7cf8c47 100644 --- a/tests/data/data.json +++ b/tests/data/data.json @@ -658,6 +658,30 @@ "communication_language": "fre", "rollover_settings": { "account_transfer": "rollover_no_transfer" + }, + "acquisition_settings": { + "shipping_informations": { + "name": "sion shipping dept", + "email": "reroilstest+sionshipping@gmail.com", + "phone": "+447763324594", + "address": { + "street": "Av. de la gare 134", + "city": "Sion", + "zip_code": "1950", + "country": "sz" + }, + "extra": "VAT number: 123456-78-90" + }, + "billing_informations": { + "name": "sion billing dept", + "email": "reroilstest+sionshipping@gmail.com", + "address": { + "street": "Place de la planta 12", + "city": "Sion", + "zip_code": "1950", + "country": "sz" + } + } } }, "lib5": { diff --git a/tests/fixtures/acquisition.py b/tests/fixtures/acquisition.py index 552ad033f9..cf440b9dc0 100644 --- a/tests/fixtures/acquisition.py +++ b/tests/fixtures/acquisition.py @@ -16,23 +16,19 @@ # along with this program. If not, see . """Common pytest fixtures and plugins.""" - - from copy import deepcopy +import mock import pytest from api.acquisition.acq_utils import _make_resource from rero_ils.modules.acquisition.acq_accounts.api import AcqAccount, AcqAccountsSearch -from rero_ils.modules.acquisition.acq_invoices.api import ( - AcquisitionInvoice, - AcquisitionInvoicesSearch, -) from rero_ils.modules.acquisition.acq_order_lines.api import ( AcqOrderLine, AcqOrderLinesSearch, ) from rero_ils.modules.acquisition.acq_orders.api import AcqOrder, AcqOrdersSearch +from rero_ils.modules.acquisition.acq_orders.models import AcqOrderStatus from rero_ils.modules.acquisition.acq_receipt_lines.api import ( AcqReceiptLine, AcqReceiptLinesSearch, @@ -314,7 +310,7 @@ def acq_account_fiction_sion_data(acquisition): @pytest.fixture(scope="module") def acq_account_fiction_sion( - app, lib_saxon, acq_account_fiction_sion_data, budget_2020_sion + app, lib_sion, acq_account_fiction_sion_data, budget_2020_sion ): """Load acq_account lib sion fiction record.""" acac = AcqAccount.create( @@ -410,10 +406,22 @@ def acq_receipt_fiction_martigny( app, lib_martigny, acq_order_fiction_martigny, + acq_order_line_fiction_martigny, acq_receipt_fiction_martigny_data, acq_account_fiction_martigny, ): """Load acq_receipt lib martigny fiction record.""" + if acq_order_fiction_martigny.status == AcqOrderStatus.PENDING: + with mock.patch( + "rero_ils.modules.notifications.dispatcher.Dispatcher.dispatch_notifications", + mock.MagicMock(return_value={"sent": 1}), + ): + acq_order_fiction_martigny.send_order( + [ + {"type": "to", "address": "ils@foo.com"}, + {"type": "reply_to", "address": "admin@foo.com"}, + ] + ) acor = AcqReceipt.create( data=acq_receipt_fiction_martigny_data, delete_pid=False, @@ -427,8 +435,9 @@ def acq_receipt_fiction_martigny( @pytest.fixture(scope="module") def acq_receipt_line_1_fiction_martigny( app, - acq_receipt_fiction_martigny, + acq_order_fiction_martigny, acq_order_line_fiction_martigny, + acq_receipt_fiction_martigny, acq_receipt_line_1_fiction_martigny_data, ): """Load acq_receipt_line_1 lib martigny fiction record.""" @@ -445,8 +454,9 @@ def acq_receipt_line_1_fiction_martigny( @pytest.fixture(scope="module") def acq_receipt_line_2_fiction_martigny( app, - acq_receipt_fiction_martigny, + acq_order_fiction_martigny, acq_order_line2_fiction_martigny, + acq_receipt_fiction_martigny, acq_receipt_line_2_fiction_martigny_data, ): """Load acq_receipt_line_2 lib martigny fiction record.""" @@ -496,10 +506,22 @@ def acq_receipt_fiction_saxon( lib_saxon, vendor_martigny, acq_order_fiction_saxon, + acq_order_line_fiction_saxon, acq_receipt_fiction_saxon_data, acq_account_books_saxon, ): """Load acq_receipt lib saxon fiction record.""" + if acq_order_fiction_saxon.status == AcqOrderStatus.PENDING: + with mock.patch( + "rero_ils.modules.notifications.dispatcher.Dispatcher.dispatch_notifications", + mock.MagicMock(return_value={"sent": 1}), + ): + acq_order_fiction_saxon.send_order( + [ + {"type": "to", "address": "ils@foo.com"}, + {"type": "reply_to", "address": "admin@foo.com"}, + ] + ) acre = AcqReceipt.create( data=acq_receipt_fiction_saxon_data, delete_pid=False, @@ -513,8 +535,9 @@ def acq_receipt_fiction_saxon( @pytest.fixture(scope="module") def acq_receipt_line_fiction_saxon( app, - acq_receipt_fiction_saxon, + acq_order_fiction_saxon, acq_order_line_fiction_saxon, + acq_receipt_fiction_saxon, acq_receipt_line_fiction_saxon_data, ): """Load acq_receipt_line lib saxon fiction record.""" @@ -561,11 +584,23 @@ def acq_receipt_fiction_sion( app, lib_sion, vendor_sion, + acq_account_fiction_sion, acq_order_fiction_sion, + acq_order_line_fiction_sion, acq_receipt_fiction_sion_data, - acq_account_fiction_sion, ): """Load acq_receipt lib sion fiction record.""" + if acq_order_fiction_sion.status == AcqOrderStatus.PENDING: + with mock.patch( + "rero_ils.modules.notifications.dispatcher.Dispatcher.dispatch_notifications", + mock.MagicMock(return_value={"sent": 1}), + ): + acq_order_fiction_sion.send_order( + [ + {"type": "to", "address": "ils@foo.com"}, + {"type": "reply_to", "address": "admin@foo.com"}, + ] + ) acor = AcqReceipt.create( data=acq_receipt_fiction_sion_data, delete_pid=False, @@ -579,8 +614,9 @@ def acq_receipt_fiction_sion( @pytest.fixture(scope="module") def acq_receipt_line_fiction_sion( app, - acq_receipt_fiction_sion, + acq_order_fiction_sion, acq_order_line_fiction_sion, + acq_receipt_fiction_sion, acq_receipt_line_fiction_sion_data, ): """Load acq_receipt_line lib sion fiction record.""" @@ -609,9 +645,9 @@ def acq_order_line_fiction_martigny_data_tmp(acquisition): @pytest.fixture(scope="module") def acq_order_line_fiction_martigny( app, + acq_order_fiction_martigny, acq_account_fiction_martigny, document, - acq_order_fiction_martigny, acq_order_line_fiction_martigny_data, ): """Load acq_order_line lib martigny fiction record.""" @@ -684,6 +720,7 @@ def acq_order_line_fiction_saxon_data(acquisition): @pytest.fixture(scope="module") def acq_order_line_fiction_saxon( app, + document, acq_account_books_saxon, acq_order_fiction_saxon, acq_order_line_fiction_saxon_data, @@ -708,6 +745,7 @@ def acq_order_line_fiction_sion_data(acquisition): @pytest.fixture(scope="module") def acq_order_line_fiction_sion( app, + document, acq_account_fiction_sion, acq_order_fiction_sion, acq_order_line_fiction_sion_data, @@ -890,29 +928,17 @@ def acq_full_structure_a(client, lib_martigny, vendor_martigny, document, org_ma order_10 = _make_resource( client, "acor", - { - "vendor": {"$ref": vendor_ref}, - "library": {"$ref": lib_ref}, - "type": "monograph", - }, + {"vendor": {"$ref": vendor_ref}, "library": {"$ref": lib_ref}}, ) order_20 = _make_resource( client, "acor", - { - "vendor": {"$ref": vendor_ref}, - "library": {"$ref": lib_ref}, - "type": "monograph", - }, + {"vendor": {"$ref": vendor_ref}, "library": {"$ref": lib_ref}}, ) order_30 = _make_resource( client, "acor", - { - "vendor": {"$ref": vendor_ref}, - "library": {"$ref": lib_ref}, - "type": "monograph", - }, + {"vendor": {"$ref": vendor_ref}, "library": {"$ref": lib_ref}}, ) # OrderLines ========================================== orderline_10_1 = _make_resource( @@ -948,13 +974,24 @@ def acq_full_structure_a(client, lib_martigny, vendor_martigny, document, org_ma "amount": 33, }, ) + for order in [order_10, order_20, order_30]: + with mock.patch( + "rero_ils.modules.notifications.dispatcher.Dispatcher.dispatch_notifications", + mock.MagicMock(return_value={"sent": 1}), + ): + order.send_order( + [ + {"type": "to", "address": "ils@foo.com"}, + {"type": "reply_to", "address": "admin@foo.com"}, + ] + ) + # Reception =========================================== reception_10_1 = _make_resource( client, "acre", { "acq_order": {"$ref": get_ref("acor", order_10.pid)}, - "exchange_rate": 1, "amount_adjustments": [ { "label": "handling fees", @@ -970,7 +1007,6 @@ def acq_full_structure_a(client, lib_martigny, vendor_martigny, document, org_ma "acre", { "acq_order": {"$ref": get_ref("acor", order_30.pid)}, - "exchange_rate": 1, "library": {"$ref": lib_ref}, }, ) diff --git a/tests/ui/acq_invoices/test_acq_invoices_jsonresolver.py b/tests/ui/acq_invoices/test_acq_invoices_jsonresolver.py deleted file mode 100644 index d20eb068e6..0000000000 --- a/tests/ui/acq_invoices/test_acq_invoices_jsonresolver.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Acq order JSONResolver tests.""" - -import pytest -from invenio_records.api import Record -from jsonref import JsonRefError - -from rero_ils.modules.utils import extracted_data_from_ref - - -def test_acq_invoices_jsonresolver(acq_invoice_fiction_martigny): - """Acquisition invoices resolver tests.""" - rec = Record.create( - {"acq_invoice": {"$ref": "https://bib.rero.ch/api/acq_invoices/acin1"}} - ) - assert extracted_data_from_ref(rec.get("acq_invoice")) == "acin1" - # deleted record - acq_invoice_fiction_martigny.delete() - with pytest.raises(JsonRefError): - type(rec)(rec.replace_refs()).dumps() - - # non existing record - rec = Record.create( - {"acq_invoice": {"$ref": "https://bib.rero.ch/api/acq_invoices/n_e"}} - ) - with pytest.raises(JsonRefError): - type(rec)(rec.replace_refs()).dumps() diff --git a/tests/ui/acq_invoices/test_acq_invoices_mapping.py b/tests/ui/acq_invoices/test_acq_invoices_mapping.py deleted file mode 100644 index c5d121bc57..0000000000 --- a/tests/ui/acq_invoices/test_acq_invoices_mapping.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019 RERO -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Acquisition invoice record mapping tests.""" -from utils import get_mapping - -from rero_ils.modules.acquisition.acq_invoices.api import ( - AcquisitionInvoice, - AcquisitionInvoicesSearch, -) - - -def test_acq_invoices_es_mapping( - es, - db, - lib_martigny, - vendor_martigny, - acq_invoice_fiction_martigny_data, - document, - document_ref, - acq_order_fiction_martigny, - acq_order_line_fiction_martigny, - acq_order_line2_fiction_martigny, -): - """Test acquisition account elasticsearch mapping.""" - search = AcquisitionInvoicesSearch() - mapping = get_mapping(search.Meta.index) - assert mapping - invoice = AcquisitionInvoice.create( - acq_invoice_fiction_martigny_data, dbcommit=True, reindex=True, delete_pid=True - ) - assert mapping == get_mapping(search.Meta.index) - invoice.delete(force=True, dbcommit=True, delindex=True) diff --git a/tests/ui/acq_orders/test_acq_orders_api.py b/tests/ui/acq_orders/test_acq_orders_api.py index b4b3dc6838..4705ab6810 100644 --- a/tests/ui/acq_orders/test_acq_orders_api.py +++ b/tests/ui/acq_orders/test_acq_orders_api.py @@ -59,18 +59,6 @@ def test_order_properties( acol1["is_cancelled"] = False acol1.update(acol1, dbcommit=True, reindex=True) - # ORDER DATE -------------------------------------------------------------- - assert acor.order_date is None - - acol2["order_date"] = yesterday.strftime("%Y-%m-%d") - acol2.update(acol2, dbcommit=True, reindex=True) - assert acor.order_date == yesterday.strftime("%Y-%m-%d") - assert acor.status == AcqOrderStatus.ORDERED - - # reset changes - del acol2["order_date"] - acol2.update(acol2, dbcommit=True, reindex=True) - # NOTES ------------------------------------------------------------------- note_content = "test note content" assert acor.get_note(AcqOrderNoteType.VENDOR) is None diff --git a/tests/ui/acq_receipt_lines/test_acq_receipt_lines_api.py b/tests/ui/acq_receipt_lines/test_acq_receipt_lines_api.py index 2c1a357f6a..7c8dd05ae4 100644 --- a/tests/ui/acq_receipt_lines/test_acq_receipt_lines_api.py +++ b/tests/ui/acq_receipt_lines/test_acq_receipt_lines_api.py @@ -38,7 +38,6 @@ def test_receipt_lines_properties( # ORDER LINE -------------------------------------------------------------- assert acrl1.order_line_pid == acq_order_line_fiction_martigny.pid acol = acq_order_line_fiction_martigny - assert acol.receipt_date.strftime("%Y-%m-%d") == acrl1.get("receipt_date") # NOTE -------------------------------------------------------------------- assert acrl1.get_note(AcqReceiptLineNoteType.STAFF) diff --git a/tests/ui/acq_receipts/test_acq_receipts_api.py b/tests/ui/acq_receipts/test_acq_receipts_api.py index 6b517d6b7b..57d914b33c 100644 --- a/tests/ui/acq_receipts/test_acq_receipts_api.py +++ b/tests/ui/acq_receipts/test_acq_receipts_api.py @@ -24,28 +24,11 @@ from rero_ils.modules.utils import extracted_data_from_ref -def test_receipts_custom_validation( - acq_order_fiction_martigny, - acq_account_fiction_martigny, - acq_receipt_fiction_martigny, - acq_receipt_fiction_martigny_data, -): - """test receipts custom validations.""" - acre1 = acq_receipt_fiction_martigny - # TEST ADJUSTMENT AMOUNT WITH BAD DECIMALS -------------------------------- - acre1["amount_adjustments"][0]["amount"] = 1.000003 - with pytest.raises(ValidationError) as err: - acre1 = acre1.update(acre1, dbcommit=True, reindex=True) - assert "must be multiple of 0.01" in str(err) - - acre1["amount_adjustments"][0]["amount"] = -99999.990 - acre1 = acre1.update(acre1, dbcommit=True, reindex=True) - acre1.update(acq_receipt_fiction_martigny_data, dbcommit=True, reindex=True) - - def test_receipts_properties( - acq_order_fiction_martigny, acq_account_fiction_martigny, + acq_order_fiction_martigny, + acq_order_line_fiction_martigny, + acq_order_line2_fiction_martigny, acq_receipt_fiction_martigny, acq_receipt_line_1_fiction_martigny, acq_receipt_line_2_fiction_martigny, @@ -63,8 +46,7 @@ def test_receipts_properties( assert acre1.order_pid == acq_order_fiction_martigny.pid # NOTE -------------------------------------------------------------------- assert acre1.get_note(AcqReceiptNoteType.STAFF) - # EXCHANGE_RATE ----------------------------------------------------------- - assert acre1.exchange_rate + # AMOUNT ------------------------------------------------------------------ adj_amount = sum(adj.get("amount") for adj in acre1.amount_adjustments) wished_amount = sum([acrl1.total_amount, acrl2.total_amount, adj_amount]) @@ -85,3 +67,22 @@ def test_receipts_properties( assert all(pid in lines_pid for pid in acre1.get_receipt_lines("pids")) assert acre1.get_receipt_lines("count") == 2 + + +def test_receipts_custom_validation( + acq_order_fiction_martigny, + acq_account_fiction_martigny, + acq_receipt_fiction_martigny, + acq_receipt_fiction_martigny_data, +): + """test receipts custom validations.""" + acre1 = acq_receipt_fiction_martigny + # TEST ADJUSTMENT AMOUNT WITH BAD DECIMALS -------------------------------- + acre1["amount_adjustments"][0]["amount"] = 1.000003 + with pytest.raises(ValidationError) as err: + acre1 = acre1.update(acre1, dbcommit=True, reindex=True) + assert "must be multiple of 0.01" in str(err) + + acre1["amount_adjustments"][0]["amount"] = -99999.990 + acre1 = acre1.update(acre1, dbcommit=True, reindex=True) + acre1.update(acq_receipt_fiction_martigny_data, dbcommit=True, reindex=True) diff --git a/tests/ui/acq_receipts/test_acq_receipts_mapping.py b/tests/ui/acq_receipts/test_acq_receipts_mapping.py index e2ea556c50..f3265c67b5 100644 --- a/tests/ui/acq_receipts/test_acq_receipts_mapping.py +++ b/tests/ui/acq_receipts/test_acq_receipts_mapping.py @@ -17,6 +17,7 @@ # along with this program. If not, see . """Acquisition receipt record mapping tests.""" +import mock from utils import get_mapping from rero_ils.modules.acquisition.acq_receipts.api import AcqReceipt, AcqReceiptsSearch @@ -28,6 +29,7 @@ def test_acq_receipts_es_mapping( lib_martigny, vendor_martigny, acq_order_fiction_martigny, + acq_order_line_fiction_martigny, acq_account_fiction_martigny, acq_receipt_fiction_martigny_data, ): @@ -35,6 +37,16 @@ def test_acq_receipts_es_mapping( search = AcqReceiptsSearch() mapping = get_mapping(search.Meta.index) assert mapping + with mock.patch( + "rero_ils.modules.notifications.dispatcher.Dispatcher.dispatch_notifications", + mock.MagicMock(return_value={"sent": 1}), + ): + acq_order_fiction_martigny.send_order( + [ + {"type": "to", "address": "ils@foo.com"}, + {"type": "reply_to", "address": "admin@foo.com"}, + ] + ) receipt = AcqReceipt.create( acq_receipt_fiction_martigny_data, dbcommit=True, reindex=True, delete_pid=True ) diff --git a/tests/ui/vendors/test_vendors_api.py b/tests/ui/vendors/test_vendors_api.py index 474cdd1127..4bbb2c1985 100644 --- a/tests/ui/vendors/test_vendors_api.py +++ b/tests/ui/vendors/test_vendors_api.py @@ -44,9 +44,3 @@ def test_vendors_properties(vendor_martigny, vendor_sion): assert vendor_martigny.order_email == vendor_martigny.get_contact( VendorContactType.DEFAULT ).get("email") - - -def test_vendors_get_links_to_me(vendor_martigny, acq_invoice_fiction_martigny): - """Test vendors relations.""" - links = vendor_martigny.get_links_to_me(True) - assert acq_invoice_fiction_martigny.pid in links["acq_invoices"]