feat(121+122): smsplanet conversation, notifications, default footer
Phase 121 — SMSPLANET Conversation + Notifications:
- migration 20260512_000110 adds smsplanet conversation + notifications tables
- src/Modules/Sms (SmsConversationService, SmsMessageRepository, SmsplanetWebhookController)
- src/Modules/Notifications (Repository, Controller, ApiController)
- order SMS tab, notification center, sender mode, inbound webhook
- public notifications.js + layouts/app.php integration
Phase 122 — SMSPLANET Default SMS Footer:
- migration 20260512_000111 adds smsplanet_integration_settings.default_footer
- footer appended to test SMS and order SMS, validated against 918 char limit
- settings textarea + compact order SMS note when footer configured
Bundled (could not split per-phase without hunk staging):
- routes/web.php (also carries Phase 118 fakturownia redirects)
- DOCS/{ARCHITECTURE,DB_SCHEMA,TECH_CHANGELOG}.md (118 + 121 + 122 entries)
- .paul/codebase/{architecture,db_schema,tech_changelog}.md (118 + 121 + 122)
- .paul/STATE.md, ROADMAP.md, changelog/2026-05-12.md (UNIFY closure)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,9 @@ $invoiceConfigsList = is_array($invoiceConfigs ?? null) ? $invoiceConfigs : [];
|
||||
$invoiceRequestedFlag = (int) ($orderRow['invoice_requested'] ?? 0) === 1;
|
||||
$emailTemplatesList = is_array($emailTemplates ?? null) ? $emailTemplates : [];
|
||||
$emailMailboxesList = is_array($emailMailboxes ?? null) ? $emailMailboxes : [];
|
||||
$smsMessagesList = is_array($smsMessages ?? null) ? $smsMessages : [];
|
||||
$smsPhoneValue = trim((string) ($smsPhone ?? ''));
|
||||
$smsDefaultFooterConfigured = (bool) ($smsDefaultFooterConfigured ?? false);
|
||||
$historyList = is_array($history ?? null) ? $history : [];
|
||||
$activityLogList = is_array($activityLog ?? null) ? $activityLog : [];
|
||||
$statusPanelList = is_array($statusPanel ?? null) ? $statusPanel : [];
|
||||
@@ -181,6 +184,7 @@ foreach ($addressesList as $address) {
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="shipments"><?= $e($t('orders.details.tabs.shipments')) ?> (<?= $e((string) (count($shipmentsList) + count($packagesList))) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="payments"><?= $e($t('orders.details.tabs.payments')) ?> (<?= $e((string) count($paymentsList)) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="documents"><?= $e($t('orders.details.tabs.documents')) ?> (<?= $e((string) (count($documentsList) + count($receiptsList))) ?>)</button>
|
||||
<button type="button" class="order-details-tab" data-order-tab-target="sms"><?= $e($t('orders.details.tabs.sms')) ?> (<?= $e((string) count($smsMessagesList)) ?>)</button>
|
||||
</section>
|
||||
|
||||
<div class="order-tab-panel is-active" data-order-tab-panel="details">
|
||||
@@ -973,6 +977,62 @@ foreach ($addressesList as $address) {
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="order-tab-panel" data-order-tab-panel="sms">
|
||||
<section class="card mt-16">
|
||||
<div class="order-sms-head">
|
||||
<h3 class="section-title"><?= $e($t('orders.details.sms.title')) ?></h3>
|
||||
<?php if ($smsPhoneValue !== ''): ?>
|
||||
<span class="badge badge--muted"><?= $e($smsPhoneValue) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="order-sms-thread mt-12">
|
||||
<?php if ($smsMessagesList === []): ?>
|
||||
<div class="muted"><?= $e($t('orders.details.sms.empty')) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($smsMessagesList as $smsMessage): ?>
|
||||
<?php
|
||||
$direction = (string) ($smsMessage['direction'] ?? '');
|
||||
$isOutbound = $direction === 'outbound';
|
||||
$messageId = trim((string) ($smsMessage['message_id'] ?? ''));
|
||||
$status = trim((string) ($smsMessage['status'] ?? ''));
|
||||
?>
|
||||
<article class="order-sms-bubble<?= $isOutbound ? ' order-sms-bubble--outbound' : ' order-sms-bubble--inbound' ?>">
|
||||
<div class="order-sms-bubble__meta">
|
||||
<span><?= $e($isOutbound ? $t('orders.details.sms.outbound') : $t('orders.details.sms.inbound')) ?></span>
|
||||
<span><?= $e((string) ($smsMessage['created_at'] ?? '')) ?></span>
|
||||
</div>
|
||||
<div class="order-sms-bubble__body"><?= nl2br($e((string) ($smsMessage['body'] ?? ''))) ?></div>
|
||||
<?php if ($isOutbound && ($status !== '' || $messageId !== '')): ?>
|
||||
<div class="order-sms-bubble__meta">
|
||||
<?php if ($status !== ''): ?><span><?= $e($status) ?></span><?php endif; ?>
|
||||
<?php if ($messageId !== ''): ?><span>ID: <?= $e($messageId) ?></span><?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<form class="order-sms-form mt-16" method="post" action="/orders/<?= $e((string) ($orderId ?? 0)) ?>/sms/send">
|
||||
<input type="hidden" name="_token" value="<?= $e((string) ($csrfToken ?? '')) ?>">
|
||||
<label class="form-field">
|
||||
<span class="field-label"><?= $e($t('orders.details.sms.phone')) ?></span>
|
||||
<input class="form-control" type="tel" name="phone" inputmode="tel" value="<?= $e($smsPhoneValue) ?>" required>
|
||||
</label>
|
||||
<label class="form-field">
|
||||
<span class="field-label"><?= $e($t('orders.details.sms.message')) ?></span>
|
||||
<textarea class="form-control" name="message" rows="3" maxlength="918" required></textarea>
|
||||
<?php if ($smsDefaultFooterConfigured): ?>
|
||||
<span class="order-sms-footer-note"><?= $e($t('orders.details.sms.footer_note')) ?></span>
|
||||
<?php endif; ?>
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn--primary"><?= $e($t('orders.details.sms.send')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1002,7 +1062,9 @@ foreach ($addressesList as $address) {
|
||||
});
|
||||
});
|
||||
|
||||
var forceTab = <?= json_encode($flashSuccessMsg !== '' && strpos($flashSuccessMsg, 'Przesylka') !== false ? 'shipments' : '') ?>;
|
||||
var queryTab = '';
|
||||
try { queryTab = new URLSearchParams(window.location.search).get('tab') || ''; } catch (e) {}
|
||||
var forceTab = queryTab || <?= json_encode($flashSuccessMsg !== '' && strpos($flashSuccessMsg, 'Przesylka') !== false ? 'shipments' : '') ?>;
|
||||
var savedTab = null;
|
||||
try { savedTab = localStorage.getItem(storageKey); } catch (e) {}
|
||||
setActiveTab(forceTab || savedTab || 'details');
|
||||
|
||||
Reference in New Issue
Block a user