openapi: 3.0.3
info:
  title: IAXYS Orquestrador — API Mobility (substitui WOOFFICE)
  version: 0.1.0-draft
  description: >
    Contratos dos endpoints que o orquestrador IAXYS expõe para a Mobility,
    substituindo as chamadas SOAP/XML do WOOFFICE por JSON. Rascunho para
    validação técnica com Hugo/Eduarda. Nomes de campos espelham o payload
    ImportacaoVenda para reduzir o esforço de adaptação do middleware.
servers:
  - url: https://mobility-chi.vercel.app/api/mobility/v1
security:
  - apiKey: []
paths:
  /vendas:
    post:
      summary: Importar venda (substitui ExportarVendasMobilToWooffice)
      description: >
        Recebe a venda completa. Processamento assíncrono: o orquestrador valida,
        decompõe em chamadas Omie (UpsertCliente, IncluirOS, IncluirContaReceber,
        IncluirContaPagar) e grava o detalhe nas tabelas externas.
        Idempotente por (empresa, filial, file).
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/VendaImportacao' }
      responses:
        '202':
          description: Aceita para processamento
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Protocolo' }
        '409': { description: Venda já importada (mesmo file) — retorna estado atual }
        '422': { description: Falha de validação (campos/domínios) }
  /vendas/{file}:
    get:
      summary: Status da importação
      parameters:
        - { name: file, in: path, required: true, schema: { type: string }, example: "00341130" }
      responses:
        '200':
          description: Estado da venda no pipeline
          content:
            application/json:
              schema: { $ref: '#/components/schemas/VendaStatus' }
  /vendas/{file}/credito:
    get:
      summary: Consultar venda e itens financeiros (substitui ConsultarCrédito)
      description: >
        Consolida ConsultarOS + ListarContasReceber/Pagar do Omie com o cálculo
        de rentabilidade do orquestrador. Mesma semântica do TurVendaDadosModelo.
      parameters:
        - { name: file, in: path, required: true, schema: { type: string } }
      responses:
        '200':
          content:
            application/json:
              schema: { $ref: '#/components/schemas/VendaCredito' }
  /cotacoes:
    get:
      summary: Consultar câmbio (substitui ConsultarCâmbio)
      description: Cotação por moeda, tipo de operação e data, mantida pela instância de cotações IAXYS (fonte PTAX/BC).
      parameters:
        - { name: moeda, in: query, required: true, schema: { type: string }, example: USD }
        - { name: tipo, in: query, required: true, schema: { type: string }, example: Carro }
        - { name: data, in: query, schema: { type: string, format: date }, example: "2026-08-21" }
        - { name: dias, in: query, schema: { type: integer, default: 1 }, description: Quantidade de dias retroativos }
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Cotacao' }
  /webhooks/status-venda:
    post:
      summary: (Callback IAXYS → Mobility) notificação de mudança de status
      description: >
        Opcional — o orquestrador chama a Mobility quando a venda muda de estado
        (INTEGRADO, ERRO). Evita polling em /vendas/{file}.
      requestBody:
        content:
          application/json:
            schema: { $ref: '#/components/schemas/VendaStatus' }
      responses:
        '200': { description: Recebido }
components:
  securitySchemes:
    apiKey: { type: apiKey, in: header, name: X-Api-Key }
  schemas:
    VendaImportacao:
      type: object
      required: [file, empresa, filial, cliente, dataCriacao, movimentos, recebimentos]
      properties:
        file:            { type: string, example: "00341130" }
        empresa:         { type: integer, example: 29 }
        filial:          { type: integer, example: 26 }
        cliente:         { type: integer, description: id do cliente na Mobility, example: 1518 }
        agente:
          type: object
          properties:
            codigoIntegracao: { type: integer, example: 68131 }
            nome:  { type: string }
            email: { type: string }
        ehPacote:        { type: boolean }
        produto:         { type: integer, example: 800 }
        formaPagamento:  { type: integer, example: 3 }
        formaRecebimento:{ type: integer, example: 4 }
        dataCriacao:     { type: string, format: date-time }
        dataEmissao:     { type: string, format: date-time }
        movimentos:
          type: array
          items: { $ref: '#/components/schemas/ReservaCarro' }
        recebimentos:
          type: array
          items: { $ref: '#/components/schemas/Recebimento' }
        pagamentos:
          type: array
          items: { $ref: '#/components/schemas/Pagamento' }
        reservaVinculada: { type: string, nullable: true, description: localizador da reserva de origem, example: "FOJOKLB" }
    ReservaCarro:
      type: object
      required: [codigoWooMobil, localizadorFrontOffice, dataRetirada, dataEntrega, valores]
      properties:
        codigoWooMobil:  { type: integer, example: 341130 }
        localizadorFrontOffice: { type: string, example: "FOPB8XW" }
        confirmacao:     { type: string }
        numeroReservaGds:{ type: string, example: "23831846BR3" }
        locadora:        { type: object, properties: { codigo: {type: integer}, sigla: {type: string, example: ZI}, cnpj: {type: string, nullable: true} } }
        origemIata:      { type: string, example: MIA }
        destinoIata:     { type: string, example: MIA }
        dataRetirada:    { type: string, format: date-time }
        dataEntrega:     { type: string, format: date-time }
        localRetirada:   { type: string }
        localEntrega:    { type: string }
        classeDoCarro:   { type: string, example: Premium }
        tipoVeiculo:     { type: string, example: XXAR }
        rateCode:        { type: string, example: H8 }
        transmissao:     { type: string }
        arCondicionado:  { type: boolean }
        condutores:
          type: array
          items:
            type: object
            properties:
              nome: {type: string}
              sobrenome: {type: string}
              tipo: {type: string, example: ADT}
              tipoDocumento: {type: string, example: CPF}
              documento: {type: string, description: transmitir completo; armazenado cifrado}
        valores:
          type: object
          properties:
            tarifa:       { type: number, example: 389.08 }
            tarifaNet:    { type: number }
            taxaServico:  { type: number }
            markup:       { type: number }
            descontoCliente: { type: number }
            moedaEstrangeira: { type: string, nullable: true, example: USD }
            tarifaEstrangeira: { type: number, nullable: true, example: 71.00 }
            valorCambio:  { type: number, nullable: true, example: 5.48 }
            comissao:
              type: object
              properties:
                recebida:  { type: number, example: 77.81 }
                pctRecebido: { type: number, example: 20.0 }
                repassada: { type: number }
                pctRepassado: { type: number }
    Recebimento:
      type: object
      required: [codigoWooMobil, valor, formaRecebimento]
      properties:
        codigoWooMobil:  { type: integer }
        valor:           { type: number, example: 389.08 }
        formaRecebimento:{ type: integer, example: 4 }
        numeroParcelas:  { type: integer, default: 1 }
        desconto:        { type: number }
        dataConfirmacao: { type: string, format: date-time }
        cartao:
          type: object
          nullable: true
          description: PAN nunca é armazenado — apenas mascarado
          properties:
            bandeira: {type: string, example: MC}
            nsu: {type: string}
            codigoTransacao: {type: string}
            operadoraId: {type: integer, example: 358}
            titular: {type: string}
            numero: {type: string, description: transmitido p/ conciliação; armazenado mascarado}
            parcelas: {type: integer}
    Pagamento:
      type: object
      required: [codigoWooMobil, valor]
      properties:
        codigoWooMobil:    { type: integer }
        pessoa:            { type: integer, example: 1518 }
        valor:             { type: number, example: 93.92 }
        formaPagamento:    { type: integer, example: 10 }
        pagamentoDeComissao: { type: boolean }
        dataConfirmacao:   { type: string, format: date-time }
    Protocolo:
      type: object
      properties:
        protocolo: { type: string, example: "MOB-20260826-000123" }
        file:      { type: string, example: "00341130" }
        status:    { type: string, example: RECEBIDO }
    VendaStatus:
      type: object
      properties:
        file:    { type: string }
        status:  { type: string, enum: [RECEBIDO, VALIDADO, ENVIANDO, INTEGRADO, ERRO, RETRY] }
        osOmie:  { type: object, properties: { nCodOS: {type: integer}, cCodIntOS: {type: string} } }
        titulosReceber: { type: array, items: { type: object, properties: { codigoLancamentoOmie: {type: integer}, valor: {type: number}, status: {type: string} } } }
        titulosPagar:   { type: array, items: { type: object, properties: { codigoLancamentoOmie: {type: integer}, valor: {type: number}, status: {type: string} } } }
        erros:   { type: array, items: { type: string } }
    VendaCredito:
      type: object
      description: Equivalente ao TurVendaDadosModelo do WOOFFICE
      properties:
        file:            { type: string, example: "00341130" }
        situacao:        { type: string, example: VendaImportada }
        formaDePagamento:{ type: string, example: FATURADO }
        formaDeRecebimento: { type: string, example: CC }
        valorTotalCre:   { type: number, example: 23.47 }
        valorTotalCpa:   { type: number, example: 116.34 }
        valorRentabilidade: { type: number, example: -92.87 }
        percentualRentabilidade: { type: number, example: -79.11 }
        itens:
          type: array
          items:
            type: object
            properties:
              codigoWooMobil: { type: integer }
              tipo:      { type: string, enum: [CRE, CPA] }
              subProduto:{ type: string, example: CARRO }
              situacao:  { type: string, enum: [Previsto, Real] }
              localizador: { type: string }
              total:     { type: number }
              vinculoComFinanceiro: { type: boolean }
              vinculoComDuplicata:  { type: boolean }
    Cotacao:
      type: object
      properties:
        moeda: { type: string, example: USD }
        tipo:  { type: string, example: Carro }
        data:  { type: string, format: date }
        valor: { type: number, example: 5.4800 }
        fonte: { type: string, example: PTAX }
