Added ability for clients to approve a quote, converting it to an invoice

This commit is contained in:
Hillel Coren 2015-02-16 18:15:05 +02:00
parent 2a297e3d3f
commit 89269f4bd7
18 changed files with 62 additions and 37 deletions

View File

@ -133,23 +133,13 @@ class InvoiceController extends \BaseController
public function view($invitationKey) public function view($invitationKey)
{ {
$invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail(); $invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice; $invoice = $invitation->invoice;
if (!$invoice || $invoice->is_deleted) { if (!$invoice || $invoice->is_deleted) {
return View::make('invoices.deleted'); return View::make('invoices.deleted');
} }
if ($invoice->is_quote && $invoice->quote_invoice_id) {
$invoice = Invoice::scope($invoice->quote_invoice_id, $invoice->account_id)->firstOrFail();
if (!$invoice || $invoice->is_deleted) {
return View::make('invoices.deleted');
}
}
$invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country'); $invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country');
$client = $invoice->client; $client = $invoice->client;
if (!$client || $client->is_deleted) { if (!$client || $client->is_deleted) {
@ -169,7 +159,7 @@ class InvoiceController extends \BaseController
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date); $invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = $client->account->isPro(); $invoice->is_pro = $client->account->isPro();
$contact = $invitation->contact; $contact = $invitation->contact;
$contact->setVisible([ $contact->setVisible([
@ -179,6 +169,7 @@ class InvoiceController extends \BaseController
'phone', ]); 'phone', ]);
$data = array( $data = array(
'isConverted' => $invoice->quote_invoice_id ? true : false,
'showClientHeader' => true, 'showClientHeader' => true,
'showBreadcrumbs' => false, 'showBreadcrumbs' => false,
'hideLogo' => $client->account->isWhiteLabel(), 'hideLogo' => $client->account->isWhiteLabel(),

View File

@ -614,10 +614,6 @@ class PaymentController extends \BaseController
$account->save(); $account->save();
} }
if ($invoice->is_quote) {
$invoice = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
}
$payment = Payment::createNew($invitation); $payment = Payment::createNew($invitation);
$payment->invitation_id = $invitation->id; $payment->invitation_id = $invitation->id;
$payment->account_gateway_id = $accountGateway->id; $payment->account_gateway_id = $accountGateway->id;

View File

@ -141,7 +141,7 @@ class QuoteController extends \BaseController
$clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id); $clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
Session::flash('message', trans('texts.converted_to_invoice')); Session::flash('message', trans('texts.converted_to_invoice'));
return Redirect::to('invoices/'.$clone->public_id); return Redirect::to('invoices/'.$clone->public_id);
} }
$statusId = Input::get('statusId'); $statusId = Input::get('statusId');
@ -156,4 +156,24 @@ class QuoteController extends \BaseController
return Redirect::to('quotes'); return Redirect::to('quotes');
} }
public function approve($invitationKey)
{
$invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
if ($invoice->is_quote && !$invoice->quote_invoice_id) {
Activity::approveQuote($invitation);
$invoice = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
Session::flash('message', trans('texts.converted_to_invoice'));
foreach ($invoice->invitations as $invitationClone) {
if ($invitation->contact_id == $invitationClone->contact_id) {
$invitationKey = $invitationClone->invitation_key;
}
}
}
return Redirect::to("view/{$invitationKey}");
}
} }

View File

@ -510,6 +510,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -500,6 +500,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -508,5 +508,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -480,6 +480,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -501,6 +501,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -503,6 +503,6 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -511,6 +511,7 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -509,7 +509,7 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -504,7 +504,7 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -491,7 +491,7 @@ return array(
'payment_email' => 'Payment Email', 'payment_email' => 'Payment Email',
'quote_email' => 'Quote Email', 'quote_email' => 'Quote Email',
'reset_all' => 'Reset All', 'reset_all' => 'Reset All',
'approve' => 'Approve',
); );

View File

@ -231,6 +231,19 @@ class Activity extends Eloquent
$activity->save(); $activity->save();
} }
public static function approveQuote($invitation) {
$activity = Activity::getBlank($invitation);
$activity->client_id = $invitation->invoice->client_id;
$activity->invitation_id = $invitation->id;
$activity->contact_id = $invitation->contact_id;
$activity->invoice_id = $invitation->invoice_id;
$activity->activity_type_id = ACTIVITY_TYPE_APPROVE_QUOTE;
$activity->message = Utils::encodeActivity($invitation->contact, 'approved', $invitation->invoice);
$activity->balance = $invitation->invoice->client->balance;
$activity->save();
}
public static function createPayment($payment) public static function createPayment($payment)
{ {
$client = $payment->client; $client = $payment->client;

View File

@ -80,7 +80,6 @@ class InvoiceRepository
$query = \DB::table('invitations') $query = \DB::table('invitations')
->join('invoices', 'invoices.id', '=', 'invitations.invoice_id') ->join('invoices', 'invoices.id', '=', 'invitations.invoice_id')
->join('clients', 'clients.id', '=', 'invoices.client_id') ->join('clients', 'clients.id', '=', 'invoices.client_id')
//->join('contacts', 'contacts.client_id', '=', 'clients.id')
->where('invitations.contact_id', '=', $contactId) ->where('invitations.contact_id', '=', $contactId)
->where('invitations.deleted_at', '=', null) ->where('invitations.deleted_at', '=', null)
->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE) ->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE)
@ -99,7 +98,6 @@ class InvoiceRepository
} }
return $table->addColumn('due_date', function ($model) { return Utils::fromSqlDate($model->due_date); }) return $table->addColumn('due_date', function ($model) { return Utils::fromSqlDate($model->due_date); })
//->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
->make(); ->make();
} }

View File

@ -46,6 +46,7 @@ Route::post('get_started', 'AccountController@getStarted');
// Client visible pages // Client visible pages
Route::get('view/{invitation_key}', 'InvoiceController@view'); Route::get('view/{invitation_key}', 'InvoiceController@view');
Route::get('approve/{invitation_key}', 'QuoteController@approve');
Route::get('payment/{invitation_key}', 'PaymentController@show_payment'); Route::get('payment/{invitation_key}', 'PaymentController@show_payment');
Route::post('payment/{invitation_key}', 'PaymentController@do_payment'); Route::post('payment/{invitation_key}', 'PaymentController@do_payment');
Route::get('complete', 'PaymentController@offsite_payment'); Route::get('complete', 'PaymentController@offsite_payment');
@ -228,6 +229,7 @@ define("ACTIVITY_TYPE_RESTORE_INVOICE", 25);
define("ACTIVITY_TYPE_RESTORE_CLIENT", 26); define("ACTIVITY_TYPE_RESTORE_CLIENT", 26);
define("ACTIVITY_TYPE_RESTORE_PAYMENT", 27); define("ACTIVITY_TYPE_RESTORE_PAYMENT", 27);
define("ACTIVITY_TYPE_RESTORE_CREDIT", 28); define("ACTIVITY_TYPE_RESTORE_CREDIT", 28);
define("ACTIVITY_TYPE_APPROVE_QUOTE", 29);
define('DEFAULT_INVOICE_NUMBER', '0001'); define('DEFAULT_INVOICE_NUMBER', '0001');
define('RECENTLY_VIEWED_LIMIT', 8); define('RECENTLY_VIEWED_LIMIT', 8);

View File

@ -81,6 +81,7 @@
var needsRefresh = false; var needsRefresh = false;
function refreshPDF() { function refreshPDF() {
PDFJS.disableWorker = true;
if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChromium))) { if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChromium))) {
var string = getPDFString(); var string = getPDFString();
if (!string) return; if (!string) return;

View File

@ -22,18 +22,20 @@
<div class="container"> <div class="container">
<p>&nbsp;</p> <p>&nbsp;</p>
<div class="pull-right" style="text-align:right">
@if ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring) @if ($invoice->is_quote)
<div class="pull-right" style="text-align:right"> {{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}&nbsp;&nbsp;
{{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}&nbsp;&nbsp; @if (!$isConverted)
{{ Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) }} {{ Button::success_link(URL::to('approve/' . $invitation->invitation_key), trans('texts.approve'), array('class' => 'btn-lg')) }}
</div> @endif
@elseif ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring)
{{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}&nbsp;&nbsp;
{{ Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) }}
@else @else
<div class="pull-right"> {{ Button::success('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
{{ Button::success('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
</div>
@endif @endif
</div>
<div class="clearfix"></div><p>&nbsp;</p> <div class="clearfix"></div><p>&nbsp;</p>
<script type="text/javascript"> <script type="text/javascript">