A vevői értesítések ne bukjanak némán, és ne írjunk e-mail-címet konzolra

Élesben kiderült, hogy a "Rendelésed feldolgozás alatt" sablon TÖRZSE üres volt
(<p></p>), az "elkészült" sablon TÁRGYA pedig a másikról másolódott át. Egyik sem
tűnt fel, mert a szolgáltatás hiányzó vagy inaktív sablonnál némán kilépett
(return 0, nyom nélkül).

- Nop.Services.Logging.ILogger bekötve (teljesen minősítve, hogy ne ütközzön a
  Microsoft.Extensions.Logging.ILogger-rel). A bejegyzések az Admin → Rendszer →
  Napló alatt kereshetők.
- Hiányzó és inaktív sablon külön ágon, beszédes figyelmeztetéssel: sablonnév,
  store és rendelésszám. A hiányzó sablon üzenete kimondja az okot is — a
  sablonokat az InstallAsync hozza létre, ami már telepített pluginnál nem fut le
  újra —, hogy aki a naplóban találkozik vele, ne kelljen újra végignyomoznia.
- Console.WriteLine törölve: a vevő e-mail-címét írta a szerver konzoljára.
- Null-ágak lezárva: ha sem a sablon e-mail-fiókja, sem az alapértelmezett nincs
  meg, illetve ha a rendelés vevője nem található (törölt vevő) — eddig az utóbbi
  a customer.Email-nél szállt el.

A sablonok tartalmát külön, tranzakcióba csomagolt SQL-lel javítottuk éles DB-n;
a szövegek forrása a FruitBankPlugin.InstallAsync kanonikus alapértéke, hogy ne
legyen drift a kód és az éles adat között.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 13:00:25 +02:00
co-authored by Claude Opus 5
parent ced5e6a738
commit 5a7de3a414
@@ -34,6 +34,9 @@ public class FruitBankNotificationService(
IQueuedEmailService queuedEmailService,
IStoreService storeService,
ITokenizer tokenizer,
// A nop natív naplózója: a bejegyzések az Admin → Rendszer → Napló alatt megjelennek. Enélkül egy elmaradt
// vevői értesítés nyomtalan maradna — élesben pontosan ez rejtett el egy üres törzsű sablont.
Nop.Services.Logging.ILogger logger,
MessagesSettings messagesSettings) : WorkflowMessageService(commonSettings,
emailAccountSettings,
addressService,
@@ -168,17 +171,48 @@ public class FruitBankNotificationService(
var templates = await messageTemplateService.GetMessageTemplatesByNameAsync(templateName, store.Id);
var messageTemplate = templates?.FirstOrDefault();
if (messageTemplate is null || !messageTemplate.IsActive)
// A hiányzó/inaktív sablon eddig NÉMÁN nyelte el az értesítést (`return 0`, nyom nélkül). Egy vevőnek szóló
// levél elmaradása nem maradhat láthatatlan — a naplóból utólag is kideríthető.
if (messageTemplate is null)
{
await logger.WarningAsync(
$"FruitBank értesítés kimaradt: a(z) '{templateName}' üzenetsablon nem létezik (store: {store.Id}; rendelés: #{order.Id}). " +
"A sablonokat a plugin InstallAsync-je hozza létre, ami már telepített pluginnál nem fut le újra — ilyenkor kézzel kell pótolni.");
return 0;
}
if (!messageTemplate.IsActive)
{
await logger.WarningAsync(
$"FruitBank értesítés kimaradt: a(z) '{templateName}' üzenetsablon INAKTÍV (store: {store.Id}; rendelés: #{order.Id}).");
return 0;
}
var emailAccount = await emailAccountService.GetEmailAccountByIdAsync(messageTemplate.EmailAccountId)
?? await emailAccountService.GetEmailAccountByIdAsync(emailAccountSettings.DefaultEmailAccountId);
if (emailAccount is null)
{
await logger.ErrorAsync(
$"FruitBank értesítés kimaradt: nincs használható e-mail fiók a(z) '{templateName}' sablonhoz " +
$"(sablon fiókja: {messageTemplate.EmailAccountId}; alapértelmezett: {emailAccountSettings.DefaultEmailAccountId}; rendelés: #{order.Id}).");
return 0;
}
var tokens = new List<Token>();
await messageTokenProvider.AddStoreTokensAsync(tokens, store, emailAccount, order.CustomerLanguageId);
await messageTokenProvider.AddOrderTokensAsync(tokens, order, order.CustomerLanguageId);
var customer = await customerService.GetCustomerByIdAsync(order.CustomerId);
// Törölt/hiányzó vevőnél nincs kinek küldeni — eddig a lentebbi customer.Email-nél szállt el.
if (customer is null)
{
await logger.ErrorAsync(
$"FruitBank értesítés kimaradt: a(z) #{order.Id} rendelés vevője nem található (customerId: {order.CustomerId}; sablon: '{templateName}').");
return 0;
}
await messageTokenProvider.AddCustomerTokensAsync(tokens, customer);
tokens.Add(new Token("Order.MeasurableNote", measurableNote, true));
@@ -195,8 +229,6 @@ public class FruitBankNotificationService(
customerEmail = (await addressService.GetAddressByIdAsync(addressId)).Email ?? customer.Email;
}
Console.WriteLine($"Customer email determined as: {customerEmail} (addressId: {addressId})");
var toName = $"{customer.FirstName} {customer.LastName}".Trim();
if (string.IsNullOrWhiteSpace(toName)) toName = customer.Email;