{"item":[{"name":"Plan","description":"Planning — creating trips that take into account all the specified constraints, based on the data about orders, performers and transport.\n\n#### Data preparation\n\n* Preparing orders — all the orders that are ready for planning are converted for the required number of hours ahead.\n\n* Preparing resources — all the available resources (performers, transport) are converted.\n\n* After the data is sent to the server, the input data is cleansed automatically, and only valid data is passed to planning. To get the result of cleansing the original task, use data cleansing for planning.\n\n#### Running the planner\n\n* Calling the planning method — the prepared json (which contains Orders and Resources) and the authorization token (api_key) are passed to the planning method.\n\n* Error handling — if the response code differs from 200, the error must be handled: its number and details are returned in the response to the request.\n\n* Getting the response — if the response code equals 200, the received data must be saved for further processing.\n\n#### Processing the result\n\n* Trips — the structure contains the assignments of orders to performers.\n\n* Statistics — the structure contains general statistical information about all the trips.\n\n* Validations — the structure contains information about the validity of the input data.\n\n### Modes\n\nPlanning requests can be executed in synchronous and asynchronous modes.\n\n#### Synchronous\n\n\"plan_sync\"\n\nIn the synchronous mode the result is returned in the response to the input data.\n\nThis mode is recommended **only for development and testing** on small tasks (up to 100 entities, up to 1 minute of planning).\n\n#### Asynchronous\n\n\"plan_async\"\n\nIn the asynchronous mode the response to the data contains the identifier of the solution, which can be used to get the current execution progress and, if the planning is finished, the planning result.\n\nThis mode is recommended for use in the main system.","item":[{"id":"caba5bf7-46b5-5e96-8285-541c009ec9e1","name":"Planning (ASYNC)","request":{"name":"Planning (ASYNC)","description":{"content":"Starting trip planning - after loading and checking the data, the `process_code` is returned.\n\nUsing the `process_code`, you can find out calculation state and get result,\nand also cancel calculation and delete temporary data (otherwise they will be automatically deleted according to the ttl specified in the calculation settings).","type":"text/plain"},"url":{"path":["universal","plan","calculation-async"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"436941e1-d2dd-58ac-aff7-19fb5b527bb3","name":"Planning (SYNC)","request":{"name":"Planning (SYNC)","description":{"content":"Sync method for trip planning.\n\nUse only for testing and manual plannings.\n\nFor production use async method.","type":"text/plain"},"url":{"path":["universal","plan","calculation"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"2f080404-7b88-5ed2-a39b-720bbcf87f3b","name":"Cancel calculation","request":{"name":"Cancel calculation","description":{"content":"Cancel calculation by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","plan","calculation-async",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[],"method":"DELETE","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"debfa6bf-894c-545e-a5be-bbc7ebc2b76c","name":"Calculation state","request":{"name":"Calculation state","description":{"content":"Read calculation state by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","plan","state",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"e73f18ca-cd6b-58ff-9287-573323564e77","name":"Getting the result","request":{"name":"Getting the result","description":{"content":"Getting the planning result based on the calculation identifier.","type":"text/plain"},"url":{"path":["universal","plan","result",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"170b719c-3ba1-55bf-8629-006041ff0993","name":"Result removal","request":{"name":"Result removal","description":{"content":"Removal of the planning result by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","plan","result",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[],"method":"DELETE","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"e512924f-02d0-55d0-8ac3-aa98024ef9c0","name":"Data validation","request":{"name":"Data validation","description":{"content":"Check data before using.","type":"text/plain"},"url":{"path":["universal","plan","validation"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"a953ddcf-203a-5b80-9dcf-d35b0ce6dc4d","name":"Data refine","request":{"name":"Data refine","description":{"content":"Cleaning up data for planning before calculation - entities that cannot participate in planning are removed from the original dataset:\n * Locations that no one references (depending on the `remove_locations` flag)\n * Orders that no performer can fulfill\n * Performers and transport that cannot fulfill any order","type":"text/plain"},"url":{"path":["universal","plan","refine"],"host":["{{baseUrl}}"],"query":[{"key":"remove_locations","value":"true","disabled":true,"description":{"content":"Flag responsible for deleting a location when cleaning data. If `true` is specified, locations that are not referenced by any entity in the dataset are deleted.","type":"text/plain"}}],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"48fa5cac-415a-5c41-8263-905b52f5cc57","name":"Calculation of statistics on trips","request":{"name":"Calculation of statistics on trips","description":{"content":"Calculation of statistics for existing trips","type":"text/plain"},"url":{"path":["universal","plan","statistics"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}}]},{"name":"Replan","description":"Replanning — creating new trips on the basis of already existing trips, taking facts into account.\n\n### Stages\n\nReplanning runs in several stages:\n\n1. validation, can be called separately via data validation.\n2. cleanup, applying facts and creating planning constraints based on the existing trips, can be called separately via data refinement.\n3. planning, can be called separately via planning.\n\n### Settings\n\nDepending on the replanning settings, the task can be reduced to planning (when everything is allowed: `reorder: true, plan_new_orders: true, create_new_trips: true`) or to updating travel times between orders (when everything is forbidden: `reorder: false, plan_new_orders: false, create_new_trips: false`).\n\n### Accounting for existing trips\n\n* Trips are transformed into `hardlink` assignments — i.e. the performer and transport shifts assigned to a trip cannot be used in other trips.\n* For demands that were planned in the source trips, the alternative possible events are removed and the execution sequence is fixed via `precedence_in_trip`; if these demands already had an execution sequence specified, it will be overwritten.\n* Orders from a trip that can no longer be performed remain assigned to the performer and end up in the `waitlist`.\n* If the `replan_settings.replan_strategy.allow_possible_events` strategy is disabled, all possible events except the planned one are removed.\n\n### Accounting for the current time\n\n* If the current time `actualize_settings.current_time` is not set in the data, the time when the server received the request is used.\n* If the current time is greater than the left boundary of the time windows of all events and shifts, then the left boundary is shifted to the current time.\n* The allowed lateness `actualize_settings.max_delay_duration` is added to the right boundary of the time windows of all events and shifts.\n* If a performer has several shifts, the right boundary of a shift is extended to the start of the next shift, since shifts cannot overlap.\n* Soft time windows are adjusted only if the demand duration does not allow the order to be performed within the soft window.\n\n### Accounting for facts\n\n* Only facts that occurred before `actualize_settings.current_time` (by the `time` field) are taken into account, no matter how long before the current time the fact occurred.\n* When there are several facts (of the same type and referencing the same entities), only the latest one by the `time` field is taken into account.\n* If the list of facts is empty, only existing trips and the current time are accounted for.\n\n#### Accounting for the location-change fact `GEOTRACK_UPDATED`\n\n* To account for the fact, the `locations` list must contain a location (existing or new) that describes the performer's new location.\n* If the trip has started (the fact time is later than the planned trip start time), the transport is considered to be in the same location as the performer — i.e. the `start_location_key` of both the performer and the transport is changed.\n* If the trip has not started (the fact time is before the planned trip start time), only the performer's start location is changed; the transport location stays as in the source data.\n\n#### Accounting for the order-completion fact `ORDER_DONE`\n\n* The order, its demands and the locations associated with them (if no other entities reference them) are removed from the data being actualized.\n* The cargo is considered unloaded from the transport.\n\n#### Accounting for the demand-start facts `DEMAND_START`\n\n* Only one open `DEMAND_START` fact is allowed per trip (it is closed by a `DEMAND_DONE` fact) — since a performer can perform only one demand at a time.\n* The remaining work time for the demand is reduced by the time already spent on it (computed as the length of the interval between the `DEMAND_START` fact and `actualize_settings.current_time`).\n* If there is a fact about working on a demand that contradicts the planned sequence in the specified trip, this demand will be completed first, then the trip will continue according to the planned sequence.\n* An order fact has higher priority than facts about the demands of that order (if demand facts contradict the order fact, they will not be taken into account).\n\n#### Accounting for the partial-order-completion facts `DEMAND_DONE`\n\n* If all of an order's demands are completed, it is considered finished (the actions are the same as for processing the `ORDER_DONE` fact).\n* If a demand of type `WORK` is completed, the demand is removed from the order.\n* If a demand of type `DROP` is completed, the demand and its cargo, as well as the corresponding demand of type `PICKUP`, are removed from the order.\n* If a demand of type `DROP_FROM_BOX` is completed, the demand and its cargo are removed from the order.\n* If a demand of type `PICKUP` is completed for an order, the corresponding demands of type `DROP` will be converted into demands of type `DROP_FROM_BOX`.\n* If a demand of type `PICKUP_TO_BOX` is completed, the demand and its cargo are removed and the capacity of the corresponding transport box is reduced (compatibilities are not changed in this case).\n\n#### Accounting for the trip-completion facts `TRIP_DONE`\n\n* If all orders on a trip are fulfilled, it is considered complete (the actions are similar to processing the `TRIP_DONE` fact).\n* A completed trip is returned as a result of replanning with an empty `states` list.","item":[{"id":"0ecd2de4-6a73-5d72-b2de-f28176ee5169","name":"Replanning (ASYNC)","request":{"name":"Replanning (ASYNC)","description":{"content":"Starting trip replanning - changing existing and creating new trips based on the facts and data about orders, performers and transport.\n \nAfter loading and checking the data, the `process_code` is returned.\n\nUsing the `process_code`, you can find out calculation state and get result,\nand also cancel calculation and delete temporary data (otherwise they will be automatically deleted according to the ttl specified in the calculation settings).\n\nAn replan task can be transformed into a plan task using data processing.","type":"text/plain"},"url":{"path":["universal","replan","calculation-async"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"7a134490-690d-57d2-a7a4-679fd56e8165","name":"Replanning (SYNC)","request":{"name":"Replanning (SYNC)","description":{"content":"Sync method for trips replanning.\n\nUse only for testing and manual plannings.\n\nFor production use async method.","type":"text/plain"},"url":{"path":["universal","replan","calculation"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"f780f283-ef0e-581e-9d76-8f33487051fc","name":"Cancel calculation","request":{"name":"Cancel calculation","description":{"content":"Cancel calculation by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","replan","calculation-async",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[],"method":"DELETE","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"161cda38-1696-53c0-8dcc-dd2500ab5afc","name":"Calculation state","request":{"name":"Calculation state","description":{"content":"Read calculation state by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","replan","state",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"9896d55c-6302-508d-9e28-907719d9ad3e","name":"Getting the result","request":{"name":"Getting the result","description":{"content":"Getting the replanning result based on the calculation identifier.","type":"text/plain"},"url":{"path":["universal","replan","result",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"c65bbc2e-eeb9-5891-865b-f3aa70634d81","name":"Result removal","request":{"name":"Result removal","description":{"content":"Removal of the planning result by the calculation identifier.","type":"text/plain"},"url":{"path":["universal","replan","result",":process_code"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"11111111-2222-3333-4444-555555555555","key":"process_code","disabled":false,"description":{"content":"(Required) Unique process identifier.","type":"text/plain"}}]},"header":[],"method":"DELETE","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"6c5471b0-14de-53cb-b050-4b707c21a407","name":"Data validation","request":{"name":"Data validation","description":{"content":"Check data before using.","type":"text/plain"},"url":{"path":["universal","replan","validation"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"65be57db-682d-54bf-b079-cade64268d34","name":"Data refine","request":{"name":"Data refine","description":{"content":"Cleaning up data for re-planning before calculation:\n * If one entity is referenced by several facts, only the latest one by the time field is taken into account; if the time is the same, a random one is taken into account.\n * All facts that occurred later than `actualize_settings.current_time` are deleted.\n * If `plan_new_orders: false` is specified - all orders that are not in the specified trips are removed from the original task.\n * If `create_new_trips: false` is specified - all performers and transport that are not in the specified trips are removed from the original task, and unplanned shifts of performers and transport that are in the specified trips are also removed.\n * Afterwards, cleaning up data for planning is performed.\n\nAs a result, a task for planning is returned.","type":"text/plain"},"url":{"path":["universal","replan","refine"],"host":["{{baseUrl}}"],"query":[{"key":"remove_locations","value":"true","disabled":true,"description":{"content":"Flag responsible for deleting a location when cleaning data. If `true` is specified, locations that are not referenced by any entity in the dataset are deleted.","type":"text/plain"}}],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}}]},{"name":"Convert","description":"Data conversion.","item":[{"id":"21ddcbd4-3c18-5bac-85d6-b04110dc7803","name":"JSON >> XLSX","request":{"name":"JSON >> XLSX","description":{"content":"Used for conversion of data to the VRt.Universal XLSX format.","type":"text/plain"},"url":{"path":["universal","convert","json-to-xlsx"],"host":["{{baseUrl}}"],"query":[{"key":"timezone","value":"3","disabled":true,"description":{"content":"Target time zone.","type":"text/plain"}}],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/octet-stream"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"8885c878-cf9f-57b6-be37-2e310f4afdb1","name":"XLSX >> JSON","request":{"name":"XLSX >> JSON","description":{"content":"Used for data conversion from the VRt.Universal XLSX format to the VRt.Universal JSON format.","type":"text/plain"},"url":{"path":["universal","convert","xlsx-to-json"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/octet-stream"},{"key":"Accept","value":"application/json"}],"method":"POST","body":{"mode":"raw","raw":""},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"2e518c71-ea39-51d2-93e5-ee7203c06f97","name":"JSON >> THRIFT","request":{"name":"JSON >> THRIFT","description":{"content":"Used for conversion of input data to the THRIFT format.","type":"text/plain"},"url":{"path":["universal","convert","json-to-thrift"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"text/plain"}],"method":"POST","body":{"mode":"raw","raw":"","options":{"raw":{"headerFamily":"json","language":"json"}}},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}}]},{"name":"System","description":"System functions.\nAuxiliary functionality common to all services.","item":[{"id":"40721c5a-4e3f-578a-b651-8eed44a85c02","name":"Checking the availability","request":{"name":"Checking the availability","description":{"content":"Checking the service availability.","type":"text/plain"},"url":{"path":["universal","system","check"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"9844d4f0-fb45-5b6c-9fae-f305732913fe","name":"Getting the service version","request":{"name":"Getting the service version","description":{"content":"Getting the service version.","type":"text/plain"},"url":{"path":["universal","system","version"],"host":["{{baseUrl}}"],"query":[],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}},{"id":"ef12ce94-8885-5cb5-8633-7a30f732c107","name":"Getting the documentation","request":{"name":"Getting the documentation","description":{"content":"Getting the file with this service documentation.","type":"text/plain"},"url":{"path":["universal","file",":filename"],"host":["{{baseUrl}}"],"query":[],"variable":[{"type":"any","value":"file_en.html","key":"filename","disabled":false,"description":{"content":"(Required) File name.","type":"text/plain"}}]},"header":[{"key":"Accept","value":"text/html"}],"method":"GET","body":{},"auth":null},"response":[],"event":[],"protocolProfileBehavior":{"disableBodyPruning":true}}]}],"auth":{"type":"bearer","bearer":[{"type":"any","value":"{{bearerToken}}","key":"token"}]},"event":[],"variable":[{"key":"baseUrl","value":"https://api.edge7.veeroute.cloud"}],"info":{"_postman_id":"3a36da42-4fd0-59eb-bb95-b1fbc8fb676b","name":"VRt.Universal [UV]","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json","description":{"content":"# Description\n\nProgramming interface for universal trip planning.\n\n## Capabilities\n\n* Ability to pick up cargo from any location\n* Ability to drop off cargo at any location\n* Paired demands of several types: `PICKUP` (loading), `DROP` (unloading)\n* Single demands of several types: `DROP_FROM_BOX` (unloading of cargo that is already in the box), `PICKUP_TO_BOX` (picking up cargo into the box without subsequent unloading), `WORK` (work at a location without moving cargo)\n* A complex order may consist of any number of demands of any types\n* Transport and performers are split into separate entities; during planning, an optimal assignment of a performer to a transport is performed\n* Transport has multiple boxes — each of which can hold cargo and has its own characteristics\n* Compatibility check between cargo and transport based on cargo dimensions (length, width, height, additional capacity parameters)\n* Compatibility check between cargo and transport box (allowing to take into account box features: refrigerator, thermo bag, fasteners, etc.)\n* Replacement demands — i.e. the ability to perform one of several substitute demands, the choice being made based on the demand's geographic location and time window\n\n## Supported constraints\n\nConstraints on a **performer**:\n\n* Start/finish location\n* Accounting for the performer's travel to the transport's start point\n* Performer availability schedule — a list of time windows during which the performer can travel and perform work at locations\n* Maximum work duration of the performer within a given time period\n\nConstraints on **transport**:\n\n* Start/finish location\n* Transport availability schedule — a list of time windows during which the transport can travel\n* Maximum route length\n* Multiple boxes in the transport, each with its own parameters\n* Upper limit on summed capacities (mass, volume, number of orders, number of demands)\n\nConstraints on an **order**:\n\n* Hard time windows\n* Ability to specify different allowed location work windows and desired demand execution windows\n* Order of demand execution within a route\n* List of desired execution time windows with different costs for each of them\n\n## Compatibilities used\n\nEntities are compatible if the list of features of one entity fully covers the list of restrictions of another entity (the opposite for `performer_blacklist` — the lists must not overlap).\n\nSupported compatibilities:\n\n| Name | Restrictions | Features |\n|-------------------------|----------------------------------|------------------------------|\n| Order – Performer | order.performer_restrictions | performer.performer_features |\n| Order – Not-Performer | order.performer_blacklist | performer.performer_features |\n| Cargo – Box | order.cargo.box_restrictions | transport.box.box_features |\n| Location – Transport | location.transport_restrictions | transport.transport_features |\n| Transport – Performer | transport.performer_restrictions | performer.performer_features |\n| Performer – Transport | performer.transport_restrictions | transport.transport_features |\n| Order – Order | order.order_restrictions | order.order_features |\n| Cargo – Cargo | cargo.cargo_restrictions | cargo.cargo_features |\n\nExamples of business rules:\n\n| Name | Example business rule |\n|-------------------------|--------------------------------------------------------------------------------------------------------|\n| Order – Performer | To perform the order the driver must have a special permit |\n| Order – Not-Performer | The driver is on the blacklist |\n| Cargo – Box | A box with a special temperature mode is required to transport frozen products |\n| Location – Transport | Restrictions on transport height |\n| Transport – Performer | For freight transport the driver must hold category `C` |\n| Performer – Transport | The driver is allowed to work only on a specific transport |\n| Order – Order | Fish and fruit cannot be transported in the same box |\n| Cargo – Cargo | Two cargos cannot be placed simultaneously in the same transport box, but can be placed sequentially |\n\n## Hardlinks\n\nThe hardlinks mechanism (`hardlinks`) is used to specify requirements for orders, a performer and a transport to be in the same trip.\n\nA hardlink guarantees that the entities are in the same trip and does not guarantee that the entity is actually planned.\nFor example, if the performer cannot complete the order in time, the order will not be planned, but it will still be assigned to the trip (it will end up in `waitlist`).\n\nA hardlink also does not cancel the specified compatibilities (and the penalties for compatibility violations).\nFor example, if an order cannot be performed by the performer, it will not be planned but will be assigned to the trip (it will end up in `waitlist`).\n\n## Cargo placement in the box\n\nList of an object's rotation capabilities (in 90-degree increments):\n\n* `ALL` — can be rotated around any axis any number of times\n* `YAW` — can be rotated once around the vertical axis (around its own axis)\n* `PITCH` — can be rotated once around the transverse axis (set vertically)\n* `ROLL` — can be rotated once around the longitudinal axis (laid on its side)\n\n## Trip model\n\nA trip is described by a list of performer states; a performer can be in several states at the same time (e.g. be inside a location's working time window and at the same time perform an order at the same location).\n\nValues of the flags responsible for the geographic position (multiple flags may be active at the same time):\n\n* `AROUND_LOCATION` — the performer is near the location, in the process of parking or leaving it.\n* `INSIDE_LOCATION` — the performer is at the location.\n\nValues of the flags responsible for being inside time windows (multiple flags may be active at the same time):\n\n* `INSIDE_WORKING_WINDOW` — the performer is inside the working time window.\n* `INSIDE_LOCATION_WINDOW` — the performer is inside the location's operating time.\n* `INSIDE_EVENT_HARD_WINDOW` — the performer is inside the hard time window.\n* `INSIDE_EVENT_SOFT_WINDOW` — the performer is inside the soft time window.\n\nValues of the flags responsible for actions (only one flag can be active at a time):\n\n* `ON_DEMAND` — the performer started working on a demand.\n* `WAITING` — the performer started waiting.\n* `RELOCATING` — the performer started moving to the next stop.\n* `BREAK` — the performer started a break.\n* `REST` — the performer started a long rest.\n* `ARRIVAL` — the performer started parking.\n* `DEPARTURE` — the performer finished leaving the parking.\n\nValues of the flags responsible for the logical state:\n\n* `DURING_ROUNDTRIP` — the performer is performing a round trip.\n\n### Example route with multiple states at every moment in time\n\n| Time | Set of active flags | Location / Order / Demand / Event | Comment |\n|:------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------|:-----------------------------------------------------------------|\n| 10:00 | INSIDE_LOCATION
AROUND_LOCATION | 2 / - / - / - | Start location |\n| 10:05 | AROUND_LOCATION
DEPARTURE | 2 / - / - / - | Left the parking |\n| 10:10 | RELOCATING
DEPARTURE | 2 / - / - / - | Driving to the first order |\n| 10:20 | AROUND_LOCATION
ARRIVAL | 2 / - / - / - | Arrived at the first order |\n| 10:40 | AROUND_LOCATION
INSIDE_LOCATION
WAITING | 2 / - / - / - | Parked |\n| 11:00 | AROUND_LOCATION
INSIDE_LOCATION
INSIDE_LOCATION_WINDOW
WAITING
INSIDE_EVENT_HARD_WINDOW | 2 / - / - / - | The location's window opened and the order became available |\n| 11:25 | AROUND_LOCATION
INSIDE_LOCATION
INSIDE_LOCATION_WINDOW
ON_DEMAND
INSIDE_WORKING_WINDOW
INSIDE_EVENT_HARD_WINDOW | 2 / 1 / 2 / 3 | Waited for a performer change |\n| 11:30 | AROUND_LOCATION
INSIDE_LOCATION
INSIDE_LOCATION_WINDOW
ON_DEMAND
INSIDE_WORKING_WINDOW
INSIDE_EVENT_HARD_WINDOW
INSIDE_EVENT_SOFT_WINDOW | 2 / 1 / 2 / 3 | While working — a soft window opened |\n| 11:40 | AROUND_LOCATION
INSIDE_LOCATION
INSIDE_LOCATION_WINDOW
INSIDE_WORKING_WINDOW | 2 / - / - / - | Finished working |\n| 11:45 | AROUND_LOCATION
DEPARTURE
INSIDE_WORKING_WINDOW | 2 / - / - / - | Left the parking |\n| 11:45 | RELOCATING
INSIDE_WORKING_WINDOW | - / - / - / - | Driving to the next order |\n\n## Round trips\n\nA trip consists of one or more round trips.\n\nThe round-trip flag `DURING_ROUNDTRIP` is set when work on a demand starts and is removed in one of three cases:\n\n* the performer arrived at the next location to stop using the transport\n* the performer arrived at a location that separates round trips\n* the performer stopped using the transport (in a location that does not separate round trips, after performing some other action)\n\nBetween the end of one round trip and the beginning of another there can be no `RELOCATING` change of location, but the following can occur: `WAITING`, performer's `BREAK`, performer's `REST`.\n\nA location separates a trip into round trips in one of two cases:\n\n* if the location has a throughput limit `timetable.limits` (in this case there can be more than one location separating the trip)\n* if the location is simultaneously the start and finish location of all performers and transports, as well as of all `PICKUP`-type demands (in this case there will be only one location separating the trip)\n\nExamples of such locations (depending on the problem statement) include:\n\n* distribution centers when delivering goods to stores or warehouses for long-haul transportation tasks\n* stores or warehouses when delivering goods to customers in last-mile tasks\n* dumps in waste collection tasks\n\n## Planning configuration\n\nFor each planning run it is possible to specify a planning configuration that defines the objective function, the desired route quality, and the calculation speed.\n\nThe configuration name is passed in the `trips_settings.configuration` field.\n\nMain configurations:\n\n| Name | Goal |\n|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **optimize_distance** | Place as many orders as possible, then optimize the total mileage (the number of transports is chosen based on the mileage); used by default |\n| **optimize_transports** | Place as many orders as possible, while using as little transport as possible; all else being equal, optimize the working time of performers |\n| **optimize_locality_grouping** | Place as many orders as possible, while striving to optimize visual route grouping but not the number of routes |\n| **optimize_cars_then_distance** | Place as many orders as possible, then optimize the number of transports, then the mileage |\n| **optimize_time** | Place as many orders as possible, then optimize the total working time of performers |\n| **optimize_cars_then_time** | Place as many orders as possible, then optimize the number of transports, then the total working time of performers |\n| **optimize_money** | Optimize \"reward for completing orders − costs\"; consists of rewards for demands and the costs of performers and transports (the optimized value is non-negative) |\n\nAdditional configurations:\n\n| Name | Goal |\n|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **visual_grouping** | Place as many orders as possible, while using as little transport as possible, with visually grouped routes |\n| **optimize_visual_grouping** | Place as many orders as possible, then evenly distribute orders taking transport accessibility zones into account (similar to visual_grouping but visual grouping is computed differently) |\n| **optimize_cars_then_locality_grouping** | Place as many orders as possible, then optimize the number of transports, then the visual route grouping |\n| **optimize_cars_then_single_location_grouping_sequenced** | Place as many orders as possible, then optimize the number of cars, then reliability |\n\nIn addition to the existing planning options, an objective function can be created specifically for a client's business processes (request a configuration).\n\nFor development we recommend using **optimize_cars_then_distance**, as this configuration does not require fine-tuning of tariffs and order costs.\n\n## Data validation\n\nValidation of input data consists of several stages described below.\n\n### 1. Schema check\n\nIf a request does not pass schema validation, planning is not started at all and such an error is returned together with code 400 in `schema_errors`.\n\nWe recommend validating the request against the schema (or the yaml file) before sending it to the server.\n\n### 2. Check for logical errors that prevent planning from continuing\n\nData that is correct against the schema goes through the second validation stage to determine whether planning can be started.\n\nExamples of errors at this stage are keys pointing to empty entities, or all orders being incompatible with all performers — i.e. anything that makes the planning task meaningless.\n\nThese errors are returned together with code 400 in `logical_errors`.\n\n### 3. Check for logical errors that prevent planning from continuing\n\nAt the third stage each entity is checked individually.\n\nAll entities that fail the check are removed from the original task and are not sent to planning.\n\nDepending on the `treat_warnings_as_errors` setting, the results of this type of check are returned in `warnings` together with code 400, or together with the planning result.\n\n### 4. Checks during planning\n\nSome checks can only be performed during planning.\n\nFor example — that according to the specified tariffs and the current traffic forecast it is physically impossible to drive to a particular point.\n\nThe results of these checks are returned in `warnings` together with the planning result.\n\nContact Support:\n Name: Veeroute Support Team\n Email: support@veeroute.com","type":"text/plain"}}}