diff --git a/admin/DashboardController.php b/admin/DashboardController.php
index cd64f6e..e17782a 100644
--- a/admin/DashboardController.php
+++ b/admin/DashboardController.php
@@ -1017,7 +1017,12 @@ HTML;
$botOptions .= "\n";
}
- $pageTitle = $isEdit ? 'Editar Empresa' : 'Nueva Empresa';
+ $pageTitle = $isEdit ? 'Editar Empresa' : 'Nueva Empresa';
+ $errorBanner = '';
+ if (!empty($_GET['error'])) {
+ $errText = self::h(urldecode($_GET['error']));
+ $errorBanner = "
⚠ {$errText}
";
+ }
echo Layout::open($pageTitle, 'companies', $user['name'] ?? 'Admin');
// ── Tab: Números WhatsApp ─────────────────────────────────────────────
@@ -1251,6 +1256,7 @@ HTML : '';
{$pageTitle}
← Empresas
+ {$errorBanner}
{$tabsHtml}
diff --git a/public/index.php b/public/index.php
index 8e437e5..46ed24d 100644
--- a/public/index.php
+++ b/public/index.php
@@ -241,12 +241,17 @@ $routes = [
// ─── Guardar empresa (crear/actualizar) ─────────────────────────────────
['POST', '/admin/company/save', fn() => (function () {
SessionAuth::require();
- $data = $_POST;
- $id = CompanyRepository::save($data);
- if ($id > 0) {
- header('Location: /admin/companies?msg=' . ($data['id'] ?? 0 > 0 ? 'updated' : 'created'));
- } else {
- header('Location: /admin/companies?msg=error');
+ $data = $_POST;
+ $isNew = empty($data['id']) || (int)$data['id'] === 0;
+ try {
+ CompanyRepository::save($data);
+ header('Location: /admin/companies?msg=' . ($isNew ? 'created' : 'updated'));
+ } catch (\RuntimeException $e) {
+ $errMsg = urlencode($e->getMessage());
+ $redirect = $isNew
+ ? '/admin/companies/new?error=' . $errMsg
+ : '/admin/company/edit?id=' . (int)$data['id'] . '&error=' . $errMsg;
+ header('Location: ' . $redirect);
}
exit;
})()],
diff --git a/services/CompanyRepository.php b/services/CompanyRepository.php
index 617a905..4cece14 100644
--- a/services/CompanyRepository.php
+++ b/services/CompanyRepository.php
@@ -33,12 +33,23 @@ class CompanyRepository
return db()->query("SELECT * FROM companies WHERE {$where} ORDER BY name")->fetchAll();
}
+ /**
+ * @throws \RuntimeException with a human-readable message on DB error
+ */
public static function save(array $data): int
{
$db = db();
$id = (int)($data['id'] ?? 0);
$fields = ['name', 'display_name', 'phone_number_id', 'display_phone', 'api_base_url', 'api_key', 'bot_type', 'requires_approval', 'is_active', 'config_json', 'erp_active_users'];
+
+ // Checkboxes: absent when unchecked — explicitly set to 0 so UPDATE clears them
+ foreach (['requires_approval', 'is_active'] as $cb) {
+ if (!array_key_exists($cb, $data)) {
+ $data[$cb] = 0;
+ }
+ }
+
$params = [];
$sets = [];
foreach ($fields as $f) {
@@ -48,18 +59,19 @@ class CompanyRepository
}
}
- if ($id > 0) {
- $params[] = $id;
- $stmt = $db->prepare("UPDATE companies SET " . implode(', ', $sets) . " WHERE id = ?");
- $stmt->execute($params);
- return $id;
- } else {
- // Ensure required fields
- $required = ['name', 'api_base_url'];
- $insertData = [];
- foreach ($required as $r) {
- $insertData[$r] = $data[$r] ?? '';
+ try {
+ if ($id > 0) {
+ $params[] = $id;
+ $db->prepare("UPDATE companies SET " . implode(', ', $sets) . " WHERE id = ?")
+ ->execute($params);
+ return $id;
}
+
+ // INSERT — require name
+ if (trim($data['name'] ?? '') === '') {
+ throw new \RuntimeException('El nombre de la empresa es requerido.');
+ }
+ $insertData = [];
foreach ($fields as $f) {
if (array_key_exists($f, $data)) {
$insertData[$f] = $data[$f];
@@ -67,9 +79,17 @@ class CompanyRepository
}
$cols = implode(', ', array_keys($insertData));
$vals = implode(', ', array_fill(0, count($insertData), '?'));
- $stmt = $db->prepare("INSERT INTO companies ({$cols}) VALUES ({$vals})");
- $stmt->execute(array_values($insertData));
+ $db->prepare("INSERT INTO companies ({$cols}) VALUES ({$vals})")
+ ->execute(array_values($insertData));
return (int)$db->lastInsertId();
+
+ } catch (\PDOException $e) {
+ $msg = $e->getMessage();
+ // Duplicate entry on name unique key
+ if (str_contains($msg, '1062') || str_contains($msg, 'Duplicate entry')) {
+ throw new \RuntimeException('Ya existe una empresa con ese nombre.');
+ }
+ throw new \RuntimeException('Error al guardar: ' . $msg);
}
}