De-fork POS chrome/assets and import CRM products only
Deploy Ladill POS / deploy (push) Successful in 32s

Finish removing the upstream platform fork: drop the Hosting/SSL/Domain
notification classes + their mail views, the email/mailbox/domains/hosting
view trees, the Mini/Afia/search/paystack partials and unused components, and
the now-orphan support helpers (DomainConfig, MailboxPricing,
ResellerClubLegacy), SmsService, and fork configs (afia, hosting, domain,
email, mailbox, qr, mail_brands, notifications, ...). Reparent the
notifications page off the hosting layout onto the POS app layout (it had
referenced undefined hosting./mini. routes). Computed the removable set from a
reachability scan of the POS view graph; kept views reference no removed
routes/services.

Branding: favicon now uses the updated favicon.ico (favicon.svg removed);
signed-out fallback logo points at the POS logo.

CRM import: constrain the catalogue pull to type=product so CRM services are
never imported as POS products (server-side filter + defensive client skip).

Test suite green (8 passed, 29 assertions); all routes resolve and every
remaining Blade compiles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
isaacclad
2026-06-24 00:40:01 +00:00
co-authored by Claude Opus 4.8
parent 46b5091b1e
commit b7c7a32ee6
87 changed files with 34 additions and 5410 deletions
-43
View File
@@ -1,43 +0,0 @@
<?php
namespace App\Services\Billing;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class SmsService
{
public function send(string $to, string $message): void
{
$apiKey = config('services.termii.api_key', '');
$senderId = config('services.termii.sender_id', config('app.name', 'LaDill'));
if ($apiKey === '') {
return;
}
$phone = preg_replace('/\D+/', '', $to);
if (strlen($phone) < 9) {
return;
}
if (strlen($phone) === 9) {
$phone = '233'.$phone;
} elseif (str_starts_with($phone, '0')) {
$phone = '233'.substr($phone, 1);
}
try {
Http::timeout(10)->post('https://v3.api.termii.com/api/sms/send', [
'api_key' => $apiKey,
'to' => $phone,
'from' => $senderId,
'sms' => $message,
'type' => 'plain',
'channel' => 'dnd',
]);
} catch (\Throwable $e) {
Log::warning('SMS send failed', ['to' => $phone, 'error' => $e->getMessage()]);
}
}
}
@@ -13,7 +13,8 @@ class CrmProductImportService
*/
public function import(string $ownerRef): array
{
$response = CrmClient::for($ownerRef)->products(['active' => 1, 'per_page' => 500]);
// CRM catalogues both products and services; POS only stocks products.
$response = CrmClient::for($ownerRef)->products(['type' => 'product', 'active' => 1, 'per_page' => 500]);
$rows = (array) ($response['data'] ?? []);
if ($rows === []) {
@@ -24,6 +25,11 @@ class CrmProductImportService
$updated = 0;
foreach ($rows as $row) {
// Defensive: skip services in case an older CRM API ignores the type filter.
if (($row['type'] ?? 'product') !== 'product') {
continue;
}
$name = trim((string) ($row['name'] ?? ''));
if ($name === '') {
continue;