mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Proposals
This commit is contained in:
parent
4eb904bf5d
commit
5dfb90604b
@ -60,9 +60,9 @@ class ProposalController extends BaseController
|
|||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'proposals',
|
'url' => 'proposals',
|
||||||
'title' => trans('texts.new_proposal'),
|
'title' => trans('texts.new_proposal'),
|
||||||
'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
'invoices' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
||||||
'templates' => ProposalTemplate::whereAccountId($account->id)->orWhereNull('account_id')->orderBy('name')->get(),
|
'templates' => ProposalTemplate::whereAccountId($account->id)->orWhereNull('account_id')->orderBy('name')->get(),
|
||||||
'quotePublicId' => $request->quote_id,
|
'invoicePublicId' => $request->invoicee_id,
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('proposals.edit', $data);
|
return View::make('proposals.edit', $data);
|
||||||
@ -86,9 +86,9 @@ class ProposalController extends BaseController
|
|||||||
'method' => 'PUT',
|
'method' => 'PUT',
|
||||||
'url' => 'proposals/' . $proposal->public_id,
|
'url' => 'proposals/' . $proposal->public_id,
|
||||||
'title' => trans('texts.edit_proposal'),
|
'title' => trans('texts.edit_proposal'),
|
||||||
'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
'invoices' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
||||||
'templates' => ProposalTemplate::whereAccountId($account->id)->orWhereNull('account_id')->orderBy('name')->get(),
|
'templates' => ProposalTemplate::whereAccountId($account->id)->orWhereNull('account_id')->orderBy('name')->get(),
|
||||||
'quotePublicId' => $proposal->quote ? $proposal->quote->public_id : null,
|
'invoicePublicId' => $proposal->invoice ? $proposal->invoice->public_id : null,
|
||||||
'templatePublicId' => $proposal->proposal_template ? $proposal->proposal_template->public_id : null,
|
'templatePublicId' => $proposal->proposal_template ? $proposal->proposal_template->public_id : null,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class Proposal extends EntityModel
|
|||||||
/**
|
/**
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function quote()
|
public function invoice()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\Invoice')->withTrashed();
|
return $this->belongsTo('App\Models\Invoice')->withTrashed();
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@ class ProposalDatatable extends EntityDatatable
|
|||||||
[
|
[
|
||||||
'quote',
|
'quote',
|
||||||
function ($model) {
|
function ($model) {
|
||||||
if (! Auth::user()->can('viewByOwner', [ENTITY_QUOTE, $model->quote_user_id])) {
|
if (! Auth::user()->can('viewByOwner', [ENTITY_QUOTE, $model->invoice_user_id])) {
|
||||||
return $model->quote_number;
|
return $model->invoice_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
return link_to("quotes/{$model->quote_public_id}", $model->quote_number)->toHtml();
|
return link_to("quotes/{$model->invoice_public_id}", $model->invoice_number)->toHtml();
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -25,7 +25,7 @@ class ProposalRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
$query = DB::table('proposals')
|
$query = DB::table('proposals')
|
||||||
->where('proposals.account_id', '=', Auth::user()->account_id)
|
->where('proposals.account_id', '=', Auth::user()->account_id)
|
||||||
->leftjoin('invoices', 'invoices.id', '=', 'proposals.quote_id')
|
->leftjoin('invoices', 'invoices.id', '=', 'proposals.invoice_id')
|
||||||
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->leftJoin('proposal_templates', 'proposal_templates.id', '=', 'proposals.proposal_template_id')
|
->leftJoin('proposal_templates', 'proposal_templates.id', '=', 'proposals.proposal_template_id')
|
||||||
@ -44,9 +44,9 @@ class ProposalRepository extends BaseRepository
|
|||||||
'clients.user_id as client_user_id',
|
'clients.user_id as client_user_id',
|
||||||
'clients.public_id as client_public_id',
|
'clients.public_id as client_public_id',
|
||||||
'invoices.invoice_number as quote',
|
'invoices.invoice_number as quote',
|
||||||
'invoices.invoice_number as quote_number',
|
'invoices.invoice_number as invoice_number',
|
||||||
'invoices.public_id as quote_public_id',
|
'invoices.public_id as invoice_public_id',
|
||||||
'invoices.user_id as quote_user_id',
|
'invoices.user_id as invoice_user_id',
|
||||||
'proposal_templates.name as template',
|
'proposal_templates.name as template',
|
||||||
'proposal_templates.public_id as template_public_id',
|
'proposal_templates.public_id as template_public_id',
|
||||||
'proposal_templates.user_id as template_user_id'
|
'proposal_templates.user_id as template_user_id'
|
||||||
@ -79,8 +79,8 @@ class ProposalRepository extends BaseRepository
|
|||||||
|
|
||||||
$proposal->fill($input);
|
$proposal->fill($input);
|
||||||
|
|
||||||
if (isset($input['quote_id'])) {
|
if (isset($input['invoice_id'])) {
|
||||||
$proposal->quote_id = $input['quote_id'] ? Invoice::getPrivateId($input['quote_id']) : null;
|
$proposal->invoice_id = $input['invoice_id'] ? Invoice::getPrivateId($input['invoice_id']) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($input['proposal_template_id'])) {
|
if (isset($input['proposal_template_id'])) {
|
||||||
|
@ -89,7 +89,7 @@ class AddSubscriptionFormat extends Migration
|
|||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
$table->boolean('is_deleted')->default(false);
|
$table->boolean('is_deleted')->default(false);
|
||||||
|
|
||||||
$table->unsignedInteger('quote_id')->index();
|
$table->unsignedInteger('invoice_id')->index();
|
||||||
$table->unsignedInteger('proposal_template_id')->nullable()->index();
|
$table->unsignedInteger('proposal_template_id')->nullable()->index();
|
||||||
$table->text('private_notes');
|
$table->text('private_notes');
|
||||||
$table->mediumText('html');
|
$table->mediumText('html');
|
||||||
@ -97,13 +97,34 @@ class AddSubscriptionFormat extends Migration
|
|||||||
|
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
$table->foreign('quote_id')->references('id')->on('invoices')->onDelete('cascade');
|
$table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
||||||
$table->foreign('proposal_template_id')->references('id')->on('proposal_templates')->onDelete('cascade');
|
$table->foreign('proposal_template_id')->references('id')->on('proposal_templates')->onDelete('cascade');
|
||||||
|
|
||||||
$table->unsignedInteger('public_id')->index();
|
$table->unsignedInteger('public_id')->index();
|
||||||
$table->unique(['account_id', 'public_id']);
|
$table->unique(['account_id', 'public_id']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::create('proposal_invitations', function ($table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('account_id');
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('contact_id');
|
||||||
|
$table->unsignedInteger('proposal_id')->index();
|
||||||
|
$table->string('invitation_key')->index()->unique();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->timestamp('sent_date')->nullable();
|
||||||
|
$table->timestamp('viewed_date')->nullable();
|
||||||
|
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
|
||||||
|
$table->foreign('proposal_id')->references('id')->on('proposals')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->unsignedInteger('public_id')->index();
|
||||||
|
$table->unique(['account_id', 'public_id']);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,5 +146,6 @@ class AddSubscriptionFormat extends Migration
|
|||||||
Schema::dropIfExists('proposal_templates');
|
Schema::dropIfExists('proposal_templates');
|
||||||
Schema::dropIfExists('proposal_snippets');
|
Schema::dropIfExists('proposal_snippets');
|
||||||
Schema::dropIfExists('proposal_categories');
|
Schema::dropIfExists('proposal_categories');
|
||||||
|
Schema::dropIfExists('proposal_invitations');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
->method($method)
|
->method($method)
|
||||||
->id('mainForm')
|
->id('mainForm')
|
||||||
->rules([
|
->rules([
|
||||||
'quote_id' => 'required',
|
'invoice_id' => 'required',
|
||||||
]) !!}
|
]) !!}
|
||||||
|
|
||||||
@if ($proposal)
|
@if ($proposal)
|
||||||
@ -33,9 +33,9 @@
|
|||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{!! Former::select('quote_id')->addOption('', '')
|
{!! Former::select('invoice_id')->addOption('', '')
|
||||||
->label(trans('texts.quote'))
|
->label(trans('texts.quote'))
|
||||||
->addGroupClass('quote-select') !!}
|
->addGroupClass('invoice-select') !!}
|
||||||
{!! Former::select('proposal_template_id')->addOption('', '')
|
{!! Former::select('proposal_template_id')->addOption('', '')
|
||||||
->label(trans('texts.template'))
|
->label(trans('texts.template'))
|
||||||
->addGroupClass('template-select') !!}
|
->addGroupClass('template-select') !!}
|
||||||
@ -66,8 +66,8 @@
|
|||||||
<div id="gjs"></div>
|
<div id="gjs"></div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var quotes = {!! $quotes !!};
|
var invoices = {!! $invoices !!};
|
||||||
var quoteMap = {};
|
var invoiceMap = {};
|
||||||
|
|
||||||
var templates = {!! $templates !!};
|
var templates = {!! $templates !!};
|
||||||
var templateMap = {};
|
var templateMap = {};
|
||||||
@ -94,10 +94,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mergeTemplate(html) {
|
function mergeTemplate(html) {
|
||||||
var quoteId = $('select#quote_id').val();
|
var invoiceId = $('select#invoice_id').val();
|
||||||
var quote = quoteMap[quoteId];
|
var invoice = invoiceMap[invoiceId];
|
||||||
|
|
||||||
if (!quote) {
|
if (!invoice) {
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,20 +111,20 @@
|
|||||||
field = match.substring(1, match.length);
|
field = match.substring(1, match.length);
|
||||||
field = toSnakeCase(field);
|
field = toSnakeCase(field);
|
||||||
|
|
||||||
if (field == 'quote_number') {
|
if (field == 'invoice_number') {
|
||||||
field = 'invoice_number';
|
field = 'invoice_number';
|
||||||
} else if (field == 'valid_until') {
|
} else if (field == 'valid_until') {
|
||||||
field = 'due_date';
|
field = 'due_date';
|
||||||
} else if (field == 'quote_date') {
|
} else if (field == 'invoice_date') {
|
||||||
field = 'invoice_date';
|
field = 'invoice_date';
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = getDescendantProp(quote, field) || ' ';
|
var value = getDescendantProp(invoice, field) || ' ';
|
||||||
value = doubleDollarSign(value) + '';
|
value = doubleDollarSign(value) + '';
|
||||||
value = value.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
value = value.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
||||||
|
|
||||||
if (field == 'amount' || field == 'partial') {
|
if (field == 'amount' || field == 'partial') {
|
||||||
value = formatMoneyInvoice(value, quote);
|
value = formatMoneyInvoice(value, invoice);
|
||||||
} else if (['invoice_date', 'due_date'].indexOf(field) >= 0) {
|
} else if (['invoice_date', 'due_date'].indexOf(field) >= 0) {
|
||||||
value = moment.utc(value).format('{{ $account->getMomentDateFormat() }}');
|
value = moment.utc(value).format('{{ $account->getMomentDateFormat() }}');
|
||||||
}
|
}
|
||||||
@ -137,20 +137,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
var quoteId = {{ ! empty($quotePublicId) ? $quotePublicId : 0 }};
|
var invoiceId = {{ ! empty($invoicePublicId) ? $invoicePublicId : 0 }};
|
||||||
var $quoteSelect = $('select#quote_id');
|
var $invoiceSelect = $('select#invoice_id');
|
||||||
for (var i = 0; i < quotes.length; i++) {
|
for (var i = 0; i < invoices.length; i++) {
|
||||||
var quote = quotes[i];
|
var invoice = invoices[i];
|
||||||
quoteMap[quote.public_id] = quote;
|
invoiceMap[invoice.public_id] = invoice;
|
||||||
$quoteSelect.append(new Option(quote.invoice_number + ' - ' + getClientDisplayName(quote.client), quote.public_id));
|
$invoiceSelect.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(invoice.client), invoice.public_id));
|
||||||
}
|
}
|
||||||
@include('partials/entity_combobox', ['entityType' => ENTITY_QUOTE])
|
@include('partials/entity_combobox', ['entityType' => ENTITY_INVOICE])
|
||||||
if (quoteId) {
|
if (invoiceId) {
|
||||||
var quote = quoteMap[quoteId];
|
var invoice = invoiceMap[invoiceId];
|
||||||
$quoteSelect.val(quote.public_id);
|
$invoiceSelect.val(invoice.public_id);
|
||||||
setComboboxValue($('.quote-select'), quote.public_id, quote.invoice_number + ' - ' + getClientDisplayName(quote.client));
|
setComboboxValue($('.invoice-select'), invoice.public_id, invoice.invoice_number + ' - ' + getClientDisplayName(invoice.client));
|
||||||
}
|
}
|
||||||
$quoteSelect.change(loadTemplate);
|
$invoiceSelect.change(loadTemplate);
|
||||||
|
|
||||||
var templateId = {{ ! empty($templatePublicId) ? $templatePublicId : 0 }};
|
var templateId = {{ ! empty($templatePublicId) ? $templatePublicId : 0 }};
|
||||||
var $proposal_templateSelect = $('select#proposal_template_id');
|
var $proposal_templateSelect = $('select#proposal_template_id');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user