openapi: 3.0.3
info:
  title: DxPrint Driver API
  version: 1.0.0
  contact:
    name: Suport DxPrint
    email: support@dxprint.ro
  description: |
    API-ul HTTP expus de driverul DxPrint in modul embedded.

    Toate raspunsurile JSON folosesc un camp `success`. Cand comanda trimisa
    echipamentului fiscal esueaza, `errorMessages` contine codurile si mesajele
    primite. Driverul poate permite o singura operatie asupra echipamentului la
    un moment dat. Un apel concurent poate primi raspunsul `400` cu mesajul
    "Bonul este in executie. Incercati din nou!".

    Autentificarea Basic este necesara numai daca utilizatorul si parola HTTP
    sunt configurate in driver. Portul implicit este `8080`, dar poate fi
    schimbat din configuratie.
servers:
  - url: http://127.0.0.1:{port}
    description: Driver local
    variables:
      port:
        default: "8080"
        description: Portul HTTP configurat in DxPrint
security:
  - basicAuth: []
  - {}
tags:
  - name: Bonuri
    description: Tiparirea bonurilor si informatii despre ultimul bon
  - name: Echipament
    description: Configuratia si starea echipamentului fiscal
  - name: Numerar
    description: Depuneri si retrageri de numerar
  - name: Rapoarte
    description: Tiparirea si citirea rapoartelor fiscale
  - name: Periferice
    description: Sertarul de numerar si afisajul clientului

paths:
  /receipts:
    post:
      tags: [Bonuri]
      operationId: printSaleReceipt
      summary: Tipareste un bon
      description: |
        Tipareste un bon fiscal sau nefiscal. Pentru un bon fiscal, `products`
        si `payments` trebuie sa contina cel putin un element. Pentru un bon
        nefiscal, driverul proceseaza comentariile, codul fiscal si codurile de
        bare, fara sa valideze produsele si platile.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SaleReceipt"
            example:
              uuid: 367769fa-0bff-4cbe-8cbb-904955dfa876
              isNonFiscalReceipt: false
              products:
                - name: Cafea
                  quantity: 2
                  price: 12.5
                  department: 1
                  vat: "2"
                  unit: BUC
                  comments: []
                  barcodes: []
                  isSubtotalDiscount: false
              payments:
                - paymentType: Card
                  amount: 25
      responses:
        "200":
          description: Bon tiparit
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReceiptResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /receipts/status:
    get:
      tags: [Bonuri]
      operationId: getLastReceiptStatus
      summary: Citeste starea ultimului bon
      description: |
        Intoarce numarul bonului curent, numarul raportului Z si totalul
        bonurilor. Campurile legate de blocarea raportului Z nu sunt disponibile
        pe echipamentele Daisy si lipsesc din raspuns.
      responses:
        "200":
          description: Starea ultimului bon
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReceiptStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /receipts/header:
    get:
      tags: [Bonuri]
      operationId: getReceiptHeaderLines
      summary: Citeste antetul bonului
      responses:
        "200":
          description: Liniile configurate in antet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HeaderFooterResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /receipts/footer:
    get:
      tags: [Bonuri]
      operationId: getReceiptFooterLines
      summary: Citeste subsolul bonului
      responses:
        "200":
          description: Liniile configurate in subsol
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HeaderFooterResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /vats:
    get:
      tags: [Echipament]
      operationId: getVatList
      summary: Citeste cotele TVA
      responses:
        "200":
          description: Cotele TVA programate in echipament
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VatListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /units:
    get:
      tags: [Echipament]
      operationId: getUnitsList
      summary: Citeste unitatile de masura
      description: Disponibil numai pentru echipamentele Daisy.
      responses:
        "200":
          description: Unitatile de masura programate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UnitListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /status:
    get:
      tags: [Echipament]
      operationId: getDeviceStatus
      summary: Citeste starea si configuratia echipamentului
      responses:
        "200":
          description: Informatii despre echipament, firma, TVA si licenta
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeviceStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /status/network:
    get:
      tags: [Echipament]
      operationId: getDeviceNetworkStatus
      summary: Citeste configuratia de retea
      description: Disponibil numai pentru echipamentele Datecs.
      responses:
        "200":
          description: Configuratia interfetei de retea a echipamentului
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NetworkStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /status/lastsync:
    get:
      tags: [Echipament]
      operationId: getLastSyncStatus
      summary: Citeste starea ultimei sincronizari
      description: Disponibil numai pentru echipamentele Datecs.
      responses:
        "200":
          description: Starea ultimei sincronizari a raportului Z
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SyncStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /money/deposit:
    post:
      tags: [Numerar]
      operationId: depositMoney
      summary: Inregistreaza o depunere de numerar
      parameters:
        - $ref: "#/components/parameters/Amount"
      responses:
        "200":
          description: Depunerea a fost inregistrata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MoneyResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /money/withdraw:
    post:
      tags: [Numerar]
      operationId: withdrawMoney
      summary: Inregistreaza o retragere de numerar
      parameters:
        - $ref: "#/components/parameters/Amount"
      responses:
        "200":
          description: Retragerea a fost inregistrata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MoneyResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/x:
    post:
      tags: [Rapoarte]
      operationId: printReportX
      summary: Tipareste raportul X
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/z:
    post:
      tags: [Rapoarte]
      operationId: printReportZ
      summary: Tipareste raportul Z
      description: Raport fiscal de inchidere zilnica.
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/ecr:
    post:
      tags: [Rapoarte]
      operationId: printEcrReport
      summary: Tipareste raportul ECR
      description: Disponibil numai pentru echipamentele Datecs.
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/departments:
    post:
      tags: [Rapoarte]
      operationId: printDepartmentsReport
      summary: Tipareste raportul pe departamente
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/items/groups:
    post:
      tags: [Rapoarte]
      operationId: printProductGroupsReport
      summary: Tipareste raportul pe grupe de produse
      description: Disponibil numai pentru echipamentele Datecs.
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/plu:
    post:
      tags: [Rapoarte]
      operationId: printPluReport
      summary: Tipareste raportul PLU Z
      description: Disponibil numai pentru echipamentele Daisy.
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/operators:
    post:
      tags: [Rapoarte]
      operationId: printOperatorsReport
      summary: Tipareste raportul X pe operatori
      description: Disponibil numai pentru echipamentele Daisy.
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/detailed/z:
    post:
      tags: [Rapoarte]
      operationId: printDetailedReportByZ
      summary: Tipareste un raport detaliat dupa numere Z
      parameters:
        - $ref: "#/components/parameters/FromZ"
        - $ref: "#/components/parameters/ToZ"
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/summary/z:
    post:
      tags: [Rapoarte]
      operationId: printSummaryReportByZ
      summary: Tipareste un raport sumar dupa numere Z
      parameters:
        - $ref: "#/components/parameters/FromZ"
        - $ref: "#/components/parameters/ToZ"
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/detailed/date:
    post:
      tags: [Rapoarte]
      operationId: printDetailedReportByDate
      summary: Tipareste un raport detaliat dupa data
      parameters:
        - $ref: "#/components/parameters/FromDate"
        - $ref: "#/components/parameters/ToDate"
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/summary/date:
    post:
      tags: [Rapoarte]
      operationId: printSummaryReportByDate
      summary: Tipareste un raport sumar dupa data
      parameters:
        - $ref: "#/components/parameters/FromDate"
        - $ref: "#/components/parameters/ToDate"
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/fmz:
    post:
      tags: [Rapoarte]
      operationId: getFiscalMemoryZReportByDate
      summary: Citeste raportul Z din memoria fiscala
      description: Disponibil numai pentru echipamentele Datecs.
      parameters:
        - $ref: "#/components/parameters/FromDate"
        - $ref: "#/components/parameters/ToDate"
        - name: sumar
          in: query
          required: false
          description: "`true` pentru raport sumar, `false` sau lipsa pentru raport detaliat."
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Liniile raportului citit din memoria fiscala
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StringListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/fmd:
    post:
      tags: [Rapoarte]
      operationId: getFiscalMemoryDocuments
      summary: Citeste sau tipareste documente din memoria fiscala dupa interval
      description: |
        Disponibil numai pentru echipamentele Datecs. Cand `tip_actiune` este
        `tiparire`, `content` este o lista goala. La `listare`, `content` contine
        documentele gasite.
      parameters:
        - $ref: "#/components/parameters/FromDateTime"
        - $ref: "#/components/parameters/ToDateTime"
        - $ref: "#/components/parameters/ActionType"
        - name: tip_document
          in: query
          required: true
          description: Tipul documentelor cautate.
          schema:
            type: string
            enum: [bonfiscal, raportz]
      responses:
        "200":
          description: Documentele gasite sau confirmarea tiparirii
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FiscalDocumentsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /reports/fmd/bynumber:
    post:
      tags: [Rapoarte]
      operationId: getFiscalMemoryDocumentByNumber
      summary: Citeste sau tipareste un document din memoria fiscala dupa numar
      description: |
        Disponibil numai pentru echipamentele Datecs. Daca `bf` lipseste sau
        este zero, `z` identifica un raport Z. Daca `bf` este pozitiv, perechea
        `z` si `bf` identifica un bon fiscal.
      parameters:
        - name: z
          in: query
          required: true
          description: Numarul raportului Z.
          schema:
            type: integer
            minimum: 1
          example: 6945
        - name: bf
          in: query
          required: false
          description: Numarul bonului fiscal din raportul Z.
          schema:
            type: integer
            minimum: 1
          example: 489
        - $ref: "#/components/parameters/ActionType"
      responses:
        "200":
          description: Documentul gasit sau confirmarea tiparirii
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FiscalDocumentResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /drawer/open:
    post:
      tags: [Periferice]
      operationId: openDrawer
      summary: Deschide sertarul de numerar
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /customer/display:
    post:
      tags: [Periferice]
      operationId: setCustomerDisplay
      summary: Trimite mesaje catre afisajul clientului
      description: |
        Fiecare element genereaza o comanda. `location` poate fi `0`, `1` sau
        `2`. Pentru pozitiile `1` si `2`, mesajul nu poate fi gol. Echipamentul
        foloseste cel mult primele 20 de caractere ale mesajului.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              minItems: 1
              items:
                $ref: "#/components/schemas/CustomerDisplayMessage"
            example:
              - location: 0
                message: ""
              - location: 1
                message: Total 25.00 RON
      responses:
        "200":
          $ref: "#/components/responses/CommandSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "405":
          $ref: "#/components/responses/MethodNotAllowed"
        "500":
          $ref: "#/components/responses/InternalServerError"

components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

  parameters:
    Amount:
      name: amount
      in: query
      required: true
      description: Suma operatiunii, exprimata in moneda configurata pe echipament.
      schema:
        type: number
        format: double
        minimum: 0
      example: 10.5
    FromZ:
      name: from
      in: query
      required: true
      description: Primul numar Z inclus in raport.
      schema:
        type: integer
        minimum: 0
      example: 1
    ToZ:
      name: to
      in: query
      required: true
      description: Ultimul numar Z inclus in raport. Trebuie sa fie cel putin egal cu `from`.
      schema:
        type: integer
        minimum: 0
      example: 2
    FromDate:
      name: from
      in: query
      required: true
      description: Data de inceput in format `DD-MM-YY`.
      schema:
        type: string
        pattern: '^\d{2}-\d{2}-\d{2}$'
      example: 01-08-23
    ToDate:
      name: to
      in: query
      required: true
      description: Data de sfarsit in format `DD-MM-YY`. Trebuie sa fie ulterioara datei `from`.
      schema:
        type: string
        pattern: '^\d{2}-\d{2}-\d{2}$'
      example: 02-08-23
    FromDateTime:
      name: from
      in: query
      required: true
      description: Data si ora de inceput in format `DD-MM-YYThh:mm:ss`.
      schema:
        type: string
        pattern: '^\d{2}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$'
      example: 01-08-23T00:00:00
    ToDateTime:
      name: to
      in: query
      required: true
      description: Data si ora de sfarsit in format `DD-MM-YYThh:mm:ss`.
      schema:
        type: string
        pattern: '^\d{2}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$'
      example: 30-08-23T23:59:59
    ActionType:
      name: tip_actiune
      in: query
      required: true
      description: "`listare` citeste continutul, iar `tiparire` il tipareste pe echipament."
      schema:
        type: string
        enum: [listare, tiparire]

  responses:
    CommandSuccess:
      description: Comanda a fost executata
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WebResponse"
          example:
            statusCode: 200
            success: true
    BadRequest:
      description: Parametri invalizi, operatie nepermisa de echipament sau eroare la executarea comenzii
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            statusCode: 400
            success: false
            errorMessages:
              - errorCode: "-1011"
                message: VALOARE_INCORECTA
    Unauthorized:
      description: Credentialele Basic Auth lipsesc sau sunt incorecte
      headers:
        WWW-Authenticate:
          description: Domeniul de autentificare DxPrint.
          schema:
            type: string
          example: Basic realm="DxPrint"
      content:
        text/plain:
          schema:
            type: string
          example: Autentificare incorecta
    NotFound:
      description: Documentul fiscal nu a fost gasit
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    MethodNotAllowed:
      description: Metoda HTTP nu este permisa pentru endpoint
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    InternalServerError:
      description: Handlerul a intampinat o eroare neasteptata
      content:
        text/plain:
          schema:
            type: string
          example: Internal Server Error

  schemas:
    ErrorMessage:
      type: object
      properties:
        message:
          type: string
          description: Mesajul returnat de driver sau de echipamentul fiscal.
        errorCode:
          type: string
          description: Codul erorii, daca echipamentul sau validarea furnizeaza unul.
      example:
        errorCode: "-1011"
        message: VALOARE_INCORECTA

    WebResponse:
      type: object
      required: [statusCode, success]
      properties:
        statusCode:
          type: integer
          description: Codul HTTP copiat in corpul raspunsului.
          example: 200
        success:
          type: boolean
        errorMessages:
          type: array
          items:
            $ref: "#/components/schemas/ErrorMessage"
        content:
          description: Continutul specific operatiei. Lipseste pentru comenzile fara rezultat.

    ErrorResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [errorMessages]
          properties:
            success:
              type: boolean
              enum: [false]
            errorMessages:
              type: array
              minItems: 1
              items:
                $ref: "#/components/schemas/ErrorMessage"

    SaleReceipt:
      type: object
      required: [isNonFiscalReceipt]
      properties:
        uuid:
          type: string
          description: Identificator transmis inapoi in raspuns. Driverul il foloseste si in numele fisierului de jurnal pentru apelurile bulk.
          example: 367769fa-0bff-4cbe-8cbb-904955dfa876
        fiscalCode:
          type: string
          maxLength: 18
          description: Codul fiscal al clientului.
        isNonFiscalReceipt:
          type: boolean
          description: "`false` pentru bon fiscal, `true` pentru bon nefiscal."
        discount:
          $ref: "#/components/schemas/Discount"
        headerComments:
          type: array
          items:
            $ref: "#/components/schemas/Comment"
        products:
          type: array
          items:
            $ref: "#/components/schemas/Product"
          description: Obligatoriu si cu cel putin un element pentru bonurile fiscale.
        payments:
          type: array
          items:
            $ref: "#/components/schemas/Payment"
          description: Obligatoriu si cu cel putin un element pentru bonurile fiscale.
        footerComments:
          type: array
          items:
            $ref: "#/components/schemas/Comment"
        barcodes:
          type: array
          items:
            $ref: "#/components/schemas/Barcode"

    Product:
      type: object
      required: [name, quantity, vat]
      properties:
        name:
          type: string
          minLength: 1
        quantity:
          type: number
          format: double
          exclusiveMinimum: true
          minimum: 0
        price:
          type: number
          format: double
        department:
          type: integer
          minimum: 0
          maximum: 99
          default: 0
        vat:
          type: string
          minLength: 1
          description: Indexul cotei TVA din `/vats`, de exemplu `2`, sau procentul, de exemplu `19%`.
        unit:
          type: string
          description: Unitatea de masura. Pentru Daisy, valoarea trebuie sa existe in `/units`; valoarea implicita este `BUC`.
        comments:
          type: array
          items:
            $ref: "#/components/schemas/Comment"
        barcodes:
          type: array
          items:
            $ref: "#/components/schemas/Barcode"
        discount:
          $ref: "#/components/schemas/Discount"
        isSubtotalDiscount:
          type: boolean
          default: false
          description: Aplica discountul tuturor produselor adaugate pana la acest produs.

    Discount:
      type: object
      required: [discountType, amount]
      properties:
        discountType:
          type: string
          enum: [PercentIncrease, PercentDiscount, ValueIncrease, ValueDiscount]
        amount:
          type: number
          format: double
          minimum: 0
          description: Pentru tipurile procentuale intervalul acceptat este 0-100. Pentru tipurile valorice maximul este 21474836.47.

    Payment:
      type: object
      required: [paymentType, amount]
      properties:
        paymentType:
          type: string
          enum: [Cash, Card, Credit, MealTicket, ValueTicket, Voucher, Modern, CardAvansNumerar, Other]
        amount:
          type: number
          format: double
          minimum: 0
          description: Valoarea `0` cere echipamentului sa incaseze soldul ramas.

    Barcode:
      type: object
      required: [barcode, barcodeType]
      properties:
        barcode:
          type: string
          minLength: 3
          description: EAN-8 cere exact 8 cifre, EAN-13 exact 13 cifre, Code128 accepta 3-31 caractere ASCII, iar QRCode 3-279 caractere ASCII.
        barcodeType:
          type: string
          enum: [Ean8, Ean13, Code128, QRCode]
        barcodeSize:
          type: integer
          minimum: 0
          maximum: 8
          default: 0
          description: Dimensiunea QR. Valoarea `0` foloseste dimensiunea implicita `3`.

    Comment:
      type: object
      properties:
        message:
          type: string
        bold:
          type: boolean
          default: false
        italic:
          type: boolean
          default: false
        underline:
          type: boolean
          default: false
        doubleSize:
          type: boolean
          default: false
        align:
          type: integer
          enum: [0, 1, 2]
          default: 0
          description: "`0` stanga, `1` centru, `2` dreapta."

    ReceiptNumber:
      type: object
      properties:
        uuid:
          type: string
        numarBonCurent:
          type: string
        numarRaportZ:
          type: string
        numarTotalBonuriZ:
          type: string

    ReceiptResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/ReceiptNumber"

    ReceiptStatus:
      type: object
      required: [currentReceiptNumber, currentZNumber, receiptTotalCount]
      properties:
        currentReceiptNumber:
          type: integer
        currentZNumber:
          type: integer
        receiptTotalCount:
          type: integer
        zReportBlockDatetime:
          type: string
          nullable: true
          description: Data si ora la care lipsa raportului Z blocheaza echipamentul. Disponibil numai pentru Datecs.
        isReceiptIssuedAfterZReport:
          type: boolean
          nullable: true
          description: Indica daca s-a emis un bon dupa ultimul raport Z. Disponibil numai pentru Datecs.

    ReceiptStatusResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/ReceiptStatus"

    HeaderFooterText:
      type: object
      required: [index, text]
      properties:
        index:
          type: integer
          minimum: 0
        text:
          type: string

    HeaderFooterResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              type: array
              items:
                $ref: "#/components/schemas/HeaderFooterText"

    Vat:
      type: object
      required: [index, value]
      properties:
        index:
          type: integer
        value:
          type: number
          format: double
          description: Procentul TVA.

    VatListResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              type: array
              items:
                $ref: "#/components/schemas/Vat"

    UnitOfMeasure:
      type: object
      required: [index, value]
      properties:
        index:
          type: integer
        value:
          type: string

    UnitListResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              type: array
              items:
                $ref: "#/components/schemas/UnitOfMeasure"

    FirmInformation:
      type: object
      required: [serialNumber, fiscalNumber, cif, headerLineOne, headerLineTwo, headerLines, footerLines]
      properties:
        serialNumber:
          type: string
        fiscalNumber:
          type: string
        cif:
          type: string
        headerLineOne:
          type: string
          deprecated: true
          description: Pastrat pentru compatibilitate. Folositi `headerLines`.
        headerLineTwo:
          type: string
          deprecated: true
          description: Pastrat pentru compatibilitate. Folositi `headerLines`.
        headerLines:
          type: array
          items:
            $ref: "#/components/schemas/HeaderFooterText"
        footerLines:
          type: array
          items:
            $ref: "#/components/schemas/HeaderFooterText"

    DemoLicenceDetail:
      type: object
      nullable: true
      properties:
        serie:
          type: string
        expirare:
          type: string

    DeviceStatus:
      type: object
      required:
        - name
        - serialNumber
        - firmwareRevision
        - firmwareDate
        - currentDate
        - isZReportRequired
        - isFiscalized
        - isResident
        - isEmbedded
        - ecrMode
        - logicNumber
        - baudRate
        - connInterface
        - firm
        - vats
        - units
        - isDemoLicence
        - demoLicenceDetail
        - currentLicence
        - driverVersion
      properties:
        name:
          type: string
        serialNumber:
          type: string
        firmwareRevision:
          type: string
        firmwareDate:
          type: string
        currentDate:
          type: string
        isZReportRequired:
          type: boolean
        isFiscalized:
          type: boolean
        isResident:
          type: boolean
        isEmbedded:
          type: boolean
        ecrMode:
          type: string
          enum: [Normal, Testare, Service, Scolarizare, Unknown]
        logicNumber:
          type: integer
        baudRate:
          type: string
        connInterface:
          type: string
        firm:
          allOf:
            - $ref: "#/components/schemas/FirmInformation"
          nullable: true
        vats:
          type: array
          items:
            $ref: "#/components/schemas/Vat"
        units:
          type: array
          items:
            $ref: "#/components/schemas/UnitOfMeasure"
        isDemoLicence:
          type: boolean
        demoLicenceDetail:
          $ref: "#/components/schemas/DemoLicenceDetail"
        currentLicence:
          type: string
        driverVersion:
          type: string

    DeviceStatusResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/DeviceStatus"

    NetworkStatus:
      type: object
      required: [macAddress, dhcpActive, ipAddress, netmask, gateway, primaryDns, secondaryDns, lanPort]
      properties:
        macAddress:
          type: string
        dhcpActive:
          type: boolean
        ipAddress:
          type: string
        netmask:
          type: string
        gateway:
          type: string
        primaryDns:
          type: string
        secondaryDns:
          type: string
        lanPort:
          type: string

    NetworkStatusResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/NetworkStatus"

    SyncStatus:
      type: object
      required: [lastSyncDate, lastSyncZNum, lastSyncState, lastSyncErrorCode]
      properties:
        lastSyncDate:
          type: string
          format: date-time
        lastSyncZNum:
          type: integer
        lastSyncState:
          type: string
          description: Starea conexiunii folosite la sincronizarea raportului Z.
        lastSyncErrorCode:
          type: string

    SyncStatusResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/SyncStatus"

    MoneyInputOutputStatus:
      type: object
      required: [cashSum, cashIn, cashOut]
      properties:
        cashSum:
          type: number
          format: double
        cashIn:
          type: number
          format: double
        cashOut:
          type: number
          format: double

    MoneyResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              $ref: "#/components/schemas/MoneyInputOutputStatus"

    StringListResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              type: array
              items:
                type: string

    FiscalMemoryDocument:
      type: object
      properties:
        numarZ:
          type: string
        numarBonFiscal:
          type: string
        dataRaportZ:
          type: string
        continutDocument:
          type: array
          items:
            type: string

    FiscalDocumentsResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          required: [content]
          properties:
            content:
              type: array
              items:
                $ref: "#/components/schemas/FiscalMemoryDocument"

    FiscalDocumentResponse:
      allOf:
        - $ref: "#/components/schemas/WebResponse"
        - type: object
          properties:
            content:
              allOf:
                - $ref: "#/components/schemas/FiscalMemoryDocument"
              nullable: true

    CustomerDisplayMessage:
      type: object
      required: [location]
      properties:
        location:
          type: integer
          enum: [0, 1, 2]
        message:
          type: string
          description: Obligatoriu si diferit de sirul gol pentru pozitiile `1` si `2`.
