diff --git a/src/config/config.ts b/src/config/config.ts index 600b988100..f6f7602e56 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -636,7 +636,7 @@ export class Configuration { pass: process.env.REALUNIT_MAIL_PASS, fromAddress: process.env.REALUNIT_MAIL_USER, displayName: 'RealUnit', - template: 'user-v2', + template: 'realUnit', }, }), }, diff --git a/src/shared/i18n/de/mail.json b/src/shared/i18n/de/mail.json index 3eae4fda78..e0faefee0a 100644 --- a/src/shared/i18n/de/mail.json +++ b/src/shared/i18n/de/mail.json @@ -414,5 +414,75 @@ }, "message": "Dein Verifizierungscode lautet:
{code}", "closing": "Der Verifizierungscode ist für {expiration} Minuten gültig. Bitte teile diesen Verifizierungscode nicht mit anderen Personen. Wenn du keinen Verifizierungscode angefordert hast, kontaktiere bitte unverzüglich den Support unter [url:https://app.dfx.swiss/support]." + }, + "wallets": { + "realunit": { + "general": { + "dfx_team_closing": "RealUnit Schweiz AG", + "dfx_closing_message": "", + "support": "Bei technischen Problemen mit der App wenden Sie sich bitte an
[url:https://support.realunit.ch]", + "thanks": "Vielen Dank für Ihr Vertrauen", + "welcome": "Guten Tag {name}", + "team_questions": "Sollten Sie Fragen haben, steht Ihnen das RealUnit-Team gerne unter info@realunit.ch zur Verfügung.", + "personal_closing": "Freundliche Grüsse,
{closingName}" + }, + "payment": { + "crypto_output": { + "title": "Transfer Ihrer RealUnit-Token", + "salutation": "Wir haben Ihnen die RealUnit-Token in Ihr Wallet überwiesen" + }, + "fiat_output": { + "title": "Verkauf RealUnit-Token – Überweisung erfolgt", + "salutation": "Sie haben Ihre RealUnit-Token erfolgreich verkauft" + }, + "processing": { + "title": "Verkauf Ihrer RealUnit-Token", + "salutation": "Ihre Verkaufstransaktion wird nun verarbeitet" + }, + "fiat_input": { + "title": "Kauf RealUnit-Token – Einzahlung wird geprüft", + "salutation": "Vielen Dank für den Kauf unserer RealUnit-Aktientoken" + }, + "chargeback": { + "fiat": { + "title": "Verkauf RealUnit-Token – Rückerstattung", + "salutation": "Ihr Verkaufsauftrag konnte nicht durchgeführt werden" + }, + "crypto": { + "title": "Verkauf RealUnit-Token aktuell nicht möglich", + "salutation": "Ihre RealUnit-Token wurden Ihrem Wallet zurückerstattet" + }, + "introduction": "Grund:
{reason}", + "reasons": { + "monthly_limit": "Sie haben die monatliche Limite von CHF 1'000.– ohne vollständige Verifizierung überschritten", + "annual_limit": "Sie haben die jährliche Limite von CHF 100'000.– ohne erweiterte Verifizierung überschritten", + "annual_limit_without_kyc": "Sie haben die Jahreslimite ohne KYC-Verifizierung überschritten", + "kyc_data_needed": "Für den Verkauf werden Ihre vollständigen KYC-Daten benötigt", + "video_ident_needed": "Für den Verkauf ist eine Video-Verifizierung nötig", + "high_risk_kyc_needed": "Aus regulatorischen Gründen ist eine vollständige Verifizierung nötig" + } + } + }, + "kyc": { + "failed": { + "title": "Verkauf RealUnit-Token – Video-Verifizierung erforderlich", + "salutation": "Aus regulatorischen Gründen ist eine Video-Verifizierung erforderlich" + }, + "missing_data": { + "title": "Verkauf RealUnit-Token – Bitte vervollständigen Sie Ihre Stammdaten", + "salutation": "In Ihrem Profil fehlen einzelne Stammdaten" + }, + "reminder": { + "title": "Erinnerung: Ihr Verkauf wartet auf Verifizierung", + "salutation": "Ihr Verkaufsauftrag wartet weiterhin auf Ihre Verifizierung" + } + }, + "verification_code": { + "email": { + "title": "Erinnerung: Bestätigung Ihrer E-Mailadresse", + "salutation": "Bitte bestätigen Sie Ihre E-Mailadresse" + } + } + } } } diff --git a/src/shared/i18n/en/mail.json b/src/shared/i18n/en/mail.json index 74f962b256..c5951810bb 100644 --- a/src/shared/i18n/en/mail.json +++ b/src/shared/i18n/en/mail.json @@ -414,5 +414,75 @@ }, "message": "Your verification code is:
{code}", "closing": "The verification code is valid for {expiration} minutes. Please do not share this verification code with other people. If you have not requested a verification code, please contact support immediately via [url:https://app.dfx.swiss/support]." + }, + "wallets": { + "realunit": { + "general": { + "dfx_team_closing": "RealUnit Schweiz AG", + "dfx_closing_message": "", + "support": "For technical issues with the app, please contact
[url:https://support.realunit.ch]", + "thanks": "Thank you for your trust", + "welcome": "Dear {name}", + "team_questions": "Should you have any questions, the RealUnit team is happy to assist at info@realunit.ch.", + "personal_closing": "Kind regards,
{closingName}" + }, + "payment": { + "crypto_output": { + "title": "Transfer of your RealUnit tokens", + "salutation": "We have transferred the RealUnit tokens to your wallet" + }, + "fiat_output": { + "title": "Sale of RealUnit tokens – Payout completed", + "salutation": "You have successfully sold your RealUnit tokens" + }, + "processing": { + "title": "Sale of your RealUnit tokens", + "salutation": "Your sell transaction is now being processed" + }, + "fiat_input": { + "title": "Purchase of RealUnit tokens – Payment under review", + "salutation": "Thank you for purchasing our RealUnit equity tokens" + }, + "chargeback": { + "fiat": { + "title": "Sale of RealUnit tokens – Refund", + "salutation": "Your sell order could not be executed" + }, + "crypto": { + "title": "Sale of RealUnit tokens currently not possible", + "salutation": "Your RealUnit tokens have been returned to your wallet" + }, + "introduction": "Reason:
{reason}", + "reasons": { + "monthly_limit": "You have exceeded the monthly limit of CHF 1'000 without full verification", + "annual_limit": "You have exceeded the annual limit of CHF 100'000 without extended verification", + "annual_limit_without_kyc": "You have exceeded the annual limit without KYC verification", + "kyc_data_needed": "Full KYC data is required for the sale", + "video_ident_needed": "A video verification is required for the sale", + "high_risk_kyc_needed": "Full verification is required for regulatory reasons" + } + } + }, + "kyc": { + "failed": { + "title": "Sale of RealUnit tokens – Video verification required", + "salutation": "Video verification is required for regulatory reasons" + }, + "missing_data": { + "title": "Sale of RealUnit tokens – Please complete your profile data", + "salutation": "Some profile data is missing" + }, + "reminder": { + "title": "Reminder: Your sale is waiting for verification", + "salutation": "Your sell order is still waiting for your verification" + } + }, + "verification_code": { + "email": { + "title": "Reminder: Confirm your email address", + "salutation": "Please confirm your email address" + } + } + } } } diff --git a/src/subdomains/supporting/notification/factories/mail.factory.ts b/src/subdomains/supporting/notification/factories/mail.factory.ts index 817e2782cd..5738ea0256 100644 --- a/src/subdomains/supporting/notification/factories/mail.factory.ts +++ b/src/subdomains/supporting/notification/factories/mail.factory.ts @@ -148,13 +148,14 @@ export class MailFactory { if (this.isDisabledMailWallet(context, wallet)) return undefined; const lang = userData.language.symbol.toLowerCase(); + const walletName = wallet?.name; return new UserMailV2( { to: userData.mail, - subject: this.translate(title, lang), - salutation: salutation && this.translate(salutation.key, lang, salutation.params), - texts: texts && this.getMailAffix(texts, lang), + subject: this.translate(title, lang, undefined, walletName), + salutation: salutation && this.translate(salutation.key, lang, salutation.params, walletName), + texts: texts && this.getMailAffix(texts, lang, walletName), correlationId, options, }, @@ -170,12 +171,13 @@ export class MailFactory { if (this.isDisabledMailWallet(context, wallet)) return undefined; const lang = userData.language.symbol; + const walletName = wallet?.name; return new PersonalMail({ to: userData.mail, bcc, - subject: this.translate(title, lang), - prefix: prefix && this.getMailAffix(prefix, lang), + subject: this.translate(title, lang, undefined, walletName), + prefix: prefix && this.getMailAffix(prefix, lang, walletName), banner, from, displayName, @@ -186,8 +188,15 @@ export class MailFactory { //*** TRANSLATION METHODS ***// - public translate(key: string, lang: string, args?: any): string { - return this.i18n.translate(key, { lang: lang.toLowerCase(), args }); + public translate(key: string, lang: string, args?: any, walletName?: string): string { + const lowerLang = lang.toLowerCase(); + if (walletName) { + const innerKey = key.replace(/^mail\./, ''); + const walletKey = `mail.wallets.${walletName.toLowerCase()}.${innerKey}`; + const walletValue = this.i18n.translate(walletKey, { lang: lowerLang, args }) as string; + if (walletValue !== walletKey) return walletValue; + } + return this.i18n.translate(key, { lang: lowerLang, args }); } //*** MAIL BUILDING METHODS ***// @@ -201,14 +210,14 @@ export class MailFactory { ); } - private getMailAffix(affix: TranslationItem[], lang = 'en'): MailAffix[] { + private getMailAffix(affix: TranslationItem[], lang = 'en', walletName?: string): MailAffix[] { return affix .filter((i) => i) - .map((i) => this.mapMailAffix(i, lang).flat()) + .map((i) => this.mapMailAffix(i, lang, walletName).flat()) .flat(); } - private mapMailAffix(element: TranslationItem, lang: string): MailAffix[] { + private mapMailAffix(element: TranslationItem, lang: string, walletName?: string): MailAffix[] { switch (element.key) { case MailKey.SPACE: return [DefaultEmptyLine]; @@ -217,18 +226,21 @@ export class MailFactory { return [ DefaultEmptyLine, { - text: this.translate(`${MailTranslationKey.GENERAL}.dfx_team_closing`, lang), + text: this.translate(`${MailTranslationKey.GENERAL}.dfx_team_closing`, lang, undefined, walletName), style: UserMailDefaultStyle, }, - { text: this.translate(`${MailTranslationKey.GENERAL}.dfx_closing_message`, lang), style: 'Zapfino' }, + { + text: this.translate(`${MailTranslationKey.GENERAL}.dfx_closing_message`, lang, undefined, walletName), + style: 'Zapfino', + }, DefaultEmptyLine, DefaultEmptyLine, ]; default: { const params = Util.removeNullFields(element.params); - const translatedParams = this.translateParams(params, lang); - const text = this.translate(element.key, lang, translatedParams); + const translatedParams = this.translateParams(params, lang, walletName); + const text = this.translate(element.key, lang, translatedParams, walletName); const specialTag = this.parseSpecialTag(text); return [ @@ -266,10 +278,10 @@ export class MailFactory { return match ? { text: match[1], textSuffix: match[4], tag: match[2], value: match[3] } : undefined; } - private translateParams(params: TranslationParams, lang: string): TranslationParams { + private translateParams(params: TranslationParams, lang: string, walletName?: string): TranslationParams { return params ? Object.entries(params) - .map(([key, value]) => [key, this.translate(value, lang, params)]) + .map(([key, value]) => [key, this.translate(value, lang, params, walletName)]) .reduce((prev, [key, value]) => { prev[key] = value; return prev; diff --git a/src/subdomains/supporting/notification/templates/realUnit.hbs b/src/subdomains/supporting/notification/templates/realUnit.hbs new file mode 100644 index 0000000000..f1ddb350bf --- /dev/null +++ b/src/subdomains/supporting/notification/templates/realUnit.hbs @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + {{!-- Logo Block --}} +
+
+
+ + + +
+
+
+ + + + + + + +
+ + + + +
+ RealUnit Schweiz AG +
+
+ +
+
+
+ + +
+
+
+ + + + + {{!-- Salutation Block --}} +
+
+
+ + + +
+
+
+ + + + + + + +
+
+

{{salutation}}

+
+
+ +
+
+
+ + +
+
+
+ + + + + {{!-- Prefix Block --}} + {{#each prefix}} +
+
+
+ + + +
+
+
+ + + + + + + +
+
+ + {{!-- Future Button --}} + {{!-- + {{SEE DETAILS}} + --}} + +

{{{this.text}}}

+ {{#if this.url}}{{this.url.text}} + {{#if this.url.textSuffix}}{{this.url.textSuffix}}{{/if}} + {{/if}} + {{#if this.mail}}{{this.mail.address}} + {{#if this.mail.textSuffix}}{{this.mail.textSuffix}}{{/if}} + {{/if}} +
+
+ +
+
+
+ + +
+
+
+ {{/each}} + + + + + {{!-- Table Block --}} + {{#each table}} +
+
+
+ + + +
+
+
+ + + + + + + + + +
+ {{this.text}} + + {{this.value}} +
+ +
+
+
+ + +
+
+
+ {{/each}} + + + + + {{!-- Suffix Block --}} + {{#each suffix}} +
+
+
+ + + +
+
+
+ + + + + + + +
+
+ + {{!-- Future Button --}} + {{!-- + {{SEE DETAILS}} + --}} + +

{{{this.text}}}

+ {{#if this.url}}{{this.url.text}} + {{#if this.url.textSuffix}}{{this.url.textSuffix}}{{/if}} + {{/if}} + {{#if this.mail}}{{this.mail.address}} + {{#if this.mail.textSuffix}}{{this.mail.textSuffix}}{{/if}} + {{/if}} +
+
+ +
+
+
+ + +
+
+
+ {{/each}} + + + + + {{!-- Texts Block --}} + {{#each texts}} +
+
+
+ + + +
+
+
+ + + + + + + +
+
+

{{{this.text}}}

+ {{#if this.url}} + {{#if this.url.button}}{{/if}} + {{#if this.url.button}}{{/if}} + {{#if this.url.button}}{{else}}{{/if}} + {{this.url.text}} + + {{#if this.url.button}}{{/if}} + {{#if this.url.textSuffix}} {{this.url.textSuffix}} {{/if}} + {{/if}} + {{#if this.mail}}{{this.mail.address}} + {{#if this.mail.textSuffix}}{{this.mail.textSuffix}}{{/if}} + {{/if}} +
+
+ +
+
+
+ + +
+
+
+ {{/each}} + + + + + +
+ + + + +