openapi: 3.0.3
info:
  title: SAP Integration Service API
  description: |
    # SAP Business One Integration Service
    
    This microservice provides a RESTful API interface for integrating documents from your Head Office system to SAP Business One via the Service Layer API, plus direct SAP HANA database access for querying business data.
    
    ## Features
    - 🔐 Secure API with authentication
    - 📄 Document Processing (Invoices, Credit Notes, Payments, Purchase Orders, Good Receipts, Stock Transfers)
    - 📦 Batch Processing support
    - 🔄 Automatic SAP session management
    - 📊 Comprehensive logging and audit trail
    - 🚀 High performance with connection pooling
    - 🗄️ Direct SAP HANA database access for querying Items, Groups, Vendors, Warehouses, etc.
    - 🔍 SQL query execution with prepared statements and SQL injection prevention
    
    ## Integration Methods
    
    ### 1. SAP Service Layer API
    For document creation and processing (Invoices, Purchase Orders, Stock Transfers, etc.)
    
    ### 2. SAP HANA Direct Access
    For querying business data (Item Master Data, Item Groups, VAT Groups, UOM Groups, Price Lists, Warehouses, Vendors, Barcodes, etc.)
    
    ## Authentication
    All API endpoints (except health checks) require an API key to be provided in the `X-API-Key` header.
    
    ## Base URL
    Production: `https://your-server.com/api/v1`  
    Development: `http://localhost:3001/api/v1`
    
  version: 1.0.0
  contact:
    name: SAP Integration Team
    email: support@yourcompany.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: http://localhost:3001/api/v1
    description: Development server
  - url: https://your-server.com/api/v1
    description: Production server

tags:
  - name: Health
    description: Health check endpoints
  - name: Invoices
    description: Sales invoice operations
  - name: Credit Notes
    description: Credit note (refund) operations
  - name: Payments
    description: Payment operations
  - name: Good Receipts
    description: Purchase delivery note operations (goods receipt from suppliers)
  - name: Documents
    description: Generic document operations
  - name: Batch
    description: Batch processing operations
  - name: Utilities
    description: Utility endpoints
  - name: SAP HANA
    description: Direct SAP HANA database access endpoints for querying business data (Items, Groups, Vendors, Warehouses, etc.)

security:
  - ApiKeyAuth: []

paths:
  /health:
    get:
      tags:
        - Health
      summary: Health Check
      description: Check if the service is healthy and SAP connection is active
      security: []
      operationId: getHealth
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
              example:
                status: healthy
                service: SAP Integration Service
                version: 1.0.0
                timestamp: "2025-01-08T10:30:45.123Z"
                uptime: 3600
                environment: production
                sap:
                  connected: true
                  url: "https://192.168.10.153:50000/b1s/v1"

  /health/detailed:
    get:
      tags:
        - Health
      summary: Detailed Health Check
      description: Get detailed health information including system metrics
      security: []
      operationId: getDetailedHealth
      responses:
        '200':
          description: Detailed health information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetailedHealthResponse'

  /health/sap:
    get:
      tags:
        - Health
      summary: SAP Connection Status
      description: Check SAP Service Layer connection status
      operationId: getSAPHealth
      responses:
        '200':
          description: SAP connection is active
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAPHealthResponse'
        '503':
          description: SAP connection is down
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /invoices:
    post:
      tags:
        - Invoices
      summary: Create Invoice
      description: Create a new sales invoice in SAP B1
      operationId: createInvoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceRequest'
            examples:
              basic:
                $ref: '#/components/examples/BasicInvoice'
              detailed:
                $ref: '#/components/examples/DetailedInvoice'
      responses:
        '201':
          description: Invoice created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
              example:
                success: true
                message: "Invoice processed successfully"
                sapDocEntry: 12345
                sapDocNum: "INV-2025-001"
                documentType: "Invoice"
                duration: "234ms"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'

  /credit-notes:
    post:
      tags:
        - Credit Notes
      summary: Create Credit Note
      description: Create a credit note (refund) in SAP B1
      operationId: createCreditNote
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreditNoteRequest'
            examples:
              basic:
                $ref: '#/components/examples/BasicCreditNote'
      responses:
        '201':
          description: Credit note created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'

  /good-receipts:
    post:
      tags:
        - Good Receipts
      summary: Create Good Receipt
      description: |
        Create a Purchase Delivery Note (Goods Receipt PO) in SAP B1 for receiving goods from suppliers.
        
        **Transformation Process:**
        - Head Office sends request in simplified format
        - Node.js service transforms to exact Java POJO format
        - SAP API receives data matching org.shini.sap_integration.pojo.goodReceipt.GoodReceipt structure
        
        **Examples:**
        - `sapPojo`: SAP POJO format (what gets sent to SAP API after transformation)
      operationId: createGoodReceipt
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoodReceiptRequest'
            examples:
              sapPojo:
                $ref: '#/components/examples/SAPPOJOFormat'
      responses:
        '201':
          description: Good Receipt created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
              example:
                success: true
                message: "Good Receipt processed successfully"
                sapDocEntry: 67890
                sapDocNum: "GR-2025-001"
                documentType: "GoodReceipt"
                duration: "189ms"
        '202':
          description: |
            **Technical Reference:** SAP POJO Format
            
            This shows the exact format that gets sent to the SAP API after transformation.
            This matches your Java POJO classes exactly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAPGoodReceiptFormat'
              example:
                DocType: "dDocument_Items"
                DocObjectCode: "oPurchaseDeliveryNotes"
                PriceSource: "dpsManual"
                CardCode: "V00001"
                CardName: "ABC Suppliers Ltd"
                DocDate: "2025-01-08"
                DocDueDate: "2025-01-15"
                SalesPersonCode: 5
                U_BaseEntry: "98765"
                U_BRANCH: "BR01"
                DocumentLines:
                  - LineNum: 0
                    ItemCode: "RAW001"
                    ItemDescription: "Raw Material Type A"
                    BarCode: "1234567890123"
                    Quantity: 50
                    BaseQty: 50
                    WarehouseCode: "WH01"
                    UnitPrice: 15.50
                    BaseEntry: "98765"
                    BaseType: "22"
                    BaseLine: 0
                    CostingCode: "DEPT-PROD"
                    CostingCode2: "PROJECT-A" 
                    U_Comments: "Minor quantity variance noted"
                    CorrectQuantity: 49.5
                  - LineNum: 1
                    ItemCode: "FRESH001"
                    ItemDescription: "Fresh Product"
                    Quantity: 25
                    WarehouseCode: "WH-FRESH"
                    UnitPrice: 8.75
                    BaseEntry: "98765"
                    BaseType: "22"
                    BaseLine: 1
                    U_CostEvent: "HARVEST-2025"
                    U_FreshUOM: "KG"
                    U_FreshQty: 24.8
                    U_FreshPrice: 8.50
                    BatchNumbers:
                      - BatchNumber: "BATCH-2025-001"
                        Quantity: 30
                        ManufacturingDate: "2024-12-01"
                        ExpiryDate: "2026-12-01"
                      - BatchNumber: "BATCH-2025-002"
                        Quantity: 20
                        ManufacturingDate: "2024-12-15"
                        ExpiryDate: "2026-12-15"
                  - LineNum: 2
                    ItemCode: "RAW002"
                    ItemDescription: "Raw Material Type B"
                    Quantity: 25
                    WarehouseCode: "WH01"
                    UnitPrice: 22
                    BaseEntry: "98765"
                    BaseType: "22"
                    BaseLine: 1
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'
    
    get:
      tags:
        - Good Receipts
      summary: Get Good Receipts (Filtered SAP POJO Format)
      description: |
        Returns Good Receipts data in filtered SAP POJO format with only essential fields.
        
        **Perfect for testing Java POJO deserialization!**
        
        **Filtered Fields Returned:**
        - Main: DocType, DocObjectCode, PriceSource, CardCode, CardName, DocDate, DocDueDate, SalesPersonCode, U_BaseEntry, U_BRANCH
        - DocumentLines: LineNum, BaseLine, ItemCode, ItemDescription, BarCode, BaseEntry, Quantity, BaseQty, BaseType, WarehouseCode, U_Comments, CorrectQuantity, UnitPrice, CostingCode, CostingCode2, U_CostEvent, U_FreshUOM, U_FreshQty, U_FreshPrice, UoMEntry, UoMCode
        
        Response structure matches:
        - `org.shini.sap_integration.pojo.goodReceipt.GoodReceipt`  
        - `org.shini.sap_integration.pojo.goodReceipt.GoodReceiptDetail`
      operationId: getGoodReceipts
      responses:
        '200':
          description: Good Receipts data in SAP POJO format
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SAPGoodReceiptFormat'
              example:
                - DocType: "dDocument_Items"
                  DocObjectCode: "oPurchaseDeliveryNotes"
                  PriceSource: "dpsManual"
                  CardCode: "V00001"
                  CardName: "ABC Suppliers Ltd"
                  DocDate: "2025-01-08T00:00:00.000Z"
                  DocDueDate: "2025-01-15T00:00:00.000Z"
                  SalesPersonCode: 5
                  U_BaseEntry: "98765"
                  U_BRANCH: "BR01"
                  DocumentLines:
                    - LineNum: 0
                      BaseLine: 0
                      ItemCode: "RAW001"
                      ItemDescription: "Raw Material Type A"
                      BarCode: "1234567890123"
                      BaseEntry: "98765"
                      Quantity: 50.0
                      BaseQty: 50.0
                      BaseType: "22"
                      WarehouseCode: "WH01"
                      U_Comments: "Minor quantity variance noted"
                      CorrectQuantity: 49.5
                      UnitPrice: 15.5
                      CostingCode: "DEPT-PROD"
                      CostingCode2: "PROJECT-A"
                    - LineNum: 1
                      BaseLine: 1
                      ItemCode: "FRESH001"
                      ItemDescription: "Fresh Product"
                      BaseEntry: "98765"
                      Quantity: 25.0
                      BaseType: "22"
                      WarehouseCode: "WH-FRESH"
                      UnitPrice: 8.75
                      U_CostEvent: "HARVEST-2025"
                      U_FreshUOM: "KG"
                      U_FreshQty: 24.8
                      U_FreshPrice: 8.5
                - DocType: "dDocument_Items"
                  DocObjectCode: "oPurchaseDeliveryNotes"
                  PriceSource: "dpsManual"
                  CardCode: "V00002"
                  CardName: "XYZ Materials Inc"
                  DocDate: "2025-01-09T00:00:00.000Z"
                  DocDueDate: "2025-01-16T00:00:00.000Z"
                  SalesPersonCode: 3
                  U_BaseEntry: "98766"
                  U_BRANCH: "BR02"
                  DocumentLines:
                    - LineNum: 0
                      BaseLine: 0
                      ItemCode: "RAW002"
                      ItemDescription: "Raw Material Type B"
                      BaseEntry: "98766"
                      Quantity: 25.0
                      BaseType: "22"
                      WarehouseCode: "WH01"
                      UnitPrice: 22.0
                      UoMEntry: 1
                      UoMCode: "KG"
                      VolumeUnit: null
                      Volume: 0.0
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /ap-invoices:
    post:
      tags:
        - AP Invoices
      summary: Create AP Invoice
      description: |
        Create a Purchase Invoice (AP Invoice) in SAP B1 for recording invoices from suppliers.
        
        **Transformation Process:**
        - Head Office sends request in simplified format
        - Node.js service transforms to exact Java POJO format
        - SAP API receives data matching org.shini.sap_integration.pojo.apInvoice.APInvoice structure
        
        **Key Difference from Good Receipt:**
        - BaseType: "20" (AP Invoice) vs "22" (Good Receipt)
        - DocObjectCode: "oPurchaseInvoices" vs "oPurchaseDeliveryNotes"
        
        **Examples:**
        - `sapPojo`: SAP POJO format (what gets sent to SAP API after transformation)
      operationId: createAPInvoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/APInvoiceRequest'
            examples:
              sapPojo:
                $ref: '#/components/examples/SAPAPInvoicePOJOFormat'
      responses:
        '201':
          description: AP Invoice created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
              example:
                success: true
                message: "AP Invoice processed successfully"
                sapDocEntry: 78901
                sapDocNum: "AP-2025-001"
                documentType: "APInvoice"
                duration: "195ms"
        '202':
          description: |
            **Technical Reference:** SAP POJO Format
            
            This shows the exact format that gets sent to the SAP API after transformation.
            This matches your Java POJO classes exactly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAPAPInvoiceFormat'
              example:
                DocType: "dDocument_Items"
                DocObjectCode: "oPurchaseInvoices"
                PriceSource: "dpsManual"
                CardCode: "V00001"
                CardName: "ABC Suppliers Ltd"
                DocDate: "2025-01-08"
                DocDueDate: "2025-01-15"
                SalesPersonCode: 5
                U_BaseEntry: "GR-001"
                U_BRANCH: "BR01"
                DocumentLines:
                  - LineNum: 0
                    ItemCode: "RAW001"
                    ItemDescription: "Raw Material Type A"
                    BarCode: "1234567890123"
                    Quantity: 50
                    BaseQty: 50
                    WarehouseCode: "WH01"
                    UnitPrice: 15.50
                    BaseEntry: "98765"
                    BaseType: "20"
                    BaseLine: 0
                    CostingCode: "DEPT-PROD"
                    CostingCode2: "PROJECT-A"
                    U_Comments: "Invoice line item 1"
                    CorrectQuantity: 50.0
                    UoMEntry: 1
                    UoMCode: "KG"
                    VolumeUnit: null
                    Volume: 0.0
                  - LineNum: 1
                    ItemCode: "RAW002"
                    ItemDescription: "Raw Material Type B"
                    Quantity: 25
                    WarehouseCode: "WH02"
                    UnitPrice: 22.00
                    BaseEntry: "98765"
                    BaseType: "20"
                    BaseLine: 1
                    U_CostEvent: "PURCHASE"
                    U_FreshUOM: "PCS"
                    U_FreshQty: 25.0
                    U_FreshPrice: 22.00
                    UoMEntry: 2
                    UoMCode: "PCS"
                    VolumeUnit: null
                    Volume: 0.0
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: AP Invoice already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error: "AP Invoice already exists in SAP"
                isDuplicate: true
                duplicateKey: "API-2025-001"
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      tags:
        - AP Invoices
      summary: Get AP Invoices (Filtered SAP POJO Format)
      description: |
        Returns AP Invoices data in filtered SAP POJO format with only essential fields.
        
        **Perfect for testing Java POJO deserialization!**
        
        **Filtered Fields Returned:**
        - Main: DocType, DocObjectCode, PriceSource, CardCode, CardName, DocDate, DocDueDate, SalesPersonCode, U_BaseEntry, U_BRANCH
        - DocumentLines: LineNum, BaseLine, ItemCode, ItemDescription, BarCode, BaseEntry, Quantity, BaseQty, BaseType, WarehouseCode, U_Comments, CorrectQuantity, UnitPrice, CostingCode, CostingCode2, U_CostEvent, U_FreshUOM, U_FreshQty, U_FreshPrice, UoMEntry, UoMCode
        
        Response structure matches:
        - `org.shini.sap_integration.pojo.apInvoice.APInvoice`  
        - `org.shini.sap_integration.pojo.apInvoice.APInvoiceDetail`
      operationId: getAPInvoices
      responses:
        '200':
          description: AP Invoices data in SAP POJO format
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SAPAPInvoiceFormat'
              example:
                - DocType: "dDocument_Items"
                  DocObjectCode: "oPurchaseInvoices"
                  PriceSource: "dpsManual"
                  CardCode: "V00001"
                  CardName: "ABC Suppliers Ltd"
                  DocDate: "2025-01-08T00:00:00.000Z"
                  DocDueDate: "2025-01-15T00:00:00.000Z"
                  SalesPersonCode: 5
                  U_BaseEntry: "GR-001"
                  U_BRANCH: "BR01"
                  DocumentLines:
                    - LineNum: 0
                      BaseLine: 0
                      ItemCode: "RAW001"
                      ItemDescription: "Raw Material Type A"
                      BarCode: "1234567890123"
                      BaseEntry: "98765"
                      Quantity: 50.0
                      BaseQty: 50.0
                      BaseType: "20"
                      WarehouseCode: "WH01"
                      U_Comments: "Invoice line item 1"
                      CorrectQuantity: 50.0
                      UnitPrice: 15.5
                      CostingCode: "DEPT-PROD"
                      CostingCode2: "PROJECT-A"
                      U_CostEvent: "PURCHASE"
                      U_FreshUOM: "KG"
                      U_FreshQty: 50.0
                      U_FreshPrice: 15.5
                      UoMEntry: 1
                      UoMCode: "KG"
                      VolumeUnit: null
                      Volume: 0.0
                    - LineNum: 1
                      BaseLine: 1
                      ItemCode: "RAW002"
                      ItemDescription: "Raw Material Type B"
                      BaseEntry: "98765"
                      Quantity: 25.0
                      BaseType: "20"
                      WarehouseCode: "WH02"
                      UnitPrice: 22.0
                      U_CostEvent: "PURCHASE"
                      U_FreshUOM: "PCS"
                      U_FreshQty: 25.0
                      U_FreshPrice: 22.0
                      UoMEntry: 2
                      UoMCode: "PCS"
                      VolumeUnit: null
                      Volume: 0.0
                - DocType: "dDocument_Items"
                  DocObjectCode: "oPurchaseInvoices"
                  PriceSource: "dpsManual"
                  CardCode: "V00002"
                  CardName: "XYZ Materials Inc"
                  DocDate: "2025-01-09T00:00:00.000Z"
                  DocDueDate: "2025-01-16T00:00:00.000Z"
                  SalesPersonCode: 3
                  U_BaseEntry: "GR-002"
                  U_BRANCH: "BR02"
                  DocumentLines:
                    - LineNum: 0
                      BaseLine: 0
                      ItemCode: "RAW003"
                      ItemDescription: "Raw Material Type C"
                      BaseEntry: "98766"
                      Quantity: 30.0
                      BaseType: "20"
                      WarehouseCode: "WH01"
                      UnitPrice: 18.0
                      UoMEntry: 1
                      UoMCode: "KG"
                      VolumeUnit: null
                      Volume: 0.0
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /ap-invoices/from-good-receipt/{docentry}:
    post:
      tags:
        - AP Invoices
      summary: Create AP Invoice from Good Receipt
      description: |
        Create an AP Invoice based on a Good Receipt with overridden quantities and unit prices.
        
        **Process Flow:**
        1. Fetches the Good Receipt using the provided DocEntry
        2. Retrieves all DocumentLines from the fetched Good Receipt
        3. Overrides quantity and unitPrice from the request body lines
        4. Creates an AP Invoice with the modified data
        
        **Key Features:**
        - Uses Good Receipt header data (supplier, dates, etc.)
        - Copies line item details from Good Receipt
        - Overrides quantity and unitPrice per line as specified
        - Automatically sets BaseType to "20" (AP Invoice)
        - Links back to original Good Receipt via baseEntry
        
        **Override Matching:**
        - Lines are matched by itemCode (preferred) or lineNum
        - Each override line must match an existing Good Receipt line
        
        **Use Cases:**
        - Partial invoicing of goods received
        - Price adjustments after goods receipt
        - Quantity corrections for invoicing
      operationId: createAPInvoiceFromGoodReceipt
      parameters:
        - name: docentry
          in: path
          required: true
          description: Good Receipt DocEntry to base the AP Invoice on
          schema:
            type: string
            example: "12345"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - lines
              properties:
                lines:
                  type: array
                  minItems: 1
                  description: Array of line overrides with quantity and unitPrice changes
                  items:
                    type: object
                    required:
                      - quantity
                      - unitPrice
                    properties:
                      itemCode:
                        type: string
                        description: Item code to match (preferred matching method)
                        example: "RAW001"
                      lineNum:
                        type: integer
                        description: Line number to match (alternative matching method)
                        example: 0
                      quantity:
                        type: number
                        minimum: 0.01
                        description: New quantity for this line
                        example: 30.00
                      unitPrice:
                        type: number
                        minimum: 0
                        description: New unit price for this line
                        example: 18.75
                      baseQty:
                        type: number
                        description: Base quantity (optional override)
                        example: 30.00
            examples:
              byItemCode:
                summary: Override by Item Code
                description: Match Good Receipt lines by item code
                value:
                  lines:
                    - itemCode: "RAW001"
                      quantity: 45.0
                      unitPrice: 16.50
                    - itemCode: "RAW002"
                      quantity: 20.0
                      unitPrice: 25.00
              byLineNum:
                summary: Override by Line Number
                description: Match Good Receipt lines by line number
                value:
                  lines:
                    - lineNum: 0
                      quantity: 45.0
                      unitPrice: 16.50
                    - lineNum: 1
                      quantity: 20.0
                      unitPrice: 25.00
              mixed:
                summary: Mixed Matching
                description: Mix of item code and line number matching
                value:
                  lines:
                    - itemCode: "RAW001"
                      quantity: 45.0
                      unitPrice: 16.50
                    - lineNum: 1
                      quantity: 20.0
                      unitPrice: 25.00
                    - itemCode: "FRESH001"
                      quantity: 15.0
                      unitPrice: 12.00
      responses:
        '201':
          description: AP Invoice created successfully from Good Receipt
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/DocumentResponse'
                  - type: object
                    properties:
                      baseGoodReceiptEntry:
                        type: string
                        description: Original Good Receipt DocEntry
                      linesProcessed:
                        type: integer
                        description: Number of lines processed
              example:
                success: true
                message: "AP Invoice created successfully from Good Receipt"
                sapDocEntry: "78901"
                sapDocNum: "API-2025-001"
                documentType: "APInvoice"
                duration: "245ms"
                baseGoodReceiptEntry: "12345"
                linesProcessed: 2
        '400':
          description: Bad request - invalid parameters or missing lines
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                noLines:
                  summary: No override lines provided
                  value:
                    success: false
                    error: "At least one line with quantity and unitPrice overrides is required"
                    errorCode: "BAD_REQUEST"
                    timestamp: "2025-01-08T10:30:45.123Z"
                noMatchingLine:
                  summary: No matching Good Receipt line found
                  value:
                    success: false
                    error: "No matching Good Receipt line found for RAW999"
                    errorCode: "BAD_REQUEST"
                    timestamp: "2025-01-08T10:30:45.123Z"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Good Receipt not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error: "Good Receipt with DocEntry 12345 not found: Document not found in SAP"
                errorCode: "NOT_FOUND"
                timestamp: "2025-01-08T10:30:45.123Z"
        '409':
          description: AP Invoice already exists (duplicate)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error: "AP Invoice already exists in SAP"
                errorCode: "CONFLICT"
                timestamp: "2025-01-08T10:30:45.123Z"
                isDuplicate: true
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'

  /stock-transfers:
    post:
      tags:
        - Stock Transfers
      summary: Create Stock Transfer
      description: |
        Create a Stock Transfer in SAP B1 for transferring stock between warehouses.
        
        **Transformation Process:**
        - Head Office sends request in simplified format
        - Node.js service transforms to exact Java POJO format
        - SAP API receives data matching org.shini.sap_integration.pojo.stockTransfer.StockTransfer structure
        
        **Key Features:**
        - Warehouse-to-warehouse transfers
        - Transfer types: "Waste" or "Damage"
        - Uses StockTransferLines instead of DocumentLines
        - Default values: PriceList="1", UseBaseUnits="tNO"
        
        **Examples:**
        - `sapPojo`: SAP POJO format (what gets sent to SAP API after transformation)
      operationId: createStockTransfer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StockTransferRequest'
            examples:
              sapPojo:
                $ref: '#/components/examples/SAPStockTransferPOJOFormat'
      responses:
        '201':
          description: Stock Transfer created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
              example:
                success: true
                message: "Stock Transfer processed successfully"
                sapDocEntry: 89012
                sapDocNum: "ST-2025-001"
                documentType: "StockTransfer"
                duration: "201ms"
        '202':
          description: |
            **Technical Reference:** SAP POJO Format
            
            This shows the exact format that gets sent to the SAP API after transformation.
            This matches your Java POJO classes exactly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAPStockTransferFormat'
              example:
                DocDate: "2025-09-15"
                DueDate: "2025-09-15"
                FromWarehouse: "WH008"
                ToWarehouse: "DMG-WHS"
                U_BaseEntry: null
                U_Type: "Waste"
                PriceList: 1
                DocumentLines:
                  - LineNum: 0
                    ItemCode: "530"
                    ItemDescription: "MENTOS PURE FRESH SP MINT 15.75GR"
                    Quantity: 48
                    WarehouseCode: "DMG-WHS"
                    FromWarehouseCode: "WH008"
                    UseBaseUnits: "tNO"
                    MeasureUnit: "piece"
                    UoMEntry: 1
                    UoMCode: "pcs"
                    UnitPrice: 0
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: Stock Transfer already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error: "Stock Transfer already exists in SAP"
                isDuplicate: true
                duplicateKey: "ST-2025-001"
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      tags:
        - Stock Transfers
      summary: Get Stock Transfers (Filtered SAP POJO Format)
      description: |
        Returns Stock Transfers data in filtered SAP POJO format with only essential fields.
        
        **Perfect for testing Java POJO deserialization!**
        
        **Filtered Fields Returned:**
        - Main: DocEntry, DocNum, DocDate, DueDate, FromWarehouse, ToWarehouse, U_BaseEntry, U_Type, PriceList
        - StockTransferLines: LineNum, ItemCode, ItemDescription, Quantity, WarehouseCode, FromWarehouseCode, UseBaseUnits, MeasureUnit, UoMEntry, UoMCode, UnitPrice
        
        Response structure matches:
        - `org.shini.sap_integration.pojo.stockTransfer.StockTransfer`  
        - `org.shini.sap_integration.pojo.stockTransfer.StockTransferDetail`
      operationId: getStockTransfers
      responses:
        '200':
          description: Stock Transfers data in SAP POJO format
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SAPStockTransferFormat'
              example:
                - DocEntry: null
                  DocNum: null
                  DocDate: "2025-01-08T00:00:00.000Z"
                  DueDate: "2025-01-15T00:00:00.000Z"
                  FromWarehouse: "WH01"
                  ToWarehouse: "WH02"
                  U_BaseEntry: "ST-001"
                  U_Type: "Waste"
                  PriceList: "1"
                  StockTransferLines:
                    - LineNum: 0
                      ItemCode: "RAW001"
                      ItemDescription: "Raw Material Item 001"
                      Quantity: 10.0
                      WarehouseCode: "WH02"
                      FromWarehouseCode: "WH01"
                      UseBaseUnits: "tNO"
                      MeasureUnit: "KG"
                      UoMEntry: "1"
                      UoMCode: "KG"
                      UnitPrice: 25.5
                    - LineNum: 1
                      ItemCode: "RAW002"
                      ItemDescription: "Raw Material Item 002"
                      Quantity: 5.0
                      WarehouseCode: "WH02"
                      FromWarehouseCode: "WH01"
                      UseBaseUnits: "tNO"
                      MeasureUnit: "PCS"
                      UoMEntry: "2"
                      UoMCode: "PCS"
                      UnitPrice: 15.75
                - DocEntry: null
                  DocNum: null
                  DocDate: "2025-01-09T00:00:00.000Z"
                  DueDate: "2025-01-16T00:00:00.000Z"
                  FromWarehouse: "WH02"
                  ToWarehouse: "WH03"
                  U_BaseEntry: "ST-002"
                  U_Type: "Damage"
                  PriceList: "1"
                  StockTransferLines:
                    - LineNum: 0
                      ItemCode: "RAW003"
                      ItemDescription: "Raw Material Item 003"
                      Quantity: 15.0
                      WarehouseCode: "WH03"
                      FromWarehouseCode: "WH02"
                      UseBaseUnits: "tNO"
                      MeasureUnit: "KG"
                      UoMEntry: "1"
                      UoMCode: "KG"
                      UnitPrice: 18.0
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /payments:
    post:
      tags:
        - Payments
      summary: Create Payment
      description: Create an incoming payment in SAP B1
      operationId: createPayment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentRequest'
            examples:
              cash:
                $ref: '#/components/examples/CashPayment'
              creditCard:
                $ref: '#/components/examples/CreditCardPayment'
              bankTransfer:
                $ref: '#/components/examples/BankTransferPayment'
      responses:
        '201':
          description: Payment created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'

  /documents/batch:
    post:
      tags:
        - Batch
      summary: Batch Process Documents
      description: Process multiple documents in a single request (max 100 documents)
      operationId: processBatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchRequest'
            example:
              documents:
                - type: invoice
                  data:
                    transactionKey: "BATCH-INV-001"
                    customerCode: "C00001"
                    lines:
                      - itemCode: "ITEM001"
                        quantity: 2
                        unitPrice: 50
                        warehouseCode: "WH01"
                - type: payment
                  data:
                    paymentKey: "BATCH-PAY-001"
                    customerCode: "C00001"
                    amount: 100
                    paymentMethod: "Cash"
      responses:
        '200':
          description: Batch processed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /documents/types:
    get:
      tags:
        - Utilities
      summary: Get Document Types
      description: Get list of supported document types
      operationId: getDocumentTypes
      responses:
        '200':
          description: List of document types
          content:
            application/json:
              schema:
                type: object
                properties:
                  types:
                    type: array
                    items:
                      type: string
                    example: ["invoice", "creditnote", "payment", "incomingpayment"]
                  count:
                    type: integer
                    example: 4
        '401':
          $ref: '#/components/responses/Unauthorized'

  /documents/{type}/validate:
    post:
      tags:
        - Documents
      summary: Validate Document
      description: Validate a document (invoice, creditNote, payment, or goodreceipt) without posting to SAP
      operationId: validateDocument
      parameters:
        - $ref: '#/components/parameters/DocumentType'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
            examples:
              invoice:
                summary: Validate Invoice
                value:
                  transactionKey: "TRX-VALIDATE-001"
                  customerCode: "C00001"
                  lines:
                    - itemCode: "ITEM001"
                      quantity: 1
                      unitPrice: 25
                      warehouseCode: "WH01"
              goodreceipt:
                summary: Validate Good Receipt
                value:
                  transactionKey: "GR-VALIDATE-001"
                  supplierCode: "V00001"
                  supplierName: "ABC Suppliers Ltd"
                  docDate: "2025-01-08"
                  referenceNumber: "VALIDATE-REF-001"
                  comments: "Validation test - batch managed items"
                  lines:
                    - itemCode: "RAW001"
                      itemDescription: "Raw Material Type A"
                      quantity: 50
                      unitPrice: 10.00
                      warehouseCode: "WH01"
                      taxCode: "VAT16"
                      batchNumbers:
                        - number: "BATCH-001"
                          quantity: 30
                          manufacturingDate: "2024-12-01"
                          expiryDate: "2026-12-01"
                        - number: "BATCH-002"
                          quantity: 20
                          manufacturingDate: "2024-12-15"
                          expiryDate: "2026-12-15"
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /documents/{type}:
    get:
      tags:
        - Documents
      summary: Query Documents
      description: Query documents (invoice, creditNote, payment, or goodreceipt) from SAP with filters
      operationId: queryDocuments
      parameters:
        - $ref: '#/components/parameters/DocumentType'
        - $ref: '#/components/parameters/Filter'
        - $ref: '#/components/parameters/Select'
        - $ref: '#/components/parameters/Top'
        - $ref: '#/components/parameters/Skip'
      responses:
        '200':
          description: List of documents
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
    
    post:
      tags:
        - Documents
      summary: Create Document
      description: Create a document of specified type (invoice, creditNote, payment, or goodreceipt)
      operationId: createDocument
      parameters:
        - $ref: '#/components/parameters/DocumentType'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
            examples:
              invoice:
                summary: Invoice Document
                value:
                  transactionKey: "TRX-001"
                  customerCode: "C00001"
                  lines:
                    - itemCode: "ITEM001"
                      quantity: 2
                      unitPrice: 50
                      warehouseCode: "WH01"
              goodreceipt:
                summary: Good Receipt Document
                value:
                  transactionKey: "GR-001"
                  supplierCode: "V00001"
                  supplierName: "ABC Suppliers Ltd"
                  docDate: "2025-01-08"
                  referenceNumber: "PO-12345"
                  branch: "BR01"
                  comments: "Goods received - complete delivery"
                  lines:
                    - itemCode: "RAW001"
                      itemDescription: "Raw Material Type A"
                      quantity: 100
                      unitPrice: 15.50
                      warehouseCode: "WH01"
                      baseEntry: "98765"
                      baseLine: 0
                      baseType: "22"
                      taxCode: "VAT16"
                      costingCode: "CC001"
                    - itemCode: "RAW002"
                      itemDescription: "Raw Material Type B"
                      quantity: 50
                      unitPrice: 22.00
                      warehouseCode: "WH01"
                      serialNumbers: ["SN-001", "SN-002"]
      responses:
        '201':
          description: Document created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'

  /documents/{type}/{docEntry}:
    get:
      tags:
        - Documents
      summary: Get Document
      description: Get a specific document (invoice, creditNote, payment, or goodreceipt) from SAP
      operationId: getDocument
      parameters:
        - $ref: '#/components/parameters/DocumentType'
        - $ref: '#/components/parameters/DocEntry'
      responses:
        '200':
          description: Document data
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

  /documents/{type}/{docEntry}/cancel:
    post:
      tags:
        - Documents
      summary: Cancel Document
      description: Cancel a document (invoice, creditNote, payment, or goodreceipt) in SAP
      operationId: cancelDocument
      parameters:
        - $ref: '#/components/parameters/DocumentType'
        - $ref: '#/components/parameters/DocEntry'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  description: Cancellation reason
                  example: "Customer request"
      responses:
        '200':
          description: Document cancelled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  sapDocEntry:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

  /purchase-orders/purchase-order-lion:
    post:
      tags:
        - Purchase Orders
      summary: Create Purchase Order with Barcode Validation (LION)
      description: |
        Create a Purchase Order with automatic barcode validation and data enrichment from SAP HANA database.
        
        **Process Flow:**
        1. Validates all document lines have barcodes
        2. Queries `CX_PURE_ITEM_LIST` view in SAP HANA for each barcode
        3. Verifies ItemCode matches the barcode in database
        4. Enriches lines with VAT Groups, UoM data from database
        5. Submits enriched PO to SAP Service Layer
        
        **Validation Rules:**
        - ✅ **All lines MUST have barcodes** (no empty/null barcodes allowed)
        - ✅ **Barcode MUST exist** in `CX_PURE_ITEM_LIST`
        - ✅ **ItemCode MUST match** the database ItemCode for that barcode
        - ❌ **Any validation failure** → Entire PO is rejected
        
        **Data Enrichment (from CX_PURE_ITEM_LIST):**
        - `VatGroup` ← `VatGroupPu` (Purchase VAT Group)
        - `UoMEntry` ← `UomEntry` (Unit of Measurement Entry)
        - `UoMCode` ← `UomCode` (Unit of Measurement Code)
        - `MeasureUnit` ← `UomCode` (Same as UoMCode)
        - `ItemDescription` ← `ItemName` (Optional override)
        
        **User Data Preserved:**
        - `UnitPrice` - NOT overridden (user's price is used)
        - `Quantity` - User's quantity
        - `WarehouseCode` - User's warehouse
        
        **Error Scenarios:**
        - Missing barcode → `400 Bad Request`
        - Barcode not found → `400 Bad Request`
        - ItemCode mismatch → `400 Bad Request`
        - SAP submission error → `500 Internal Server Error`
      operationId: createPurchaseOrderLion
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - CardCode
                - CardName
                - DocDate
                - DocDueDate
                - U_Branch
                - DocumentLines
              properties:
                CardCode:
                  type: string
                  description: Vendor/Supplier code
                  example: "P-00255"
                CardName:
                  type: string
                  description: Vendor/Supplier name
                  example: "Khalil Daowd Ali Alsrkhi"
                DocDate:
                  type: string
                  format: date
                  description: Document date (YYYY-MM-DD)
                  example: "2025-10-01"
                DocDueDate:
                  type: string
                  format: date
                  description: Document due date (YYYY-MM-DD)
                  example: "2025-10-15"
                Comments:
                  type: string
                  description: Optional comments
                  example: "Purchase order for fresh produce"
                U_Branch:
                  type: string
                  description: Branch/Warehouse identifier
                  example: "WH005"
                DocumentLines:
                  type: array
                  minItems: 1
                  description: Array of purchase order line items
                  items:
                    type: object
                    required:
                      - ItemCode
                      - BarCode
                      - Quantity
                      - UnitPrice
                      - WarehouseCode
                    properties:
                      LineNum:
                        type: integer
                        description: Line number (optional, will be auto-assigned if not provided)
                        example: 0
                      ItemCode:
                        type: string
                        description: Item code (must match barcode in database)
                        example: "11038"
                      ItemDescription:
                        type: string
                        description: Item description (will be enriched from database)
                        example: "SPINACH (BUNCH)"
                      Quantity:
                        type: number
                        description: Order quantity (must be > 0)
                        example: 30
                      UnitPrice:
                        type: number
                        description: Unit price (preserved, not overridden)
                        example: 2.50
                      BarCode:
                        type: string
                        description: Item barcode (REQUIRED, validated against CX_PURE_ITEM_LIST)
                        example: "00297"
                      WarehouseCode:
                        type: string
                        description: Warehouse code
                        example: "WH005"
            example:
              CardCode: "P-00255"
              CardName: "Khalil Daowd Ali Alsrkhi"
              DocDate: "2025-10-01"
              DocDueDate: "2025-10-15"
              Comments: "Fresh produce order"
              U_Branch: "WH005"
              DocumentLines:
                - LineNum: 0
                  ItemCode: "11038"
                  ItemDescription: "SPINACH (BUNCH)"
                  Quantity: 30
                  UnitPrice: 2.50
                  BarCode: "00297"
                  WarehouseCode: "WH005"
                - LineNum: 1
                  ItemCode: "11034"
                  ItemDescription: "SPINACH"
                  Quantity: 20
                  UnitPrice: 2.00
                  BarCode: "00296"
                  WarehouseCode: "WH005"
      responses:
        '201':
          description: Purchase Order created successfully with enriched data
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "Purchase Order LION created successfully"
                  data:
                    type: object
                    properties:
                      sapDocEntry:
                        type: integer
                        description: SAP Document Entry number
                        example: 1631
                      sapDocNum:
                        type: integer
                        description: SAP Document Number
                        example: 240000725
                      enrichedLinesCount:
                        type: integer
                        description: Number of lines that were enriched
                        example: 2
                      validation:
                        type: object
                        properties:
                          totalLines:
                            type: integer
                            example: 2
                          validatedLines:
                            type: integer
                            example: 2
                          allValid:
                            type: boolean
                            example: true
                  timestamp:
                    type: string
                    format: date-time
              example:
                success: true
                message: "Purchase Order LION created successfully"
                data:
                  sapDocEntry: 1631
                  sapDocNum: 240000725
                  enrichedLinesCount: 2
                  validation:
                    totalLines: 2
                    validatedLines: 2
                    allValid: true
                timestamp: "2025-10-01T20:30:00.000Z"
        '400':
          description: Validation error (missing barcode, barcode not found, ItemCode mismatch, or invalid data)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                  timestamp:
                    type: string
                    format: date-time
                  errorCode:
                    type: string
                  details:
                    type: object
                    properties:
                      validationErrors:
                        type: array
                        items:
                          type: object
                          properties:
                            line:
                              type: integer
                            barcode:
                              type: string
                            expectedItemCode:
                              type: string
                            receivedItemCode:
                              type: string
                            error:
                              type: string
                      totalLines:
                        type: integer
                      failedLines:
                        type: integer
              examples:
                missingBarcode:
                  summary: Missing Barcode
                  value:
                    success: false
                    error: "Barcode is required for all document lines (Line 1)"
                    timestamp: "2025-10-01T20:30:00.000Z"
                    errorCode: "VALIDATION_ERROR"
                barcodeNotFound:
                  summary: Barcode Not Found
                  value:
                    success: false
                    error: "Barcode '9999999999' not found in item list (Line 0)"
                    timestamp: "2025-10-01T20:30:00.000Z"
                    errorCode: "VALIDATION_ERROR"
                    details:
                      validationErrors:
                        - line: 0
                          barcode: "9999999999"
                          error: "Barcode '9999999999' not found in item list (Line 0)"
                      totalLines: 2
                      failedLines: 1
                itemCodeMismatch:
                  summary: ItemCode Mismatch
                  value:
                    success: false
                    error: "ItemCode mismatch for barcode '00297': Expected '11038', but got 'WRONG123' (Line 0)"
                    timestamp: "2025-10-01T20:30:00.000Z"
                    errorCode: "VALIDATION_ERROR"
                    details:
                      validationErrors:
                        - line: 0
                          barcode: "00297"
                          expectedItemCode: "11038"
                          receivedItemCode: "WRONG123"
                          error: "ItemCode mismatch for barcode '00297': Expected '11038', but got 'WRONG123' (Line 0)"
                      totalLines: 2
                      failedLines: 1
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          description: SAP Service Layer error or internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                  timestamp:
                    type: string
                    format: date-time
                  errorCode:
                    type: string
                  details:
                    type: object

  /purchase-orders:
    post:
      tags:
        - Purchase Orders
      summary: Create Purchase Order
      description: |\
        Create a Purchase Order document in SAP B1 using exact Java POJO format.
        
        **Java POJO Compliance:**
        - Matches org.shini.sap_integration.pojo.purchaseorders.PurchaseOrder
        - Matches org.shini.sap_integration.pojo.purchaseorders.PurchaseOrderDetail
        
        **Key Features:**
        - Exact field name matching with Java POJOs
        - Complete document lifecycle tracking
        - Duplicate detection using transaction keys
        
        **Use Cases:**
        - Create purchase orders to suppliers/vendors
        - Automate procurement processes
      operationId: createPurchaseOrder
      requestBody:
        required: true
        content:
          'application/json':
            schema:
              type: object
              properties:
                DocType:
                  type: string
                  example: "dDocument_Items"
                DocumentStatus:
                  type: string
                  example: "bost_Open"
                CardCode:
                  type: string
                  example: "V00001"
                CardName:
                  type: string
                  example: "Sample Supplier Ltd"
                DocDate:
                  type: string
                  format: date
                  example: "2025-01-12"
                DocDueDate:
                  type: string
                  format: date
                  example: "2025-01-19"
                SalesPersonCode:
                  type: string
                  example: "-1"
                DiscPrcnt:
                  type: number
                  example: 0
                Comments:
                  type: string
                  example: "Monthly procurement order"
                PriceMode:
                  type: string
                  example: "pmdNet"
                U_Branch:
                  type: string
                  example: "BR01"
                DocumentLines:
                  type: array
                  items:
                    type: object
                    properties:
                      LineNum:
                        type: integer
                        example: 0
                      ItemCode:
                        type: string
                        example: "RAW001"
                      ItemDescription:
                        type: string
                        example: "Raw Material Item 001"
                      Quantity:
                        type: number
                        example: 100
                      UnitPrice:
                        type: number
                        example: 25.50
                      LineTotal:
                        type: number
                        example: 2550.00
                      VatGroup:
                        type: string
                        example: "VAT_16"
                      VolumeUnit:
                        type: integer
                        example: 4
                      DiscountPercent:
                        type: number
                        example: 0
                      WarehouseCode:
                        type: string
                        example: "WH01"
                      BarCode:
                        type: string
                        example: "1234567890123"
                      MeasureUnit:
                        type: string
                        example: "KG"
                      UoMEntry:
                        type: string
                        example: "1"
                      UoMCode:
                        type: string
                        example: "KG"
                      InventoryQuantity:
                        type: number
                        example: 100
                      UnitsOfMeasurment:
                        type: number
                        example: 1
                      LineStatus:
                        type: string
                        example: "bost_Open"
                      PriceSource:
                        type: string
                        example: "dpsManual"
                      OpenQuantity:
                        type: number
                        example: 100
                      U_FreshQty:
                        type: number
                        example: 100
                      U_FreshPrice:
                        type: number
                        example: 25.50
                      U_CostEvent:
                        type: string
                        example: "PURCHASE"
                      U_FreshUOM:
                        type: string
                        example: "KG"
            example:
              DocType: "dDocument_Items"
              DocumentStatus: "bost_Open"
              CardCode: "V00001"
              CardName: "Sample Supplier Ltd"
              DocDate: "2025-01-12"
              DocDueDate: "2025-01-19"
              SalesPersonCode: "-1"
              DiscPrcnt: 0
              Comments: "Monthly procurement order"
              PriceMode: "pmdNet"
              U_Branch: "BR01"
              DocumentLines:
                - LineNum: 0
                  ItemCode: "RAW001"
                  ItemDescription: "Raw Material Item 001"
                  Quantity: 100
                  UnitPrice: 25.50
                  LineTotal: 2550.00
                  VatGroup: "VAT_16"
                  VolumeUnit: 4
                  DiscountPercent: 0
                  WarehouseCode: "WH01"
                  BarCode: "1234567890123"
                  MeasureUnit: "KG"
                  UoMEntry: "1"
                  UoMCode: "KG"
                  InventoryQuantity: 100
                  UnitsOfMeasurment: 1
                  LineStatus: "bost_Open"
                  PriceSource: "dpsManual"
                  OpenQuantity: 100
                  U_FreshQty: 100
                  U_FreshPrice: 25.50
                  U_CostEvent: "PURCHASE"
                  U_FreshUOM: "KG"
      responses:
        '201':
          description: Purchase Order created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentResponse'
              example:
                success: true
                message: "Purchase Order created successfully"
                sapDocEntry: 12345
                sapDocNum: "PO-2025-001"
                documentType: "PurchaseOrder"
                transactionKey: "PO-2025-001"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      tags:
        - Purchase Orders
      summary: Get Purchase Orders
      description: |\
        Retrieve Purchase Orders from SAP B1 in Java POJO format.
        
        **Features:**
        - Returns sample POJO data if no SAP data exists
        - Perfect for testing integration
        - Shows exact field names and data types
      operationId: getPurchaseOrders
      parameters:
        - name: $top
          in: query
          description: Maximum number of records to return
          required: false
          schema:
            type: integer
            default: 10
      responses:
        '200':
          description: Purchase Orders retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    DocEntry:
                      type: string
                      example: "12345"
                    DocNum:
                      type: string
                      example: "PO-2025-001"
                    CardCode:
                      type: string
                      example: "V00001"
                    DocumentLines:
                      type: array
                      items:
                        type: object
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /purchase-orders/{docentry}:
    get:
      tags:
        - Purchase Orders
      summary: Get Purchase Order by DocEntry
      description: |\
        Retrieve a specific Purchase Order from SAP B1 by DocEntry in Java POJO format.
        
        **Features:**
        - Returns the exact POJO format matching the POST request body
        - Direct SAP data retrieval using DocEntry
        - Perfect for individual Purchase Order lookup
        - 404 error if Purchase Order doesn't exist
      operationId: getPurchaseOrderByDocEntry
      parameters:
        - name: docentry
          in: path
          required: true
          description: SAP Purchase Order DocEntry number
          schema:
            type: integer
            example: 12345
      responses:
        '200':
          description: Purchase Order retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  DocEntry:
                    type: integer
                    example: 12345
                  DocNum:
                    type: integer 
                    example: 240000725
                  Cancelled:
                    type: string
                    example: "tNO"
                  DocType:
                    type: string
                    example: "dDocument_Items"
                  DocumentStatus:
                    type: string
                    example: "bost_Open"
                  DocDate:
                    type: string
                    format: date
                    example: "2024-12-01"
                  DocDueDate:
                    type: string
                    format: date
                    example: "2024-12-01"
                  CardCode:
                    type: string
                    example: "P-00255"
                  CardName:
                    type: string
                    example: "Khalil Daowd Ali Alsrkhi"
                  DiscPrcnt:
                    type: number
                    example: 0
                  DocTotal:
                    type: number
                    nullable: true
                    example: null
                  SalesPersonCode:
                    type: integer
                    example: -1
                  Comments:
                    type: string
                    nullable: true
                    example: null
                  PriceMode:
                    type: string
                    example: "pmdGross"
                  U_Branch:
                    type: string
                    example: "WH005"
                  DocumentLines:
                    type: array
                    items:
                      type: object
                      properties:
                        LineNum:
                          type: integer
                          example: 0
                        ItemCode:
                          type: string
                          example: "11038"
                        ItemDescription:
                          type: string
                          example: "SPINACH (BUNCH)"
                        Quantity:
                          type: number
                          example: 30
                        UnitPrice:
                          type: number
                          example: 0
                        LineTotal:
                          type: number
                          example: 0
                        VatGroup:
                          type: string
                          example: "PV002"
                        VolumeUnit:
                          type: integer
                          example: 4
                        DiscountPercent:
                          type: number
                          example: 0
                        WarehouseCode:
                          type: string
                          example: "WH005"
                        BarCode:
                          type: string
                          example: "00297"
                        MeasureUnit:
                          type: string
                          example: "Manual"
                        UoMEntry:
                          type: integer
                          example: -1
                        UoMCode:
                          type: string
                          example: "Manual"
                        InventoryQuantity:
                          type: number
                          example: 30
                        UnitsOfMeasurment:
                          type: integer
                          example: 1
                        LineStatus:
                          type: string
                          example: "bost_Open"
                        PriceSource:
                          type: string
                          example: "dpsManual"
                        OpenQuantity:
                          type: number
                          example: 0
                        U_FreshQty:
                          type: string
                          example: "30.000000"
                        U_FreshPrice:
                          type: string
                          example: "0"
                        U_CostEvent:
                          type: string
                          example: "N"
                        U_FreshUOM:
                          type: string
                          nullable: true  
                          example: null
              example:
                DocEntry: 12345
                DocNum: 240000725
                Cancelled: "tNO"
                DocType: "dDocument_Items"
                DocumentStatus: "bost_Open"
                DocDate: "2024-12-01"
                DocDueDate: "2024-12-01"
                CardCode: "P-00255"
                CardName: "Khalil Daowd Ali Alsrkhi"
                DiscPrcnt: 0
                DocTotal: null
                SalesPersonCode: -1
                Comments: null
                PriceMode: "pmdGross"
                U_Branch: "WH005"
                DocumentLines:
                  - LineNum: 0
                    ItemCode: "11038"
                    ItemDescription: "SPINACH (BUNCH)"
                    Quantity: 30
                    UnitPrice: 0
                    LineTotal: 0
                    VatGroup: "PV002"
                    VolumeUnit: 4
                    DiscountPercent: 0
                    WarehouseCode: "WH005"
                    BarCode: "00297"
                    MeasureUnit: "Manual"
                    UoMEntry: -1
                    UoMCode: "Manual"
                    InventoryQuantity: 30
                    UnitsOfMeasurment: 1
                    LineStatus: "bost_Open"
                    PriceSource: "dpsManual"
                    OpenQuantity: 0
                    U_FreshQty: "30.000000"
                    U_FreshPrice: "0"
                    U_CostEvent: "N"
                    U_FreshUOM: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/status:
    get:
      tags:
        - SAP HANA
      summary: Check SAP HANA Connection Status
      description: |
        Returns the health status of the SAP HANA database connection, including:
        - Connection pool statistics
        - Active/available connections
        - Database connectivity test
        - HANA client availability
      operationId: getHanaStatus
      responses:
        '200':
          description: HANA connection status retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  database:
                    type: object
                    properties:
                      success:
                        type: boolean
                      timestamp:
                        type: string
                        format: date-time
                      poolStats:
                        $ref: '#/components/schemas/HanaPoolStats'
                  pool:
                    $ref: '#/components/schemas/HanaPoolStats'
                  timestamp:
                    type: string
                    format: date-time
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/query:
    post:
      tags:
        - SAP HANA
      summary: Execute Custom SQL Query
      description: |
        Execute a custom SQL query against the SAP HANA database.
        
        **Security Features:**
        - SQL injection prevention
        - Query validation
        - Prepared statement support
        
        **Supported Query Types:**
        - SELECT statements
        - JOIN operations
        - Aggregate functions
        - WHERE clauses with parameters
      operationId: executeHanaQuery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - query
              properties:
                query:
                  type: string
                  description: SQL query to execute (SELECT statements only for security)
                  example: 'SELECT "ItemCode", "ItemName" FROM "OITM" WHERE "validFor" = ? LIMIT ?'
                params:
                  type: array
                  description: Query parameters for prepared statements
                  items:
                    oneOf:
                      - type: string
                      - type: number
                      - type: boolean
                  example: ["Y", 10]
                options:
                  type: object
                  properties:
                    returnMetadata:
                      type: boolean
                      description: Include column metadata in response
                      default: false
      responses:
        '200':
          description: Query executed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                  rowCount:
                    type: integer
                  duration:
                    type: string
                    example: "145ms"
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/items:
    get:
      tags:
        - SAP HANA
      summary: Get Item Master Data
      description: |
        Retrieve item master data from SAP HANA (OITM table).
        
        **Returns:**
        - ItemCode, ItemName, ForeignName
        - Item Groups, Categories, Sub-groups
        - VAT Groups, UoM Groups
        - Barcodes, Suppliers
        - Pricing information
        - Warehouse data
        - Custom fields
      operationId: getHanaItems
      parameters:
        - name: itemCode
          in: query
          schema:
            type: string
          description: Filter by item code
          example: "10000"
        - name: itemName
          in: query
          schema:
            type: string
          description: Filter by item name (partial match)
          example: "spinach"
        - name: groupCode
          in: query
          schema:
            type: integer
          description: Filter by item group code
          example: 114
        - name: active
          in: query
          schema:
            type: string
            enum: [Y, N]
          description: Filter by active status (validFor field)
          example: "Y"
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
            maximum: 1000
          description: Maximum number of records to return
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
          description: Number of records to skip (for pagination)
      responses:
        '200':
          description: Items retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/HanaItem'
                  rowCount:
                    type: integer
                  pagination:
                    type: object
                    properties:
                      limit:
                        type: integer
                      offset:
                        type: integer
                      hasMore:
                        type: boolean
                  duration:
                    type: string
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/item-groups:
    get:
      tags:
        - SAP HANA
      summary: Get Item Groups
      description: Retrieve all item groups from SAP HANA (OITB table)
      operationId: getHanaItemGroups
      responses:
        '200':
          description: Item groups retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        GroupCode:
                          type: integer
                          example: 104
                        GroupName:
                          type: string
                          example: "BEVERAGES"
                  rowCount:
                    type: integer
                    example: 22
              example:
                success: true
                data:
                  - GroupCode: 104
                    GroupName: "BEVERAGES"
                  - GroupCode: 105
                    GroupName: "GROCERY"
                  - GroupCode: 114
                    GroupName: "PRODUCE"
                rowCount: 22
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/vat-groups:
    get:
      tags:
        - SAP HANA
      summary: Get VAT Groups
      description: Retrieve all VAT groups from SAP HANA (OVTG table)
      operationId: getHanaVatGroups
      responses:
        '200':
          description: VAT groups retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        Code:
                          type: string
                        Name:
                          type: string
                        Rate:
                          type: number
                  rowCount:
                    type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/uom-groups:
    get:
      tags:
        - SAP HANA
      summary: Get UOM Groups
      description: Retrieve all Unit of Measurement groups from SAP HANA (OUGP table)
      operationId: getHanaUomGroups
      responses:
        '200':
          description: UOM groups retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        UgpEntry:
                          type: integer
                        UgpCode:
                          type: string
                        UgpName:
                          type: string
                        BaseUom:
                          type: integer
                  rowCount:
                    type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/price-lists:
    get:
      tags:
        - SAP HANA
      summary: Get Price Lists
      description: Retrieve all price lists from SAP HANA (OPLN table)
      operationId: getHanaPriceLists
      responses:
        '200':
          description: Price lists retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        ListNum:
                          type: integer
                        ListName:
                          type: string
                        IsGrossPrice:
                          type: string
                        Active:
                          type: string
                        BasePriceList:
                          type: integer
                  rowCount:
                    type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/warehouses:
    get:
      tags:
        - SAP HANA
      summary: Get Warehouses
      description: Retrieve all warehouses from SAP HANA (OWHS table)
      operationId: getHanaWarehouses
      responses:
        '200':
          description: Warehouses retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        WhsCode:
                          type: string
                        WhsName:
                          type: string
                        Street:
                          type: string
                        City:
                          type: string
                        Country:
                          type: string
                  rowCount:
                    type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/vendors:
    get:
      tags:
        - SAP HANA
      summary: Get Vendors
      description: Retrieve vendor/supplier data from SAP HANA (OCRD table where CardType = 'S')
      operationId: getHanaVendors
      parameters:
        - name: cardCode
          in: query
          schema:
            type: string
          description: Filter by vendor code
        - name: cardName
          in: query
          schema:
            type: string
          description: Filter by vendor name (partial match)
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
          description: Maximum number of records to return
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
          description: Number of records to skip
      responses:
        '200':
          description: Vendors retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        CardCode:
                          type: string
                        CardName:
                          type: string
                        CardType:
                          type: string
                        Phone1:
                          type: string
                        E_Mail:
                          type: string
                        Address:
                          type: string
                  rowCount:
                    type: integer
                  pagination:
                    type: object
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/item-barcodes/{itemCode}:
    get:
      tags:
        - SAP HANA
      summary: Get Item Barcodes
      description: Retrieve all barcodes for a specific item from SAP HANA (OBCD table)
      operationId: getItemBarcodes
      parameters:
        - name: itemCode
          in: path
          required: true
          schema:
            type: string
          description: Item code to retrieve barcodes for
          example: "10000"
      responses:
        '200':
          description: Barcodes retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        ItemCode:
                          type: string
                        BcdCode:
                          type: string
                        BcdEntry:
                          type: integer
                        UomEntry:
                          type: integer
                  rowCount:
                    type: integer
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/validate-barcode/{barcode}:
    get:
      tags:
        - SAP HANA
      summary: Validate Barcode Uniqueness
      description: Check if a barcode already exists in SAP HANA and return associated item details if found
      operationId: validateBarcode
      parameters:
        - name: barcode
          in: path
          required: true
          schema:
            type: string
          description: Barcode to validate
          example: "6253506001260"
      responses:
        '200':
          description: Barcode validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  exists:
                    type: boolean
                    description: Whether the barcode exists in the database
                  data:
                    type: object
                    description: Item details if barcode exists
                    properties:
                      ItemCode:
                        type: string
                      ItemName:
                        type: string
                      BcdCode:
                        type: string
                      UomEntry:
                        type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/schema:
    get:
      tags:
        - SAP HANA
      summary: List Available Schemas
      description: Retrieve list of all available schemas in the SAP HANA database
      operationId: getHanaSchemas
      responses:
        '200':
          description: Schemas retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        SCHEMA_NAME:
                          type: string
                  rowCount:
                    type: integer
        '500':
          $ref: '#/components/responses/InternalError'

  /hana/table-columns/{schema}/{table}:
    get:
      tags:
        - SAP HANA
      summary: Get Table Column Metadata
      description: Retrieve column definitions and metadata for a specific table in SAP HANA
      operationId: getTableColumns
      parameters:
        - name: schema
          in: path
          required: true
          schema:
            type: string
          description: Schema name
          example: "SHINI_EXTRA_JO"
        - name: table
          in: path
          required: true
          schema:
            type: string
          description: Table name
          example: "OITM"
      responses:
        '200':
          description: Table columns retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        COLUMN_NAME:
                          type: string
                        DATA_TYPE_NAME:
                          type: string
                        LENGTH:
                          type: integer
                        IS_NULLABLE:
                          type: string
                        DEFAULT_VALUE:
                          type: string
                  rowCount:
                    type: integer
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication

  parameters:
    DocumentType:
      name: type
      in: path
      required: true
      description: Document type
      schema:
        type: string
        enum: [invoice, creditNote, payment, goodreceipt]
        example: invoice
    
    DocEntry:
      name: docEntry
      in: path
      required: true
      description: SAP document entry number
      schema:
        type: string
        example: "12345"
    
    Filter:
      name: filter
      in: query
      description: OData filter expression
      schema:
        type: string
        example: "DocStatus eq 'O'"
    
    Select:
      name: select
      in: query
      description: Fields to return
      schema:
        type: string
        example: "DocEntry,DocNum,CardCode,DocTotal"
    
    Top:
      name: top
      in: query
      description: Number of records to return
      schema:
        type: integer
        default: 20
        minimum: 1
        maximum: 1000
    
    Skip:
      name: skip
      in: query
      description: Number of records to skip
      schema:
        type: integer
        default: 0
        minimum: 0

  schemas:
    # Health Schemas
    HealthResponse:
      type: object
      properties:
        status:
          type: string
          enum: [healthy, degraded, unhealthy]
        service:
          type: string
        version:
          type: string
        timestamp:
          type: string
          format: date-time
        uptime:
          type: number
          description: Uptime in seconds
        environment:
          type: string
        sap:
          type: object
          properties:
            connected:
              type: boolean
            url:
              type: string

    # SAP HANA Schemas
    HanaPoolStats:
      type: object
      properties:
        poolSize:
          type: integer
          description: Total number of connections in the pool
          example: 2
        activeConnections:
          type: integer
          description: Number of connections currently in use
          example: 0
        availableConnections:
          type: integer
          description: Number of connections available for use
          example: 2
        isInitialized:
          type: boolean
          description: Whether the pool has been initialized
          example: true
        reconnectAttempts:
          type: integer
          description: Number of reconnection attempts made
          example: 0
        hanaClientAvailable:
          type: boolean
          description: Whether the SAP HANA native client is installed
          example: true
        config:
          type: object
          properties:
            min:
              type: integer
              example: 2
            max:
              type: integer
              example: 10
            idleTimeout:
              type: integer
              example: 30000
            acquireTimeout:
              type: integer
              example: 60000

    HanaItem:
      type: object
      description: SAP Item Master Data from OITM table
      properties:
        ItemCode:
          type: string
          example: "10000"
        ItemName:
          type: string
          example: "Bzuriyeh turmaric powder 110g"
        ForeignName:
          type: string
          example: "بزورية مسحوق كركم110غم"
        ItemsGroupCode:
          type: integer
          example: 105
        BarCode:
          type: string
          example: "6253501471174"
        PurchaseItem:
          type: string
          enum: [Y, N]
        SalesItem:
          type: string
          enum: [Y, N]
        InventoryItem:
          type: string
          enum: [Y, N]
        ItemType:
          type: string
          enum: [I, L, T, F]
          description: I=Item, L=Labor, T=Travel, F=Fixed Asset
        SalesVATGroup:
          type: string
          example: "SV009"
        PurchaseVATGroup:
          type: string
          example: "PV009"
        U_MA_ItemSubGroup:
          type: string
          example: "PEPPER & SPICES"
        U_MA_ItemCategory:
          type: string
          example: "POUCHES SPICES"
        U_CUSTOM_AOP_UOM:
          type: string
          enum: [Y, N]
        UoMGroupEntry:
          type: integer
          example: 31
        InventoryUoMEntry:
          type: integer
          example: 1
        U_ItemSerial:
          type: string
          nullable: true
        U_SCALE_ITEM:
          type: string
          enum: [Y, N]
        U_SCALE_PIECE:
          type: string
          enum: [Y, N]
        DefaultSalesUoMEntry:
          type: integer
        DefaultPurchasingUoMEntry:
          type: integer
        Mainsupplier:
          type: string
          example: "P-00078"
        Valid:
          type: string
          enum: [Y, N]
          description: Whether item is active
        Frozen:
          type: string
          enum: [Y, N]
        CreateDate:
          type: string
          format: date-time
        UpdateDate:
          type: string
          format: date-time

    DetailedHealthResponse:
      allOf:
        - $ref: '#/components/schemas/HealthResponse'
        - type: object
          properties:
            server:
              type: object
              properties:
                hostname:
                  type: string
                platform:
                  type: string
                nodeVersion:
                  type: string
                memory:
                  type: object
                cpu:
                  type: object
            process:
              type: object
              properties:
                pid:
                  type: integer
                memory:
                  type: object
                cpuUsage:
                  type: object

    SAPHealthResponse:
      type: object
      properties:
        status:
          type: string
          enum: [connected, disconnected, error]
        session:
          type: object
          properties:
            active:
              type: boolean
            timeout:
              type: integer
            loginTime:
              type: string
              format: date-time
            age:
              type: object
        config:
          type: object
          properties:
            url:
              type: string
            company:
              type: string
            user:
              type: string

    # Document Line Schema
    DocumentLine:
      type: object
      required:
        - itemCode
        - quantity
        - unitPrice
        - warehouseCode
      properties:
        itemCode:
          type: string
          description: Item/Product code
          example: "ITEM001"
        barcode:
          type: string
          description: Item barcode
          example: "1234567890123"
        description:
          type: string
          description: Item description
          example: "Product Name"
        quantity:
          type: number
          minimum: 0.01
          description: Quantity
          example: 2
        unitPrice:
          type: number
          minimum: 0
          description: Unit price
          example: 50.00
        totalAmount:
          type: number
          description: Line total amount
          example: 100.00
        discountPercent:
          type: number
          minimum: 0
          maximum: 100
          description: Discount percentage
          example: 10
        taxCode:
          type: string
          description: Tax code
          example: "VAT16"
        warehouseCode:
          type: string
          description: Warehouse code
          example: "WH01"
        projectCode:
          type: string
          description: Project code
          example: "PROJ01"
        costCenter:
          type: string
          description: Cost center
        notes:
          type: string
          description: Line notes
        serialNumbers:
          type: array
          items:
            type: string
          description: Serial numbers for serialized items
        batchNumbers:
          type: array
          items:
            type: object
            properties:
              number:
                type: string
              quantity:
                type: number

    # Invoice Request Schema
    InvoiceRequest:
      type: object
      required:
        - lines
      properties:
        transactionKey:
          type: string
          description: Unique transaction identifier
          example: "TRX-001"
        businessDate:
          type: string
          format: date
          description: Business date (YYYY-MM-DD)
          example: "2025-01-08"
        dueDate:
          type: string
          format: date
          description: Due date
        customerCode:
          type: string
          description: Customer code in SAP
          example: "C00001"
        customerName:
          type: string
          description: Customer name
          example: "John Doe"
        currency:
          type: string
          description: Currency code
          example: "JOD"
        exchangeRate:
          type: number
          description: Exchange rate
          example: 1
        warehouseCode:
          type: string
          description: Default warehouse code
          example: "WH01"
        projectCode:
          type: string
          description: Project code
          example: "PROJ01"
        storeCode:
          type: string
          description: Store code
          example: "STORE01"
        terminalId:
          type: string
          description: Terminal ID
          example: "TERM01"
        referenceNumber:
          type: string
          description: External reference number
        comments:
          type: string
          description: Invoice comments
        discountPercent:
          type: number
          minimum: 0
          maximum: 100
          description: Overall discount percentage
        salesPersonCode:
          type: string
          description: Sales person code
        paymentTerms:
          type: integer
          description: Payment terms code
        lines:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/DocumentLine'
        shippingAddress:
          type: object
          properties:
            code:
              type: string
            street:
              type: string
            city:
              type: string
            country:
              type: string

    # Credit Note Request Schema
    CreditNoteRequest:
      type: object
      required:
        - lines
      properties:
        transactionKey:
          type: string
          description: Unique transaction identifier
          example: "CN-001"
        businessDate:
          type: string
          format: date
          description: Business date (YYYY-MM-DD)
        customerCode:
          type: string
          description: Customer code in SAP
          example: "C00001"
        customerName:
          type: string
          description: Customer name
        originalInvoiceDocEntry:
          type: string
          description: Original invoice document entry
          example: "12345"
        originalInvoiceKey:
          type: string
          description: Original invoice transaction key
          example: "TRX-001"
        refundReason:
          type: string
          description: Reason for refund
          example: "Customer return"
        comments:
          type: string
          description: Credit note comments
        lines:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/DocumentLine'

    # Good Receipt Request Schema
    GoodReceiptRequest:
      type: object
      description: Good Receipt request matching Java POJO structure (org.shini.sap_integration.pojo.goodReceipt.GoodReceipt)
      required:
        - lines
      properties:
        transactionKey:
          type: string
          description: Unique transaction identifier
          example: "GR-001"
        supplierCode:
          type: string
          description: Supplier/Vendor code in SAP
          example: "V00001"
        supplierName:
          type: string
          description: Supplier/Vendor name
          example: "ABC Suppliers Ltd"
        docDate:
          type: string
          format: date
          description: Document date (YYYY-MM-DD)
          example: "2025-01-08"
        docDueDate:
          type: string
          format: date
          description: Due date
        referenceNumber:
          type: string
          description: External reference number
          example: "PO-12345"
        branch:
          type: string
          description: Branch code
          example: "BR01"
        baseEntry:
          type: string
          description: Base document entry (Purchase Order)
        comments:
          type: string
          description: Receipt comments
        warehouseCode:
          type: string
          description: Default warehouse code
          example: "WH01"
        salesPersonCode:
          type: integer
          description: Sales person code
        project:
          type: string
          description: Project code
        lines:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/GoodReceiptLine'

    # Good Receipt Line Schema
    GoodReceiptLine:
      type: object
      description: Good Receipt line item matching Java POJO structure (org.shini.sap_integration.pojo.goodReceipt.GoodReceiptDetail)
      required:
        - itemCode
        - quantity
        - warehouseCode
      properties:
        itemCode:
          type: string
          description: Item/Product code
          example: "ITEM001"
        barcode:
          type: string
          description: Item barcode
        itemDescription:
          type: string
          description: Item description
          example: "Raw Material A"
        quantity:
          type: number
          minimum: 0.01
          description: Quantity received
          example: 100
        baseQty:
          type: number
          description: Base quantity
        unitPrice:
          type: number
          minimum: 0
          description: Unit price
          example: 15.50
        warehouseCode:
          type: string
          description: Warehouse code
          example: "WH01"
        baseEntry:
          type: string
          description: Purchase Order DocEntry
        baseLine:
          type: integer
          description: Purchase Order line number
        baseType:
          type: string
          description: Base document type (22 = Purchase Order)
          default: "22"
        taxCode:
          type: string
          description: Tax code
        discountPercent:
          type: number
          minimum: 0
          maximum: 100
        projectCode:
          type: string
          description: Project code
        costingCode:
          type: string
          description: Cost center 1
        costingCode2:
          type: string
          description: Cost center 2
        comments:
          type: string
          description: Line comments
        correctQuantity:
          type: number
          description: Corrected quantity
        costEvent:
          type: string
          description: Cost event
        tempPrice:
          type: number
          description: Temporary price
        freshUOM:
          type: string
          description: Fresh unit of measure (for perishables)
        freshQty:
          type: number
          description: Fresh quantity
        freshPrice:
          type: number
          description: Fresh price
        batchNumbers:
          type: array
          description: Batch numbers for batch-managed items
          items:
            type: object
            properties:
              number:
                type: string
                description: Batch number
              quantity:
                type: number
                description: Quantity in this batch
              expiryDate:
                type: string
                format: date
                description: Expiry date
              manufacturingDate:
                type: string
                format: date
                description: Manufacturing date
        serialNumbers:
          type: array
          description: Serial numbers for serialized items
          items:
            type: string

    # Payment Request Schema
    PaymentRequest:
      type: object
      required:
        - amount
        - paymentMethod
      properties:
        paymentKey:
          type: string
          description: Unique payment identifier
          example: "PAY-001"
        paymentDate:
          type: string
          format: date
          description: Payment date
        customerCode:
          type: string
          description: Customer code
          example: "C00001"
        customerName:
          type: string
          description: Customer name
        amount:
          type: number
          minimum: 0.01
          description: Payment amount
          example: 100.00
        currency:
          type: string
          description: Currency code
          example: "JOD"
        paymentMethod:
          type: string
          enum: [Cash, Check, CreditCard, BankTransfer]
          description: Payment method
          example: "Cash"
        reference:
          type: string
          description: Payment reference
        remarks:
          type: string
          description: Payment remarks
        invoiceDocEntry:
          type: string
          description: Invoice to apply payment to
        invoices:
          type: array
          description: Multiple invoices to apply payment to
          items:
            type: object
            properties:
              docEntry:
                type: string
              amount:
                type: number
        # Cash payment fields
        cashAccount:
          type: string
          description: GL account for cash payment
        # Check payment fields
        checkNumber:
          type: string
          description: Check number
        bankCode:
          type: string
          description: Bank code
        # Credit card fields
        cardType:
          type: string
          description: Credit card type
        authorizationCode:
          type: string
          description: Authorization code
        # Bank transfer fields
        transferReference:
          type: string
          description: Bank transfer reference

    # Batch Request Schema
    BatchRequest:
      type: object
      required:
        - documents
      properties:
        documents:
          type: array
          minItems: 1
          maxItems: 100
          items:
            type: object
            required:
              - type
              - data
            properties:
              type:
                type: string
                enum: [invoice, creditNote, payment, goodreceipt]
              data:
                type: object
                additionalProperties: true

    # Response Schemas
    DocumentResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: "Document processed successfully"
        sapDocEntry:
          type: string
          description: SAP document entry number
          example: "12345"
        sapDocNum:
          type: string
          description: SAP document number
          example: "INV-2025-001"
        documentType:
          type: string
          example: "Invoice"
        duration:
          type: string
          example: "234ms"
        data:
          type: object
          description: Additional SAP response data

    # SAP API Format Schema (What actually gets sent to SAP)
    SAPGoodReceiptFormat:
      type: object
      description: Exact format sent to SAP API - Java POJO structure (org.shini.sap_integration.pojo.goodReceipt.GoodReceipt)
      properties:
        DocType:
          type: string
          example: "dDocument_Items"
          description: Fixed document type
        DocObjectCode:
          type: string
          example: "oPurchaseDeliveryNotes"
          description: Fixed object code
        PriceSource:
          type: string
          example: "dpsManual"
          description: Fixed price source
        CardCode:
          type: string
          example: "V00001"
          description: Supplier/Vendor code
        CardName:
          type: string
          example: "ABC Suppliers Ltd"
          description: Supplier/Vendor name
        DocDate:
          type: string
          example: "2025-01-08"
          description: Document date
        DocDueDate:
          type: string
          example: "2025-01-15"
          description: Document due date
        SalesPersonCode:
          type: integer
          example: 5
          description: Sales person code
        U_BaseEntry:
          type: string
          example: "98765"
          description: Custom field - Base entry reference
        U_BRANCH:
          type: string
          example: "BR01"
          description: Custom field - Branch code
        DocumentLines:
          type: array
          description: Array of line items in SAP POJO format
          items:
            $ref: '#/components/schemas/SAPGoodReceiptLineFormat'

    SAPGoodReceiptLineFormat:
      type: object
      description: SAP POJO line format (org.shini.sap_integration.pojo.goodReceipt.GoodReceiptDetail)
      properties:
        LineNum:
          type: integer
          example: 0
          description: Auto-assigned line number
        ItemCode:
          type: string
          example: "RAW001"
          description: Item code
        ItemDescription:
          type: string
          example: "Raw Material Type A"
          description: Item description
        BarCode:
          type: string
          example: "1234567890123"
          description: Item barcode
        Quantity:
          type: number
          example: 50
          description: Item quantity
        BaseQty:
          type: number
          example: 50
          description: Base quantity
        WarehouseCode:
          type: string
          example: "WH01"
          description: Warehouse code
        UnitPrice:
          type: number
          example: 15.50
          description: Unit price
        BaseEntry:
          type: string
          example: "98765"
          description: Base document entry
        BaseType:
          type: string
          example: "22"
          description: Base document type (PO)
        BaseLine:
          type: integer
          example: 0
          description: Base document line
        CorrectQuantity:
          type: number
          example: 49.5
          description: Correct quantity (direct POJO field)
        CostingCode:
          type: string
          example: "DEPT-PROD"
          description: Costing code 1
        CostingCode2:
          type: string
          example: "PROJECT-A"
          description: Costing code 2
        U_Comments:
          type: string
          example: "Quality checked"
          description: Custom field - Line comments
        U_CostEvent:
          type: string
          example: "HARVEST-2025"
          description: Custom field - Cost event
        U_FreshUOM:
          type: string
          example: "KG"
          description: Custom field - Fresh UOM
        U_FreshQty:
          type: number
          example: 24.8
          description: Custom field - Fresh quantity
        U_FreshPrice:
          type: number
          example: 8.50
          description: Custom field - Fresh price
        UoMEntry:
          type: integer
          example: 1
          description: Unit of Measure Entry
        UoMCode:
          type: string
          example: "KG"
          description: Unit of Measure Code
        VolumeUnit:
          type: string
          nullable: true
          example: null
          description: Volume unit (always null)
        Volume:
          type: number
          example: 0.0
          description: Volume (always 0.0)
        BatchNumbers:
          type: array
          description: Batch numbers for batch-managed items
          items:
            type: object
            properties:
              BatchNumber:
                type: string
                example: "BATCH-2025-001"
              Quantity:
                type: number
                example: 30
              ManufacturingDate:
                type: string
                example: "2024-12-01"
              ExpiryDate:
                type: string
                example: "2026-12-01"

    # AP Invoice Request Schema  
    APInvoiceRequest:
      type: object
      description: AP Invoice request matching Java POJO structure (org.shini.sap_integration.pojo.apInvoice.APInvoice)
      required:
        - lines
      properties:
        transactionKey:
          type: string
          example: "API-2025-001"
          description: Unique transaction identifier
        supplierCode:
          type: string
          example: "V00001"
          description: Supplier/Vendor code (can also use vendorCode or cardCode)
        vendorCode:
          type: string
          example: "V00001"
          description: Alternative to supplierCode
        cardCode:
          type: string
          example: "V00001"
          description: Alternative to supplierCode
        supplierName:
          type: string
          example: "ABC Suppliers Ltd"
          description: Supplier/Vendor name (can also use vendorName or cardName)
        vendorName:
          type: string
          example: "ABC Suppliers Ltd"
          description: Alternative to supplierName
        cardName:
          type: string
          example: "ABC Suppliers Ltd"
          description: Alternative to supplierName
        docDate:
          type: string
          example: "2025-01-08"
          description: Invoice date (can also use businessDate)
        businessDate:
          type: string
          example: "2025-01-08"
          description: Alternative to docDate
        docDueDate:
          type: string
          example: "2025-01-15"
          description: Invoice due date (can also use dueDate)
        dueDate:
          type: string
          example: "2025-01-15"
          description: Alternative to docDueDate
        salesPersonCode:
          type: integer
          example: 5
          description: Sales person code
        baseEntry:
          type: string
          example: "GR-001"
          description: Base entry reference (can also use sourceDocumentId)
        sourceDocumentId:
          type: string
          example: "GR-001"
          description: Alternative to baseEntry
        branch:
          type: string
          example: "BR01"
          description: Branch code
        priceSource:
          type: string
          example: "dpsManual"
          description: Price source method
        lines:
          type: array
          description: Array of AP Invoice line items
          minItems: 1
          items:
            type: object
            required:
              - itemCode
              - quantity
            properties:
              itemCode:
                type: string
                example: "RAW001"
                description: Item code
              itemDescription:
                type: string
                example: "Raw Material Type A"
                description: Item description (can also use description)
              description:
                type: string
                example: "Raw Material Type A"
                description: Alternative to itemDescription
              quantity:
                type: number
                example: 50
                description: Quantity
              warehouseCode:
                type: string
                example: "WH01"
                description: Warehouse code (can also use warehouse)
              unitPrice:
                type: number
                example: 15.50
                description: Unit price
              uomEntry:
                type: integer
                example: 1
                description: Unit of Measure Entry (can also use UoMEntry)
              UoMEntry:
                type: integer
                example: 1
                description: Alternative to uomEntry
              uomCode:
                type: string
                example: "KG"
                description: Unit of Measure Code (can also use UoMCode)
              UoMCode:
                type: string
                example: "KG"
                description: Alternative to uomCode

    # SAP AP Invoice Format Schema (What actually gets sent to SAP)
    SAPAPInvoiceFormat:
      type: object
      description: Exact format sent to SAP API - Java POJO structure (org.shini.sap_integration.pojo.apInvoice.APInvoice)
      properties:
        DocType:
          type: string
          example: "dDocument_Items"
          description: Fixed document type
        DocObjectCode:
          type: string
          example: "oPurchaseInvoices"
          description: Fixed object code for AP Invoice
        PriceSource:
          type: string
          example: "dpsManual"
          description: Fixed price source
        CardCode:
          type: string
          example: "V00001"
          description: Supplier/Vendor code
        CardName:
          type: string
          example: "ABC Suppliers Ltd"
          description: Supplier/Vendor name
        DocDate:
          type: string
          example: "2025-01-08"
          description: Invoice date
        DocDueDate:
          type: string
          example: "2025-01-15"
          description: Invoice due date
        SalesPersonCode:
          type: integer
          example: 5
          description: Sales person code
        U_BaseEntry:
          type: string
          example: "GR-001"
          description: Custom field - Base entry reference
        U_BRANCH:
          type: string
          example: "BR01"
          description: Custom field - Branch code
        DocumentLines:
          type: array
          description: Array of line items in SAP POJO format
          items:
            $ref: '#/components/schemas/SAPAPInvoiceLineFormat'

    SAPAPInvoiceLineFormat:
      type: object
      description: SAP POJO line format (org.shini.sap_integration.pojo.apInvoice.APInvoiceDetail)
      properties:
        LineNum:
          type: integer
          example: 0
          description: Auto-assigned line number
        ItemCode:
          type: string
          example: "RAW001"
          description: Item code
        ItemDescription:
          type: string
          example: "Raw Material Type A"
          description: Item description
        BarCode:
          type: string
          example: "1234567890123"
          description: Item barcode
        Quantity:
          type: number
          example: 50
          description: Item quantity
        BaseQty:
          type: number
          example: 50
          description: Base quantity
        WarehouseCode:
          type: string
          example: "WH01"
          description: Warehouse code
        UnitPrice:
          type: number
          example: 15.50
          description: Unit price
        BaseEntry:
          type: string
          example: "98765"
          description: Base document entry
        BaseType:
          type: string
          example: "20"
          description: Base document type (AP Invoice - different from Good Receipt "22")
        BaseLine:
          type: integer
          example: 0
          description: Base document line
        CorrectQuantity:
          type: number
          example: 50.0
          description: Correct quantity (direct POJO field)
        CostingCode:
          type: string
          example: "DEPT-PROD"
          description: Costing code 1
        CostingCode2:
          type: string
          example: "PROJECT-A"
          description: Costing code 2
        U_Comments:
          type: string
          example: "Invoice line item"
          description: Custom field - Line comments
        U_CostEvent:
          type: string
          example: "PURCHASE"
          description: Custom field - Cost event
        U_FreshUOM:
          type: string
          example: "KG"
          description: Custom field - Fresh UOM
        U_FreshQty:
          type: number
          example: 50.0
          description: Custom field - Fresh quantity
        U_FreshPrice:
          type: number
          example: 15.50
          description: Custom field - Fresh price
        UoMEntry:
          type: integer
          example: 1
          description: Unit of Measure Entry
        UoMCode:
          type: string
          example: "KG"
          description: Unit of Measure Code
        VolumeUnit:
          type: string
          nullable: true
          example: null
          description: Volume unit (always null)
        Volume:
          type: number
          example: 0.0
          description: Volume (always 0.0)

    # Stock Transfer Request Schema  
    StockTransferRequest:
      type: object
      description: Stock Transfer request matching Java POJO structure (org.shini.sap_integration.pojo.stockTransfer.StockTransfer)
      required:
        - lines
        - fromWarehouse
        - toWarehouse
      properties:
        transactionKey:
          type: string
          example: "ST-2025-001"
          description: Unique transaction identifier
        docDate:
          type: string
          example: "2025-01-08"
          description: Transfer date (can also use businessDate)
        businessDate:
          type: string
          example: "2025-01-08"
          description: Alternative to docDate
        dueDate:
          type: string
          example: "2025-01-15"
          description: Due date (can also use docDueDate)
        docDueDate:
          type: string
          example: "2025-01-15"
          description: Alternative to dueDate
        fromWarehouse:
          type: string
          example: "WH01"
          description: Source warehouse code (can also use fromWarehouseCode)
        fromWarehouseCode:
          type: string
          example: "WH01"
          description: Alternative to fromWarehouse
        toWarehouse:
          type: string
          example: "WH02"
          description: Destination warehouse code (can also use toWarehouseCode)
        toWarehouseCode:
          type: string
          example: "WH02"
          description: Alternative to toWarehouse
        baseEntry:
          type: string
          example: "ST-001"
          description: Base entry reference (can also use sourceDocumentId or u_BaseEntry)
        sourceDocumentId:
          type: string
          example: "ST-001"
          description: Alternative to baseEntry
        u_BaseEntry:
          type: string
          example: "ST-001"
          description: Alternative to baseEntry
        type:
          type: string
          enum: ["Waste", "Damage"]
          example: "Waste"
          description: Transfer type - Waste OR Damage (can also use u_Type or transferType)
        u_Type:
          type: string
          enum: ["Waste", "Damage"]
          example: "Waste"
          description: Alternative to type
        transferType:
          type: string
          enum: ["Waste", "Damage"]
          example: "Waste"
          description: Alternative to type
        priceList:
          type: string
          example: "1"
          description: Price list (defaults to "1")
        lines:
          type: array
          description: Array of Stock Transfer line items
          minItems: 1
          items:
            type: object
            required:
              - itemCode
              - quantity
            properties:
              itemCode:
                type: string
                example: "RAW001"
                description: Item code
              itemDescription:
                type: string
                example: "Raw Material Type A"
                description: Item description (can also use description)
              description:
                type: string
                example: "Raw Material Type A"
                description: Alternative to itemDescription
              quantity:
                type: number
                example: 50
                description: Quantity to transfer
              warehouseCode:
                type: string
                example: "WH02"
                description: Destination warehouse code (can also use warehouse)
              warehouse:
                type: string
                example: "WH02"
                description: Alternative to warehouseCode
              fromWarehouseCode:
                type: string
                example: "WH01"
                description: Source warehouse code (can also use fromWarehouse)
              fromWarehouse:
                type: string
                example: "WH01"
                description: Alternative to fromWarehouseCode
              useBaseUnits:
                type: string
                enum: ["tNO", "tYES"]
                example: "tNO"
                description: Use base units (defaults to "tNO")
              measureUnit:
                type: string
                example: "KG"
                description: Measure unit (can also use unit)
              unit:
                type: string
                example: "KG"
                description: Alternative to measureUnit
              uomEntry:
                type: string
                example: "1"
                description: Unit of Measure Entry (can also use UoMEntry) - as string
              UoMEntry:
                type: string
                example: "1"
                description: Alternative to uomEntry - as string
              uomCode:
                type: string
                example: "KG"
                description: Unit of Measure Code (can also use UoMCode)
              UoMCode:
                type: string
                example: "KG"
                description: Alternative to uomCode
              unitPrice:
                type: number
                example: 15.50
                description: Unit price

    # SAP Stock Transfer Format Schema (What actually gets sent to SAP)
    SAPStockTransferFormat:
      type: object
      description: Exact format sent to SAP API - Java POJO structure (org.shini.sap_integration.pojo.stockTransfer.StockTransfer)
      properties:
        DocEntry:
          type: string
          nullable: true
          example: null
          description: Document entry (assigned by SAP)
        DocNum:
          type: string
          nullable: true
          example: null
          description: Document number (assigned by SAP)
        DocDate:
          type: string
          example: "2025-01-08"
          description: Transfer date
        DueDate:
          type: string
          example: "2025-01-15"
          description: Due date
        FromWarehouse:
          type: string
          example: "WH01"
          description: Source warehouse code
        ToWarehouse:
          type: string
          example: "WH02"
          description: Destination warehouse code
        U_BaseEntry:
          type: string
          example: "ST-001"
          description: Custom field - Base entry reference
        U_Type:
          type: string
          enum: ["Waste", "Damage"]
          example: "Waste"
          description: Custom field - Transfer type (Waste OR Damage)
        PriceList:
          type: string
          example: "1"
          description: Price list
        StockTransferLines:
          type: array
          description: Array of line items in SAP POJO format
          items:
            $ref: '#/components/schemas/SAPStockTransferLineFormat'

    SAPStockTransferLineFormat:
      type: object
      description: SAP POJO line format (org.shini.sap_integration.pojo.stockTransfer.StockTransferDetail)
      properties:
        LineNum:
          type: integer
          example: 0
          description: Auto-assigned line number
        ItemCode:
          type: string
          example: "RAW001"
          description: Item code
        ItemDescription:
          type: string
          example: "Raw Material Type A"
          description: Item description
        Quantity:
          type: number
          example: 50
          description: Item quantity
        WarehouseCode:
          type: string
          example: "WH02"
          description: Destination warehouse code
        FromWarehouseCode:
          type: string
          example: "WH01"
          description: Source warehouse code
        UseBaseUnits:
          type: string
          enum: ["tNO", "tYES"]
          example: "tNO"
          description: Use base units flag
        MeasureUnit:
          type: string
          example: "KG"
          description: Measure unit
        UoMEntry:
          type: string
          example: "1"
          description: Unit of Measure Entry (as string)
        UoMCode:
          type: string
          example: "KG"
          description: Unit of Measure Code
        UnitPrice:
          type: number
          example: 15.50
          description: Unit price

    BatchResponse:
      type: object
      properties:
        processed:
          type: integer
          example: 10
        successful:
          type: integer
          example: 8
        failed:
          type: integer
          example: 2
        duration:
          type: string
          example: "1234ms"
        results:
          type: array
          items:
            type: object
        errors:
          type: array
          items:
            type: object

    ValidationResponse:
      type: object
      properties:
        valid:
          type: boolean
        isDuplicate:
          type: boolean
        message:
          type: string
        error:
          type: string

    QueryResponse:
      type: object
      properties:
        documents:
          type: array
          items:
            type: object
        count:
          type: integer
        top:
          type: integer
        skip:
          type: integer

    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Error message
          example: "Invalid request"
        errorCode:
          type: string
          description: Error code
          example: "BAD_REQUEST"
        timestamp:
          type: string
          format: date-time
        details:
          type: object
          description: Additional error details
        sapError:
          type: object
          description: SAP-specific error information

  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: "Invalid request data"
            errorCode: "BAD_REQUEST"
            timestamp: "2025-01-08T10:30:45.123Z"

    Unauthorized:
      description: Unauthorized - Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: "Invalid API key"
            errorCode: "UNAUTHORIZED"
            timestamp: "2025-01-08T10:30:45.123Z"

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: "Document not found"
            errorCode: "NOT_FOUND"
            timestamp: "2025-01-08T10:30:45.123Z"

    Conflict:
      description: Conflict - Document already exists
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: "Document already exists in SAP"
            errorCode: "CONFLICT"
            timestamp: "2025-01-08T10:30:45.123Z"
            details:
              duplicateKey: "TRX-001"

    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - type: object
                properties:
                  errors:
                    type: array
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                        message:
                          type: string
          example:
            success: false
            error: "Validation failed"
            errorCode: "VALIDATION_ERROR"
            timestamp: "2025-01-08T10:30:45.123Z"
            errors:
              - field: "lines"
                message: "At least one line item is required"

    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error: "Internal server error"
            errorCode: "INTERNAL_ERROR"
            timestamp: "2025-01-08T10:30:45.123Z"

  examples:
    BasicInvoice:
      summary: Basic Invoice
      value:
        transactionKey: "TRX-001"
        customerCode: "C00001"
        businessDate: "2025-01-08"
        lines:
          - itemCode: "ITEM001"
            quantity: 2
            unitPrice: 50.00
            warehouseCode: "WH01"

    DetailedInvoice:
      summary: Detailed Invoice with all fields
      value:
        transactionKey: "TRX-002"
        businessDate: "2025-01-08"
        dueDate: "2025-02-08"
        customerCode: "C00001"
        customerName: "ABC Company Ltd"
        currency: "JOD"
        exchangeRate: 1
        warehouseCode: "WH01"
        projectCode: "PROJ01"
        storeCode: "STORE01"
        terminalId: "TERM01"
        referenceNumber: "PO-12345"
        comments: "Rush order - deliver by end of week"
        discountPercent: 5
        salesPersonCode: "SP001"
        paymentTerms: 30
        lines:
          - itemCode: "ITEM001"
            barcode: "1234567890123"
            description: "Widget A - Blue"
            quantity: 10
            unitPrice: 25.50
            totalAmount: 255.00
            discountPercent: 0
            taxCode: "VAT16"
            warehouseCode: "WH01"
            projectCode: "PROJ01"
            costCenter: "CC001"
            notes: "Handle with care"
          - itemCode: "ITEM002"
            description: "Widget B - Red"
            quantity: 5
            unitPrice: 35.00
            totalAmount: 175.00
            taxCode: "VAT16"
            warehouseCode: "WH01"
        shippingAddress:
          code: "SHIP001"
          street: "123 Main St"
          city: "Amman"
          country: "JO"

    BasicCreditNote:
      summary: Basic Credit Note
      value:
        transactionKey: "CN-001"
        customerCode: "C00001"
        originalInvoiceKey: "TRX-001"
        refundReason: "Customer return - damaged goods"
        lines:
          - itemCode: "ITEM001"
            quantity: 1
            unitPrice: 50.00
            warehouseCode: "WH01"

    CashPayment:
      summary: Cash Payment
      value:
        paymentKey: "PAY-001"
        customerCode: "C00001"
        amount: 100.00
        paymentMethod: "Cash"
        cashAccount: "1010"
        remarks: "Cash payment at counter"

    CreditCardPayment:
      summary: Credit Card Payment
      value:
        paymentKey: "PAY-002"
        customerCode: "C00001"
        amount: 250.00
        paymentMethod: "CreditCard"
        cardType: "Visa"
        authorizationCode: "AUTH123456"
        invoiceDocEntry: "12345"

    BankTransferPayment:
      summary: Bank Transfer Payment
      value:
        paymentKey: "PAY-003"
        customerCode: "C00001"
        amount: 500.00
        paymentMethod: "BankTransfer"
        transferReference: "TRF-20250108-001"
        invoices:
          - docEntry: "12345"
            amount: 300.00
          - docEntry: "12346"
            amount: 200.00
    SAPPOJOFormat:
      summary: SAP POJO Format - Exact output sent to SAP API (matches Java classes)
      description: |
        This shows the exact format that gets sent to the SAP API after transformation.
        Matches your Java POJO classes:
        - org.shini.sap_integration.pojo.goodReceipt.GoodReceipt
        - org.shini.sap_integration.pojo.goodReceipt.GoodReceiptDetail
      value:
        DocType: "dDocument_Items"
        DocObjectCode: "oPurchaseDeliveryNotes"
        PriceSource: "dpsManual"
        CardCode: "V00001"
        CardName: "ABC Suppliers Ltd"
        DocDate: "2025-01-08"
        DocDueDate: "2025-01-15"
        SalesPersonCode: 5
        U_BaseEntry: "98765"
        U_BRANCH: "BR01"
        DocumentLines:
          - LineNum: 0
            BaseLine: 0
            ItemCode: "RAW001"
            ItemDescription: "Raw Material Type A"
            BarCode: "1234567890123"
            BaseEntry: "98765"
            Quantity: 50
            BaseQty: 50
            BaseType: "22"
            WarehouseCode: "WH01"
            U_Comments: "Minor quantity variance noted"
            CorrectQuantity: 49.5
            UnitPrice: 15.5
            CostingCode: "DEPT-PROD"
            CostingCode2: "PROJECT-A"
          - LineNum: 1
            BaseLine: 1
            ItemCode: "FRESH001"
            ItemDescription: "Fresh Product"
            BaseEntry: "98765"
            Quantity: 25
            BaseType: "22"
            WarehouseCode: "WH-FRESH"
            UnitPrice: 8.75
            U_CostEvent: "HARVEST-2025"
            U_FreshUOM: "KG"
            U_FreshQty: 24.8
            U_FreshPrice: 8.5
          - LineNum: 2
            BaseLine: 1
            ItemCode: "RAW002"
            ItemDescription: "Raw Material Type B"
            BaseEntry: "98765"
            Quantity: 25
            BaseType: "22"
            WarehouseCode: "WH01"
            UnitPrice: 22
            UoMEntry: 1
            UoMCode: "KG"
            VolumeUnit: null
            Volume: 0.0

    SAPAPInvoicePOJOFormat:
      summary: SAP AP Invoice POJO Format - Exact output sent to SAP API (matches Java classes)
      description: |
        This shows the exact format that gets sent to the SAP API after transformation.
        Matches your Java POJO classes:
        - org.shini.sap_integration.pojo.apInvoice.APInvoice
        - org.shini.sap_integration.pojo.apInvoice.APInvoiceDetail
        
        **Key Difference:** BaseType is "20" (AP Invoice) instead of "22" (Good Receipt)
      value:
        DocType: "dDocument_Items"
        DocObjectCode: "oPurchaseInvoices"
        PriceSource: "dpsManual"
        CardCode: "V00001"
        CardName: "ABC Suppliers Ltd"
        DocDate: "2025-01-08"
        DocDueDate: "2025-01-15"
        SalesPersonCode: 5
        U_BaseEntry: "GR-001"
        U_BRANCH: "BR01"
        DocumentLines:
          - LineNum: 0
            BaseLine: 0
            ItemCode: "RAW001"
            ItemDescription: "Raw Material Type A"
            BarCode: "1234567890123"
            BaseEntry: "98765"
            Quantity: 50
            BaseQty: 50
            BaseType: "20"
            WarehouseCode: "WH01"
            U_Comments: "Invoice line item 1"
            CorrectQuantity: 50.0
            UnitPrice: 15.5
            CostingCode: "DEPT-PROD"
            CostingCode2: "PROJECT-A"
            U_CostEvent: "PURCHASE"
            U_FreshUOM: "KG"
            U_FreshQty: 50.0
            U_FreshPrice: 15.5
            UoMEntry: 1
            UoMCode: "KG"
            VolumeUnit: null
            Volume: 0.0
          - LineNum: 1
            BaseLine: 1
            ItemCode: "RAW002"
            ItemDescription: "Raw Material Type B"
            BaseEntry: "98765"
            Quantity: 25
            BaseType: "20"
            WarehouseCode: "WH02"
            UnitPrice: 22.0
            U_CostEvent: "PURCHASE"
            U_FreshUOM: "PCS"
            U_FreshQty: 25.0
            U_FreshPrice: 22.0
            UoMEntry: 2
            UoMCode: "PCS"
            VolumeUnit: null
            Volume: 0.0
          - LineNum: 2
            BaseLine: 2
            ItemCode: "RAW003"
            ItemDescription: "Raw Material Type C"
            BaseEntry: "98765"
            Quantity: 30
            BaseType: "20"
            WarehouseCode: "WH01"
            UnitPrice: 18.0
            U_Comments: "AP Invoice line item 3"
            CorrectQuantity: 30.0
            CostingCode: "DEPT-PROD"
            UoMEntry: 1
            UoMCode: "KG"
            VolumeUnit: null
            Volume: 0.0

    SAPStockTransferPOJOFormat:
      summary: SAP Stock Transfer POJO Format - Exact output sent to SAP API (matches Java classes)
      description: |
        This shows the exact format that gets sent to the SAP API after transformation.
        Matches your Java POJO classes:
        - org.shini.sap_integration.pojo.stockTransfer.StockTransfer
        - org.shini.sap_integration.pojo.stockTransfer.StockTransferDetail
        
        **Key Features:** Uses StockTransferLines, warehouse transfers, Waste/Damage types
      value:
        DocDate: "2025-01-08"
        DueDate: "2025-01-15"
        FromWarehouse: "WH01"
        ToWarehouse: "WH02"
        U_BaseEntry: "ST-001"
        U_Type: "Waste"
        PriceList: "1"
        StockTransferLines:
          - LineNum: 0
            ItemCode: "RAW001"
            ItemDescription: "Raw Material Type A"
            Quantity: 50
            WarehouseCode: "WH02"
            FromWarehouseCode: "WH01"
            UseBaseUnits: "tNO"
            MeasureUnit: "KG"
            UoMEntry: "1"
            UoMCode: "KG"
            UnitPrice: 15.50
          - LineNum: 1
            ItemCode: "RAW002"
            ItemDescription: "Raw Material Type B"
            Quantity: 25
            WarehouseCode: "WH02"
            FromWarehouseCode: "WH01"
            UseBaseUnits: "tNO"
            MeasureUnit: "PCS"
            UoMEntry: "2"
            UoMCode: "PCS"
            UnitPrice: 22.00
          - LineNum: 2
            ItemCode: "RAW003"
            ItemDescription: "Raw Material Type C"
            Quantity: 15
            WarehouseCode: "WH02"
            FromWarehouseCode: "WH01"
            UseBaseUnits: "tNO"
            MeasureUnit: "KG"
            UoMEntry: "1"
            UoMCode: "KG"
            UnitPrice: 18.00
