{"id":23122689,"url":"https://github.com/folio-org/mod-orders","last_synced_at":"2025-08-17T02:31:05.862Z","repository":{"id":33999095,"uuid":"144846100","full_name":"folio-org/mod-orders","owner":"folio-org","description":"Orders business logic module","archived":false,"fork":false,"pushed_at":"2024-10-29T12:46:34.000Z","size":8329,"stargazers_count":5,"open_issues_count":3,"forks_count":8,"subscribers_count":24,"default_branch":"master","last_synced_at":"2024-10-29T15:14:34.881Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/folio-org.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-15T11:43:30.000Z","updated_at":"2024-10-28T16:14:12.000Z","dependencies_parsed_at":"2024-03-04T11:44:19.714Z","dependency_job_id":"bf5a1428-370b-416d-9387-c76478c7c487","html_url":"https://github.com/folio-org/mod-orders","commit_stats":null,"previous_names":[],"tags_count":94,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/folio-org%2Fmod-orders","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/folio-org%2Fmod-orders/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/folio-org%2Fmod-orders/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/folio-org%2Fmod-orders/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/folio-org","download_url":"https://codeload.github.com/folio-org/mod-orders/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230080755,"owners_count":18169617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-17T07:29:47.560Z","updated_at":"2025-08-17T02:31:05.854Z","avatar_url":"https://github.com/folio-org.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mod-orders\n\nCopyright (C) 2018-2023 The Open Library Foundation\n\nThis software is distributed under the terms of the Apache License,\nVersion 2.0. See the file \"[LICENSE](LICENSE)\" for more information.\n\n## Introduction\n\nThis is the Orders business logic module.\n\n## Additional information\n\n### Additional Permissions Required\n * In case an acquisition unit has to be assigned to the Order it is required that user should have \n   `orders.acquisitions-units-assignments.assign` to create a purchase order\n * In case an acquisition unit has to be modified(added/deleted) in the order, the user should have\n   `orders.acquisitions-units-assignments.manage` to update a purchase Order\n * If the setting \"isApprovalRequired\" is set to true,an order approval is required to `OPEN` an order and the user should have\n   `orders.item.approve` permissions to `approve` an order\n\n### Purchase Order logic\nUpon receiving a request to create a PO, it does the following:\n* Validate PO content (vendor, acquisition units, settings based validation like order lines limit and etc.); then\n* Save a PO object in `Pending` status; then \n* Retrieve the `id` of the PO and pass that to the related PO lines; then\n* Save the PO lines; then\n* In case an order is in `Open` status and updates are required in the Inventory, it does the following:\n  * Find or create instance record; then\n  * Update PO lines with instance record identifier; then \n  * Find or create holding record; then\n  * Find or create item record per unit of physical/electronic quantity identified in the order line record\n  * Update a PO object; then \n* Retrieve the encumbrance transactions associated with each PO line based on fund distributions; then\n* Make the appropriate encumbrance transactions against the associated funds\n\nUpon receiving a request to update a PO, it does the following:\n* validate PO content (vendor, acquisition units, settings based validation like order lines limit and etc.); then\n* if provided PO doesn't contain PO Lines, just update the PO information via the `PUT /orders-storage/purchase-orders/\u003cid\u003e` endpoint\n* if provided PO contain PO Lines:\n  * Get the current list of PO Lines for this order; then\n  * Compare the provided list of PO Lines with what's in the database:\n    * if PO Line already exists, update it and any sub-objects\n    * if PO Line exists in the database, but not in the request, delete this PO Line\n    * if PO Line exists in the request but not in the database, create PO Line\n* In case an order's status changes from `Pending` to `Open` and updates are required in the Inventory, it does the following:\n  * Find or create instance record; then\n  * Update PO lines with instance record identifier; then \n  * Find or create holding record; then\n  * Find or create item record per unit of physical/electronic quantity identified in the order line record\n  * Update a PO object with `Open` status \n\nUpon receiving a request to delete a PO, it does the following:\n* Validate if PO is not restricted by acquisitions units or a user is a member of assigned units; then\n* Retrieve PO lines by the `id` of the PO and delete them; then\n* Delete PO\n\n### Purchase Order Line logic\nUpon receiving a request to create a PO Line, it does the following:\n* Validate PO Line content (interrelated fields, acquisition units based validation, settings based validation like order lines limit and etc.); then\n* Save a PO Line sub-objects in the storage; then \n* Save a PO Line content with references to the created sub-objects in the storage.\n\nUpon receiving a request to update a PO Line, it does the following:\n* Validate PO Line content (interrelated fields, acquisition units based validation and etc.); then\n* Retrieve PO Line data from storage; then\n* Validate that PO id of the PO Line from storage corresponds to order id in the path; then\n* Final step is to store the updated PO Line content with references to the created/updated sub-objects. The `PUT` request is being sent to [/orders-storage/po-lines/{id}](https://s3.amazonaws.com/foliodocs/api/mod-orders-storage/po-line.html#orders_storage_po_lines__id__put) endpoint.\n\nNote: the PO Line update might lead to Order's workflow status update (see [MODORDERS-218](https://issues.folio.org/browse/MODORDERS-218) for more details)\n\nUpon receiving a request to delete a PO Line, it does the following:\n* Validate if PO is not restricted by acquisitions units or a user is a member of assigned units; then\n* Retrieve PO line by the `id`; then\n* Validate that PO `id` of the PO Line corresponds to order id in the path; then\n* Delete PO Line and its sub-objects\n\n### Receiving logic \nUpon receiving a request to receive resources, it does the following:\n* Retrieve piece records from the orders storage based on the [request body](https://github.com/folio-org/acq-models/blob/master/mod-orders/schemas/receivingCollection.json).\n* For those pieces which have item id the process is like following:\n  * Retrieve items from inventory.\n  * Update item entities with barcode (if specified) and status\n  * Send PUT requests to inventory to update items. In case any errors happen while updating items, the logic just collects them and does not stop entire process\n* Update piece records with receiving information and send PUT requests to orders storage. If any errors happen, just collect them.  \n  The following is expected to be update in piece:\n  * `receivingStatus`: in case the `itemStatus` is `On order` the status is set to `Expected`, otherwise to `Received`\n  * `locationId`: from the request\n  * `receivedDate`: current date or `null` in case the `itemStatus` is `On order` \n* Retrieve all involved PO Lines from the storage and updates receipt status.\n  * If all pieces of an order line have been received, the receipt status is `Fully Received`. \n  * If more than one, but less than the total number of pieces have been received, it is `Partially Received`.\n  * If none received, it is `Awaiting Receipt`.\n  * If the calculated status is the same as current one, no update is made\n* Prepare [response](https://github.com/folio-org/acq-models/blob/master/mod-orders/schemas/receivingResults.json) to the client taking into account any error happened processing particular piece record.\n\nSample of the requests:\n  * Request to receive pieces for 2 PO Lines\n    ```json\n    {\n      \"toBeReceived\": [\n        {\n          \"poLineId\": \"0804ddec-6545-404a-b54d-a693f505681d\",\n          \"received\": 1,\n          \"receivedItems\": [\n            {\n              \"barcode\": \"0987654111\",\n              \"itemStatus\": \"Received\",\n              \"locationId\": \"fcd64ce1-6995-48f0-840e-89ffa2288371\",\n              \"pieceId\": \"cb9b0468-f2b4-4a13-b64c-662c4c9ec3ed\"\n            }\n          ]\n        },\n        {\n          \"poLineId\": \"7f0c4975-885e-47d5-8d5a-793dffbba9b2\",\n          \"received\": 1,\n          \"receivedItems\": [\n            {\n              \"barcode\": \"0987654333\",\n              \"itemStatus\": \"In transit\",\n              \"locationId\": \"758258bc-ecc1-41b8-abca-f7b610822ffd\",\n              \"pieceId\": \"20241b8c-9076-4cf5-817b-f2c1e2cb242f\"\n            }\n          ]\n        }\n      ],\n      \"totalRecords\": 2\n    }\n    ```\n  * Request to move a received piece back to `Expected`\n    ```json\n    {\n      \"toBeReceived\": [\n        {\n          \"poLineId\": \"f217a5c2-2c56-4d05-9412-a96cfc8e52de\",\n          \"received\": 1,\n          \"receivedItems\": [\n            {\n              \"itemStatus\": \"On order\",\n              \"pieceId\": \"56fbfde4-6335-4dd7-9a03-d100821f1d18\"\n            }\n          ]\n        }\n      ],\n      \"totalRecords\": 1\n    }\n    ```\n\nNote: receiving might lead to Order's workflow status update (see [MODORDERS-218](https://issues.folio.org/browse/MODORDERS-218) for more details)\n\n### Acquisitions units\nCRUD APIs are available to manage acquisitions units and memberships (user-unit relations).  \nIn order to avoid reference integrity issues when deleting acquisition units that are assigned to records, the logic implements a \"soft delete\" approach.\n* When client sends `DELETE /acquisitions-units/units/\u003cid\u003e`, the logic gets acquisitions unit by specified id and updates it setting `isDeleted` to `true`\n* When client sends `GET /acquisitions-units/units?query=\u003ccql\u003e` and `\u003ccql\u003e` does not contain criteria by `isDeleted`, the logic will search for records with `isDeleted==false`.\n* To get all the units regardless of `isDeleted` value, the request should be like `GET /acquisitions-units/units?query=isDeleted=* AND (\u003ccql\u003e)`\n\n### Kafka Integration\nduring tenant init, mod-orders creates producer with numPartitions which can be customized with env vars below:\n* DI_ORDER_CREATED_READY_FOR_POST_PROCESSING_PARTITIONS\n* DI_ORDER_CREATED_PARTITIONS\n* DI_PENDING_ORDER_CREATED_PARTITIONS\nDefault value is 1\n\n### Issue tracker\n\nSee project [MODORDERS](https://issues.folio.org/browse/MODORDERS)\nat the [FOLIO issue tracker](https://dev.folio.org/guidelines/issue-tracker).\n\n### Other documentation\n\nOther [modules](https://dev.folio.org/source-code/#server-side) are described,\nwith further FOLIO Developer documentation at\n[dev.folio.org](https://dev.folio.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffolio-org%2Fmod-orders","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffolio-org%2Fmod-orders","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffolio-org%2Fmod-orders/lists"}