import React, { useEffect, useState } from 'react'; const names = { issuer: 'Dados do emitente', client: 'Dados dos clientes', payment: 'Instruções de pagamento', service_drafts: 'Preparação de prestações', billing_drafts: 'Preparação de facturação' }; const profileFields = { nuit: 'NUIT', address: 'Morada', locality: 'Localidade', country: 'País' }; const paymentFields = { label: 'Designação das instruções', bank: 'Banco (se aplicável)', holder: 'Titular (se aplicável)', account_number: 'Identificador de conta (se aplicável)', nib: 'NIB (se aplicável)', iban: 'IBAN (se aplicável)', swift: 'SWIFT (se aplicável)', bank_code: 'Código bancário (se aplicável)', currency: 'Moeda das instruções (opcional)' }; const states = { missing: 'Por completar / confirmar aplicabilidade', filled_not_validated: 'Preenchido — não validado', validation_pending: 'Validação pendente', stale: 'Origem alterada — rever' }; const isDraft = kind => kind.endsWith('_drafts'); export default function DocumentPreparationWorkspace({ context, can, api, perform, busy }) { const initial = can('issuer_documents.view') ? 'issuer' : can('client_documents.view') ? 'client' : 'billing_drafts'; const [kind, setKind] = useState(initial); return ; } function DocumentPreparationArea({ kind, onSelect, context, can, api, perform, busy }) { const prefix = kind => kind === 'client' ? 'client_documents' : isDraft(kind) ? 'draft_documents' : 'issuer_documents'; const permitted = (kind, action) => can(`${prefix(kind)}.${action}`, isDraft(kind) ? context.unit?.id ?? null : null); const options = Object.keys(names).filter(kind => permitted(kind, 'view') && (!isDraft(kind) || context.unit)); const [records, setRecords] = useState([]); const [selectedId, setSelectedId] = useState(null); const [record, setRecord] = useState(null); const [form, setForm] = useState({}); const [payments, setPayments] = useState([]); const [error, setError] = useState(''); const path = `/api/document-preparation/${kind}`; async function load() { const result = await api(path); setRecords(result.records); } async function open(id) { setError(''); try { const result = await api(`${path}/${id}`); setRecord(result); setSelectedId(id); setForm({ ...result.data, ...(isDraft(kind) ? { currency: result.currency || '', price_mode: result.data.price_mode || 'undefined', units: result.lines.map((_, i) => result.data.units?.[i] || ''), payment_instruction_ids: result.data.payment_instruction_ids || [] } : {}) }); } catch (e) { setError(e.message); } } useEffect(() => { setRecord(null); setSelectedId(null); setError(''); load().then(() => { if (kind === 'issuer') open(context.company.id); }).catch(e => setError(e.message)); if (isDraft(kind) && can('issuer_documents.view')) api('/api/document-preparation/payment').then(data => setPayments(data.records)).catch(e => setError(e.message)); }, [kind, context.token]); function change(field, value) { setForm(current => ({ ...current, [field]: value })); } async function save(e) { e.preventDefault(); const fields = kind === 'payment' ? [...Object.keys(paymentFields), 'instructions'] : isDraft(kind) ? ['service_date','period_start','period_end','payment_terms','proposed_due_date','price_mode','units','payment_instruction_ids','currency'] : Object.keys(profileFields); const data = Object.fromEntries(fields.map(field => [field, form[field] === undefined || form[field] === '' ? null : form[field]])); data.version = record?.version || 0; if (isDraft(kind)) data.draft_version = record.draft_version; await perform(async () => { const result = await api(`${path}/${selectedId ?? 0}`, 'PATCH', data, context.token); await load(); await open(result.id); }, 'Preparação guardada com histórico. Preenchido não significa validado.'); } const editable = permitted(kind, 'edit') && !record?.locked; const text = (field, label, type = 'text') => ; return <>

PREPARAÇÃO DOCUMENTAL

Dados para facturação

Completar e reutilizar informação. Sem emissão fiscal, recebimentos ou lançamentos.

{options.map(option => )}
{error &&
{error}
} {!options.length ?

Sem acesso documental explícito neste contexto.

:

{names[kind]}

{kind === 'payment' && editable && }{!records.length &&

Ainda não existem registos. Clientes e rascunhos são criados nos menus existentes.

}{records.map(item => )}
{record ? <>

{record.name || names[kind]}

{record.origin || 'Instruções do emitente'} · Versão {record.version}

{record.locked &&

Confirmação B1 preservada. Esta preparação está bloqueada para edição.

}
{['issuer','client'].includes(kind) && <>

O nome não é duplicado. Para o alterar, use Empresa ou Clientes, conforme os seus direitos. O cliente pode continuar a ser criado apenas com nome.

{Object.entries(profileFields).map(([field,label]) => text(field,label))}
} {kind === 'payment' && <>

Configuração do emitente para facilitar o pagamento. Não é uma pergunta ao cliente sobre como pagará e não cria qualquer recebimento.

Não introduza palavras-passe, tokens, PIN, códigos de segurança ou dados de cartões. Dados introduzidos pelo utilizador, sem verificação bancária.

{Object.entries(paymentFields).map(([field,label]) => text(field,label))}