fix: repair ErpSync upsert — no duplicate key + preserve config_json
- Added UNIQUE KEY on companies.name in DB so ON DUPLICATE KEY UPDATE actually fires instead of always inserting - Removed config_json and phone_number_id from upsert: those hold admin-configured bot data and should never be overwritten by ERP sync - Skip placeholder API key to avoid sending a fake Bearer token - Improved error reporting: curl errors, raw response preview, per-company error labels Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
332c808bf2
commit
838cc651b2
+24
-15
@@ -9,11 +9,11 @@ class ErpSync
|
|||||||
$apiKey = env('ERP_SYNC_API_KEY', '');
|
$apiKey = env('ERP_SYNC_API_KEY', '');
|
||||||
|
|
||||||
if ($apiUrl === '') {
|
if ($apiUrl === '') {
|
||||||
return ['error' => 'ERP_SYNC_API_URL no configurado'];
|
return ['error' => 'ERP_SYNC_API_URL no configurado en .env'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$httpHeader = ['Accept: application/json'];
|
$httpHeader = ['Accept: application/json'];
|
||||||
if ($apiKey !== '') {
|
if ($apiKey !== '' && $apiKey !== 'token_para_sincronizar_empresas') {
|
||||||
$httpHeader[] = 'Authorization: Bearer ' . $apiKey;
|
$httpHeader[] = 'Authorization: Bearer ' . $apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,15 +26,20 @@ class ErpSync
|
|||||||
|
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$curlErr = curl_error($ch);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($curlErr !== '') {
|
||||||
|
return ['error' => 'cURL error: ' . $curlErr];
|
||||||
|
}
|
||||||
|
|
||||||
if ($httpCode !== 200) {
|
if ($httpCode !== 200) {
|
||||||
return ['error' => "HTTP {$httpCode}", 'response' => mb_substr((string)$response, 0, 1000)];
|
return ['error' => "HTTP {$httpCode}", 'response' => mb_substr((string)$response, 0, 500)];
|
||||||
}
|
}
|
||||||
|
|
||||||
$companies = json_decode($response, true);
|
$companies = json_decode($response, true);
|
||||||
if (!is_array($companies)) {
|
if (!is_array($companies)) {
|
||||||
return ['error' => 'JSON inválido del ERP'];
|
return ['error' => 'Respuesta no es JSON válido', 'raw' => mb_substr((string)$response, 0, 300)];
|
||||||
}
|
}
|
||||||
|
|
||||||
$synced = 0;
|
$synced = 0;
|
||||||
@@ -45,42 +50,46 @@ class ErpSync
|
|||||||
self::upsert($company);
|
self::upsert($company);
|
||||||
$synced++;
|
$synced++;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$errors[] = $e->getMessage();
|
$errors[] = ($company['name'] ?? '?') . ': ' . $e->getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['synced' => $synced, 'errors' => $errors];
|
return ['synced' => $synced, 'total' => count($companies), 'errors' => $errors];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function upsert(array $data): void
|
private static function upsert(array $data): void
|
||||||
{
|
{
|
||||||
|
$name = trim($data['name'] ?? '');
|
||||||
|
if ($name === '') {
|
||||||
|
throw new \InvalidArgumentException('name es requerido');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never overwrite config_json — that holds all bot flows/menus configured by admins.
|
||||||
|
// Never overwrite phone_number_id — set manually per company.
|
||||||
$stmt = db()->prepare("
|
$stmt = db()->prepare("
|
||||||
INSERT INTO companies
|
INSERT INTO companies
|
||||||
(name, display_name, phone_number_id, display_phone, api_base_url, api_key, bot_type, requires_approval, is_active, config_json)
|
(name, display_name, display_phone, api_base_url, api_key, bot_type, requires_approval, is_active)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
name = VALUES(name),
|
|
||||||
display_name = VALUES(display_name),
|
display_name = VALUES(display_name),
|
||||||
|
display_phone = VALUES(display_phone),
|
||||||
api_base_url = VALUES(api_base_url),
|
api_base_url = VALUES(api_base_url),
|
||||||
api_key = VALUES(api_key),
|
api_key = VALUES(api_key),
|
||||||
bot_type = VALUES(bot_type),
|
bot_type = VALUES(bot_type),
|
||||||
requires_approval = VALUES(requires_approval),
|
requires_approval = VALUES(requires_approval),
|
||||||
is_active = VALUES(is_active),
|
is_active = VALUES(is_active),
|
||||||
config_json = VALUES(config_json),
|
|
||||||
updated_at = NOW()
|
updated_at = NOW()
|
||||||
");
|
");
|
||||||
|
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$data['name'] ?? '',
|
$name,
|
||||||
$data['display_name'] ?? $data['name'] ?? '',
|
$data['display_name'] ?? $name,
|
||||||
$data['phone_number_id'] ?? '',
|
|
||||||
$data['display_phone'] ?? '',
|
$data['display_phone'] ?? '',
|
||||||
$data['api_base_url'] ?? '',
|
$data['api_base_url'] ?? '',
|
||||||
$data['api_key'] ?? '',
|
$data['api_key'] ?? '',
|
||||||
$data['bot_type'] ?? 'normal',
|
in_array($data['bot_type'] ?? '', ['ai', 'normal', 'hybrid']) ? $data['bot_type'] : 'normal',
|
||||||
(int)($data['requires_approval'] ?? 0),
|
(int)($data['requires_approval'] ?? 0),
|
||||||
(int)($data['is_active'] ?? 1),
|
(int)($data['is_active'] ?? 1),
|
||||||
isset($data['config_json']) ? (is_string($data['config_json']) ? $data['config_json'] : json_encode($data['config_json'])) : null,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user