2018-01-30 19:58:55 +01:00
|
|
|
@extends('header')
|
|
|
|
|
|
|
|
@section('head')
|
|
|
|
@parent
|
|
|
|
|
2018-02-05 20:04:49 +01:00
|
|
|
@include('money_script')
|
|
|
|
@include('proposals.grapesjs_header')
|
2018-01-30 19:58:55 +01:00
|
|
|
|
|
|
|
@stop
|
|
|
|
|
|
|
|
@section('content')
|
|
|
|
|
2018-02-01 07:47:17 +01:00
|
|
|
{!! Former::open($url)
|
|
|
|
->method($method)
|
2018-02-09 14:54:21 +01:00
|
|
|
->onsubmit('return onFormSubmit(event)')
|
2018-02-12 09:43:31 +01:00
|
|
|
->id('mainForm')
|
2018-03-14 12:03:30 +01:00
|
|
|
->autocomplete('off')
|
2018-02-11 09:18:05 +01:00
|
|
|
->addClass('warn-on-exit')
|
2018-02-01 07:47:17 +01:00
|
|
|
->rules([
|
2018-02-07 15:16:31 +01:00
|
|
|
'invoice_id' => 'required',
|
2018-02-01 07:47:17 +01:00
|
|
|
]) !!}
|
2018-01-30 19:58:55 +01:00
|
|
|
|
2018-02-01 10:24:53 +01:00
|
|
|
@if ($proposal)
|
|
|
|
{!! Former::populate($proposal) !!}
|
|
|
|
@endif
|
|
|
|
|
|
|
|
<span style="display:none">
|
|
|
|
{!! Former::text('public_id') !!}
|
2018-02-12 09:43:31 +01:00
|
|
|
{!! Former::text('action') !!}
|
2018-02-04 20:34:38 +01:00
|
|
|
{!! Former::text('html') !!}
|
|
|
|
{!! Former::text('css') !!}
|
2018-02-01 10:24:53 +01:00
|
|
|
</span>
|
|
|
|
|
2018-01-30 19:58:55 +01:00
|
|
|
<div class="row">
|
|
|
|
<div class="col-lg-12">
|
|
|
|
<div class="panel panel-default">
|
|
|
|
<div class="panel-body">
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-md-6">
|
2018-02-07 15:16:31 +01:00
|
|
|
{!! Former::select('invoice_id')->addOption('', '')
|
2018-01-30 19:58:55 +01:00
|
|
|
->label(trans('texts.quote'))
|
2018-02-07 15:16:31 +01:00
|
|
|
->addGroupClass('invoice-select') !!}
|
2018-02-04 17:42:13 +01:00
|
|
|
{!! Former::select('proposal_template_id')->addOption('', '')
|
2018-01-30 19:58:55 +01:00
|
|
|
->label(trans('texts.template'))
|
|
|
|
->addGroupClass('template-select') !!}
|
|
|
|
|
2018-02-01 07:47:17 +01:00
|
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
2018-02-04 17:42:13 +01:00
|
|
|
{!! Former::textarea('private_notes')
|
|
|
|
->style('height: 100px') !!}
|
2018-01-30 19:58:55 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<center class="buttons">
|
|
|
|
{!! Button::normal(trans('texts.cancel'))
|
|
|
|
->appendIcon(Icon::create('remove-circle'))
|
|
|
|
->asLinkTo(HTMLUtils::previousUrl('/proposals')) !!}
|
|
|
|
|
2018-02-13 11:32:53 +01:00
|
|
|
@if ($proposal)
|
|
|
|
{!! Button::primary(trans('texts.download'))
|
|
|
|
->withAttributes(['onclick' => 'onDownloadClick()'])
|
|
|
|
->appendIcon(Icon::create('download-alt')) !!}
|
|
|
|
@endif
|
2018-02-11 12:09:29 +01:00
|
|
|
|
2018-01-30 19:58:55 +01:00
|
|
|
{!! Button::success(trans("texts.save"))
|
2018-02-12 10:23:16 +01:00
|
|
|
->withAttributes(['id' => 'saveButton'])
|
2018-02-09 14:54:21 +01:00
|
|
|
->submit()
|
2018-01-30 19:58:55 +01:00
|
|
|
->appendIcon(Icon::create('floppy-disk')) !!}
|
2018-02-11 10:14:47 +01:00
|
|
|
|
2018-02-12 10:23:16 +01:00
|
|
|
{!! Button::info(trans('texts.email'))
|
|
|
|
->withAttributes(['id' => 'emailButton', 'onclick' => 'onEmailClick()'])
|
|
|
|
->appendIcon(Icon::create('send')) !!}
|
2018-02-12 09:43:31 +01:00
|
|
|
|
2018-02-12 10:23:16 +01:00
|
|
|
@if ($proposal)
|
2018-02-11 10:14:47 +01:00
|
|
|
{!! DropdownButton::normal(trans('texts.more_actions'))
|
|
|
|
->withContents($proposal->present()->moreActions()) !!}
|
|
|
|
@endif
|
|
|
|
|
2018-01-30 19:58:55 +01:00
|
|
|
</center>
|
|
|
|
|
|
|
|
{!! Former::close() !!}
|
|
|
|
|
|
|
|
<div id="gjs"></div>
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
2018-02-07 15:16:31 +01:00
|
|
|
var invoices = {!! $invoices !!};
|
|
|
|
var invoiceMap = {};
|
2018-01-30 19:58:55 +01:00
|
|
|
|
|
|
|
var templates = {!! $templates !!};
|
|
|
|
var templateMap = {};
|
2018-02-12 10:23:16 +01:00
|
|
|
var isFormSubmitting = false;
|
2018-01-30 19:58:55 +01:00
|
|
|
|
2018-02-09 14:54:21 +01:00
|
|
|
function onFormSubmit() {
|
2018-02-12 10:23:16 +01:00
|
|
|
// prevent duplicate form submissions
|
|
|
|
if (isFormSubmitting) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
isFormSubmitting = true;
|
|
|
|
$('#saveButton, #emailButton').prop('disabled', true);
|
|
|
|
|
2018-02-04 20:34:38 +01:00
|
|
|
$('#html').val(grapesjsEditor.getHtml());
|
|
|
|
$('#css').val(grapesjsEditor.getCss());
|
2018-02-09 14:54:21 +01:00
|
|
|
|
|
|
|
return true;
|
2018-02-01 07:47:17 +01:00
|
|
|
}
|
|
|
|
|
2018-02-12 10:23:16 +01:00
|
|
|
function onEmailClick() {
|
2018-02-12 10:34:48 +01:00
|
|
|
sweetConfirm(function() {
|
|
|
|
$('#action').val('email');
|
|
|
|
$('#saveButton').click();
|
|
|
|
})
|
2018-02-12 10:23:16 +01:00
|
|
|
}
|
|
|
|
|
2018-02-11 19:03:48 +01:00
|
|
|
@if ($proposal)
|
|
|
|
function onDownloadClick() {
|
|
|
|
location.href = "{{ url("/proposals/{$proposal->public_id}/download") }}";
|
|
|
|
}
|
|
|
|
@endif
|
2018-02-11 12:09:29 +01:00
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
function loadTemplate() {
|
2018-02-05 11:52:02 +01:00
|
|
|
var templateId = $('select#proposal_template_id').val();
|
|
|
|
var template = templateMap[templateId];
|
|
|
|
|
|
|
|
if (! template) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
var html = mergeTemplate(template.html);
|
|
|
|
|
2018-02-12 13:55:56 +01:00
|
|
|
grapesjsEditor.CssComposer.getAll().reset();
|
2018-02-07 11:38:59 +01:00
|
|
|
grapesjsEditor.setComponents(html);
|
|
|
|
grapesjsEditor.setStyle(template.css);
|
2018-02-05 12:28:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function mergeTemplate(html) {
|
2018-02-07 15:16:31 +01:00
|
|
|
var invoiceId = $('select#invoice_id').val();
|
|
|
|
var invoice = invoiceMap[invoiceId];
|
2018-02-05 11:52:02 +01:00
|
|
|
|
2018-02-07 15:16:31 +01:00
|
|
|
if (!invoice) {
|
2018-02-05 12:28:08 +01:00
|
|
|
return html;
|
|
|
|
}
|
2018-02-05 11:52:02 +01:00
|
|
|
|
2018-02-09 13:31:53 +01:00
|
|
|
invoice.account = {!! auth()->user()->account->load('country') !!};
|
|
|
|
|
2018-02-14 10:00:24 +01:00
|
|
|
var regExp = new RegExp(/\$[a-z][\w\.]*/g);
|
2018-02-05 12:28:08 +01:00
|
|
|
var matches = html.match(regExp);
|
2018-02-05 11:52:02 +01:00
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
if (matches) {
|
|
|
|
for (var i=0; i<matches.length; i++) {
|
|
|
|
var match = matches[i];
|
2018-02-05 11:52:02 +01:00
|
|
|
|
2018-02-09 13:31:53 +01:00
|
|
|
field = match.replace('$quote.', '$');
|
|
|
|
field = field.substring(1, field.length);
|
2018-02-05 12:28:08 +01:00
|
|
|
field = toSnakeCase(field);
|
2018-02-05 11:52:02 +01:00
|
|
|
|
2018-02-09 13:31:53 +01:00
|
|
|
if (field == 'quote_number') {
|
2018-02-05 12:28:08 +01:00
|
|
|
field = 'invoice_number';
|
2018-02-05 20:04:49 +01:00
|
|
|
} else if (field == 'valid_until') {
|
|
|
|
field = 'due_date';
|
2018-02-09 13:31:53 +01:00
|
|
|
} else if (field == 'quote_date') {
|
2018-02-05 20:04:49 +01:00
|
|
|
field = 'invoice_date';
|
2018-02-09 13:31:53 +01:00
|
|
|
} else if (field == 'footer') {
|
|
|
|
field = 'invoice_footer';
|
|
|
|
} else if (match == '$account.phone') {
|
|
|
|
field = 'account.work_phone';
|
|
|
|
} else if (match == '$client.phone') {
|
|
|
|
field = 'client.phone';
|
2018-02-05 11:52:02 +01:00
|
|
|
}
|
2018-02-05 12:28:08 +01:00
|
|
|
|
2018-03-06 11:24:07 +01:00
|
|
|
if (field == 'logo_url') {
|
|
|
|
var value = "{{ $account->getLogoURL() }}";
|
|
|
|
} else if (field == 'quote_image_url') {
|
|
|
|
var value = "{{ asset('/images/quote.png') }}";
|
|
|
|
} else if (match == '$client.name') {
|
|
|
|
var value = getClientDisplayName(invoice.client);
|
|
|
|
} else {
|
|
|
|
var value = getDescendantProp(invoice, field) || ' ';
|
|
|
|
}
|
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
value = doubleDollarSign(value) + '';
|
|
|
|
value = value.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
2018-02-05 20:04:49 +01:00
|
|
|
|
2018-02-09 13:42:15 +01:00
|
|
|
if (['amount', 'partial', 'client.balance', 'client.paid_to_date'].indexOf(field) >= 0) {
|
2018-02-07 15:16:31 +01:00
|
|
|
value = formatMoneyInvoice(value, invoice);
|
2018-02-09 13:31:53 +01:00
|
|
|
} else if (['invoice_date', 'due_date', 'partial_due_date'].indexOf(field) >= 0) {
|
2018-02-05 20:04:49 +01:00
|
|
|
value = moment.utc(value).format('{{ $account->getMomentDateFormat() }}');
|
|
|
|
}
|
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
html = html.replace(match, value);
|
2018-02-05 11:52:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
return html;
|
2018-02-05 11:52:02 +01:00
|
|
|
}
|
|
|
|
|
2018-02-11 10:14:47 +01:00
|
|
|
@if ($proposal)
|
|
|
|
function onArchiveClick() {
|
|
|
|
submitForm_proposal('archive', {{ $proposal->id }});
|
|
|
|
}
|
|
|
|
|
2018-03-14 11:24:17 +01:00
|
|
|
function onDeleteClick() {
|
|
|
|
submitForm_proposal('delete', {{ $proposal->id }});
|
|
|
|
}
|
2018-02-11 10:14:47 +01:00
|
|
|
@endif
|
2018-02-11 12:09:29 +01:00
|
|
|
|
2018-01-30 19:58:55 +01:00
|
|
|
$(function() {
|
2018-02-07 15:16:31 +01:00
|
|
|
var invoiceId = {{ ! empty($invoicePublicId) ? $invoicePublicId : 0 }};
|
|
|
|
var $invoiceSelect = $('select#invoice_id');
|
|
|
|
for (var i = 0; i < invoices.length; i++) {
|
|
|
|
var invoice = invoices[i];
|
|
|
|
invoiceMap[invoice.public_id] = invoice;
|
|
|
|
$invoiceSelect.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(invoice.client), invoice.public_id));
|
2018-01-30 19:58:55 +01:00
|
|
|
}
|
2018-02-07 15:16:31 +01:00
|
|
|
@include('partials/entity_combobox', ['entityType' => ENTITY_INVOICE])
|
|
|
|
if (invoiceId) {
|
|
|
|
var invoice = invoiceMap[invoiceId];
|
2018-02-08 09:59:39 +01:00
|
|
|
if (invoice) {
|
|
|
|
$invoiceSelect.val(invoice.public_id);
|
|
|
|
setComboboxValue($('.invoice-select'), invoice.public_id, invoice.invoice_number + ' - ' + getClientDisplayName(invoice.client));
|
|
|
|
}
|
2018-02-04 17:42:13 +01:00
|
|
|
}
|
2018-02-07 15:16:31 +01:00
|
|
|
$invoiceSelect.change(loadTemplate);
|
2018-01-30 19:58:55 +01:00
|
|
|
|
2018-02-04 17:42:13 +01:00
|
|
|
var templateId = {{ ! empty($templatePublicId) ? $templatePublicId : 0 }};
|
|
|
|
var $proposal_templateSelect = $('select#proposal_template_id');
|
2018-01-30 19:58:55 +01:00
|
|
|
for (var i = 0; i < templates.length; i++) {
|
|
|
|
var template = templates[i];
|
|
|
|
templateMap[template.public_id] = template;
|
2018-02-01 07:47:17 +01:00
|
|
|
$proposal_templateSelect.append(new Option(template.name, template.public_id));
|
2018-01-30 19:58:55 +01:00
|
|
|
}
|
|
|
|
@include('partials/entity_combobox', ['entityType' => ENTITY_PROPOSAL_TEMPLATE])
|
2018-02-04 17:42:13 +01:00
|
|
|
if (templateId) {
|
|
|
|
var template = templateMap[templateId];
|
2018-02-09 15:02:28 +01:00
|
|
|
$proposal_templateSelect.val(template.public_id);
|
2018-02-04 17:42:13 +01:00
|
|
|
setComboboxValue($('.template-select'), template.public_id, template.name);
|
|
|
|
}
|
2018-02-05 12:28:08 +01:00
|
|
|
$proposal_templateSelect.change(loadTemplate);
|
2018-02-04 21:10:40 +01:00
|
|
|
})
|
2018-01-30 19:58:55 +01:00
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
</script>
|
|
|
|
|
2018-02-11 10:14:47 +01:00
|
|
|
@include('partials.bulk_form', ['entityType' => ENTITY_PROPOSAL])
|
2018-02-05 12:28:08 +01:00
|
|
|
@include('proposals.grapesjs', ['entity' => $proposal])
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
|
|
$(function() {
|
2018-02-13 08:15:14 +01:00
|
|
|
grapesjsEditor.on('canvas:drop', function(event, block) {
|
|
|
|
if (! block.attributes || block.attributes.type != 'image') {
|
|
|
|
var html = mergeTemplate(grapesjsEditor.getHtml());
|
|
|
|
grapesjsEditor.setComponents(html);
|
|
|
|
}
|
2018-02-05 12:28:08 +01:00
|
|
|
});
|
2018-02-09 15:02:28 +01:00
|
|
|
|
|
|
|
@if (! $proposal && $templatePublicId)
|
|
|
|
loadTemplate();
|
|
|
|
@endif
|
2018-02-05 12:28:08 +01:00
|
|
|
});
|
2018-01-30 19:58:55 +01:00
|
|
|
|
2018-02-05 12:28:08 +01:00
|
|
|
</script>
|
2018-02-04 22:03:26 +01:00
|
|
|
|
2018-01-30 19:58:55 +01:00
|
|
|
@stop
|