mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Working on quotes
This commit is contained in:
parent
a14e00d520
commit
aa3a3f174f
@ -41,40 +41,10 @@ class InvoiceController extends \BaseController {
|
||||
|
||||
public function getDatatable($clientPublicId = null)
|
||||
{
|
||||
$query = $this->invoiceRepo->getInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch'));
|
||||
$table = Datatable::query($query);
|
||||
$accountId = Auth::user()->account_id;
|
||||
$search = Input::get('sSearch');
|
||||
|
||||
if (!$clientPublicId) {
|
||||
$table->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; });
|
||||
}
|
||||
|
||||
$table->addColumn('invoice_number', function($model) { return link_to('invoices/' . $model->public_id . '/edit', $model->invoice_number); });
|
||||
|
||||
if (!$clientPublicId) {
|
||||
$table->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||
}
|
||||
|
||||
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
||||
->addColumn('amount', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||
->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
||||
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
||||
->addColumn('dropdown', function($model)
|
||||
{
|
||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
'.trans('texts.select').' <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">'.trans('texts.edit_invoice').'</a></li>
|
||||
<li><a href="' . URL::to('payments/create/' . $model->client_public_id . '/' . $model->public_id ) . '">'.trans('texts.enter_payment').'</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">'.trans('texts.archive_invoice').'</a></li>
|
||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">'.trans('texts.delete_invoice').'</a></li>
|
||||
</ul>
|
||||
</div>';
|
||||
})
|
||||
->make();
|
||||
return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_INVOICE, $search);
|
||||
}
|
||||
|
||||
public function getRecurringDatatable($clientPublicId = null)
|
||||
@ -236,6 +206,7 @@ class InvoiceController extends \BaseController {
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'entityType' => ENTITY_INVOICE,
|
||||
'account' => Auth::user()->account,
|
||||
'products' => Product::scope()->orderBy('id')->get(array('product_key','notes','cost','qty')),
|
||||
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||
|
94
app/controllers/QuoteController.php
Normal file
94
app/controllers/QuoteController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
use ninja\mailers\ContactMailer as Mailer;
|
||||
use ninja\repositories\InvoiceRepository;
|
||||
use ninja\repositories\ClientRepository;
|
||||
use ninja\repositories\TaxRateRepository;
|
||||
|
||||
class QuoteController extends \BaseController {
|
||||
|
||||
protected $mailer;
|
||||
protected $invoiceRepo;
|
||||
protected $clientRepo;
|
||||
protected $taxRateRepo;
|
||||
|
||||
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, TaxRateRepository $taxRateRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->mailer = $mailer;
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
$this->clientRepo = $clientRepo;
|
||||
$this->taxRateRepo = $taxRateRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'title' => '- Quotes',
|
||||
'entityType'=>ENTITY_QUOTE,
|
||||
'columns'=>Utils::trans(['checkbox', 'quote_number', 'client', 'quote_date', 'quote_total', 'due_date', 'status', 'action'])
|
||||
];
|
||||
|
||||
if (Invoice::scope()->where('is_recurring', '=', true)->count() > 0)
|
||||
{
|
||||
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
|
||||
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'quote_total', 'action']);
|
||||
}
|
||||
|
||||
return View::make('list', $data);
|
||||
}
|
||||
|
||||
public function getDatatable($clientPublicId = null)
|
||||
{
|
||||
$accountId = Auth::user()->account_id;
|
||||
$search = Input::get('sSearch');
|
||||
|
||||
return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search);
|
||||
}
|
||||
|
||||
public function create($clientPublicId = 0)
|
||||
{
|
||||
$client = null;
|
||||
$invoiceNumber = Auth::user()->account->getNextInvoiceNumber();
|
||||
$account = Account::with('country')->findOrFail(Auth::user()->account_id);
|
||||
|
||||
if ($clientPublicId)
|
||||
{
|
||||
$client = Client::scope($clientPublicId)->firstOrFail();
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'account' => $account,
|
||||
'invoice' => null,
|
||||
'data' => Input::old('data'),
|
||||
'invoiceNumber' => $invoiceNumber,
|
||||
'method' => 'POST',
|
||||
'url' => 'quotes',
|
||||
'title' => '- New Quote',
|
||||
'client' => $client);
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
return View::make('invoices.edit', $data);
|
||||
}
|
||||
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'entityType' => ENTITY_QUOTE,
|
||||
'account' => Auth::user()->account,
|
||||
'products' => Product::scope()->orderBy('id')->get(array('product_key','notes','cost','qty')),
|
||||
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||
'clients' => Client::scope()->with('contacts', 'country')->orderBy('name')->get(),
|
||||
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
|
||||
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
||||
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||
'invoiceLabels' => Auth::user()->account->getInvoiceLabels()
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
34
app/database/migrations/2014_05_17_175626_add_quotes.php
Normal file
34
app/database/migrations/2014_05_17_175626_add_quotes.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddQuotes extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('invoices', function($table)
|
||||
{
|
||||
$table->boolean('is_quote');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('invoices', function($table)
|
||||
{
|
||||
$table->dropColumn('is_quote');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -351,5 +351,25 @@ return array(
|
||||
'chart_builder' => 'Chart Builder',
|
||||
'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!',
|
||||
|
||||
'quote' => 'Quote',
|
||||
'quotes' => 'Quotes',
|
||||
'quote_number' => 'Quote Number',
|
||||
'quote_date' => 'Quote Date',
|
||||
'quote_total' => 'Quote Total',
|
||||
|
||||
'new_quote' => 'New Quote',
|
||||
'edit_quote' => 'Edit Quote',
|
||||
'archive_quote' => 'Archive Quote',
|
||||
'delete_quote' => 'Delete Quote',
|
||||
|
||||
'updated_quote' => 'Successfully updated quote',
|
||||
'created_quote' => 'Successfully created quote',
|
||||
'cloned_quote' => 'Successfully cloned quote',
|
||||
'emailed_quote' => 'Successfully emailed quote',
|
||||
'archived_quote' => 'Successfully archived quote',
|
||||
'archived_quotes' => 'Successfully archived :count quotes',
|
||||
'deleted_quote' => 'Successfully deleted quote',
|
||||
'deleted_quotes' => 'Successfully deleted :count quotes',
|
||||
|
||||
);
|
||||
|
||||
|
@ -32,6 +32,11 @@ class Utils
|
||||
return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV'];
|
||||
}
|
||||
|
||||
public static function isPro()
|
||||
{
|
||||
return Auth::check() && Auth::user()->isPro();
|
||||
}
|
||||
|
||||
public static function getProLabel($feature)
|
||||
{
|
||||
if (Auth::check()
|
||||
|
@ -80,6 +80,67 @@ class InvoiceRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getDatatable($accountId, $clientPublicId = null, $entityType, $search)
|
||||
{
|
||||
$query = $this->getInvoices($accountId, $clientPublicId, $search);
|
||||
|
||||
if ($entityType == ENTITY_QUOTE)
|
||||
{
|
||||
$query->where('invoices.is_quote', '=', true);
|
||||
}
|
||||
|
||||
$table = \Datatable::query($query);
|
||||
|
||||
if (!$clientPublicId)
|
||||
{
|
||||
$table->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; });
|
||||
}
|
||||
|
||||
$table->addColumn("invoice_number", function($model) use ($entityType) { return link_to("{$entityType}s/" . $model->public_id . '/edit', $model->invoice_number); });
|
||||
|
||||
if (!$clientPublicId)
|
||||
{
|
||||
$table->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||
}
|
||||
|
||||
$table->addColumn("invoice_date", function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
||||
->addColumn('amount', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); });
|
||||
|
||||
if ($entityType == ENTITY_INVOICE)
|
||||
{
|
||||
$table->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); });
|
||||
}
|
||||
|
||||
return $table->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
||||
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
||||
->addColumn('dropdown', function($model) use ($entityType)
|
||||
{
|
||||
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
'.trans('texts.select').' <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . \URL::to("{$entityType}s/".$model->public_id.'/edit') . '">'.trans("texts.edit_{$entityType}").'</a></li>';
|
||||
|
||||
if ($entityType == ENTITY_INVOICE)
|
||||
{
|
||||
$str .= '<li><a href="' . \URL::to('payments/create/' . $model->client_public_id . '/' . $model->public_id ) . '">'.trans('texts.enter_payment').'</a></li>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$str .= '';
|
||||
}
|
||||
|
||||
return $str . '<li class="divider"></li>
|
||||
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">'.trans("texts.archive_{$entityType}").'</a></li>
|
||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">'.trans("texts.delete_{$entityType}").'</a></li>
|
||||
</ul>
|
||||
</div>';
|
||||
})
|
||||
->make();
|
||||
}
|
||||
|
||||
|
||||
public function getErrors($input)
|
||||
{
|
||||
$contact = (array) $input->client->contacts[0];
|
||||
|
@ -96,6 +96,13 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::get('invoices/create/{client_id?}', 'InvoiceController@create');
|
||||
Route::post('invoices/bulk', 'InvoiceController@bulk');
|
||||
|
||||
Route::resource('quotes', 'QuoteController');
|
||||
Route::get('api/quotes/{client_id?}', array('as'=>'api.quotes', 'uses'=>'QuoteController@getDatatable'));
|
||||
/*
|
||||
Route::get('invoices/create/{client_id?}', 'InvoiceController@create');
|
||||
Route::post('invoices/bulk', 'InvoiceController@bulk');
|
||||
*/
|
||||
|
||||
Route::get('payments/{id}/edit', function() { return View::make('header'); });
|
||||
Route::resource('payments', 'PaymentController');
|
||||
Route::get('payments/create/{client_id?}/{invoice_id?}', 'PaymentController@create');
|
||||
@ -132,6 +139,7 @@ define('ENTITY_INVOICE', 'invoice');
|
||||
define('ENTITY_RECURRING_INVOICE', 'recurring_invoice');
|
||||
define('ENTITY_PAYMENT', 'payment');
|
||||
define('ENTITY_CREDIT', 'credit');
|
||||
define('ENTITY_QUOTE', 'quote');
|
||||
|
||||
define('PERSON_CONTACT', 'contact');
|
||||
define('PERSON_USER', 'user');
|
||||
|
@ -89,6 +89,9 @@
|
||||
<ul class="nav navbar-nav" style="font-weight: bold">
|
||||
{{ HTML::nav_link('dashboard', 'dashboard') }}
|
||||
{{ HTML::menu_link('client') }}
|
||||
@if (Utils::isPro())
|
||||
{{ HTML::menu_link('quote') }}
|
||||
@endif
|
||||
{{ HTML::menu_link('invoice') }}
|
||||
{{ HTML::menu_link('payment') }}
|
||||
{{ HTML::menu_link('credit') }}
|
||||
|
@ -69,6 +69,7 @@
|
||||
{{ Former::text('due_date')->data_bind("datePicker: due_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'due_date\')"></i>') }}
|
||||
</div>
|
||||
@if ($entityType == ENTITY_INVOICE)
|
||||
<div data-bind="visible: is_recurring" style="display: none">
|
||||
{{ Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id") }}
|
||||
{{ Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'")
|
||||
@ -76,6 +77,7 @@
|
||||
{{ Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'end_date\')"></i>') }}
|
||||
</div>
|
||||
@endif
|
||||
@if ($invoice && $invoice->recurring_invoice_id)
|
||||
<div class="pull-right" style="padding-top: 6px">
|
||||
Created by a {{ link_to('/invoices/'.$invoice->recurring_invoice_id, 'recurring invoice') }}
|
||||
|
Loading…
Reference in New Issue
Block a user