Files
clientflow_backend/docs/JASMIN_CLIENTFLOW.md
2026-06-09 22:55:58 +01:00

3.3 KiB

Integração Jasmin no ClientFlow

Esta versão adiciona a primeira integração Jasmin validada com testes reais em Jasmin 3.02.

O que foi validado

  • OAuth Client Credentials:
    • https://identity.primaverabss.com/connect/token
    • grant_type=client_credentials
    • scope=application
  • GET /businessCore/productInfos/getVersions
  • Clientes:
    • GET /salesCore/customerParties/getCustomerByCompanyTaxId/{nif}
    • POST /salesCore/customerParties
  • Produtos:
    • GET /salesCore/salesItems/extension/odata?$top=50
  • Orçamentos:
    • POST /sales/quotations
    • documentType=ORC
    • serie=ORC2026
  • Faturas:
    • POST /billing/invoices/fromQuotation/{quotationId} com body {}

Regras importantes descobertas

  1. O NIF deve ser pesquisado no Jasmin sem prefixo PT.
  2. O Jasmin rejeita electronicMail e telephone vazios; campos opcionais vazios são omitidos.
  3. OData tem limite de $top=100.
  4. Cliente novo pode usar partyKey=CF{NIF}.
  5. Converter orçamento em fatura exige json={}; sem body pode devolver 411 Length Required.

Novas tabelas

  • customers
  • commercial_documents
  • commercial_document_lines
  • shipments

Estas tabelas permitem o pressuposto correto:

Cliente
→ várias oportunidades
→ vários orçamentos
→ várias faturas

Fluxo na oportunidade

A página da oportunidade tem dois botões simples:

[Criar orçamento]
[Converter em fatura]

Criar orçamento faz internamente:

find_or_create_customer
create_quotation

Converter em fatura faz internamente:

pegar no orçamento ativo/mais recente
POST /billing/invoices/fromQuotation/{quotationId} com {}
grava a fatura ligada ao orçamento local

Variáveis .env

JASMIN_ENABLED=true
JASMIN_OUTBOX_ENABLED=true
JASMIN_BASE_URL=https://my.jasminsoftware.com
JASMIN_PUBLIC_URL=https://my.jasminsoftware.com
JASMIN_TOKEN_URL=https://identity.primaverabss.com/connect/token
JASMIN_SCOPE=application
JASMIN_ACCOUNT=...
JASMIN_SUBSCRIPTION=...
JASMIN_CLIENT_ID=...
JASMIN_CLIENT_SECRET=...

JASMIN_COMPANY_KEY=CTULDA
JASMIN_QUOTATION_TYPE=ORC
JASMIN_QUOTATION_SERIE=ORC2026
JASMIN_DEFAULT_PRICE_LIST=03
JASMIN_DEFAULT_PAYMENT_METHOD=TRA
JASMIN_DEFAULT_PAYMENT_TERM=00
JASMIN_DEFAULT_DELIVERY_TERM=TRANSP
JASMIN_DEFAULT_CURRENCY=EUR
JASMIN_DEFAULT_COUNTRY=PT
JASMIN_DEFAULT_CUSTOMER_GROUP=02
JASMIN_DEFAULT_PARTY_TAX_SCHEMA=CONTINENTE
JASMIN_DEFAULT_UNIT=UN
JASMIN_DEFAULT_ITEM_TAX_SCHEMA=NORMAL
JASMIN_DEFAULT_SALES_ITEM=CARREGADOR_MONO_7KW

Teste não destrutivo

python scripts/test_jasmin_connection.py

Processar outbox Jasmin

Modo seguro:

OUTBOX_TARGET_SYSTEM=jasmin JASMIN_OUTBOX_ENABLED=true OUTBOX_DRY_RUN=true python scripts/process_outbox.py

Modo real:

OUTBOX_TARGET_SYSTEM=jasmin JASMIN_OUTBOX_ENABLED=true OUTBOX_DRY_RUN=false python scripts/process_outbox.py

Dados necessários na oportunidade

Para criar cliente Jasmin novo, a oportunidade precisa de:

  • nome do cliente
  • NIF em metadata.customer_tax_id, metadata.nif ou metadata.customer.tax_id
  • morada/código postal/cidade se disponível

Para criar orçamento, as linhas da oportunidade precisam de mapear para artigos Jasmin. O serviço usa por ordem:

  1. opportunity_items.metadata.jasmin_sales_item
  2. opportunity_items.metadata.jasmin_item_key
  3. opportunity_items.sku
  4. JASMIN_DEFAULT_SALES_ITEM