{
 "openapi": "3.0.3",
 "info": {
  "title": "DMO warehouse system (Demo Surf)",
  "version": "1.0.0",
  "description": "The warehouse system behind Demo Surf's screens: logon, printers, goods receipt. Fictional data. Every request but logon and password change carries a user of the system (HTTP Basic)."
 },
 "servers": [
  {
   "url": "https://wms.dev.aicoflow.com"
  }
 ],
 "security": [
  {
   "basic": []
  }
 ],
 "components": {
  "securitySchemes": {
   "basic": {
    "type": "http",
    "scheme": "basic"
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "object",
      "properties": {
       "status": {
        "type": "integer"
       },
       "code": {
        "type": "string"
       },
       "message": {
        "type": "string"
       }
      }
     }
    }
   }
  }
 },
 "paths": {
  "/api/logon": {
   "post": {
    "operationId": "logon",
    "summary": "Checks a logon as the logon screen does: client, user, password, language",
    "description": "Answers the user, warehouse and resource. Logon messages are German.",
    "tags": [
     "Logon"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "security": [],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "client",
         "user",
         "password"
        ],
        "properties": {
         "client": {
          "type": "string",
          "description": "Client (Mandant)"
         },
         "user": {
          "type": "string",
          "description": "User"
         },
         "password": {
          "type": "string",
          "description": "Password"
         },
         "language": {
          "type": "string",
          "description": "Logon language code (DE, EN)"
         },
         "formAgeMs": {
          "type": "integer",
          "description": "How long the logon form had stood open, in ms (its cookie runs out after 5 minutes)"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/password": {
   "post": {
    "operationId": "changePassword",
    "summary": "Changes a user's password",
    "description": "It lasts until the service is reset.",
    "tags": [
     "Logon"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "security": [],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "user",
         "password",
         "newPassword",
         "repeat"
        ],
        "properties": {
         "user": {
          "type": "string",
          "description": "User"
         },
         "password": {
          "type": "string",
          "description": "Current password"
         },
         "newPassword": {
          "type": "string",
          "description": "New password, at least 4 characters"
         },
         "repeat": {
          "type": "string",
          "description": "New password again"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/logoff": {
   "post": {
    "operationId": "logoff",
    "summary": "Logs off: a posting the user left waiting for an exception code is dropped",
    "tags": [
     "Logon"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/printers/{printer}": {
   "get": {
    "operationId": "printer",
    "summary": "Checks a printer and answers it",
    "tags": [
     "Printers"
    ],
    "parameters": [
     {
      "name": "printer",
      "in": "path",
      "required": true,
      "description": "Printer",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The printer.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "printer": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/goods-receipt/lookup": {
   "get": {
    "operationId": "lookup",
    "summary": "What a code scanned into \"LB / HU / Picket\" is: an inbound delivery, an HU to book (refused when fully posted) or the open item a picket names",
    "description": "`kind` says which.",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "code",
      "in": "query",
      "required": true,
      "description": "The scanned code",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "`kind` is delivery, hu or item; then the delivery, or the HU (and the item).",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "kind": {
           "type": "string"
          },
          "delivery": {
           "type": "object"
          },
          "hu": {
           "type": "object"
          },
          "item": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/deliveries/{delivery}": {
   "get": {
    "operationId": "delivery",
    "summary": "An inbound delivery (LB), its supplier and its HUs with how many items each has open",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "delivery",
      "in": "path",
      "required": true,
      "description": "Inbound delivery (LB)",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/deliveries/{delivery}/hus/{hu}": {
   "get": {
    "operationId": "deliveryHu",
    "summary": "An HU scanned on its delivery: refused when it is not one of the delivery's, or fully posted",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "delivery",
      "in": "path",
      "required": true,
      "description": "Inbound delivery (LB)",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "hu",
      "in": "path",
      "required": true,
      "description": "HU",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/hus/{hu}": {
   "get": {
    "operationId": "hu",
    "summary": "An HU and its items, booked or open",
    "description": "An HU due for quality inspection carries a `warning`.",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "hu",
      "in": "path",
      "required": true,
      "description": "HU",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The HU: delivery, supplier, items (booked or not), how many are open, `complete`.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "hu": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/hus/{hu}/items/{picket}": {
   "get": {
    "operationId": "item",
    "summary": "The item of an HU a picket names (its product number, with or without hyphens, or the item number); refused when it is not on the HU or posted already",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "hu",
      "in": "path",
      "required": true,
      "description": "HU",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "picket",
      "in": "path",
      "required": true,
      "description": "Picket: product number (with or without hyphens) or item number",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The HU and the item: position, product, description, planned quantity, unit.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "hu": {
           "type": "object"
          },
          "item": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/goods-receipt/postings": {
   "post": {
    "operationId": "postGoodsReceipt",
    "summary": "Books one item of an HU with the quantity counted, checked as the screens check it: printer, HU, picket, quantity",
    "description": "A quantity short of the planned one needs an exception code: given with `exception` it books at once; without one the posting is held for the user (409 `exception_required`, `held`) until POST /api/goods-receipt/held gives the code. `hold` holds it at any quantity. Booking the last open item of an HU closes the HU, the last HU of a delivery the delivery: `message` then says so, `hu.complete` and `delivery.complete` are true.",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Booked. `message` is what the screen shows: the item booked, then \"HU … vollständig gebucht\" when it was the HU's last open item, then the delivery when that was its last HU (`said` the same, line by line). `posting` is the posting made, `hu` and `delivery` as they stand now (`complete`).",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "message": {
           "type": "string"
          },
          "said": {
           "type": "array"
          },
          "posting": {
           "type": "object"
          },
          "hu": {
           "type": "object"
          },
          "delivery": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "printer",
         "hu",
         "picket"
        ],
        "properties": {
         "printer": {
          "type": "string",
          "description": "Printer the labels go to"
         },
         "hu": {
          "type": "string",
          "description": "HU"
         },
         "picket": {
          "type": "string",
          "description": "Picket: the product number, with or without hyphens, or the item number"
         },
         "quantity": {
          "type": "string",
          "description": "Quantity counted, a whole number, at most the planned quantity. Left out: the planned quantity, as the screen proposes it"
         },
         "exception": {
          "type": "string",
          "description": "Exception code: 01 short quantity (only below the planned quantity), 02 damaged, 03 wrong product"
         },
         "hold": {
          "type": "boolean",
          "description": "Hold the posting for an exception code at any quantity"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/goods-receipt/held": {
   "get": {
    "operationId": "held",
    "summary": "The user's posting waiting for an exception code",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "`held`: the HU, the item, the quantity counted and the exception code the screen presets (`preset`).",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "held": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "operationId": "postHeldWithException",
    "summary": "Books the user's held posting with the exception code given",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Booked. `message` is what the screen shows: the item booked, then \"HU … vollständig gebucht\" when it was the HU's last open item, then the delivery when that was its last HU (`said` the same, line by line). `posting` is the posting made, `hu` and `delivery` as they stand now (`complete`).",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "message": {
           "type": "string"
          },
          "said": {
           "type": "array"
          },
          "posting": {
           "type": "object"
          },
          "hu": {
           "type": "object"
          },
          "delivery": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "exception"
        ],
        "properties": {
         "exception": {
          "type": "string",
          "description": "Exception code: 01 short quantity, 02 damaged, 03 wrong product"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/hus/{hu}/picket-flag": {
   "post": {
    "operationId": "printFlag",
    "summary": "Prints the picket flag of an HU",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "hu",
      "in": "path",
      "required": true,
      "description": "HU",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "printer"
        ],
        "properties": {
         "printer": {
          "type": "string",
          "description": "Printer"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/hus/{hu}/unload": {
   "post": {
    "operationId": "unload",
    "summary": "Unloads an HU (each HU once)",
    "tags": [
     "Goods receipt"
    ],
    "parameters": [
     {
      "name": "hu",
      "in": "path",
      "required": true,
      "description": "HU",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Accept-Language",
      "in": "header",
      "required": false,
      "description": "de (default) or en: the language of the messages",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Done. `message` (where there is one) is what the screen shows.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {}
        }
       }
      }
     },
     "default": {
      "description": "Refused: `error.message` is what the screen shows after \"E:\", `error.code` a stable name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 }
}