mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e4e440c9be
@ -9,14 +9,9 @@ Most online invoicing sites are expensive. They shouldn't be. The aim of this pr
|
|||||||
### Features
|
### Features
|
||||||
* Core application built using Laravel 4.1
|
* Core application built using Laravel 4.1
|
||||||
* Invoice PDF generation directly in the browser
|
* Invoice PDF generation directly in the browser
|
||||||
* Tax rates and payment terms
|
|
||||||
* Integrates with many payment providers
|
* Integrates with many payment providers
|
||||||
* Recurring invoices
|
* Recurring invoices
|
||||||
|
* Tax rates and payment terms
|
||||||
### Remaining Work
|
|
||||||
* Home dashboard
|
|
||||||
* Multiple language support
|
|
||||||
* Reports
|
|
||||||
|
|
||||||
### Steps to setup
|
### Steps to setup
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class AccountController extends \BaseController {
|
|||||||
|
|
||||||
public function setTrashVisible($entityType, $visible)
|
public function setTrashVisible($entityType, $visible)
|
||||||
{
|
{
|
||||||
Session::put("trash_{$entityType}", $visible == 'true');
|
Session::put('show_trash', $visible == 'true');
|
||||||
return Redirect::to("{$entityType}s");
|
return Redirect::to("{$entityType}s");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +300,7 @@ class AccountController extends \BaseController {
|
|||||||
|
|
||||||
$client->save();
|
$client->save();
|
||||||
$client->contacts()->save($contact);
|
$client->contacts()->save($contact);
|
||||||
|
Activity::createClient($client);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = Utils::pluralize('Successfully created ? client', $count);
|
$message = Utils::pluralize('Successfully created ? client', $count);
|
||||||
|
@ -216,6 +216,7 @@ class InvoiceController extends \BaseController {
|
|||||||
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||||
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
||||||
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||||
|
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||||
'frequencies' => array(
|
'frequencies' => array(
|
||||||
1 => 'Weekly',
|
1 => 'Weekly',
|
||||||
2 => 'Two weeks',
|
2 => 'Two weeks',
|
||||||
@ -268,10 +269,13 @@ class InvoiceController extends \BaseController {
|
|||||||
$invoice = $this->invoiceRepo->save($publicId, $invoiceData);
|
$invoice = $this->invoiceRepo->save($publicId, $invoiceData);
|
||||||
|
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
if ($account->invoice_taxes != $input->invoice_taxes || $account->invoice_item_taxes != $input->invoice_item_taxes)
|
if ($account->invoice_taxes != $input->invoice_taxes
|
||||||
|
|| $account->invoice_item_taxes != $input->invoice_item_taxes
|
||||||
|
|| $account->invoice_design_id != $input->invoice->invoice_design_id)
|
||||||
{
|
{
|
||||||
$account->invoice_taxes = $input->invoice_taxes;
|
$account->invoice_taxes = $input->invoice_taxes;
|
||||||
$account->invoice_item_taxes = $input->invoice_item_taxes;
|
$account->invoice_item_taxes = $input->invoice_item_taxes;
|
||||||
|
$account->invoice_design_id = $input->invoice->invoice_design_id;
|
||||||
$account->save();
|
$account->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddSupportForInvoiceDesigns extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('invoice_designs', function($table)
|
||||||
|
{
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name');
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('invoice_designs')->insert(['name' => 'Clean']);
|
||||||
|
DB::table('invoice_designs')->insert(['name' => 'Bold']);
|
||||||
|
DB::table('invoice_designs')->insert(['name' => 'Modern']);
|
||||||
|
|
||||||
|
Schema::table('invoices', function($table)
|
||||||
|
{
|
||||||
|
$table->unsignedInteger('invoice_design_id')->default(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->unsignedInteger('invoice_design_id')->default(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('invoices')->update(['invoice_design_id' => 1]);
|
||||||
|
DB::table('accounts')->update(['invoice_design_id' => 1]);
|
||||||
|
|
||||||
|
Schema::table('invoices', function($table)
|
||||||
|
{
|
||||||
|
$table->foreign('invoice_design_id')->references('id')->on('invoice_designs');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->foreign('invoice_design_id')->references('id')->on('invoice_designs');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('invoices', function($table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('invoices_invoice_design_id_foreign');
|
||||||
|
$table->dropColumn('invoice_design_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('accounts_invoice_design_id_foreign');
|
||||||
|
$table->dropColumn('invoice_design_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::dropIfExists('invoice_designs');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
app/models/InvoiceDesign.php
Normal file
7
app/models/InvoiceDesign.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class InvoiceDesign extends Eloquent
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $softDelete = false;
|
||||||
|
}
|
@ -13,7 +13,7 @@ class ClientRepository
|
|||||||
->where('contacts.is_primary', '=', true)
|
->where('contacts.is_primary', '=', true)
|
||||||
->select('clients.public_id','clients.name','contacts.first_name','contacts.last_name','clients.balance','clients.last_login','clients.created_at','clients.work_phone','contacts.email','clients.currency_id');
|
->select('clients.public_id','clients.name','contacts.first_name','contacts.last_name','clients.balance','clients.last_login','clients.created_at','clients.work_phone','contacts.email','clients.currency_id');
|
||||||
|
|
||||||
if (!\Session::get('trash_client'))
|
if (!\Session::get('show_trash'))
|
||||||
{
|
{
|
||||||
$query->where('clients.deleted_at', '=', null);
|
$query->where('clients.deleted_at', '=', null);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class CreditRepository
|
|||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!\Session::get('trash_credit'))
|
if (!\Session::get('show_trash'))
|
||||||
{
|
{
|
||||||
$query->where('credits.deleted_at', '=', null);
|
$query->where('credits.deleted_at', '=', null);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class InvoiceRepository
|
|||||||
->where('contacts.is_primary', '=', true)
|
->where('contacts.is_primary', '=', true)
|
||||||
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
||||||
|
|
||||||
if (!\Session::get('trash_invoice'))
|
if (!\Session::get('show_trash'))
|
||||||
{
|
{
|
||||||
$query->where('invoices.deleted_at', '=', null);
|
$query->where('invoices.deleted_at', '=', null);
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ class InvoiceRepository
|
|||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!\Session::get('trash_invoice'))
|
if (!\Session::get('show_trash'))
|
||||||
{
|
{
|
||||||
$query->where('invoices.deleted_at', '=', null);
|
$query->where('invoices.deleted_at', '=', null);
|
||||||
}
|
}
|
||||||
@ -131,6 +131,7 @@ class InvoiceRepository
|
|||||||
$invoice->terms = trim($data['terms']);
|
$invoice->terms = trim($data['terms']);
|
||||||
$invoice->public_notes = trim($data['public_notes']);
|
$invoice->public_notes = trim($data['public_notes']);
|
||||||
$invoice->po_number = trim($data['po_number']);
|
$invoice->po_number = trim($data['po_number']);
|
||||||
|
$invoice->invoice_design_id = $data['invoice_design_id'];
|
||||||
|
|
||||||
if (isset($data['tax_rate']) && Utils::parseFloat($data['tax_rate']) > 0)
|
if (isset($data['tax_rate']) && Utils::parseFloat($data['tax_rate']) > 0)
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ class PaymentRepository
|
|||||||
->where('contacts.is_primary', '=', true)
|
->where('contacts.is_primary', '=', true)
|
||||||
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type');
|
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type');
|
||||||
|
|
||||||
if (!\Session::get('trash_payment'))
|
if (!\Session::get('show_trash'))
|
||||||
{
|
{
|
||||||
$query->where('payments.deleted_at', '=', null);
|
$query->where('payments.deleted_at', '=', null);
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
{{ Former::checkbox('notify_viewed')->label(' ')->text('Email me when an invoice is <b>viewed</b>') }}
|
{{ Former::checkbox('notify_viewed')->label(' ')->text('Email me when an invoice is <b>viewed</b>') }}
|
||||||
{{ Former::checkbox('notify_paid')->label(' ')->text('Email me when an invoice is <b>paid</b>') }}
|
{{ Former::checkbox('notify_paid')->label(' ')->text('Email me when an invoice is <b>paid</b>') }}
|
||||||
|
|
||||||
{{ Former::legend('Custom messages') }}
|
{{ Former::legend('Custom Messages') }}
|
||||||
{{ Former::textarea('invoice_terms') }}
|
{{ Former::textarea('invoice_terms')->label('Set default invoice terms') }}
|
||||||
{{ Former::textarea('email_footer') }}
|
{{ Former::textarea('email_footer')->label('Set default email signature') }}
|
||||||
|
|
||||||
{{ Former::actions( Button::lg_primary_submit('Save') ) }}
|
{{ Former::actions( Button::lg_primary_submit('Save') ) }}
|
||||||
{{ Former::close() }}
|
{{ Former::close() }}
|
||||||
|
@ -207,6 +207,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="display:none">
|
||||||
|
{{ Former::select('invoice_design_id')->label('Design')->style('display:inline;width:120px')->raw()
|
||||||
|
->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ Button::normal('Download PDF', array('onclick' => 'onDownloadClick()')) }}
|
{{ Button::normal('Download PDF', array('onclick' => 'onDownloadClick()')) }}
|
||||||
|
|
||||||
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
||||||
@ -462,7 +467,7 @@
|
|||||||
refreshPDF();
|
refreshPDF();
|
||||||
}); //.trigger('change');
|
}); //.trigger('change');
|
||||||
|
|
||||||
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id').change(function() {
|
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id').change(function() {
|
||||||
refreshPDF();
|
refreshPDF();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -947,6 +952,7 @@
|
|||||||
self.invoice_items = ko.observableArray();
|
self.invoice_items = ko.observableArray();
|
||||||
self.amount = ko.observable(0);
|
self.amount = ko.observable(0);
|
||||||
self.balance = ko.observable(0);
|
self.balance = ko.observable(0);
|
||||||
|
self.invoice_design_id = ko.observable({{ $account->invoice_design_id }});
|
||||||
|
|
||||||
self.mapping = {
|
self.mapping = {
|
||||||
'client': {
|
'client': {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<label for="trashed" style="font-weight:normal">
|
<label for="trashed" style="font-weight:normal">
|
||||||
<input id="trashed" type="checkbox" onclick="setTrashVisible()"
|
<input id="trashed" type="checkbox" onclick="setTrashVisible()"
|
||||||
{{ Session::get("trash_{$entityType}") ? 'checked' : ''}}/> Show archived/deleted
|
{{ Session::get('show_trash') ? 'checked' : ''}}/> Show archived/deleted
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div id="top_right_buttons" class="pull-right">
|
<div id="top_right_buttons" class="pull-right">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user