{
    "openapi": "3.1.0",
    "info": {
        "title": "API de Parceiros Fintra",
        "version": "1.0.0",
        "description": "API de Parceiros Fintra v1 — servidor-para-servidor. A chave pertence à EMPRESA, nunca a uma pessoa, e NUNCA pode ser usada a partir de um browser (qualquer pedido com o cabeçalho Origin recebe 403). As facturas criadas por esta API nascem em RASCUNHO: a API não emite documentos fiscais. Os pagamentos são só de leitura. Todas as escritas exigem o cabeçalho Idempotency-Key."
    },
    "servers": [
        {
            "url": "https://api.fintra.co.mz/api/v1/partner",
            "description": "Produção"
        }
    ],
    "security": [
        {
            "chaveDeParceiro": []
        }
    ],
    "paths": {
        "/customers": {
            "get": {
                "operationId": "partner.customers.index",
                "tags": [
                    "PartnerCustomer"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "string"
                                                },
                                                "pagination": {
                                                    "type": "object",
                                                    "properties": {
                                                        "total": {
                                                            "type": "string"
                                                        },
                                                        "count": {
                                                            "type": "string"
                                                        },
                                                        "per_page": {
                                                            "type": "string"
                                                        },
                                                        "current_page": {
                                                            "type": "string"
                                                        },
                                                        "last_page": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "required": [
                                                        "total",
                                                        "count",
                                                        "per_page",
                                                        "current_page",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "data",
                                                "pagination"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        },
                                        {
                                            "type": "null"
                                        },
                                        {
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "operationId": "partner.customers.store",
                "description": "⚠️Cannot generate request documentation: Partner API: query sem tenant resolvido. A rota tem de ter o middleware partner.auth.",
                "summary": "O `tenant_id` vai EXPLÍCITO para o serviço. O trait `Tenantable` também o\ncarimbaria a partir da sessão que o partner.auth escreveu, mas depender\ndisso é depender de um efeito colateral de um middleware — e é assim que um\ndia se escreve nos livros da empresa errada",
                "tags": [
                    "PartnerCustomer"
                ],
                "responses": {
                    "201": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/PartnerCustomerResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "403": {
                        "$ref": "#/components/responses/AuthorizationException"
                    }
                }
            }
        },
        "/customers/{id}": {
            "get": {
                "operationId": "partner.customers.show",
                "tags": [
                    "PartnerCustomer"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerCustomerResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "operationId": "partner.customers.update",
                "description": "⚠️Cannot generate request documentation: Partner API: query sem tenant resolvido. A rota tem de ter o middleware partner.auth.",
                "summary": "O cliente é procurado pelo PartnerQuery, não por `Customer::find()`: um id\nde outra empresa tem de responder o MESMO 404 de um id inexistente. Se\nfosse `find()`, o TenantScope desta app deixaria passar as linhas de\n`tenant_id IS NULL` — os clientes globais \"Consumidor Final\" e \"Empresa\n     * Final\" — e um parceiro poderia editá-los para TODAS as empresas do Fintra",
                "tags": [
                    "PartnerCustomer"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerCustomerResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "403": {
                        "$ref": "#/components/responses/AuthorizationException"
                    }
                }
            }
        },
        "/invoices": {
            "get": {
                "operationId": "partner.invoices.index",
                "tags": [
                    "PartnerInvoice"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "string"
                                                },
                                                "pagination": {
                                                    "type": "object",
                                                    "properties": {
                                                        "total": {
                                                            "type": "string"
                                                        },
                                                        "count": {
                                                            "type": "string"
                                                        },
                                                        "per_page": {
                                                            "type": "string"
                                                        },
                                                        "current_page": {
                                                            "type": "string"
                                                        },
                                                        "last_page": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "required": [
                                                        "total",
                                                        "count",
                                                        "per_page",
                                                        "current_page",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "data",
                                                "pagination"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        },
                                        {
                                            "type": "null"
                                        },
                                        {
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "operationId": "partner.invoices.store",
                "description": "O cliente é resolvido AQUI, pelo PartnerQuery, e não por uma regra\n`exists` no FormRequest: um `customer_id` de outra empresa tem de receber o\nMESMO 404 que esse id recebe em `GET /customers/{id}` ou em\n`PUT /customers/{id}`. Se respondesse 422 \"campo inválido\", a Partner API\npassava a dar duas respostas diferentes ao mesmo id conforme a rota — e a\ndiferença entre elas é informação sobre dados de outra empresa.\n\nAs referências dentro das linhas (`product_id`, `tax_id`) ficam no\nFormRequest, em 422 com o índice da linha: são dados da linha, e a\nmensagem é idêntica para um id inexistente e para um id alheio.⚠️Cannot generate request documentation: Partner API: query sem tenant resolvido. A rota tem de ter o middleware partner.auth.",
                "summary": "Cria a factura em RASCUNHO",
                "tags": [
                    "PartnerInvoice"
                ],
                "responses": {
                    "201": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/PartnerInvoiceResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "403": {
                        "$ref": "#/components/responses/AuthorizationException"
                    }
                }
            }
        },
        "/invoices/{id}": {
            "get": {
                "operationId": "partner.invoices.show",
                "tags": [
                    "PartnerInvoice"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerInvoiceResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/payments": {
            "get": {
                "operationId": "partner.payments.index",
                "tags": [
                    "PartnerPayment"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "string"
                                                },
                                                "pagination": {
                                                    "type": "object",
                                                    "properties": {
                                                        "total": {
                                                            "type": "string"
                                                        },
                                                        "count": {
                                                            "type": "string"
                                                        },
                                                        "per_page": {
                                                            "type": "string"
                                                        },
                                                        "current_page": {
                                                            "type": "string"
                                                        },
                                                        "last_page": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "required": [
                                                        "total",
                                                        "count",
                                                        "per_page",
                                                        "current_page",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "data",
                                                "pagination"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        },
                                        {
                                            "type": "null"
                                        },
                                        {
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/payments/{id}": {
            "get": {
                "operationId": "partner.payments.show",
                "tags": [
                    "PartnerPayment"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerPaymentResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ping": {
            "get": {
                "operationId": "partner.ping",
                "tags": [
                    "PartnerPing"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "tenant_id": {
                                                    "type": "integer"
                                                },
                                                "tenant_name": {
                                                    "type": "string"
                                                },
                                                "mode": {
                                                    "type": "string"
                                                },
                                                "scopes": {
                                                    "type": "string"
                                                },
                                                "customers_visible": {
                                                    "type": "string"
                                                },
                                                "request_id": {
                                                    "type": "string"
                                                }
                                            },
                                            "required": [
                                                "tenant_id",
                                                "tenant_name",
                                                "mode",
                                                "scopes",
                                                "customers_visible",
                                                "request_id"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/products": {
            "get": {
                "operationId": "partner.products.index",
                "tags": [
                    "PartnerProduct"
                ],
                "parameters": [
                    {
                        "name": "is_for_sale",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "string"
                                                },
                                                "pagination": {
                                                    "type": "object",
                                                    "properties": {
                                                        "total": {
                                                            "type": "string"
                                                        },
                                                        "count": {
                                                            "type": "string"
                                                        },
                                                        "per_page": {
                                                            "type": "string"
                                                        },
                                                        "current_page": {
                                                            "type": "string"
                                                        },
                                                        "last_page": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "required": [
                                                        "total",
                                                        "count",
                                                        "per_page",
                                                        "current_page",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "data",
                                                "pagination"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        },
                                        {
                                            "type": "null"
                                        },
                                        {
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "operationId": "partner.products.store",
                "tags": [
                    "PartnerProduct"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PartnerProductRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/PartnerProductResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "403": {
                        "$ref": "#/components/responses/AuthorizationException"
                    }
                }
            }
        },
        "/products/{id}": {
            "get": {
                "operationId": "partner.products.show",
                "tags": [
                    "PartnerProduct"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerProductResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "operationId": "partner.products.update",
                "tags": [
                    "PartnerProduct"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PartnerProductRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "anyOf": [
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PartnerProductResource"
                                                }
                                            },
                                            "required": [
                                                "data"
                                            ]
                                        },
                                        {
                                            "type": "string"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "403": {
                        "$ref": "#/components/responses/AuthorizationException"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "chaveDeParceiro": {
                "type": "http",
                "description": "Chave opaca da empresa, emitida pelo suporte Fintra e mostrada uma única vez. Envie-a como \"Authorization: Bearer fintra_sk_live_...\". As chaves \"fintra_sk_test_...\" existem mas HOJE só respondem a GET — qualquer escrita com uma chave de teste devolve 403 test_mode_read_only.",
                "scheme": "bearer",
                "bearerFormat": ""
            }
        },
        "schemas": {
            "PartnerCustomerResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "phone": {
                        "type": "string"
                    },
                    "contact_number": {
                        "type": "string"
                    },
                    "nuit": {
                        "type": "string"
                    },
                    "address": {
                        "type": "string"
                    },
                    "created_at": {
                        "type": "string"
                    },
                    "updated_at": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "type",
                    "email",
                    "phone",
                    "contact_number",
                    "nuit",
                    "address",
                    "created_at",
                    "updated_at"
                ],
                "title": "PartnerCustomerResource"
            },
            "PartnerInvoiceItemResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "product_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "`invoice_items.name` está NULL em 98% das linhas reais (as vendas\ndo POS não a gravam), por isso cai-se no nome do produto. Sem este\nfallback a factura chegaria ao parceiro com linhas sem descrição."
                    },
                    "description": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "price": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "discount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "discount_percentage": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "tax_amount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "tax_rate": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "tax_included": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "total": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "id",
                    "product_id",
                    "name",
                    "description",
                    "quantity",
                    "price",
                    "discount",
                    "discount_percentage",
                    "tax_amount",
                    "tax_rate",
                    "tax_included",
                    "total"
                ],
                "title": "PartnerInvoiceItemResource"
            },
            "PartnerInvoiceResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "invoice_code": {
                        "type": "string",
                        "description": "Identidade do documento"
                    },
                    "payment_notice_code": {
                        "type": "string"
                    },
                    "document_type": {
                        "type": "string"
                    },
                    "is_payment_notice": {
                        "type": "boolean",
                        "description": "Documentos NÃO fiscais (proforma / aviso de cobrança) trazem estes\ndois preenchidos. É como o parceiro distingue um rascunho de uma\nfactura emitida sem ter de adivinhar pelo código."
                    },
                    "notice_kind": {
                        "type": "string"
                    },
                    "is_pos_sale": {
                        "type": "boolean"
                    },
                    "reference": {
                        "type": "string"
                    },
                    "payment_reference": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string"
                    },
                    "invoice_date": {
                        "type": "string",
                        "description": "Datas"
                    },
                    "due_date": {
                        "type": "string"
                    },
                    "currency": {
                        "type": "string",
                        "description": "Moeda"
                    },
                    "exchange_rate": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "subtotal": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Totais — SEMPRE da coluna (ver o bloco dos acessores-sombra acima)"
                    },
                    "discount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "global_discount_amount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "vat_base": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "tax": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "grand_total": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "paid_amount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "remaining_amount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notes": {
                        "type": "string"
                    },
                    "customer": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Referência mínima do cliente: id + nome. O objecto completo do\ncliente pede-se em /v1/partner/customers/{id}.",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/PartnerInvoiceItemResource"
                        }
                    },
                    "created_at": {
                        "type": "string"
                    },
                    "updated_at": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "invoice_code",
                    "payment_notice_code",
                    "document_type",
                    "is_payment_notice",
                    "notice_kind",
                    "is_pos_sale",
                    "reference",
                    "payment_reference",
                    "status",
                    "invoice_date",
                    "due_date",
                    "currency",
                    "exchange_rate",
                    "subtotal",
                    "discount",
                    "global_discount_amount",
                    "vat_base",
                    "tax",
                    "grand_total",
                    "paid_amount",
                    "remaining_amount",
                    "notes",
                    "customer",
                    "created_at",
                    "updated_at"
                ],
                "title": "PartnerInvoiceResource"
            },
            "PartnerPaymentResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "payment_code": {
                        "type": "string"
                    },
                    "payment_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "amount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "payment_method": {
                        "type": "string"
                    },
                    "payment_method_type": {
                        "type": "string"
                    },
                    "reference": {
                        "type": "string"
                    },
                    "notes": {
                        "type": "string"
                    },
                    "invoice": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Referência mínima da factura: id + código do documento.",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "invoice_code": {
                                "type": "string"
                            },
                            "payment_notice_code": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "invoice_code",
                            "payment_notice_code"
                        ]
                    },
                    "created_at": {
                        "type": "string"
                    },
                    "updated_at": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "payment_code",
                    "payment_date",
                    "amount",
                    "payment_method",
                    "payment_method_type",
                    "reference",
                    "notes",
                    "invoice",
                    "created_at",
                    "updated_at"
                ],
                "title": "PartnerPaymentResource"
            },
            "PartnerProductRequest": {
                "type": "object",
                "description": "Corpo aceite em POST/PUT /v1/partner/products.\n\n`type` e `inventory` são listas fechadas, copiadas do caminho interno\n(ProductController: GOODS|SERVICES|RAW|ASSETS|KIT e INVENTORY|NON_INVENTORY).\nNão são adivinhadas: as colunas são ENUM em MySQL e um valor fora da lista é\nrecusado pelo motor em tempo de execução, não em tempo de validação.\n\n⚠️ KIT: no Fintra um KIT explode nos componentes na VENDA e não tem stock\npróprio. Aceita-se criá-lo porque o caminho interno o aceita, mas um parceiro\nque crie um KIT sem depois montar a composição fica com um produto que não\nvende nada. Não é este endpoint que monta composições (v1 não tem BOM).\n\nFORA da lista branca, e cada um por uma razão:\n\n- `purchase_account_id`, `cogs_account_id`, `sales_account_id`,\n  `warehouse_account_id` — contas do plano de contas. Quem as preenche é o\n  hook `creating` do model (`Product::defaultAccountsFor`), a partir das\n  configurações da empresa. Um parceiro a escolher contas escreve\n  contabilidade sem saber que o está a fazer.\n- `product_code` — é gerado pela Fintra (`Product::generateProductCode`), com\n  sequência por tipo e por empresa. O código do parceiro tem sítio próprio:\n  `sku`.\n- `cost_price` — o preço de custo é a margem da empresa. A Wave 2 já o mantém\n  fora das leituras (PartnerProductResource); aceitá-lo na escrita criaria um\n  campo que se escreve e não se lê.\n- `stock` — o stock move-se com documentos (entradas, vendas, ajustes), não\n  com um PUT. Um parceiro a acertar `stock` à mão parte a conciliação com o\n  POS offline e a valorização de inventário.\n- `photo` — sem upload de imagens no v1.\n- `tenant_id`, `reference_product_id`, `project_id`, `copy_to_branches`,\n  `sync_id`, `client_id`, `synced`, `last_modified` — ids e mecânica interna.",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "GOODS",
                            "SERVICES",
                            "RAW",
                            "ASSETS",
                            "KIT"
                        ]
                    },
                    "inventory": {
                        "type": "string",
                        "enum": [
                            "INVENTORY",
                            "NON_INVENTORY"
                        ]
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 2000
                    },
                    "sku": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 100
                    },
                    "unity": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 50
                    },
                    "pos_price": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "vat_included": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "reorder_level": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "is_for_sale": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "is_for_purchase": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "tax_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "A taxa tem de ser DESTA empresa ou GLOBAL. As duas coisas, e não só\na primeira: `taxes.tenant_id` é nullable e o IVA de 16% vive como\nlinha global (o próprio ProductController assume `tax_id = 1` à\nforça quando `vat_included`). Exigir a taxa da empresa deixaria o\nparceiro sem forma nenhuma de aplicar IVA.\nA taxa de OUTRA empresa continua a ser \"não existe\" — sem isto, a\nmensagem de erro passava a confirmar ids alheios."
                    }
                },
                "required": [
                    "name",
                    "type",
                    "inventory",
                    "price"
                ],
                "title": "PartnerProductRequest"
            },
            "PartnerProductResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "product_code": {
                        "type": "string"
                    },
                    "sku": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string"
                    },
                    "unity": {
                        "type": "string"
                    },
                    "price": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "pos_price": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "vat_included": {
                        "type": "boolean"
                    },
                    "tax_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Taxa de IVA aplicável, em percentagem (16.00). Vem da relação `tax`,\ncarregada já filtrada pela empresa da chave."
                    },
                    "stock": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "reorder_level": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "tracks_inventory": {
                        "type": "string",
                        "description": "Se este produto move stock. `inventory === 'INVENTORY'` é a fonte\núnica de verdade da app (Product::tracksInventory)."
                    },
                    "is_for_sale": {
                        "type": "boolean"
                    },
                    "categories": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                },
                                "minItems": 0,
                                "maxItems": 0,
                                "additionalItems": false
                            }
                        ]
                    },
                    "created_at": {
                        "type": "string"
                    },
                    "updated_at": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "product_code",
                    "sku",
                    "description",
                    "type",
                    "unity",
                    "price",
                    "pos_price",
                    "vat_included",
                    "tax_rate",
                    "stock",
                    "reorder_level",
                    "tracks_inventory",
                    "is_for_sale",
                    "categories",
                    "created_at",
                    "updated_at"
                ],
                "title": "PartnerProductResource"
            }
        },
        "responses": {
            "ValidationException": {
                "description": "Validation error",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Errors overview."
                                },
                                "errors": {
                                    "type": "object",
                                    "description": "A detailed description of each field that failed validation.",
                                    "additionalProperties": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                }
                            },
                            "required": [
                                "message",
                                "errors"
                            ]
                        }
                    }
                }
            },
            "AuthorizationException": {
                "description": "Authorization error",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Error overview."
                                }
                            },
                            "required": [
                                "message"
                            ]
                        }
                    }
                }
            }
        }
    }
}