This commit is contained in:
Hillel Coren 2017-02-06 11:41:16 +02:00
parent 9aeacb0d15
commit 58c50edff7
6 changed files with 110 additions and 47 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('reminder'), Input::get('pdfupload'), Input::get('emailTemplate')); $this->emailInvoice($invoice);
} }
return url($invoice->getRoute()); return url($invoice->getRoute());
@ -390,16 +390,23 @@ 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('reminder'), Input::get('pdfupload'), Input::get('emailTemplate')); $this->emailInvoice($invoice);
} }
return url($invoice->getRoute()); return url($invoice->getRoute());
} }
private function emailInvoice($invoice, $reminder = false, $pdfUpload = false, $template = false) private function emailInvoice($invoice)
{ {
$reminder = Input::get('reminder');
$template = Input::get('template');
$pdfUpload = Utils::decodePDF(Input::get('pdfupload'));
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
$pdfUpload = Utils::decodePDF($pdfUpload);
if (filter_var(Input::get('save_as_default'), FILTER_VALIDATE_BOOLEAN)) {
$account = Auth::user()->account;
$account->setTemplateDefaults(Input::get('template_type'), $template['subject'], $template['body']);
}
if (! Auth::user()->confirmed) { if (! Auth::user()->confirmed) {
$errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required'); $errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required');

View File

@ -154,6 +154,18 @@ trait SendsEmails
return false; return false;
} }
public function setTemplateDefaults($type, $subject, $body)
{
if ($subject) {
$this->{"email_subject_" . $type} = $subject;
}
if ($body) {
$this->{"email_template_" . $type} = $body;
}
$this->save();
}
public function getBccEmail() public function getBccEmail()
{ {

View File

@ -2347,14 +2347,13 @@ $LANG = array(
'inactivity_logout' => 'Due to inactivity, you have been automatically logged out.', 'inactivity_logout' => 'Due to inactivity, you have been automatically logged out.',
'mark_active' => 'Mark Active', 'mark_active' => 'Mark Active',
'send_automatically' => 'Send Automatically', 'send_automatically' => 'Send Automatically',
'template' => 'Template',
'initial_email' => 'Initial Email', 'initial_email' => 'Initial Email',
'invoice_not_emailed' => 'This invoice hasn\'t been emailed.', 'invoice_not_emailed' => 'This invoice hasn\'t been emailed.',
'quote_not_emailed' => 'This quote hasn\'t been emailed.', 'quote_not_emailed' => 'This quote hasn\'t been emailed.',
'days_ago' => ':count day ago|:count days ago',
'sent_by' => 'Sent by :user', 'sent_by' => 'Sent by :user',
'recipients' => 'Recipients', 'recipients' => 'Recipients',
'today' => 'Today', 'save_as_default' => 'Save as default',
'template' => 'Template',
); );

View File

@ -20,9 +20,9 @@
float: left; float: left;
} }
.btn-info:disabled { .btn-info:disabled {
background-color: #e89259; background-color: #e89259 !important;
border-color: #e89259; border-color: #e89259 !important;
} }
#scrollable-dropdown-menu .tt-menu { #scrollable-dropdown-menu .tt-menu {
@ -750,7 +750,7 @@
</div> </div>
</div> </div>
<div class="modal-footer" style="margin-top: 0px; padding-top:0px;"> <div class="modal-footer" style="margin-top: 0px; padding-top:0px; padding-right:20px">
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">{{ trans('texts.provide_name_or_email') }}</span><span>&nbsp;</span> <span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">{{ trans('texts.provide_name_or_email') }}</span><span>&nbsp;</span>
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
<button type="button" class="btn btn-default" data-bind="click: $root.showMoreFields, text: $root.showMore() ? '{{ trans('texts.less_fields') }}' : '{{ trans('texts.more_fields') }}'"></button> <button type="button" class="btn btn-default" data-bind="click: $root.showMoreFields, text: $root.showMore() ? '{{ trans('texts.less_fields') }}' : '{{ trans('texts.more_fields') }}'"></button>
@ -1293,6 +1293,7 @@
} }
function onConfirmEmailClick() { function onConfirmEmailClick() {
$('#emailModal div.modal-footer button').attr('disabled', true);
model.invoice().is_public(true); model.invoice().is_public(true);
var accountLanguageId = parseInt({{ $account->language_id ?: '0' }}); var accountLanguageId = parseInt({{ $account->language_id ?: '0' }});
var clientLanguageId = parseInt(model.invoice().client().language_id()) || 0; var clientLanguageId = parseInt(model.invoice().client().language_id()) || 0;
@ -1309,10 +1310,6 @@
} }
} }
$(function() {
//onEmailClick();
})
function onSaveDraftClick() { function onSaveDraftClick() {
model.invoice().is_public(false); model.invoice().is_public(false);
onSaveClick(); onSaveClick();
@ -1432,6 +1429,7 @@
location.href = data; location.href = data;
}).fail(function(data) { }).fail(function(data) {
$('#saveButton, #emailButton, #draftButton').attr('disabled', false); $('#saveButton, #emailButton, #draftButton').attr('disabled', false);
$('#emailModal div.modal-footer button').attr('disabled', false);
var error = firstJSONError(data.responseJSON) || data.statusText; var error = firstJSONError(data.responseJSON) || data.statusText;
swal("{!! trans('texts.invoice_save_error') !!}", error); swal("{!! trans('texts.invoice_save_error') !!}", error);
}); });

View File

@ -8,20 +8,23 @@
</div> </div>
<div class="container" style="width: 100%; padding-bottom: 0px !important"> <div class="container" style="width: 100%; padding-bottom: 0px !important">
<div class="panel panel-default"> <div class="panel panel-default" style="margin-bottom: 0px">
<div class="panel-body"> <div class="panel-body">
{!! Former::plaintext('recipients') {!! Former::plaintext('recipients')
->value('') !!} ->value('') !!}
{!! Former::select('template') @if (Utils::isPro())
->onchange('loadTemplate()') {!! Former::select('template_type')
->options([ ->label('template')
$invoice->getEntityType() => trans('texts.initial_email'), ->onchange('loadTemplate()')
'reminder1' => trans('texts.first_reminder'), ->options([
'reminder2' => trans('texts.second_reminder'), $invoice->getEntityType() => trans('texts.initial_email'),
'reminder3' => trans('texts.third_reminder'), 'reminder1' => trans('texts.first_reminder'),
]) !!} 'reminder2' => trans('texts.second_reminder'),
'reminder3' => trans('texts.third_reminder'),
]) !!}
@endif
<br/> <br/>
<div role="tabpanel"> <div role="tabpanel">
@ -29,11 +32,13 @@
<li role="presentation" class="active"> <li role="presentation" class="active">
<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"> @if (Utils::isPro())
<a href="#customize" aria-controls="customize" role="tab" data-toggle="tab"> <li role="presentation">
{{ trans('texts.customize') }} {!! Auth::user()->isTrial() ? '<sup>' . trans('texts.pro') . '</sup>' : '' !!} <a href="#customize" aria-controls="customize" role="tab" data-toggle="tab">
</a> {{ trans('texts.customize') }} {!! Auth::user()->isTrial() ? '<sup>' . trans('texts.pro') . '</sup>' : '' !!}
</li> </a>
</li>
@endif
<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>
</li> </li>
@ -41,24 +46,24 @@
</div> </div>
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="preview"> <div role="tabpanel" class="tab-pane active" id="preview">
<div style="padding:31px 14px 0px 14px"> <div style="padding:10px 14px 0px 14px">
<div id="emailSubjectDiv"></div> <div id="emailSubjectDiv"></div>
<br/> <br/>
<div id="emailBodyDiv"></div> <div id="emailBodyDiv"></div>
</div> </div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="customize"> <div role="tabpanel" class="tab-pane" id="customize">
<br/>
{!! Former::text('emailSubject') {!! Former::text('emailSubject')
->placeholder('subject') ->placeholder('subject')
->onchange('onEmailSubjectChange()') ->onchange('onEmailSubjectChange()')
->oninput('onEmailSubjectInput()')
->raw() !!} ->raw() !!}
<br/> <br/>
<div id="templateEditor" class="form-control" style="min-height:160px"></div> <div id="templateEditor" class="form-control" style="min-height:160px"></div>
<div style="display:none"> <div style="display:none">
{!! Former::textarea("emailTemplate[body]") {!! Former::textarea("template[body]")
->raw() !!} ->raw() !!}
{!! Former::text('emailTemplate[subject]') {!! Former::text('template[subject]')
->raw() !!} ->raw() !!}
{!! Former::text('reminder') {!! Former::text('reminder')
->raw() !!} ->raw() !!}
@ -66,7 +71,6 @@
@include('partials/quill_toolbar', ['name' => 'template']) @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/>
@if (count($activities = $invoice->emailHistory())) @if (count($activities = $invoice->emailHistory()))
<table class="table table-striped data-table"> <table class="table table-striped data-table">
<tr> <tr>
@ -84,14 +88,25 @@
</td> </td>
<td> <td>
<span title="{{ $activity->present()->createdAt }}"> <span title="{{ $activity->present()->createdAt }}">
{{ $activity->present()->createdAtDate }} - {{ $activity->created_at->diffInDays() > 0 ? trans_choice('texts.days_ago', $activity->created_at->diffInDays()) : trans('texts.today') }} {{ $activity->present()->createdAtDate }} - {{ $activity->created_at->diffForHumans() }}
</span> </span>
</td> </td>
<script type="text/javascript">
@if ($activity->notes == 'reminder3')
if (!window.defaultTemplate) window.defaultTemplate = 'reminder3';
@elseif ($activity->notes == 'reminder2')
if (!window.defaultTemplate) window.defaultTemplate = 'reminder3';
@elseif ($activity->notes == 'reminder1')
if (!window.defaultTemplate) window.defaultTemplate = 'reminder2';
@else
if (!window.defaultTemplate) window.defaultTemplate = 'reminder1';
@endif
</script>
</tr> </tr>
@endforeach @endforeach
</table> </table>
@else @else
<center style="font-size:16px;color:#888888;padding-top:20px;"> <center style="font-size:16px;color:#888888;padding:30px;">
{{ trans("texts.{$invoice->getEntityType()}_not_emailed") }} {{ trans("texts.{$invoice->getEntityType()}_not_emailed") }}
</center> </center>
@endif @endif
@ -100,7 +115,12 @@
</div> </div>
</div> </div>
<div class="modal-footer" style="margin-top: 0px"> <div class="modal-footer" style="margin-top: 0px; padding-right:0px">
<div id="defaultDiv" style="display:none" class="pull-left">
{!! Former::checkbox('save_as_default')
->text('save_as_default')
->raw() !!}
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
<button type="button" class="btn btn-info" onclick="onConfirmEmailClick()">{{ trans('texts.send_email') }}</button> <button type="button" class="btn btn-info" onclick="onConfirmEmailClick()">{{ trans('texts.send_email') }}</button>
</div> </div>
@ -130,25 +150,31 @@
} }
function loadTemplate() { function loadTemplate() {
var template = dencodeEntities(emailSubjects[$('#template').val()]); @if (Utils::isPro())
var templateType = $('#template_type').val();
@else
var templateType = '{{ $invoice->getEntityType() }}';
@endif
var template = dencodeEntities(emailSubjects[templateType]);
$("#emailSubject").val(template); $("#emailSubject").val(template);
var template = dencodeEntities(emailTemplates[$('#template').val()]); var template = dencodeEntities(emailTemplates[templateType]);
emailEditor.setHTML(template); emailEditor.setHTML(template);
var reminder = $('#template').val(); var reminder = $('#template_type').val();
if (reminder == '{{ $invoice->getEntityType() }}') { if (reminder == '{{ $invoice->getEntityType() }}') {
reminder = ''; reminder = '';
} }
$('#reminder').val(reminder); $('#reminder').val(reminder);
$('#defaultDiv').hide();
refreshPreview(); refreshPreview();
} }
function refreshPreview() { function refreshPreview() {
var invoice = createInvoiceModel(); var invoice = createInvoiceModel();
invoice = calculateAmounts(invoice); invoice = calculateAmounts(invoice);
console.log(invoice);
var template = $("#emailSubject").val(); var template = $("#emailSubject").val();
$('#emailSubjectDiv').html('<b>' + renderEmailTemplate(template, invoice) + '</b>'); $('#emailSubjectDiv').html('<b>' + renderEmailTemplate(template, invoice) + '</b>');
var template = emailEditor.getHTML(); var template = emailEditor.getHTML();
@ -159,12 +185,16 @@
return $("<div/>").html(s).text(); return $("<div/>").html(s).text();
} }
function onEmailSubjectChange() { function onEmailSubjectInput() {
$("#emailTemplate\\[subject\\]").val($('#emailSubject').val()); $('#defaultDiv').show();
refreshPreview();
NINJA.formIsChanged = true; NINJA.formIsChanged = true;
} }
function onEmailSubjectChange() {
$("#template\\[subject\\]").val($('#emailSubject').val());
refreshPreview();
}
var emailEditor; var emailEditor;
$(function() { $(function() {
@ -181,18 +211,31 @@
return; return;
} }
var html = emailEditor.getHTML(); var html = emailEditor.getHTML();
$("#emailTemplate\\[body\\]").val(html); $("#template\\[body\\]").val(html);
$('#defaultDiv').show();
refreshPreview(); refreshPreview();
NINJA.formIsChanged = true; NINJA.formIsChanged = true;
}); });
@if (Utils::isPro())
if (window.defaultTemplate) {
$('#template_type').val(window.defaultTemplate);
}
@endif
}); });
</script> </script>
<style type="text/css"> <style type="text/css">
#emailModal .tab-pane {
margin-top:20px;
max-height:320px;
overflow-y:auto;
}
@media only screen and (min-width : 767px) { @media only screen and (min-width : 767px) {
.modal-dialog { .modal-dialog {
width: 670px; width: 690px;
} }
} }
</style> </style>

View File

@ -644,7 +644,11 @@ function ContactModel(data) {
str += (self.first_name() || '') + ' ' + (self.last_name() || '') + ' '; str += (self.first_name() || '') + ' ' + (self.last_name() || '') + ' ';
} }
if (self.email()) { if (self.email()) {
str += '&lt;' + self.email() + '&gt;'; if (str) {
str += '&lt;' + self.email() + '&gt;';
} else {
str += self.email();
}
} }
return str + '<br/>'; return str + '<br/>';