feat: company create with copy-from + fix missing fields
- Add phone_number_id and display_phone fields to create/edit form (were never shown or saved despite existing in the DB) - Add phone_number_id and display_phone to CompanyRepository::save() - New company form shows "Copiar configuración de empresa" dropdown: selecting an existing company pre-fills api_base_url, api_key, bot_type, config_json, etc. so admins only need to change the name and phone_number_id Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
838cc651b2
commit
84afeb598c
@@ -992,6 +992,8 @@ HTML;
|
||||
$cv = fn(string $k, string $d = '') => self::h($company[$k] ?? $d);
|
||||
$name = $cv('name');
|
||||
$display_name = $cv('display_name');
|
||||
$phone_number_id = $cv('phone_number_id');
|
||||
$display_phone = $cv('display_phone');
|
||||
$api_base_url = $cv('api_base_url');
|
||||
$api_key = $cv('api_key');
|
||||
$config_json = $cv('config_json');
|
||||
@@ -1207,6 +1209,22 @@ ROW;
|
||||
EP;
|
||||
}
|
||||
|
||||
// For "copy from" dropdown on new company form
|
||||
$copyOpts = '';
|
||||
if (!$isEdit) {
|
||||
foreach (CompanyRepository::findAll(true) as $co) {
|
||||
$cid = (int)$co['id'];
|
||||
$cn = self::h($co['name']);
|
||||
$copyOpts .= "<option value=\"{$cid}\">{$cn}</option>";
|
||||
}
|
||||
}
|
||||
$allCompaniesJson = !$isEdit
|
||||
? json_encode(
|
||||
array_column(CompanyRepository::findAll(true), null, 'id'),
|
||||
JSON_UNESCAPED_UNICODE | JSON_HEX_TAG
|
||||
)
|
||||
: '{}';
|
||||
|
||||
$tabsHtml = $isEdit ? <<<HTML
|
||||
<div style="display:flex;gap:0;border-bottom:1px solid #e5e7eb;margin-bottom:20px">
|
||||
<button class="tab-btn" id="tb-general" onclick="showTab('general')">General</button>
|
||||
@@ -1235,53 +1253,78 @@ HTML : '';
|
||||
<form method="POST" action="/admin/company/save">
|
||||
HTML;
|
||||
if ($isEdit) echo '<input type="hidden" name="id" value="' . $id . '">';
|
||||
if (!$isEdit && $copyOpts !== '') echo <<<COPY
|
||||
<div class="form-group" style="background:#f0f4ff;border:1px solid #c7d7ff;border-radius:8px;padding:14px;margin-bottom:18px">
|
||||
<label style="font-weight:700;color:#0b3d91">📋 Copiar configuración de empresa existente</label>
|
||||
<div style="display:flex;gap:10px;align-items:center;margin-top:8px;flex-wrap:wrap">
|
||||
<select id="copyFromSel" style="flex:1;min-width:200px">
|
||||
<option value="">— Selecciona empresa a copiar —</option>
|
||||
{$copyOpts}
|
||||
</select>
|
||||
<button type="button" class="btn-secondary" onclick="copyFromCompany()">Copiar campos</button>
|
||||
</div>
|
||||
<div style="font-size:11px;color:#6b7280;margin-top:6px">Copia API URL, API Key, tipo de bot, configuración JSON y endpoints. Podrás editar cada campo antes de guardar.</div>
|
||||
</div>
|
||||
COPY;
|
||||
echo <<<HTML
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>Nombre *</label>
|
||||
<input type="text" name="name" value="{$name}" required placeholder="Comercializadora ABC">
|
||||
<label>Nombre interno *</label>
|
||||
<input type="text" name="name" id="f_name" value="{$name}" required placeholder="palmas_norte">
|
||||
<div class="hint">Identificador único, sin espacios</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Nombre mostrado</label>
|
||||
<input type="text" name="display_name" value="{$display_name}" placeholder="ABC S.A.">
|
||||
<input type="text" name="display_name" id="f_display_name" value="{$display_name}" placeholder="Palmas Norte S.A.">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>WhatsApp Phone Number ID *</label>
|
||||
<input type="text" name="phone_number_id" id="f_phone_number_id" value="{$phone_number_id}" required placeholder="384710295638401" style="font-family:monospace">
|
||||
<div class="hint">ID del número en Meta / WhatsApp Business API</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Teléfono mostrado</label>
|
||||
<input type="text" name="display_phone" id="f_display_phone" value="{$display_phone}" placeholder="+57 300 123 4567">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>API Base URL *</label>
|
||||
<input type="text" name="api_base_url" value="{$api_base_url}" required placeholder="https://erp.empresa.com/api/">
|
||||
<input type="text" name="api_base_url" id="f_api_base_url" value="{$api_base_url}" required placeholder="https://erp.empresa.com/api/">
|
||||
<div class="hint">Base URL del ERP de esta empresa</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>API Key</label>
|
||||
<input type="text" name="api_key" value="{$api_key}" placeholder="Token Bearer">
|
||||
<input type="text" name="api_key" id="f_api_key" value="{$api_key}" placeholder="Token Bearer">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>Usuarios activos en ERP</label>
|
||||
<input type="number" name="erp_active_users" value="{$erp_active_users}" min="0" placeholder="0">
|
||||
<div class="hint">Define los límites de números WA. Se actualiza con sincronización ERP.</div>
|
||||
<input type="number" name="erp_active_users" id="f_erp_active_users" value="{$erp_active_users}" min="0" placeholder="0">
|
||||
<div class="hint">Define los límites de números WA.</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Tipo de Bot</label>
|
||||
<select name="bot_type">{$botOptions}</select>
|
||||
<select name="bot_type" id="f_bot_type">{$botOptions}</select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:20px;margin-bottom:14px;flex-wrap:wrap">
|
||||
<label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer">
|
||||
<input type="checkbox" name="requires_approval" value="1" {$reqAprChecked}> Requiere aprobación manual
|
||||
<input type="checkbox" name="requires_approval" id="f_requires_approval" value="1" {$reqAprChecked}> Requiere aprobación manual
|
||||
</label>
|
||||
<label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer">
|
||||
<input type="checkbox" name="is_active" value="1" {$isActChecked}> Activa
|
||||
<input type="checkbox" name="is_active" id="f_is_active" value="1" {$isActChecked}> Activa
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Configuración JSON adicional</label>
|
||||
<textarea name="config_json" rows="5" style="font-family:monospace;font-size:12px">{$config_json}</textarea>
|
||||
<label>Configuración JSON (bot: menús, flujos, etc.)</label>
|
||||
<textarea name="config_json" id="f_config_json" rows="6" style="font-family:monospace;font-size:12px">{$config_json}</textarea>
|
||||
</div>
|
||||
<div style="display:flex;gap:10px;padding-top:16px;border-top:1px solid #e5e7eb">
|
||||
<button type="submit" class="btn-primary">Guardar</button>
|
||||
<button type="submit" class="btn-primary">💾 Guardar</button>
|
||||
<a href="/admin/companies" class="btn-secondary">Cancelar</a>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1290,6 +1333,35 @@ HTML;
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
if (!$isEdit) {
|
||||
echo <<<SCRIPT
|
||||
<script>
|
||||
const ALL_COMPANIES = {$allCompaniesJson};
|
||||
function copyFromCompany() {
|
||||
const sel = document.getElementById('copyFromSel');
|
||||
const cid = parseInt(sel.value);
|
||||
if (!cid) return;
|
||||
const c = ALL_COMPANIES[cid];
|
||||
if (!c) return;
|
||||
const set = (id, val) => { const el = document.getElementById(id); if (el) el.value = val || ''; };
|
||||
set('f_display_name', c.display_name || '');
|
||||
set('f_api_base_url', c.api_base_url || '');
|
||||
set('f_api_key', c.api_key || '');
|
||||
set('f_erp_active_users', c.erp_active_users || 0);
|
||||
set('f_config_json', c.config_json || '');
|
||||
const bt = document.getElementById('f_bot_type');
|
||||
if (bt) bt.value = c.bot_type || 'normal';
|
||||
const ra = document.getElementById('f_requires_approval');
|
||||
if (ra) ra.checked = !!c.requires_approval;
|
||||
const ia = document.getElementById('f_is_active');
|
||||
if (ia) ia.checked = !!c.is_active;
|
||||
document.getElementById('f_name').focus();
|
||||
sel.value = '';
|
||||
}
|
||||
</script>
|
||||
SCRIPT;
|
||||
}
|
||||
|
||||
if ($isEdit) {
|
||||
echo <<<HTML
|
||||
<!-- Tab Números WhatsApp -->
|
||||
|
||||
Reference in New Issue
Block a user