mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-13 22:54:25 +01:00
Working on #1234
This commit is contained in:
parent
297a898dbf
commit
30045ecdbb
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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>
|
||||||
|
@ -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/...') }}",
|
||||||
|
@ -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">
|
||||||
|
Loading…
Reference in New Issue
Block a user