diff --git a/services/invoice/InvoiceService.js b/services/invoice/InvoiceService.js
index 714836b..6d6a2c8 100644
--- a/services/invoice/InvoiceService.js
+++ b/services/invoice/InvoiceService.js
@@ -11,7 +11,6 @@ const fs = require('fs/promises');
const path = require('path');
const pool = require('../../database/database');
-const CompanySettingsRepository = require('../../repositories/settings/CompanySettingsRepository');
const CoffeeShippingFeeService = require('../subscriptions/CoffeeShippingFeeService');
class InvoiceService {
@@ -19,15 +18,6 @@ class InvoiceService {
this.repo = new InvoiceRepository();
}
- _inferImageMimeFromBase64(base64) {
- const s = String(base64 || '').trim();
- if (!s) return 'image/png';
- if (s.startsWith('iVBORw0KGgo')) return 'image/png';
- if (s.startsWith('/9j/')) return 'image/jpeg';
- if (s.startsWith('R0lGOD')) return 'image/gif';
- return 'image/png';
- }
-
_templateHasVars(template, varNames) {
if (!template) return false;
return varNames.every((name) => {
@@ -47,15 +37,19 @@ class InvoiceService {
}
_resolvePieceCountForQr(abonement) {
+ const breakdown = Array.isArray(abonement?.pack_breakdown) ? abonement.pack_breakdown : [];
+ const totalPacks = breakdown.reduce((sum, item) => sum + Number(item?.packs || item?.quantity || 0), 0);
+ const piecesByPack = totalPacks ? totalPacks * 10 : null;
+ if (piecesByPack != null) {
+ if (piecesByPack >= 120) return 120;
+ if (piecesByPack >= 60) return 60;
+ return null;
+ }
+
const packGroup = String(abonement?.pack_group || '').toLowerCase();
if (packGroup.includes('120')) return 120;
if (packGroup.includes('60')) return 60;
- const breakdown = Array.isArray(abonement?.pack_breakdown) ? abonement.pack_breakdown : [];
- const totalPacks = breakdown.reduce((sum, item) => sum + Number(item?.packs || 0), 0);
- const piecesByPack = totalPacks ? totalPacks * 10 : null;
- if (piecesByPack === 60 || piecesByPack === 120) return piecesByPack;
-
return null;
}
@@ -107,35 +101,8 @@ class InvoiceService {
return items;
}
- async _getCompanySettingsQrDataUri(pieceCount) {
- const safePieceCount = pieceCount === 120 ? 120 : 60;
- try {
- const repo = new CompanySettingsRepository();
- const row = await repo.get();
- if (!row) return null;
- const raw = safePieceCount === 120 ? row?.qr_code_120_base64 : row?.qr_code_60_base64;
- const value = (raw == null) ? '' : String(raw).trim();
- if (!value) return null;
- if (value.startsWith('data:image/')) return value;
- const mime = this._inferImageMimeFromBase64(value);
- return `data:${mime};base64,${value}`;
- } catch (e) {
- logger.warn('InvoiceService._getCompanySettingsQrDataUri:error', {
- pieceCount: safePieceCount,
- message: e?.message,
- });
- return null;
- }
- }
-
async _buildQrCodeImageTag({ abonement }) {
- const pieceCount = this._resolvePieceCountForQr(abonement);
- if (!pieceCount) return '';
-
- const dataUri = await this._getCompanySettingsQrDataUri(pieceCount);
- if (!dataUri) return '';
-
- return `
`;
+ return '';
}
_escapeHtml(value) {
@@ -312,11 +279,10 @@ class InvoiceService {
_prepareVariablesForTemplate(templateHtml, variables) {
// Ensure backwards compatibility with older templates that only contain {{paymentInfoText}}
- // by injecting the Profit Planet bank block (and optionally QR) into paymentInfoText.
+ // by injecting the Profit Planet bank block into paymentInfoText.
if (!templateHtml) return variables;
const supportsBankVars = this._templateHasVars(templateHtml, ['bankAccountHolder', 'bankIban', 'bankBic']);
- const supportsQrVar = this._templateHasVars(templateHtml, ['qrCodeImage']);
const bankBlock = this._getProfitPlanetBankBlockHtml({
bankAccountHolder: variables.bankAccountHolder || 'Profit Planet GmbH',
@@ -330,11 +296,6 @@ class InvoiceService {
next.paymentInfoText = bankBlock;
}
- if (!supportsQrVar && variables.qrCodeImage) {
- // Append QR under payment info text when there's no dedicated placeholder
- next.paymentInfoText = `${next.paymentInfoText || ''}
${variables.qrCodeImage}`;
- }
-
return next;
}
@@ -559,29 +520,14 @@ class InvoiceService {
if (templateHtml) {
const supportsBankVars = this._templateHasVars(templateHtml, ['bankAccountHolder', 'bankIban', 'bankBic']);
- const supportsQrVar = this._templateHasVars(templateHtml, ['qrCodeImage']);
- const pieceCountForQr = this._resolvePieceCountForQr(abonement);
logger.info('InvoiceService._sendInvoiceEmail:template_compat', {
invoiceId: invoice?.id,
lang,
supportsBankVars,
- supportsQrVar,
- pieceCountForQr,
- hasQrImage: Boolean(variables?.qrCodeImage),
});
const varsForTemplate = this._prepareVariablesForTemplate(templateHtml, variables);
html = this._renderTemplate(templateHtml, varsForTemplate);
-
- // Final guard: if we still didn't embed QR but we expected one, force local template
- const missingQr = variables.qrCodeImage && !html.includes('data:image/png;base64,');
- if (missingQr) {
- const localTemplate = await this._loadLocalInvoiceTemplateHtml();
- if (localTemplate) {
- const varsForLocal = this._prepareVariablesForTemplate(localTemplate, variables);
- html = this._renderTemplate(localTemplate, varsForLocal);
- }
- }
}
const htmlForPdf = html || await this._buildFallbackInvoiceHtml({ invoice, items, abonement, lang });