1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00

Added ability to customize emails

This commit is contained in:
Hillel Coren 2015-02-12 22:50:05 +02:00
parent 2c6cce1707
commit 2a297e3d3f
24 changed files with 383 additions and 110 deletions

View File

@ -208,8 +208,9 @@ class AccountController extends \BaseController
} elseif ($section == ACCOUNT_IMPORT_EXPORT) {
return View::make('accounts.import_export');
} elseif ($section == ACCOUNT_ADVANCED_SETTINGS) {
$account = Auth::user()->account;
$data = [
'account' => Auth::user()->account,
'account' => $account,
'feature' => $subSection,
];
@ -242,6 +243,11 @@ class AccountController extends \BaseController
$data['invoice'] = $invoice;
$data['invoiceDesigns'] = InvoiceDesign::remember(DEFAULT_QUERY_CACHE, 'invoice_designs_cache_'.Auth::user()->maxInvoiceDesignId())
->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
} else if ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
$data['invoiceEmail'] = $account->getEmailTemplate(ENTITY_INVOICE);
$data['quoteEmail'] = $account->getEmailTemplate(ENTITY_QUOTE);
$data['paymentEmail'] = $account->getEmailTemplate(ENTITY_PAYMENT);
$data['emailFooter'] = $account->getEmailFooter();
}
return View::make("accounts.{$subSection}", $data);
@ -273,12 +279,31 @@ class AccountController extends \BaseController
return AccountController::saveInvoiceSettings();
} elseif ($subSection == ACCOUNT_INVOICE_DESIGN) {
return AccountController::saveInvoiceDesign();
} elseif ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
return AccountController::saveEmailTemplates();
}
} elseif ($section == ACCOUNT_PRODUCTS) {
return AccountController::saveProducts();
}
}
private function saveEmailTemplates()
{
if (Auth::user()->account->isPro()) {
$account = Auth::user()->account;
$account->email_template_invoice = Input::get('email_template_invoice', $account->getEmailTemplate(ENTITY_INVOICE));
$account->email_template_quote = Input::get('email_template_quote', $account->getEmailTemplate(ENTITY_QUOTE));
$account->email_template_payment = Input::get('email_template_payment', $account->getEmailTemplate(ENTITY_PAYMENT));
$account->save();
Session::flash('message', trans('texts.updated_settings'));
}
return Redirect::to('company/advanced_settings/email_templates');
}
private function saveProducts()
{
$account = Auth::user()->account;
@ -288,7 +313,6 @@ class AccountController extends \BaseController
$account->save();
Session::flash('message', trans('texts.updated_settings'));
return Redirect::to('company/products');
}

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddEmailTemplates extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->text('email_template_invoice')->nullable();
$table->text('email_template_quote')->nullable();
$table->text('email_template_payment')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('email_template_invoice');
$table->dropColumn('email_template_quote');
$table->dropColumn('email_template_payment');
});
}
}

View File

@ -499,5 +499,17 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -489,5 +489,17 @@ return array(
'select_versiony' => 'Version auswählen',
'view_history' => 'Historie anzeigen',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -503,5 +503,10 @@ return array(
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -469,5 +469,17 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -490,5 +490,17 @@ return array(
'select_versiony' => 'Choix de la verison',
'view_history' => 'Consulter l\'historique',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -492,5 +492,17 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -499,6 +499,18 @@ return array(
'current_version' => 'Current version',
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -498,6 +498,18 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -493,6 +493,18 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -480,6 +480,18 @@ return array(
'select_versiony' => 'Select version',
'view_history' => 'View History',
'edit_payment' => 'Edit Payment',
'updated_payment' => 'Successfully updated payment',
'deleted' => 'Deleted',
'restore_user' => 'Restore User',
'restored_user' => 'Successfully restored user',
'show_deleted_users' => 'Show deleted users',
'email_templates' => 'Email Templates',
'invoice_email' => 'Invoice Email',
'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email',
'reset_all' => 'Reset All',
);

View File

@ -302,4 +302,36 @@ class Account extends Eloquent
return $this;
}
public function getEmailTemplate($entityType, $message = false)
{
$field = "email_template_$entityType";
$template = $this->$field;
if ($template) {
return $template;
}
$template = "<p>\$client,</p>\r\n" .
"<p>" . trans("texts.{$entityType}_message", ['amount' => '$amount']) . "</p>\r\n";
if ($entityType != ENTITY_PAYMENT) {
$template .= "<p><a href=\"\$link\">\$link</a></p>\r\n";
}
if ($message) {
$template .= "<p>$message</p>\r\n";
}
return $template . "<p>\$footer</p>";
}
public function getEmailFooter()
{
if ($this->email_footer) {
return $this->email_footer;
} else {
return "<p>" . trans('texts.email_signature') . "<br>\$account</p>";
}
}
}

View File

@ -17,6 +17,8 @@ class ContactMailer extends Mailer
$view = 'invoice';
$subject = trans("texts.{$entityType}_subject", ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]);
$accountName = $invoice->account->getDisplayName();
$emailTemplate = $invoice->account->getEmailTemplate($entityType);
$invoiceAmount = Utils::formatMoney($invoice->amount, $invoice->client->currency_id);
foreach ($invoice->invitations as $invitation) {
if (!$invitation->user || !$invitation->user->email) {
@ -29,17 +31,17 @@ class ContactMailer extends Mailer
$invitation->sent_date = \Carbon::now()->toDateTimeString();
$invitation->save();
$data = [
'entityType' => $entityType,
'link' => $invitation->getLink(),
'clientName' => $invoice->client->getDisplayName(),
'accountName' => $accountName,
'contactName' => $invitation->contact->getDisplayName(),
'invoiceAmount' => Utils::formatMoney($invoice->amount, $invoice->client->currency_id),
'emailFooter' => $invoice->account->email_footer,
'showNinjaFooter' => !$invoice->account->isPro(),
$variables = [
'$footer' => $invoice->account->getEmailFooter(),
'$link' => $invitation->getLink(),
'$client' => $invoice->client->getDisplayName(),
'$account' => $accountName,
'$contact' => $invitation->contact->getDisplayName(),
'$amount' => $invoiceAmount
];
$data['body'] = str_replace(array_keys($variables), array_values($variables), $emailTemplate);
$fromEmail = $invitation->user->email;
$this->sendTo($invitation->contact->email, $fromEmail, $accountName, $subject, $view, $data);
@ -56,44 +58,45 @@ class ContactMailer extends Mailer
public function sendPaymentConfirmation(Payment $payment)
{
$invoice = $payment->invoice;
$view = 'payment_confirmation';
$subject = trans('texts.payment_subject', ['invoice' => $payment->invoice->invoice_number]);
$subject = trans('texts.payment_subject', ['invoice' => $invoice->invoice_number]);
$accountName = $payment->account->getDisplayName();
$emailTemplate = $invoice->account->getEmailTemplate(ENTITY_PAYMENT);
$data = [
'accountName' => $accountName,
'clientName' => $payment->client->getDisplayName(),
'emailFooter' => $payment->account->email_footer,
'paymentAmount' => Utils::formatMoney($payment->amount, $payment->client->currency_id),
'showNinjaFooter' => !$payment->account->isPro(),
$variables = [
'$footer' => $payment->account->getEmailFooter(),
'$client' => $payment->client->getDisplayName(),
'$account' => $accountName,
'$amount' => Utils::formatMoney($payment->amount, $payment->client->currency_id)
];
$data = ['body' => str_replace(array_keys($variables), array_values($variables), $emailTemplate)];
$user = $payment->invitation->user;
$this->sendTo($payment->contact->email, $user->email, $accountName, $subject, $view, $data);
}
public function sendLicensePaymentConfirmation($name, $email, $amount, $license, $productId)
{
$view = 'payment_confirmation';
$view = 'license_confirmation';
$subject = trans('texts.payment_subject');
if ($productId == PRODUCT_ONE_CLICK_INSTALL) {
$message = "Softaculous install license: $license";
$license = "Softaculous install license: $license";
} elseif ($productId == PRODUCT_INVOICE_DESIGNS) {
$message = "Invoice designs license: $license";
$license = "Invoice designs license: $license";
} elseif ($productId == PRODUCT_WHITE_LABEL) {
$message = "White label license: $license";
$license = "White label license: $license";
}
$data = [
'accountName' => trans('texts.email_from'),
'clientName' => $name,
'emailFooter' => false,
'paymentAmount' => Utils::formatMoney($amount, 1),
'showNinjaFooter' => false,
'emailMessage' => $message,
'account' => trans('texts.email_from'),
'client' => $name,
'amount' => Utils::formatMoney($amount, 1),
'license' => $license
];
$this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
}
}

View File

@ -193,6 +193,7 @@ define('ACCOUNT_INVOICE_DESIGN', 'invoice_design');
define('ACCOUNT_CHART_BUILDER', 'chart_builder');
define('ACCOUNT_USER_MANAGEMENT', 'user_management');
define('ACCOUNT_DATA_VISUALIZATIONS', 'data_visualizations');
define('ACCOUNT_EMAIL_TEMPLATES', 'email_templates');
define("ACTIVITY_TYPE_CREATE_CLIENT", 1);
define("ACTIVITY_TYPE_ARCHIVE_CLIENT", 2);

View File

@ -0,0 +1,109 @@
@extends('accounts.nav')
@section('head')
@parent
<style type="text/css">
textarea {
min-height: 100px !important;
}
</style>
@stop
@section('content')
@parent
@include('accounts.nav_advanced')
{{ Former::open()->addClass('col-md-8 col-md-offset-2 warn-on-exit') }}
{{ Former::populateField('email_template_invoice', $invoiceEmail) }}
{{ Former::populateField('email_template_quote', $quoteEmail) }}
{{ Former::populateField('email_template_payment', $paymentEmail) }}
{{ Former::legend('invoice_email') }}
<div class="row">
<div class="col-md-7">
{{ Former::textarea('email_template_invoice')->raw() }}
</div>
<div class="col-md-5" id="invoice_preview"></div>
</div>
<p>&nbsp;</p>
{{ Former::legend('quote_email') }}
<div class="row">
<div class="col-md-7">
{{ Former::textarea('email_template_quote')->raw() }}
</div>
<div class="col-md-5" id="quote_preview"></div>
</div>
<p>&nbsp;</p>
{{ Former::legend('payment_email') }}
<div class="row">
<div class="col-md-7">
{{ Former::textarea('email_template_payment')->raw() }}
</div>
<div class="col-md-5" id="payment_preview"></div>
</div>
<p>&nbsp;</p>
@if (Auth::user()->isPro())
{{ Former::actions(
Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk')
) }}
@else
<script>
$(function() {
$('form.warn-on-exit input').prop('disabled', true);
});
</script>
@endif
{{ Former::close() }}
<script type="text/javascript">
$(function() {
$('#email_template_invoice').keyup(refreshInvoice);
$('#email_template_quote').keyup(refreshQuote);
$('#email_template_payment').keyup(refreshPayment);
refreshInvoice();
refreshQuote();
refreshPayment();
});
function refreshInvoice() {
$('#invoice_preview').html(processVariables($('#email_template_invoice').val()));
}
function refreshQuote() {
$('#quote_preview').html(processVariables($('#email_template_quote').val()));
}
function refreshPayment() {
$('#payment_preview').html(processVariables($('#email_template_payment').val()));
}
function processVariables(str) {
if (!str) {
return '';
}
keys = ['footer', 'account', 'client', 'amount', 'link'];
vals = [{{ json_encode($emailFooter) }}, '{{ Auth::user()->account->getDisplayName() }}', 'Client Name', formatMoney(100), '{{ NINJA_WEB_URL }}']
for (var i=0; i<keys.length; i++) {
var regExp = new RegExp('\\$'+keys[i], 'g');
str = str.replace(regExp, vals[i]);
}
return str;
}
</script>
@stop

View File

@ -1,6 +1,7 @@
<ul class="nav nav-tabs nav nav-justified">
{{ HTML::nav_link('company/advanced_settings/invoice_settings', 'invoice_settings') }}
{{ HTML::nav_link('company/advanced_settings/invoice_design', 'invoice_design') }}
{{ HTML::nav_link('company/advanced_settings/email_templates', 'email_templates') }}
{{ HTML::nav_link('company/advanced_settings/data_visualizations', 'data_visualizations') }}
{{ HTML::nav_link('company/advanced_settings/chart_builder', 'chart_builder') }}
{{ HTML::nav_link('company/advanced_settings/user_management', 'user_management') }}

View File

@ -3,24 +3,5 @@
<head>
<meta charset="utf-8">
</head>
<body>
{{ $clientName }},<p/>
{{ trans("texts.{$entityType}_message", ['amount' => $invoiceAmount]) }}<p/>
<a href="{{ $link }}">{{ $link }}</a><p/>
@if ($emailFooter)
{{ nl2br($emailFooter) }}
@else
{{ trans('texts.email_signature') }}<br/>
{{ $accountName }}
@endif
@if ($showNinjaFooter)
<p/>
{{ trans('texts.ninja_email_footer', ['site' => '<a href="' . NINJA_WEB_URL . '/?utm_source=invoice_email_footer">Invoice Ninja</a>']) }}
@endif
</body>
<body>{{ $body }}</body>
</html>

View File

@ -1,16 +1 @@
{{ $clientName }},
{{ trans("texts.{$entityType}_message", ['amount' => $invoiceAmount]) }}
{{ $link }}
@if ($emailFooter)
{{ $emailFooter }}
@else
{{ trans('texts.email_signature') }}
{{ $accountName }}
@endif
@if ($showNinjaFooter)
{{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }}
{{ NINJA_WEB_URL }}
@endif
{{ strip_tags($body) }}

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
{{ $client }},<p/>
{{ trans('texts.payment_message', ['amount' => $amount]) }}<p/>
{{ $license }}<p/>
{{ trans('texts.email_signature') }}<br/>
{{ $account }}
</body>
</html>

View File

@ -0,0 +1,8 @@
{{ $client }},
{{ trans('texts.payment_message', ['amount' => $amount]) }}
{{ $license }}
{{ trans('texts.email_signature') }}
{{ $account }}

View File

@ -3,27 +3,5 @@
<head>
<meta charset="utf-8">
</head>
<body>
{{ $clientName }},<p/>
{{ trans('texts.payment_message', ['amount' => $paymentAmount]) }}<p/>
@if (isset($emailMessage) && $emailMessage)
{{ $emailMessage }}<p/>
@endif
@if ($emailFooter)
{{ nl2br($emailFooter) }}
@else
{{ trans('texts.email_signature') }}<br/>
{{ $accountName }}
@endif
@if ($showNinjaFooter)
<p/>
{{ trans('texts.ninja_email_footer', ['site' => '<a href="' . NINJA_WEB_URL . '/?utm_source=payment_email_footer">Invoice Ninja</a>']) }}
@endif
</body>
<body>{{ $body }}</body>
</html>

View File

@ -1,19 +1 @@
{{ $clientName }},
{{ trans('texts.payment_message', ['amount' => $paymentAmount]) }}
@if (isset($emailMessage) && $emailMessage)
{{ $emailMessage }}
@endif
@if ($emailFooter)
{{ $emailFooter }}
@else
{{ trans('texts.email_signature') }}
{{ $accountName }}
@endif
@if ($showNinjaFooter)
{{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }}
{{ NINJA_WEB_URL }}
@endif
{{ strip_tags($body) }}

View File

@ -83,7 +83,7 @@
<div class="btn-group">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
<div id="myAccountButton" class="ellipsis" style="max-width:120px">
<div id="myAccountButton" class="ellipsis" style="max-width:100px">
{{ Auth::user()->getDisplayName() }}
<span class="caret"></span>
</div>