diff --git a/app/Http/Controllers/ProposalController.php b/app/Http/Controllers/ProposalController.php index 4968ab3ecfa1..0035e6c02a51 100644 --- a/app/Http/Controllers/ProposalController.php +++ b/app/Http/Controllers/ProposalController.php @@ -88,6 +88,8 @@ class ProposalController extends BaseController 'title' => trans('texts.edit_proposal'), 'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(), 'templates' => ProposalTemplate::whereAccountId($account->id)->orWhereNull('account_id')->orderBy('name')->get(), + 'quotePublicId' => $proposal->quote ? $proposal->quote->public_id : null, + 'templatePublicId' => $proposal->proposal_template ? $proposal->proposal_template->public_id : null, ]; return View::make('proposals.edit', $data); diff --git a/app/Http/Controllers/ProposalTemplateController.php b/app/Http/Controllers/ProposalTemplateController.php index fdf297c985bf..89d0c4058734 100644 --- a/app/Http/Controllers/ProposalTemplateController.php +++ b/app/Http/Controllers/ProposalTemplateController.php @@ -53,13 +53,11 @@ class ProposalTemplateController extends BaseController { $data = [ 'account' => auth()->user()->account, - 'proposalTemplate' => null, + 'template' => null, 'method' => 'POST', 'url' => 'proposals/templates', 'title' => trans('texts.new_proposal_template'), - 'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(), 'templates' => ProposalTemplate::scope()->orderBy('name')->get(), - 'quotePublicId' => $request->quote_id, ]; return View::make('proposals/templates/edit', $data); @@ -78,12 +76,11 @@ class ProposalTemplateController extends BaseController $data = [ 'account' => auth()->user()->account, - 'proposalTemplate' => $proposalTemplate, + 'template' => $proposalTemplate, 'method' => 'PUT', 'url' => 'proposals/templates/' . $proposalTemplate->public_id, 'title' => trans('texts.edit_proposal_template'), - 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), - 'clientPublicId' => $proposalTemplate->client ? $proposalTemplate->client->public_id : null, + 'templates' => ProposalTemplate::scope()->orderBy('name')->get(), ]; return View::make('proposals/templates/edit', $data); diff --git a/app/Http/Requests/CreateProposalRequest.php b/app/Http/Requests/CreateProposalRequest.php index 70a20b632a2b..cb67fbab5c35 100644 --- a/app/Http/Requests/CreateProposalRequest.php +++ b/app/Http/Requests/CreateProposalRequest.php @@ -23,7 +23,7 @@ class CreateProposalRequest extends ProposalRequest { return [ 'quote_id' => 'required', - 'template_id' => 'required', + 'proposal_template_id' => 'required', ]; } } diff --git a/app/Models/Proposal.php b/app/Models/Proposal.php index 5228e11a933d..ce140e38806e 100644 --- a/app/Models/Proposal.php +++ b/app/Models/Proposal.php @@ -22,7 +22,7 @@ class Proposal extends EntityModel * @var array */ protected $fillable = [ - 'template_id', + 'private_notes', ]; /** @@ -62,6 +62,14 @@ class Proposal extends EntityModel return $this->belongsTo('App\Models\Invoice')->withTrashed(); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function proposal_template() + { + return $this->belongsTo('App\Models\ProposalTemplate')->withTrashed(); + } + public function getDisplayName() { return 'TODO'; diff --git a/app/Models/ProposalTemplate.php b/app/Models/ProposalTemplate.php index 551c4a11df37..0adccd25824f 100644 --- a/app/Models/ProposalTemplate.php +++ b/app/Models/ProposalTemplate.php @@ -22,6 +22,8 @@ class ProposalTemplate extends EntityModel * @var array */ protected $fillable = [ + 'name', + 'private_notes', ]; /** diff --git a/app/Ninja/Datatables/ProposalDatatable.php b/app/Ninja/Datatables/ProposalDatatable.php index 8889893c1cc6..ea1eafcef894 100644 --- a/app/Ninja/Datatables/ProposalDatatable.php +++ b/app/Ninja/Datatables/ProposalDatatable.php @@ -17,31 +17,37 @@ class ProposalDatatable extends EntityDatatable [ 'quote', function ($model) { - if (! Auth::user()->can('viewByOwner', [ENTITY_QUOTE, $model->user_id])) { + if (! Auth::user()->can('viewByOwner', [ENTITY_QUOTE, $model->quote_user_id])) { return $model->quote_number; } return link_to("quotes/{$model->quote_public_id}", $model->quote_number)->toHtml(); - //$str = link_to("quotes/{$model->quote_public_id}", $model->quote_number)->toHtml(); - //return $this->addNote($str, $model->private_notes); }, ], [ 'template', function ($model) { - return $model->template_name; + if (! Auth::user()->can('viewByOwner', [ENTITY_PROPOSAL_TEMPLATE, $model->template_user_id])) { + return $model->template; + } + + return link_to("proposals/templates/{$model->template_public_id}/edit", $model->template)->toHtml(); }, ], [ - 'created', + 'created_at', function ($model) { - return Utils::fromSqlDate($model->created_at); + if (! Auth::user()->can('viewByOwner', [ENTITY_PROPOSAL, $model->user_id])) { + return Utils::timestampToDateString(strtotime($model->created_at)); + } + + return link_to("proposals/{$model->public_id}/edit", Utils::timestampToDateString(strtotime($model->created_at)))->toHtml(); }, ], [ - 'valid_until', + 'private_notes', function ($model) { - return Utils::fromSqlDate($model->due_date); + return $this->showWithTooltip($model->private_notes); }, ], ]; diff --git a/app/Ninja/Datatables/ProposalSnippetDatatable.php b/app/Ninja/Datatables/ProposalSnippetDatatable.php index a13739574968..1ae58cd604b0 100644 --- a/app/Ninja/Datatables/ProposalSnippetDatatable.php +++ b/app/Ninja/Datatables/ProposalSnippetDatatable.php @@ -34,6 +34,12 @@ class ProposalSnippetDatatable extends EntityDatatable return link_to("proposals/categories/{$model->category_public_id}/edit", $model->category)->toHtml(); }, ], + [ + 'private_notes', + function ($model) { + return $this->showWithTooltip($model->private_notes); + }, + ], ]; } diff --git a/app/Ninja/Datatables/ProposalTemplateDatatable.php b/app/Ninja/Datatables/ProposalTemplateDatatable.php index 6189c801c969..ec9cf883916e 100644 --- a/app/Ninja/Datatables/ProposalTemplateDatatable.php +++ b/app/Ninja/Datatables/ProposalTemplateDatatable.php @@ -15,17 +15,23 @@ class ProposalTemplateDatatable extends EntityDatatable { return [ [ - 'quote', + 'name', function ($model) { if (! Auth::user()->can('editByOwner', [ENTITY_PROPOSAL_TEMPLATE, $model->user_id])) { return $model->name; } - return link_to("proposal_templates/{$model->public_id}", $model->name)->toHtml(); + return link_to("proposals/templates/{$model->public_id}", $model->name)->toHtml(); //$str = link_to("quotes/{$model->quote_public_id}", $model->quote_number)->toHtml(); //return $this->addNote($str, $model->private_notes); }, ], + [ + 'private_notes', + function ($model) { + return $this->showWithTooltip($model->private_notes); + }, + ], ]; } @@ -33,9 +39,9 @@ class ProposalTemplateDatatable extends EntityDatatable { return [ [ - trans('texts.edit_template'), + trans('texts.edit_proposal_template'), function ($model) { - return URL::to("proposal_templates/{$model->public_id}/edit"); + return URL::to("proposals/templates/{$model->public_id}/edit"); }, function ($model) { return Auth::user()->can('editByOwner', [ENTITY_PROPOSAL_TEMPLATE, $model->user_id]); diff --git a/app/Ninja/Repositories/ProposalRepository.php b/app/Ninja/Repositories/ProposalRepository.php index a2fd618ca97f..b9756011a50e 100644 --- a/app/Ninja/Repositories/ProposalRepository.php +++ b/app/Ninja/Repositories/ProposalRepository.php @@ -4,6 +4,7 @@ namespace App\Ninja\Repositories; use App\Models\Proposal; use App\Models\Invoice; +use App\Models\ProposalTemplate; use Auth; use DB; use Utils; @@ -27,6 +28,7 @@ class ProposalRepository extends BaseRepository ->leftjoin('invoices', 'invoices.id', '=', 'proposals.quote_id') ->leftjoin('clients', 'clients.id', '=', 'invoices.client_id') ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id') + ->leftJoin('proposal_templates', 'proposal_templates.id', '=', 'proposals.proposal_template_id') ->where('clients.deleted_at', '=', null) ->where('contacts.deleted_at', '=', null) ->where('contacts.is_primary', '=', true) @@ -34,12 +36,19 @@ class ProposalRepository extends BaseRepository 'proposals.public_id', 'proposals.user_id', 'proposals.deleted_at', + 'proposals.created_at', 'proposals.is_deleted', 'proposals.private_notes', DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"), 'clients.user_id as client_user_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.public_id as quote_public_id', + 'invoices.user_id as quote_user_id', + 'proposal_templates.name as template', + 'proposal_templates.public_id as template_public_id', + 'proposal_templates.user_id as template_user_id' ); $this->applyFilters($query, ENTITY_PROPOSAL); @@ -73,6 +82,10 @@ class ProposalRepository extends BaseRepository $proposal->quote_id = $input['quote_id'] ? Invoice::getPrivateId($input['quote_id']) : null; } + if (isset($input['proposal_template_id'])) { + $proposal->proposal_template_id = $input['proposal_template_id'] ? ProposalTemplate::getPrivateId($input['proposal_template_id']) : null; + } + $proposal->save(); return $proposal; diff --git a/app/Ninja/Repositories/ProposalTemplateRepository.php b/app/Ninja/Repositories/ProposalTemplateRepository.php index 450d72f55fe5..fcdae0a615e4 100644 --- a/app/Ninja/Repositories/ProposalTemplateRepository.php +++ b/app/Ninja/Repositories/ProposalTemplateRepository.php @@ -23,22 +23,13 @@ class ProposalTemplateRepository extends BaseRepository { $query = DB::table('proposal_templates') ->where('proposal_templates.account_id', '=', Auth::user()->account_id) - ->leftjoin('invoices', 'invoices.id', '=', 'proposal_templates.quote_id') - ->leftjoin('clients', 'clients.id', '=', 'invoices.client_id') - ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id') - ->where('clients.deleted_at', '=', null) - ->where('contacts.deleted_at', '=', null) - ->where('contacts.is_primary', '=', true) ->select( - 'proposal_templates.name as proposal', + 'proposal_templates.name', 'proposal_templates.public_id', 'proposal_templates.user_id', 'proposal_templates.deleted_at', 'proposal_templates.is_deleted', - 'proposal_templates.private_notes', - DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"), - 'clients.user_id as client_user_id', - 'clients.public_id as client_public_id' + 'proposal_templates.private_notes' ); $this->applyFilters($query, ENTITY_PROPOSAL_TEMPLATE); diff --git a/database/migrations/2018_01_10_073825_add_subscription_format.php b/database/migrations/2018_01_10_073825_add_subscription_format.php index 090e74fa4ff7..451176dcecf8 100644 --- a/database/migrations/2018_01_10_073825_add_subscription_format.php +++ b/database/migrations/2018_01_10_073825_add_subscription_format.php @@ -46,7 +46,7 @@ class AddSubscriptionFormat extends Migration $table->softDeletes(); $table->boolean('is_deleted')->default(false); - $table->unsignedInteger('proposal_category_id'); + $table->unsignedInteger('proposal_category_id')->nullable(); $table->string('name'); $table->text('private_notes'); @@ -89,7 +89,7 @@ class AddSubscriptionFormat extends Migration $table->boolean('is_deleted')->default(false); $table->unsignedInteger('quote_id')->index(); - $table->unsignedInteger('template_id')->index(); + $table->unsignedInteger('proposal_template_id')->index(); $table->text('private_notes'); $table->mediumText('html'); $table->mediumText('css'); @@ -97,7 +97,7 @@ class AddSubscriptionFormat extends Migration $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('quote_id')->references('id')->on('invoices')->onDelete('cascade'); - $table->foreign('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->unique(['account_id', 'public_id']); diff --git a/resources/views/proposals/edit.blade.php b/resources/views/proposals/edit.blade.php index e0beadbb3a03..ad798ec4160c 100644 --- a/resources/views/proposals/edit.blade.php +++ b/resources/views/proposals/edit.blade.php @@ -24,7 +24,7 @@ ->id('mainForm') ->rules([ 'quote_id' => 'required', - 'template_id' => 'required', + 'proposal_template_id' => 'required', ]) !!} @if ($proposal) @@ -44,13 +44,14 @@ {!! Former::select('quote_id')->addOption('', '') ->label(trans('texts.quote')) ->addGroupClass('quote-select') !!} - {!! Former::select('template_id')->addOption('', '') + {!! Former::select('proposal_template_id')->addOption('', '') ->label(trans('texts.template')) ->addGroupClass('template-select') !!}
- + {!! Former::textarea('private_notes') + ->style('height: 100px') !!}
@@ -92,14 +93,23 @@ $quoteSelect.append(new Option(quote.invoice_number + ' - ' + getClientDisplayName(quote.client), quote.public_id)); } @include('partials/entity_combobox', ['entityType' => ENTITY_QUOTE]) + if (quoteId) { + var quote = quoteMap[quoteId]; + setComboboxValue($('.quote-select'), quote.public_id, quote.invoice_number + ' - ' + getClientDisplayName(quote.client)); + } - var $proposal_templateSelect = $('select#template_id'); + var templateId = {{ ! empty($templatePublicId) ? $templatePublicId : 0 }}; + var $proposal_templateSelect = $('select#proposal_template_id'); for (var i = 0; i < templates.length; i++) { var template = templates[i]; templateMap[template.public_id] = template; $proposal_templateSelect.append(new Option(template.name, template.public_id)); } @include('partials/entity_combobox', ['entityType' => ENTITY_PROPOSAL_TEMPLATE]) + if (templateId) { + var template = templateMap[templateId]; + setComboboxValue($('.template-select'), template.public_id, template.name); + } var editor = grapesjs.init({ container : '#gjs', diff --git a/resources/views/proposals/templates/edit.blade.php b/resources/views/proposals/templates/edit.blade.php index 25cdf3f7372b..bb0289b64ab9 100644 --- a/resources/views/proposals/templates/edit.blade.php +++ b/resources/views/proposals/templates/edit.blade.php @@ -23,8 +23,7 @@ ->method($method) ->id('mainForm') ->rules([ - 'quote_id' => 'required', - 'template_id' => 'required', + 'name' => 'required', ]) !!} @if ($template) @@ -42,16 +41,16 @@
- {!! Former::select('quote_id')->addOption('', '') - ->label(trans('texts.quote')) - ->addGroupClass('quote-select') !!} + {!! Former::text('name') !!} -
-
+ +
+
+ {!! Former::textarea('private_notes') !!}
@@ -77,7 +76,12 @@ var templates = {!! $templates !!}; var templateMap = {}; + function onSaveClick() { + $('#mainForm').submit(); + } + $(function() { + /* var $proposal_templateSelect = $('select#template_id'); for (var i = 0; i < templates.length; i++) { var template = templates[i]; @@ -85,6 +89,7 @@ $templateSelect.append(new Option(template.name, template.public_id)); } @include('partials/entity_combobox', ['entityType' => ENTITY_PROPOSAL_TEMPLATE]) + */ var editor = grapesjs.init({ container : '#gjs',