diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 49e40531e048..cb4e3441321b 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -167,6 +167,12 @@ class AccountController extends \BaseController { $count = 0; $hasHeaders = Input::get('header_checkbox'); + $countries = Country::all(); + $countryMap = []; + foreach ($countries as $country) { + $countryMap[strtolower($country->name)] = $country->id; + } + foreach ($data as $row) { if ($hasHeaders) @@ -212,6 +218,11 @@ class AccountController extends \BaseController { { $client->postal_code = $value; } + else if ($field == Client::$fieldCountry) + { + $value = strtolower($value); + $client->country_id = isset($countryMap[$value]) ? $countryMap[$value] : null; + } else if ($field == Client::$fieldNotes) { $client->notes = $value; @@ -266,6 +277,7 @@ class AccountController extends \BaseController { Client::$fieldCity, Client::$fieldState, Client::$fieldPostalCode, + Client::$fieldCountry, Client::$fieldNotes, Contact::$fieldFirstName, Contact::$fieldLastName, @@ -304,6 +316,7 @@ class AccountController extends \BaseController { 'city' => Client::$fieldCity, 'state' => Client::$fieldState, 'zip|postal|code' => Client::$fieldPostalCode, + 'country' => Client::$fieldCountry, 'note' => Client::$fieldNotes, ); diff --git a/app/controllers/ActivityController.php b/app/controllers/ActivityController.php index cf1bc4fe97cb..2a551f66b3bc 100755 --- a/app/controllers/ActivityController.php +++ b/app/controllers/ActivityController.php @@ -6,15 +6,10 @@ class ActivityController extends \BaseController { { return Datatable::collection(Activity::where('account_id','=',Auth::user()->account_id) ->where('client_id','=',$clientId)->get()) - ->addColumn('date', function($model) - { - return $model->created_at->format('m/d/y h:i a'); - }) - ->addColumn('message', function($model) - { - return $model->message; - }) - ->orderColumns('date') + ->addColumn('date', function($model) { return $model->created_at->format('m/d/y h:i a'); }) + ->addColumn('message', function($model) { return $model->message; }) + ->addColumn('balance', function($model) { return '$' . $model->balance; }) + ->orderColumns('date') ->make(); } diff --git a/app/controllers/ClientController.php b/app/controllers/ClientController.php index 6da2d94ce038..45ebc493e578 100755 --- a/app/controllers/ClientController.php +++ b/app/controllers/ClientController.php @@ -14,49 +14,39 @@ class ClientController extends \BaseController { return View::make('list', array( 'entityType'=>ENTITY_CLIENT, - 'columns'=>['checkbox', 'Client', 'Contact', 'Balance', 'Last Login', 'Date Created', 'Email', 'Phone'] + 'columns'=>['checkbox', 'Client', 'Contact', 'Balance', 'Last Login', 'Date Created', 'Email', 'Phone', 'Action'] )); } public function getDatatable() { - return Datatable::collection(Client::with('contacts')->where('account_id','=',Auth::user()->account_id)->get()) - ->addColumn('checkbox', function($model) - { - return ''; - }) - ->addColumn('name', function($model) - { - //return $model->name; - return link_to('clients/' . $model->id, $model->name); - }) - ->addColumn('contact', function($model) - { - return $model->contacts[0]->getFullName(); - }) - ->addColumn('balance', function($model) - { - return '$' . $model->balance; - }) - ->addColumn('last_login', function($model) - { - return $model->contacts[0]->getLastLogin(); - }) - ->addColumn('date_created', function($model) - { - return $model->getDateCreated(); - }) - ->addColumn('email', function($model) - { - //return $model->contacts[0]->email; - return HTML::mailto($model->contacts[0]->email, $model->contacts[0]->email); - }) - ->addColumn('phone', function($model) - { - return $model->contacts[0]->phone; - }) + $clients = Client::with('contacts')->where('account_id','=',Auth::user()->account_id)->get(); + + return Datatable::collection($clients) + ->addColumn('checkbox', function($model) { return ''; }) + ->addColumn('name', function($model) { return link_to('clients/' . $model->id, $model->name); }) + ->addColumn('contact', function($model) { return $model->contacts[0]->getFullName(); }) + ->addColumn('balance', function($model) { return '$' . $model->balance; }) + ->addColumn('last_login', function($model) { return $model->contacts[0]->getLastLogin(); }) + ->addColumn('date_created', function($model) { return $model->getDateCreated(); }) + ->addColumn('email', function($model) { return HTML::mailto($model->contacts[0]->email, $model->contacts[0]->email); }) + ->addColumn('phone', function($model) { return $model->contacts[0]->phone; }) + ->addColumn('dropdown', function($model) + { + return ''; + }) ->orderColumns('name') - ->make(); + ->make(); } /** @@ -199,11 +189,6 @@ class ClientController extends \BaseController { } - /** - * Bulk update the records - * - * @return Response - */ public function bulk() { $action = Input::get('action'); @@ -223,4 +208,27 @@ class ClientController extends \BaseController { return Redirect::to('clients'); } + + public function archive($id) + { + $client = Client::find($id); + $client->delete(); + + foreach ($client->invoices as $invoice) + { + $invoice->delete(); + } + + Session::flash('message', 'Successfully archived ' . $client->name); + return Redirect::to('clients'); + } + + public function delete($id) + { + $client = Client::find($id); + $client->forceDelete(); + + Session::flash('message', 'Successfully deleted ' . $client->name); + return Redirect::to('clients'); + } } \ No newline at end of file diff --git a/app/controllers/CreditController.php b/app/controllers/CreditController.php new file mode 100755 index 000000000000..d6355d9a2e65 --- /dev/null +++ b/app/controllers/CreditController.php @@ -0,0 +1,61 @@ +ENTITY_CREDIT, + 'columns'=>['checkbox', 'Credit Number', 'Client', 'Amount', 'Credit Date'] + )); + } + + public function getDatatable($clientId = null) + { + $collection = Credit::with('client')->where('account_id','=',Auth::user()->account_id); + + if ($clientId) { + $collection->where('client_id','=',$clientId); + } + + $table = Datatable::collection($collection->get()); + + if (!$clientId) { + $table->addColumn('checkbox', function($model) { return ''; }); + } + + $table->addColumn('credit_number', function($model) { return $model->credit_number; }); + + if (!$clientId) { + $table->addColumn('client', function($model) { return link_to('clients/' . $model->client->id, $model->client->name); }); + } + + return $table->addColumn('amount', function($model){ return '$' . money_format('%i', $model->amount); }) + ->addColumn('credit_date', function($model) { return (new Carbon($model->credit_date))->toFormattedDateString(); }) + ->orderColumns('number') + ->make(); + } + + public function archive($id) + { + $credit = Credit::find($id); + $creidt->delete(); + + Session::flash('message', 'Successfully archived credit ' . $credit->credit_number); + return Redirect::to('credits'); + } + + public function delete($id) + { + $credit = Credit::find($id); + $credit->forceDelete(); + + Session::flash('message', 'Successfully deleted credit ' . $credit->credit_number); + return Redirect::to('credits'); + } +} \ No newline at end of file diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 28069dc3f1c9..f24b640c0e69 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -9,11 +9,9 @@ class InvoiceController extends \BaseController { */ public function index() { - //$invoices = Invoice::with('client')->orderBy('created_at', 'DESC')->get(); - //return View::make('invoices.index'); return View::make('list', array( 'entityType'=>ENTITY_INVOICE, - 'columns'=>['checkbox', 'Invoice Number', 'Client', 'Total', 'Amount Due', 'Invoice Date', 'Due Date', 'Status'] + 'columns'=>['checkbox', 'Invoice Number', 'Client', 'Total', 'Amount Due', 'Invoice Date', 'Due Date', 'Status', 'Action'] )); } @@ -25,43 +23,37 @@ class InvoiceController extends \BaseController { $collection->where('client_id','=',$clientId); } - $table = Datatable::collection($collection->get())->addColumn('checkbox', function($model) - { - return ''; - }) - ->addColumn('invoice_number', function($model) - { - return link_to('invoices/' . $model->id . '/edit', $model->invoice_number); - }); - - if (!$clientId) - { - $table->addColumn('client', function($model) { - return link_to('clients/' . $model->client->id, $model->client->name); - }); + $table = Datatable::collection($collection->get()); + if (!$clientId) { + $table->addColumn('checkbox', function($model) { return ''; }); } - return $table->addColumn('total', function($model) - { - return '$' . money_format('%i', $model->getTotal()); - }) - ->addColumn('amount_due', function($model) - { - return '$' . money_format('%i', $model->getTotal()); - }) - ->addColumn('invoice_date', function($model) - { - return (new Carbon($model->invoice_date))->toFormattedDateString(); - }) - ->addColumn('due_date', function($model) - { - return $model->due_date == '0000-00-00' ? '' : (new Carbon($model->due_date))->toFormattedDateString(); - }) - ->addColumn('status', function($model) - { - return $model->invoice_status->name; - }) + $table->addColumn('invoice_number', function($model) { return link_to('invoices/' . $model->id . '/edit', $model->invoice_number); }); + + if (!$clientId) { + $table->addColumn('client', function($model) { return link_to('clients/' . $model->client->id, $model->client->name); }); + } + + return $table->addColumn('total', function($model){ return '$' . money_format('%i', $model->getTotal()); }) + ->addColumn('amount_due', function($model) { return '$' . money_format('%i', $model->getTotal()); }) + ->addColumn('invoice_date', function($model) { return (new Carbon($model->invoice_date))->toFormattedDateString(); }) + ->addColumn('due_date', function($model) { return $model->due_date == '0000-00-00' ? '' : (new Carbon($model->due_date))->toFormattedDateString(); }) + ->addColumn('status', function($model) { return $model->invoice_status->name; }) + ->addColumn('dropdown', function($model) + { + return ''; + }) ->orderColumns('number') ->make(); } @@ -72,7 +64,10 @@ class InvoiceController extends \BaseController { $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.account.account_gateways')->where('key', '=', $key)->firstOrFail(); $contact = null; - Activity::viewInvoice($invitation); + $invitation->viewed_date = new date('Y-m-d H:i:s'); + $invitation->save(); + + Activity::log($invitation->invoice->client, ACTIVITY_TYPE_VIEW_INVOICE, $contact, $invitation); return View::make('invoices.view')->with('invoice', $invitation->invoice); } @@ -205,10 +200,11 @@ class InvoiceController extends \BaseController { public function edit($id) { - $invoice = Invoice::with('client', 'invoice_items')->find($id); + $invoice = Invoice::with('account.country', 'client', 'invoice_items')->find($id); trackViewed($invoice->invoice_number . ' - ' . $invoice->client->name); $data = array( + 'account' => $invoice->account, 'invoice' => $invoice, 'method' => 'PUT', 'url' => 'invoices/' . $id, @@ -224,8 +220,10 @@ class InvoiceController extends \BaseController { { $client = null; $invoiceNumber = Auth::user()->account->getNextInvoiceNumber(); - + $account = Account::with('country')->find(Auth::user()->account_id); + $data = array( + 'account' => $account, 'invoice' => null, 'invoiceNumber' => $invoiceNumber, 'method' => 'POST', @@ -280,8 +278,8 @@ class InvoiceController extends \BaseController { } else { - $client = Client::with('contacts')->find($clientId); - $contact = $client->contacts[0]; + $client = Client::with('contacts')->find($clientId); + $contact = $client->contacts()->first(); } if ($id) { @@ -290,8 +288,8 @@ class InvoiceController extends \BaseController { } else { $invoice = new Invoice; $invoice->account_id = Auth::user()->account_id; - } - + } + $invoice->client_id = $clientId; $invoice->invoice_number = Input::get('invoice_number'); $invoice->discount = 0; @@ -356,7 +354,6 @@ class InvoiceController extends \BaseController { $invitation->key = str_random(20); $invitation->save(); - Session::flash('message', 'Successfully emailed invoice'); } else { Session::flash('message', 'Successfully saved invoice'); @@ -376,8 +373,10 @@ class InvoiceController extends \BaseController { */ public function show($id) { - $invoice = Invoice::find($id); - return View::make('invoices.show')->with('invoice', $invoice); + return Redirect::to('invoices/'.$id.'/edit'); + + //$invoice = Invoice::find($id); + //return View::make('invoices.show')->with('invoice', $invoice); } /** @@ -416,4 +415,22 @@ class InvoiceController extends \BaseController { return Redirect::to('invoices'); } + + public function archive($id) + { + $invoice = Invoice::find($id); + $invoice->delete(); + + Session::flash('message', 'Successfully archived invoice ' . $invoice->invoice_number); + return Redirect::to('invoices'); + } + + public function delete($id) + { + $invoice = Invoice::find($id); + $invoice->forceDelete(); + + Session::flash('message', 'Successfully deleted invoice ' . $invoice->invoice_number); + return Redirect::to('invoices'); + } } \ No newline at end of file diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index bff7f8a0c151..f120e65d161d 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -40,4 +40,21 @@ class PaymentController extends \BaseController ->make(); } + public function archive($id) + { + $payment = Payment::find($id); + $payment->delete(); + + Session::flash('message', 'Successfully archived payment'); + return Redirect::to('payments'); + } + + public function delete($id) + { + $payment = Payment::find($id); + $payment->forceDelete(); + + Session::flash('message', 'Successfully deleted payment'); + return Redirect::to('payments'); + } } \ No newline at end of file diff --git a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php index 5f71c186ecc1..341fae4e0046 100755 --- a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php +++ b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php @@ -10,6 +10,7 @@ class ConfideSetupUsersTable extends Migration { */ public function up() { + Schema::dropIfExists('credits'); Schema::dropIfExists('activities'); Schema::dropIfExists('invitations'); Schema::dropIfExists('account_gateways'); @@ -196,6 +197,8 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); + $t->timestamp('viewed_date'); + $t->foreign('user_id')->references('id')->on('users'); $t->foreign('contact_id')->references('id')->on('contacts'); $t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade'); @@ -210,7 +213,7 @@ class ConfideSetupUsersTable extends Migration { $t->string('key'); $t->string('notes'); - $t->decimal('cost', 8, 2); + $t->decimal('cost', 10, 2); $t->integer('qty'); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); @@ -227,7 +230,7 @@ class ConfideSetupUsersTable extends Migration { $t->string('product_key'); $t->string('notes'); - $t->decimal('cost', 8, 2); + $t->decimal('cost', 10, 2); $t->integer('qty'); $t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade'); @@ -239,13 +242,14 @@ class ConfideSetupUsersTable extends Migration { $t->increments('id'); $t->unsignedInteger('invoice_id'); $t->unsignedInteger('account_id'); - $t->unsignedInteger('client_id')->nullable(); + $t->unsignedInteger('client_id'); $t->unsignedInteger('contact_id')->nullable(); - $t->unsignedInteger('user_id'); + $t->unsignedInteger('user_id')->nullable(); $t->timestamps(); $t->softDeletes(); - $t->decimal('amount', 8, 2); + $t->decimal('amount', 10, 2); + $t->date('payment_date'); $t->string('transaction_reference'); $t->string('payer_id'); @@ -256,20 +260,44 @@ class ConfideSetupUsersTable extends Migration { $t->foreign('user_id')->references('id')->on('users'); }); - Schema::create('activities', function($t) + Schema::create('credits', function($t) { $t->increments('id'); $t->unsignedInteger('account_id'); - $t->unsignedInteger('client_id'); - $t->unsignedInteger('user_id')->nullable(); + $t->unsignedInteger('client_id')->nullable(); $t->unsignedInteger('contact_id')->nullable(); - $t->unsignedInteger('invoice_id')->nullable(); - $t->unsignedInteger('payment_id')->nullable(); - $t->unsignedInteger('invitation_id')->nullable(); + $t->timestamps(); + $t->softDeletes(); + + $t->decimal('amount', 10, 2); + $t->date('credit_date'); + $t->string('credit_number'); + + $t->foreign('account_id')->references('id')->on('accounts'); + $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); + $t->foreign('contact_id')->references('id')->on('contacts'); + }); + + Schema::create('activities', function($t) + { + $t->increments('id'); $t->timestamps(); - $t->integer('activity_type_id'); + $t->unsignedInteger('account_id'); + $t->unsignedInteger('client_id'); + $t->unsignedInteger('user_id'); + $t->unsignedInteger('contact_id'); + $t->unsignedInteger('payment_id'); + $t->unsignedInteger('invoice_id'); + $t->unsignedInteger('credit_id'); + $t->text('message'); + $t->integer('activity_type_id'); + $t->decimal('adjustment', 10, 2); + $t->decimal('balance', 10, 2); + + $t->foreign('account_id')->references('id')->on('accounts'); + $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); }); } @@ -280,6 +308,7 @@ class ConfideSetupUsersTable extends Migration { */ public function down() { + Schema::dropIfExists('credits'); Schema::dropIfExists('activities'); Schema::dropIfExists('invitations'); Schema::dropIfExists('account_gateways'); diff --git a/app/models/Account.php b/app/models/Account.php index a7bb686d8472..0e694fa2b94c 100755 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -24,6 +24,11 @@ class Account extends Eloquent return $this->hasMany('AccountGateway'); } + public function country() + { + return $this->belongsTo('Country'); + } + public function isGatewayConfigured($gatewayId = 0) { if ($gatewayId) @@ -73,7 +78,7 @@ class Account extends Eloquent if ($order) { $number = intval($order->invoice_number) + 1; - return str_pad($number, 5, "0", STR_PAD_LEFT); + return str_pad($number, 4, "0", STR_PAD_LEFT); } else { diff --git a/app/models/Activity.php b/app/models/Activity.php index 1ca78a9afcd2..3c1257c92d58 100755 --- a/app/models/Activity.php +++ b/app/models/Activity.php @@ -1,13 +1,20 @@ client_id = $client->id; $activity->activity_type_id = ACTIVITY_TYPE_CREATE_CLIENT; - $activity->message = Auth::user()->getFullName() . ' created client ' . $client->name; + $activity->message = Auth::user()->getFullName() . ' created client ' . link_to('clients/'.$client->id, $client->name); + $activity->save(); } @@ -45,7 +53,7 @@ class Activity extends Eloquent $activity->invoice_id = $invoice->id; $activity->client_id = $invoice->client_id; $activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE; - $activity->message = Auth::user()->getFullName() . ' created invoice ' . $invoice->number; + $activity->message = Auth::user()->getFullName() . ' created invoice ' . link_to('invoices/'.$invoice->id, $invoice->invoice_number); $activity->save(); } @@ -55,7 +63,7 @@ class Activity extends Eloquent $activity->invoice_id = $invoice->id; $activity->client_id = $invoice->client_id; $activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_INVOICE; - $activity->message = Auth::user()->getFullName() . ' archived invoice ' . $invoice->number; + $activity->message = Auth::user()->getFullName() . ' archived invoice ' . $invoice->invoice_number; $activity->save(); } @@ -74,7 +82,7 @@ class Activity extends Eloquent if (Auth::check()) { $activity = Activity::getBlank(); - $activity->message = Auth::user()->getFullName() . ' created invoice ' . $payment->transaction_reference; + $activity->message = Auth::user()->getFullName() . ' created payment ' . $payment->transaction_reference; } else { diff --git a/app/models/Client.php b/app/models/Client.php index f87fc9288657..2b9c9bea0767 100755 --- a/app/models/Client.php +++ b/app/models/Client.php @@ -1,6 +1,6 @@ hasMany('Contact'); } + public function country() + { + return $this->belongsTo('Country'); + } + + public function getName() + { + return $this->name; + } + + public function getEntityType() + { + return ENTITY_CLIENT; + } + public function getAddress() { $str = ''; @@ -47,6 +63,9 @@ class Client extends Eloquent if ($this->postal_code) { $str .= $this->postal_code; } + if ($this->country) { + $str .= '
' . $this->country->name; + } if ($str) { diff --git a/app/models/Contact.php b/app/models/Contact.php index ddcaafa9dfda..4e99109cc4ca 100755 --- a/app/models/Contact.php +++ b/app/models/Contact.php @@ -1,6 +1,6 @@ belongsTo('Client'); } + public function getPersonType() + { + return PERSON_CONTACT; + } + public function getLastLogin() { if ($this->last_login == '0000-00-00 00:00:00') @@ -32,7 +37,7 @@ class Contact extends Eloquent if ($fullName == ' ') { - return 'Guest'; + return ''; } else { diff --git a/app/models/Credit.php b/app/models/Credit.php new file mode 100755 index 000000000000..843e798b85f1 --- /dev/null +++ b/app/models/Credit.php @@ -0,0 +1,26 @@ +belongsTo('Invoice'); + } + + public function getName() + { + return $this->credit_number; + } + + public function getEntityType() + { + return ENTITY_CREDIT; + } +} + +Credit::created(function($credit) +{ + Activity::creaateCredit($credit); +}); \ No newline at end of file diff --git a/app/models/Invoice.php b/app/models/Invoice.php index af3919dc656f..9b45e713871a 100755 --- a/app/models/Invoice.php +++ b/app/models/Invoice.php @@ -1,8 +1,13 @@ belongsTo('Account'); + } public function client() { @@ -19,6 +24,16 @@ class Invoice extends Eloquent return $this->belongsTo('InvoiceStatus'); } + public function getName() + { + return $this->invoice_number; + } + + public function getEntityType() + { + return ENTITY_INVOICE; + } + public function getTotal() { $total = 0; diff --git a/app/models/Payment.php b/app/models/Payment.php index 225bae31eedc..c52bdaea7c9c 100755 --- a/app/models/Payment.php +++ b/app/models/Payment.php @@ -1,6 +1,6 @@ belongsTo('Invoice'); } + + public function getName() + { + return ''; + //return $this->invoice_number; + } + + public function getEntityType() + { + return ENTITY_PAYMENT; + } + } Payment::created(function($payment) diff --git a/app/models/User.php b/app/models/User.php index 48b3d2eafc73..1ce2932917ff 100755 --- a/app/models/User.php +++ b/app/models/User.php @@ -4,10 +4,11 @@ use Illuminate\Auth\UserInterface; use Illuminate\Auth\Reminders\RemindableInterface; use Zizaco\Confide\ConfideUser; -class User extends ConfideUser implements UserInterface, RemindableInterface { +class User extends ConfideUser implements UserInterface, RemindableInterface, iPerson +{ protected $softDelete = true; - + public static $rules = array( /* 'username' => 'required|email|unique:users', @@ -31,12 +32,15 @@ class User extends ConfideUser implements UserInterface, RemindableInterface { */ protected $hidden = array('password'); - public function account() { return $this->belongsTo('Account'); } + public function getPersonType() + { + return PERSON_USER; + } /** * Get the unique identifier for the user. @@ -74,7 +78,7 @@ class User extends ConfideUser implements UserInterface, RemindableInterface { if ($fullName == ' ') { - return "Unknown"; + return "Guest"; } else { diff --git a/app/routes.php b/app/routes.php index 768fad1deaf1..fe72751e658b 100755 --- a/app/routes.php +++ b/app/routes.php @@ -32,27 +32,38 @@ Route::filter('auth', function() Route::group(array('before' => array('auth', 'csrf')), function() { + Route::get('home', function() { return View::make('header'); }); Route::get('account/{section?}', 'AccountController@showSection'); Route::post('account/{section?}', 'AccountController@doSection'); Route::resource('clients', 'ClientController'); Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable')); + Route::get('api/activities/{client_id?}', array('as'=>'api.activities', 'uses'=>'ActivityController@getDatatable')); Route::post('clients/bulk', 'ClientController@bulk'); + Route::get('clients/{client_id}/archive', 'ClientController@archive'); + Route::get('clients/{client_id}/delete', 'ClientController@delete'); Route::resource('invoices', 'InvoiceController'); Route::get('api/invoices/{client_id?}', array('as'=>'api.invoices', 'uses'=>'InvoiceController@getDatatable')); Route::get('invoices/create/{client_id}', 'InvoiceController@create'); Route::post('invoices/bulk', 'InvoiceController@bulk'); + Route::get('invoices/{client_id}/archive', 'InvoiceController@archive'); + Route::get('invoices/{client_id}/delete', 'InvoiceController@delete'); Route::get('payments', 'PaymentController@index'); Route::get('api/payments/{client_id?}', array('as'=>'api.payments', 'uses'=>'PaymentController@getDatatable')); Route::post('payments/bulk', 'PaymentController@bulk'); - - Route::get('home', function() { return View::make('header'); }); - Route::get('reports', function() { return View::make('header'); }); Route::get('payments/create', function() { return View::make('header'); }); + Route::get('payments/{client_id}/archive', 'PaymentController@archive'); + Route::get('payments/{client_id}/delete', 'PaymentController@delete'); - Route::get('api/activities/{client_id?}', array('as'=>'api.activities', 'uses'=>'ActivityController@getDatatable')); + Route::get('credits', 'CreditController@index'); + Route::get('api/credits/{client_id?}', array('as'=>'api.credits', 'uses'=>'CreditController@getDatatable')); + Route::get('credits/create', function() { return View::make('header'); }); + Route::get('credits/{client_id}/archive', 'CreditController@archive'); + Route::get('credits/{client_id}/delete', 'CreditController@delete'); + + Route::get('reports', function() { return View::make('header'); }); }); // Confide routes @@ -164,6 +175,7 @@ function trackViewed($name) if ($object->url == $item->url) { array_splice($viewed, $i, 1); + break; } } @@ -186,6 +198,10 @@ define("RECENTLY_VIEWED", "RECENTLY_VIEWED"); define("ENTITY_CLIENT", "client"); define("ENTITY_INVOICE", "invoice"); define("ENTITY_PAYMENT", "payment"); +define("ENTITY_CREDIT", "credit"); + +define("PERSON_CONTACT", "contact"); +define("PERSON_USER", "user"); define("ACCOUNT_DETAILS", "details"); define("ACCOUNT_SETTINGS", "settings"); @@ -194,5 +210,18 @@ define("ACCOUNT_MAP", "import_map"); define("ACCOUNT_EXPORT", "export"); -define("DEFAULT_INVOICE_NUMBER", "00001"); -define("RECENTLY_VIEWED_LIMIT", 8); \ No newline at end of file +define("DEFAULT_INVOICE_NUMBER", "0001"); +define("RECENTLY_VIEWED_LIMIT", 8); + + +interface iPerson +{ + public function getFullName(); + public function getPersonType(); +} + +interface iEntity +{ + public function getName(); + public function getEntityType(); +} \ No newline at end of file diff --git a/app/views/clients/datatable.blade.php b/app/views/clients/datatable.blade.php new file mode 100755 index 000000000000..dc8f813c2519 --- /dev/null +++ b/app/views/clients/datatable.blade.php @@ -0,0 +1,55 @@ + + + @for ($i = 0; $i < count($columns); $i++) + + @endfor + + + + @foreach($columns as $i => $c) + + @endforeach + + + + @foreach($data as $d) + + @foreach($d as $dd) + + @endforeach + + @endforeach + +
+ @if ($c == 'checkbox' && $haeCheckboxes = true) + + @else + {{ $c }} + @endif +
{{ $dd }}
+ \ No newline at end of file diff --git a/app/views/clients/show.blade.php b/app/views/clients/show.blade.php index 1ddf0c9f330e..6045380b4df9 100755 --- a/app/views/clients/show.blade.php +++ b/app/views/clients/show.blade.php @@ -39,6 +39,7 @@ {{ HTML::tab_link('#activity', 'Activity', true) }} {{ HTML::tab_link('#invoices', 'Invoices') }} {{ HTML::tab_link('#payments', 'Payments') }} + {{ HTML::tab_link('#credits', 'Credits') }}
@@ -46,7 +47,7 @@
{{ Datatable::table() - ->addColumn('Date', 'Message') + ->addColumn('Date', 'Message', 'Balance') ->setUrl(url('api/activities/'. $client->id)) ->setOptions('sPaginationType', 'bootstrap') ->setOptions('bFilter', false) @@ -57,7 +58,7 @@
{{ Datatable::table() - ->addColumn('Invoice Number', 'Amount', 'Date') + ->addColumn('Invoice Number', 'Total', 'Amount Due', 'Invoice Date', 'Due Date', 'Status') ->setUrl(url('api/invoices/' . $client->id)) ->setOptions('sPaginationType', 'bootstrap') ->setOptions('bFilter', false) @@ -66,7 +67,6 @@
- {{ Datatable::table() ->addColumn('Invoice Number', 'Amount', 'Date') ->setUrl(url('api/payments/' . $client->id)) @@ -75,6 +75,16 @@ ->render() }}
+
+ + {{ Datatable::table() + ->addColumn('Credit Number', 'Amount', 'Credit Date') + ->setUrl(url('api/credits/' . $client->id)) + ->setOptions('sPaginationType', 'bootstrap') + ->setOptions('bFilter', false) + ->render() }} + +
@stop @@ -46,13 +58,22 @@ }); $('tbody tr').click(function(event) { - if (event.target.type !== 'checkbox') { + if (event.target.type !== 'checkbox' && event.target.type !== 'button' && event.target.tagName.toLowerCase() !== 'a') { $checkbox = $(this).closest('tr').find(':checkbox'); var checked = $checkbox.prop('checked'); $checkbox.prop('checked', !checked); setArchiveEnabled(); } }); + + $('tbody tr').mouseover(function() { + $(this).closest('tr').find('.tr-action').show(); + }).mouseout(function() { + $dropdown = $(this).closest('tr').find('.tr-action'); + if (!$dropdown.hasClass('open')) { + $dropdown.hide(); + } + }); } $('#archive > button').prop('disabled', true); @@ -69,5 +90,7 @@ var checked = $('tbody :checkbox:checked').length > 0; $('#archive > button').prop('disabled', !checked); } + + @stop \ No newline at end of file diff --git a/app/views/master.blade.php b/app/views/master.blade.php index 28e1fe9ebe78..f6b7922c837d 100755 --- a/app/views/master.blade.php +++ b/app/views/master.blade.php @@ -44,6 +44,7 @@ Invoice Ninja
+ diff --git a/public/js/script.js b/public/js/script.js index 029212347ad6..bbe7c20e5733 100755 --- a/public/js/script.js +++ b/public/js/script.js @@ -28,6 +28,7 @@ function generatePDF(invoice) { doc.addImage(invoice.image, 'JPEG', 30, 30, invoice.imageWidth, invoice.imageHeight); } + /* table header */ doc.setDrawColor(200,200,200); doc.setFillColor(230,230,230); doc.rect(headerLeft - 6, headerTop + rowHeight + 4, headerRight - headerLeft + 12, rowHeight + 2, 'FD'); @@ -59,6 +60,7 @@ function generatePDF(invoice) { doc.text(qtyX, tableTop, 'Quantity'); doc.text(totalX, tableTop, 'Line Total'); + /* line items */ doc.setFontType("normal"); var line = 1; var total = 0; @@ -86,6 +88,7 @@ function generatePDF(invoice) { line += doc.splitTextToSize(item.notes, 200).length; } + /* table footer */ var x = tableTop + (line * rowHeight) + 14; doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x); @@ -100,6 +103,61 @@ function generatePDF(invoice) { totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize()); doc.text(totalX, headerTop + (2 * rowHeight), total); + /* payment stub */ + var y = 680; + doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, y - 30); + doc.setFontSize(20); + doc.text(tableLeft, y, 'Payment Stub'); + + doc.setFontSize(10); + doc.setFontType("normal"); + y += 40; + doc.text(tableLeft, y, invoice.account.name); + y += 16; + doc.text(tableLeft, y, invoice.account.address1); + if (invoice.account.address2) { + y += 16; + doc.text(tableLeft, y, invoice.account.address2); + } + y += 16; + doc.text(tableLeft, y, invoice.account.city + ', ' + invoice.account.state + ' ' + invoice.account.postal_code); + y += 16; + doc.text(tableLeft, y, invoice.account.country.name); + + + var clientX = headerRight - (doc.getStringUnitWidth(invoice.client.name) * doc.internal.getFontSize()); + var numberX = headerRight - (doc.getStringUnitWidth(invoice.invoice_number) * doc.internal.getFontSize()); + var dateX = headerRight - (doc.getStringUnitWidth(issuedOn) * doc.internal.getFontSize()); + var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize()); + + y = 720; + doc.setFontType("bold"); + doc.text(headerLeft, y, 'Client'); + doc.setFontType("normal"); + doc.text(clientX, y, invoice.client.name); + + y += 16; + doc.setFontType("bold"); + doc.text(headerLeft, y, 'Invoice #'); + doc.setFontType("normal"); + doc.text(numberX, y, invoice.invoice_number); + + y += 16; + doc.setFontType("bold"); + doc.text(headerLeft, y, 'Invoice Date'); + doc.setFontType("normal"); + doc.text(dateX, y, issuedOn); + + y += 16; + doc.setFontType("bold"); + doc.text(headerLeft, y, 'Amount Due'); + doc.setFontType("normal"); + doc.text(totalX, y, total); + + y += 16; + doc.setFontType("bold"); + doc.text(headerLeft, y, 'Amount Enclosed'); + return doc; }