1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-13 22:54:25 +01:00
This commit is contained in:
Hillel Coren 2017-02-05 23:29:11 +02:00
parent 297a898dbf
commit 30045ecdbb
8 changed files with 113 additions and 32 deletions

View File

@ -359,7 +359,7 @@ class InvoiceController extends BaseController
Session::flash('message', $message); Session::flash('message', $message);
if ($action == 'email') { if ($action == 'email') {
$this->emailInvoice($invoice, Input::get('pdfupload')); $this->emailInvoice($invoice, Input::get('reminder'), Input::get('pdfupload'), Input::get('emailTemplate'));
} }
return url($invoice->getRoute()); return url($invoice->getRoute());
@ -390,13 +390,13 @@ class InvoiceController extends BaseController
} elseif ($action == 'convert') { } elseif ($action == 'convert') {
return $this->convertQuote($request, $invoice->public_id); return $this->convertQuote($request, $invoice->public_id);
} elseif ($action == 'email') { } elseif ($action == 'email') {
$this->emailInvoice($invoice, Input::get('pdfupload')); $this->emailInvoice($invoice, Input::get('reminder'), Input::get('pdfupload'), Input::get('emailTemplate'));
} }
return url($invoice->getRoute()); return url($invoice->getRoute());
} }
private function emailInvoice($invoice, $pdfUpload) private function emailInvoice($invoice, $reminder = false, $pdfUpload = false, $template = false)
{ {
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
$pdfUpload = Utils::decodePDF($pdfUpload); $pdfUpload = Utils::decodePDF($pdfUpload);
@ -413,9 +413,9 @@ class InvoiceController extends BaseController
} else { } else {
// TODO remove this with Laravel 5.3 (https://github.com/invoiceninja/invoiceninja/issues/1303) // TODO remove this with Laravel 5.3 (https://github.com/invoiceninja/invoiceninja/issues/1303)
if (config('queue.default') === 'sync') { if (config('queue.default') === 'sync') {
$response = app('App\Ninja\Mailers\ContactMailer')->sendInvoice($invoice, false, $pdfUpload); $response = app('App\Ninja\Mailers\ContactMailer')->sendInvoice($invoice, $reminder, $pdfUpload, $template);
} else { } else {
$this->dispatch(new SendInvoiceEmail($invoice, false, $pdfUpload)); $this->dispatch(new SendInvoiceEmail($invoice, $reminder, $pdfUpload, $template));
$response = true; $response = true;
} }
} }

View File

@ -31,6 +31,11 @@ class SendInvoiceEmail extends Job implements ShouldQueue
*/ */
protected $pdfString; protected $pdfString;
/**
* @var array
*/
protected $template;
/** /**
* Create a new job instance. * Create a new job instance.
* *
@ -39,11 +44,12 @@ class SendInvoiceEmail extends Job implements ShouldQueue
* @param bool $reminder * @param bool $reminder
* @param mixed $pdfString * @param mixed $pdfString
*/ */
public function __construct(Invoice $invoice, $reminder = false, $pdfString = false) public function __construct(Invoice $invoice, $reminder = false, $pdfString = false, $template = false)
{ {
$this->invoice = $invoice; $this->invoice = $invoice;
$this->reminder = $reminder; $this->reminder = $reminder;
$this->pdfString = $pdfString; $this->pdfString = $pdfString;
$this->template = $template;
} }
/** /**
@ -53,7 +59,7 @@ class SendInvoiceEmail extends Job implements ShouldQueue
*/ */
public function handle(ContactMailer $mailer) public function handle(ContactMailer $mailer)
{ {
$mailer->sendInvoice($this->invoice, $this->reminder, $this->pdfString); $mailer->sendInvoice($this->invoice, $this->reminder, $this->pdfString, $this->template);
} }
/* /*

View File

@ -36,7 +36,7 @@ class ContactMailer extends Mailer
* *
* @return bool|null|string * @return bool|null|string
*/ */
public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false) public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false, $template = false)
{ {
if ($invoice->is_recurring) { if ($invoice->is_recurring) {
return false; return false;
@ -57,8 +57,8 @@ class ContactMailer extends Mailer
} }
$account->loadLocalizationSettings($client); $account->loadLocalizationSettings($client);
$emailTemplate = $account->getEmailTemplate($reminder ?: $entityType); $emailTemplate = !empty($template['body']) ? $template['body'] : $account->getEmailTemplate($reminder ?: $entityType);
$emailSubject = $account->getEmailSubject($reminder ?: $entityType); $emailSubject = !empty($template['subject']) ? $template['subject'] : $account->getEmailSubject($reminder ?: $entityType);
$sent = false; $sent = false;

View File

@ -2354,6 +2354,7 @@ $LANG = array(
'days_ago' => ':count day ago|:count days ago', 'days_ago' => ':count day ago|:count days ago',
'sent_by' => 'Sent by :user', 'sent_by' => 'Sent by :user',
'recipients' => 'Recipients', 'recipients' => 'Recipients',
'today' => 'Today',
); );

View File

@ -11,6 +11,8 @@
<script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script> <script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
<script src="{{ asset('js/lightbox.min.js') }}" type="text/javascript"></script> <script src="{{ asset('js/lightbox.min.js') }}" type="text/javascript"></script>
<link href="{{ asset('css/lightbox.css') }}" rel="stylesheet" type="text/css"/> <link href="{{ asset('css/lightbox.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/quill.snow.css') }}" rel="stylesheet" type="text/css"/>
<script src="{{ asset('js/quill.min.js') }}" type="text/javascript"></script>
<style type="text/css"> <style type="text/css">
select.tax-select { select.tax-select {

View File

@ -1,5 +1,5 @@
<div class="modal fade" id="emailModal" tabindex="-1" role="dialog" aria-labelledby="emailModalLabel" aria-hidden="true"> <div class="modal fade" id="emailModal" tabindex="-1" role="dialog" aria-labelledby="emailModalLabel" aria-hidden="true">
<div class="modal-dialog" style="min-width:150px"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -14,7 +14,7 @@
->value('') !!} ->value('') !!}
{!! Former::select('template') {!! Former::select('template')
->onchange('refreshPreview()') ->onchange('loadTemplate()')
->options([ ->options([
$invoice->getEntityType() => trans('texts.initial_email'), $invoice->getEntityType() => trans('texts.initial_email'),
'reminder1' => trans('texts.first_reminder'), 'reminder1' => trans('texts.first_reminder'),
@ -29,7 +29,9 @@
<a href="#preview" aria-controls="preview" role="tab" data-toggle="tab">{{ trans('texts.preview') }}</a> <a href="#preview" aria-controls="preview" role="tab" data-toggle="tab">{{ trans('texts.preview') }}</a>
</li> </li>
<li role="presentation"> <li role="presentation">
<a href="#customize" aria-controls="customize" role="tab" data-toggle="tab">{{ trans('texts.customize') }}</a> <a href="#customize" aria-controls="customize" role="tab" data-toggle="tab">
{{ trans('texts.customize') }} {!! Auth::user()->isTrial() ? '<sup>' . trans('texts.pro') . '</sup>' : '' !!}
</a>
</li> </li>
<li role="presentation"> <li role="presentation">
<a href="#history" aria-controls="history" role="tab" data-toggle="tab">{{ trans('texts.history') }}</a> <a href="#history" aria-controls="history" role="tab" data-toggle="tab">{{ trans('texts.history') }}</a>
@ -37,14 +39,30 @@
</ul> </ul>
</div> </div>
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane well active" id="preview"> <div role="tabpanel" class="tab-pane active" id="preview">
<div style="padding:31px 14px 0px 14px">
<div id="emailSubjectDiv"></div>
<br/> <br/>
<div id="emailSubject"></div> <div id="emailBodyDiv"></div>
<br/> </div>
<div id="emailBody"></div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="customize"> <div role="tabpanel" class="tab-pane" id="customize">
<br/>
{!! Former::text('emailSubject')
->placeholder('subject')
->onchange('onEmailSubjectChange()')
->raw() !!}
<br/>
<div id="templateEditor" class="form-control" style="min-height:160px"></div>
<div style="displayx:none">
{!! Former::textarea("emailTemplate[body]")
->raw() !!}
{!! Former::text('emailTemplate[subject]')
->raw() !!}
{!! Former::text('reminder')
->raw() !!}
</div>
@include('partials/quill_toolbar', ['name' => 'template'])
</div> </div>
<div role="tabpanel" class="tab-pane" id="history"> <div role="tabpanel" class="tab-pane" id="history">
<br/> <br/>
@ -65,7 +83,7 @@
</td> </td>
<td> <td>
<span title="{{ $activity->present()->createdAt }}"> <span title="{{ $activity->present()->createdAt }}">
{{ $activity->present()->createdAtDate }} - {{ trans_choice('texts.days_ago', $activity->created_at->diffInDays()) }} {{ $activity->present()->createdAtDate }} - {{ $activity->created_at->diffInDays() > 0 ? trans_choice('texts.days_ago', $activity->created_at->diffInDays()) : trans('texts.today') }}
</span> </span>
</td> </td>
</tr> </tr>
@ -105,21 +123,75 @@
emailTemplates['reminder3'] = "{{ $account->getEmailTemplate('reminder3') }}"; emailTemplates['reminder3'] = "{{ $account->getEmailTemplate('reminder3') }}";
function showEmailModal() { function showEmailModal() {
refreshPreview(); loadTemplate();
$('#recipients').html(getSendToEmails()); $('#recipients').html(getSendToEmails());
$('#emailModal').modal('show'); $('#emailModal').modal('show');
} }
function loadTemplate() {
var template = dencodeEntities(emailSubjects[$('#template').val()]);
$("#emailSubject").val(template);
var template = dencodeEntities(emailTemplates[$('#template').val()]);
emailEditor.setHTML(template);
var reminder = $('#template').val();
if (reminder == '{{ $invoice->getEntityType() }}') {
reminder = '';
}
$('#reminder').val(reminder);
refreshPreview();
}
function refreshPreview() { function refreshPreview() {
var invoice = createInvoiceModel(); var invoice = createInvoiceModel();
var template = dencodeEntities(emailSubjects[$('#template').val()]); invoice = calculateAmounts(invoice);
$('#emailSubject').html('<b>' + renderEmailTemplate(template, invoice) + '</b>'); console.log(invoice);
var template = dencodeEntities(emailTemplates[$('#template').val()]); var template = $("#emailSubject").val();
$('#emailBody').html(renderEmailTemplate(template, invoice)); $('#emailSubjectDiv').html('<b>' + renderEmailTemplate(template, invoice) + '</b>');
var template = emailEditor.getHTML();
$('#emailBodyDiv').html(renderEmailTemplate(template, invoice));
} }
function dencodeEntities(s) { function dencodeEntities(s) {
return $("<div/>").html(s).text(); return $("<div/>").html(s).text();
} }
function onEmailSubjectChange() {
$("#emailTemplate\\[subject\\]").val($('#emailSubject').val());
refreshPreview();
NINJA.formIsChanged = true;
}
var emailEditor;
$(function() {
emailEditor = new Quill('#templateEditor', {
modules: {
'toolbar': { container: '#templateToolbar' },
'link-tooltip': true
},
theme: 'snow'
});
emailEditor.setHTML('test');
emailEditor.on('text-change', function(delta, source) {
if (source == 'api') {
return;
}
var html = emailEditor.getHTML();
$("#emailTemplate\\[body\\]").val(html);
refreshPreview();
NINJA.formIsChanged = true;
});
});
</script> </script>
<style type="text/css">
@media only screen and (min-width : 767px) {
.modal-dialog {
width: 660px;
}
}
</style>

View File

@ -5,7 +5,7 @@
return ''; return '';
} }
var passwordHtml = "{!! $account->isPro() && $account->enable_portal_password && $account->send_portal_password?'<p>'.trans('texts.password').': XXXXXXXXX<p>':'' !!}"; var passwordHtml = "{!! $account->isPro() && $account->enable_portal_password && $account->send_portal_password?'<br/>'.trans('texts.password').': XXXXXXXXX<br/>':'' !!}";
@if ($account->isPro()) @if ($account->isPro())
var documentsHtml = "{!! trans('texts.email_documents_header').'<ul><li><a>'.trans('texts.email_documents_example_1').'</a></li><li><a>'.trans('texts.email_documents_example_2').'</a></li></ul>' !!}"; var documentsHtml = "{!! trans('texts.email_documents_header').'<ul><li><a>'.trans('texts.email_documents_example_1').'</a></li><li><a>'.trans('texts.email_documents_example_2').'</a></li></ul>' !!}";
@ -19,16 +19,16 @@
'dueDate': "{{ $account->formatDate($account->getDateTime()) }}", 'dueDate': "{{ $account->formatDate($account->getDateTime()) }}",
'invoiceDate': "{{ $account->formatDate($account->getDateTime()) }}", 'invoiceDate': "{{ $account->formatDate($account->getDateTime()) }}",
'client': invoice ? getClientDisplayName(invoice.client) : 'Client Name', 'client': invoice ? getClientDisplayName(invoice.client) : 'Client Name',
'amount': invoice ? formatMoneyInvoice(invoice.amount, invoice) : formatMoneyAccount(100, account), 'amount': invoice ? formatMoneyInvoice(parseFloat(invoice.partial) || parseFloat(invoice.balance_amount), invoice) : formatMoneyAccount(100, account),
'contact': invoice ? getContactDisplayName(invoice.client.contacts[0]) : 'Contact Name', 'contact': invoice ? getContactDisplayName(invoice.client.contacts[0]) : 'Contact Name',
'firstName': invoice ? invoice.client.contacts[0].first_name : 'First Name', 'firstName': invoice ? invoice.client.contacts[0].first_name : 'First Name',
'invoice': invoice ? invoice.invoice_number : '0001', 'invoice': invoice ? invoice.invoice_number : '0001',
'quote': invoice ? invoice.invoice_number : '0001', 'quote': invoice ? invoice.invoice_number : '0001',
'password': passwordHtml, 'password': passwordHtml,
'documents': documentsHtml, 'documents': documentsHtml,
'viewLink': "{{ URL::to('/view/...') }}$password", 'viewLink': '{{ link_to('#', url('/view/...')) }}$password',
'viewButton': '{!! Form::flatButton('view_invoice', '#0b4d78') !!}$password', 'viewButton': '{!! Form::flatButton('view_invoice', '#0b4d78') !!}$password',
'paymentLink': "{{ URL::to('/payment/...') }}$password", 'paymentLink': '{{ link_to('#', url('/payment/...')) }}$password',
'paymentButton': '{!! Form::flatButton('pay_now', '#36c157') !!}$password', 'paymentButton': '{!! Form::flatButton('pay_now', '#36c157') !!}$password',
'autoBill': '{{ trans('texts.auto_bill_notification_placeholder') }}', 'autoBill': '{{ trans('texts.auto_bill_notification_placeholder') }}',
'portalLink': "{{ URL::to('/client/portal/...') }}", 'portalLink': "{{ URL::to('/client/portal/...') }}",

View File

@ -1,4 +1,4 @@
<div id="toolbar-toolbar" class="toolbar ql-toolbar ql-snow"> <div id="toolbar-toolbar" class="toolbar ql-toolbar ql-snow" style="padding-left:0px;padding-right:0px">
<div id="{{ $name }}Toolbar" class="toolbar" style="padding-left: 0px"> <div id="{{ $name }}Toolbar" class="toolbar" style="padding-left: 0px">
<span class="ql-format-group"> <span class="ql-format-group">
<select title="Font" class="ql-font"> <select title="Font" class="ql-font">