1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 20:52:56 +01:00

Improving data model

This commit is contained in:
Hillel Coren 2013-12-03 19:32:33 +02:00
parent 06eb6ad240
commit 2142538e15
28 changed files with 415 additions and 238 deletions

View File

@ -55,3 +55,4 @@ Configure config/database.php and then initialize the database
* [omnipay/omnipay](https://github.com/omnipay/omnipay) - A framework agnostic, multi-gateway payment processing library for PHP 5.3+ * [omnipay/omnipay](https://github.com/omnipay/omnipay) - A framework agnostic, multi-gateway payment processing library for PHP 5.3+
* [Intervention/image](https://github.com/Intervention/image) - PHP Image Manipulation * [Intervention/image](https://github.com/Intervention/image) - PHP Image Manipulation
* [webpatser/laravel-countries](https://github.com/webpatser/laravel-countries) - Almost ISO 3166_2, 3166_3, currency, Capital and more for all countries * [webpatser/laravel-countries](https://github.com/webpatser/laravel-countries) - Almost ISO 3166_2, 3166_3, currency, Capital and more for all countries
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+

View File

@ -10,7 +10,7 @@ class AccountController extends \BaseController {
if ($guestKey) if ($guestKey)
{ {
//$user = User::where('key','=',$guestKey)->firstOrFail(); //$user = User::where('password', '=', $guestKey)->firstOrFail();
$user = User::where('password', '=', $guestKey)->first(); $user = User::where('password', '=', $guestKey)->first();
if ($user && !$user->is_guest) if ($user && !$user->is_guest)
@ -29,10 +29,7 @@ class AccountController extends \BaseController {
$random = str_random(20); $random = str_random(20);
$user = new User; $user = new User;
//$user->username = $random.'@gmail.com'; $user->password = $random;
//$user->password = $random;
//$user->email = $random.'@gmail.com';
//$user->password_confirmation = $random;
$account->users()->save($user); $account->users()->save($user);
} }
@ -46,7 +43,7 @@ class AccountController extends \BaseController {
{ {
if ($section == ACCOUNT_DETAILS) if ($section == ACCOUNT_DETAILS)
{ {
$account = Account::with('users')->find(Auth::user()->account_id); $account = Account::with('users')->findOrFail(Auth::user()->account_id);
$countries = Country::orderBy('name')->get(); $countries = Country::orderBy('name')->get();
$timezones = Timezone::orderBy('location')->get(); $timezones = Timezone::orderBy('location')->get();
@ -54,7 +51,7 @@ class AccountController extends \BaseController {
} }
else if ($section == ACCOUNT_SETTINGS) else if ($section == ACCOUNT_SETTINGS)
{ {
$account = Account::with('account_gateways')->find(Auth::user()->account_id); $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id);
$accountGateway = null; $accountGateway = null;
$config = null; $config = null;
@ -355,7 +352,7 @@ class AccountController extends \BaseController {
if ($gatewayId = Input::get('gateway_id')) if ($gatewayId = Input::get('gateway_id'))
{ {
$gateway = Gateway::find($gatewayId); $gateway = Gateway::findOrFail($gatewayId);
$fields = Omnipay::create($gateway->provider)->getDefaultParameters(); $fields = Omnipay::create($gateway->provider)->getDefaultParameters();
foreach ($fields as $field => $details) foreach ($fields as $field => $details)
@ -377,7 +374,7 @@ class AccountController extends \BaseController {
} }
else else
{ {
$account = Account::find(Auth::user()->account_id); $account = Account::findOrFail(Auth::user()->account_id);
$account->account_gateways()->forceDelete(); $account->account_gateways()->forceDelete();
if ($gatewayId) if ($gatewayId)
@ -417,7 +414,7 @@ class AccountController extends \BaseController {
} }
else else
{ {
$account = Account::find(Auth::user()->account_id); $account = Account::findOrFail(Auth::user()->account_id);
$account->name = Input::get('name'); $account->name = Input::get('name');
$account->address1 = Input::get('address1'); $account->address1 = Input::get('address1');
$account->address2 = Input::get('address2'); $account->address2 = Input::get('address2');
@ -436,7 +433,7 @@ class AccountController extends \BaseController {
$user->save(); $user->save();
if (Input::get('timezone_id')) { if (Input::get('timezone_id')) {
$timezone = Timezone::find(Input::get('timezone_id')); $timezone = Timezone::findOrFail(Input::get('timezone_id'));
Session::put('tz', $timezone->name); Session::put('tz', $timezone->name);
} }
@ -452,4 +449,57 @@ class AccountController extends \BaseController {
return Redirect::to('account/details'); return Redirect::to('account/details');
} }
} }
public function checkEmail()
{
$email = User::where('email', '=', Input::get('email'))->first();
if ($email) {
return "taken";
} else {
return "available";
}
}
public function submitSignup()
{
$rules = array(
'first_name' => 'required',
'last_name' => 'required',
'password' => 'required|min:6',
'email' => 'email|required'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Redirect::to(Input::get('path'));
}
$user = Auth::user();
$user->first_name = Input::get('first_name');
$user->last_name = Input::get('last_name');
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->registered = true;
$user->save();
$activities = Activity::scope()->get();
foreach ($activities as $activity) {
$activity->message = str_replace('Guest', $user->getFullName(), $activity->message);
$activity->save();
}
/*
Mail::send(array('html'=>'emails.welcome_html','text'=>'emails.welcome_text'), $data, function($message) use ($user)
{
$message->from('hillelcoren@gmail.com', 'Hillel Coren');
$message->to($user->email);
});
*/
Session::flash('message', 'Successfully registered');
return Redirect::to(Input::get('path'));
}
} }

View File

@ -4,8 +4,7 @@ class ActivityController extends \BaseController {
public function getDatatable($clientId) public function getDatatable($clientId)
{ {
return Datatable::collection(Activity::where('account_id','=',Auth::user()->account_id) return Datatable::collection(Activity::scope()->where('client_id','=',$clientId)->get())
->where('client_id','=',$clientId)->get())
->addColumn('date', function($model) { return $model->created_at->format('m/d/y h:i a'); }) ->addColumn('date', function($model) { return $model->created_at->format('m/d/y h:i a'); })
->addColumn('message', function($model) { return $model->message; }) ->addColumn('message', function($model) { return $model->message; })
->addColumn('balance', function($model) { return '$' . $model->balance; }) ->addColumn('balance', function($model) { return '$' . $model->balance; })

View File

@ -15,4 +15,8 @@ class BaseController extends Controller {
} }
} }
public function __construct()
{
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
}
} }

View File

@ -20,7 +20,7 @@ class ClientController extends \BaseController {
public function getDatatable() public function getDatatable()
{ {
$clients = Client::with('contacts')->where('account_id','=',Auth::user()->account_id)->get(); $clients = Client::scope()->with('contacts')->get();
return Datatable::collection($clients) return Datatable::collection($clients)
->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->id . '">'; }) ->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->id . '">'; })
@ -38,10 +38,11 @@ class ClientController extends \BaseController {
Select <span class="caret"></span> Select <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li><a href="' . URL::to('clients/'.$model->id.'/edit') . '">Edit</a></li> <li><a href="' . URL::to('invoices/create/'.$model->id) . '">New Invoice</a></li>
<li><a href="' . URL::to('clients/'.$model->id.'/edit') . '">Edit Client</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="' . URL::to('clients/'.$model->id.'/archive') . '">Archive</a></li> <li><a href="' . URL::to('clients/'.$model->id.'/archive') . '">Archive Client</a></li>
<li><a href="javascript:deleteEntity(' . $model->id. ')">Delete</a></li> <li><a href="javascript:deleteEntity(' . $model->id. ')">Delete Client</a></li>
</ul> </ul>
</div>'; </div>';
}) })
@ -84,10 +85,9 @@ class ClientController extends \BaseController {
*/ */
public function show($id) public function show($id)
{ {
$client = Client::with('contacts')->find($id); $client = Client::scope()->with('contacts')->findOrFail($id);
trackViewed($client->name); trackViewed($client->name);
return View::make('clients.show')->with('client', $client); return View::make('clients.show')->with('client', $client);
} }
@ -99,7 +99,7 @@ class ClientController extends \BaseController {
*/ */
public function edit($id) public function edit($id)
{ {
$client = Client::with('contacts')->find($id); $client = Client::scope()->with('contacts')->findOrFail($id);
$data = array( $data = array(
'client' => $client, 'client' => $client,
'method' => 'PUT', 'method' => 'PUT',
@ -133,7 +133,7 @@ class ClientController extends \BaseController {
->withInput(Input::except('password')); ->withInput(Input::except('password'));
} else { } else {
if ($id) { if ($id) {
$client = Client::find($id); $client = Client::scope()->findOrFail($id);
} else { } else {
$client = new Client; $client = new Client;
$client->account_id = Auth::user()->account_id; $client->account_id = Auth::user()->account_id;
@ -159,7 +159,7 @@ class ClientController extends \BaseController {
{ {
if (isset($contact->id) && $contact->id) if (isset($contact->id) && $contact->id)
{ {
$record = Contact::find($contact->id); $record = Contact::findOrFail($contact->id);
} }
else else
{ {
@ -192,8 +192,8 @@ class ClientController extends \BaseController {
public function bulk() public function bulk()
{ {
$action = Input::get('action'); $action = Input::get('action');
$ids = Input::get('ids'); $ids = Input::get('ids') ? Input::get('ids') : [Input::get('id')];
$clients = Client::find($ids); $clients = Client::scope()->findOrFail($ids);
foreach ($clients as $client) { foreach ($clients as $client) {
if ($action == 'archive') { if ($action == 'archive') {
@ -211,7 +211,7 @@ class ClientController extends \BaseController {
public function archive($id) public function archive($id)
{ {
$client = Client::find($id); $client = Client::scope()->findOrFail($id);
$client->delete(); $client->delete();
foreach ($client->invoices as $invoice) foreach ($client->invoices as $invoice)
@ -225,7 +225,7 @@ class ClientController extends \BaseController {
public function delete($id) public function delete($id)
{ {
$client = Client::find($id); $client = Client::scope()->findOrFail($id);
$client->forceDelete(); $client->forceDelete();
Session::flash('message', 'Successfully deleted ' . $client->name); Session::flash('message', 'Successfully deleted ' . $client->name);

View File

@ -17,7 +17,7 @@ class CreditController extends \BaseController {
public function getDatatable($clientId = null) public function getDatatable($clientId = null)
{ {
$collection = Credit::with('client')->where('account_id','=',Auth::user()->account_id); $collection = Credit::scope()->with('client');
if ($clientId) { if ($clientId) {
$collection->where('client_id','=',$clientId); $collection->where('client_id','=',$clientId);
@ -43,7 +43,7 @@ class CreditController extends \BaseController {
public function archive($id) public function archive($id)
{ {
$credit = Credit::find($id); $credit = Credit::scope()->findOrFail($id);
$creidt->delete(); $creidt->delete();
Session::flash('message', 'Successfully archived credit ' . $credit->credit_number); Session::flash('message', 'Successfully archived credit ' . $credit->credit_number);
@ -52,7 +52,7 @@ class CreditController extends \BaseController {
public function delete($id) public function delete($id)
{ {
$credit = Credit::find($id); $credit = Credit::scope()->findOrFail($id);
$credit->forceDelete(); $credit->forceDelete();
Session::flash('message', 'Successfully deleted credit ' . $credit->credit_number); Session::flash('message', 'Successfully deleted credit ' . $credit->credit_number);

View File

@ -17,7 +17,7 @@ class InvoiceController extends \BaseController {
public function getDatatable($clientId = null) public function getDatatable($clientId = null)
{ {
$collection = Invoice::with('client','invoice_items','invoice_status')->where('account_id','=',Auth::user()->account_id); $collection = Invoice::scope()->with('client','invoice_items','invoice_status');
if ($clientId) { if ($clientId) {
$collection->where('client_id','=',$clientId); $collection->where('client_id','=',$clientId);
@ -47,10 +47,10 @@ class InvoiceController extends \BaseController {
Select <span class="caret"></span> Select <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li><a href="' . URL::to('invoices/'.$model->id.'/edit') . '">Edit</a></li> <li><a href="' . URL::to('invoices/'.$model->id.'/edit') . '">Edit Invoice</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="' . URL::to('invoices/'.$model->id.'/archive') . '">Archive</a></li> <li><a href="' . URL::to('invoices/'.$model->id.'/archive') . '">Archive Invoice</a></li>
<li><a href="javascript:deleteEntity(' . $model->id . ')">Delete</a></li> <li><a href="javascript:deleteEntity(' . $model->id . ')">Delete Invoice</a></li>
</ul> </ul>
</div>'; </div>';
}) })
@ -64,13 +64,20 @@ class InvoiceController extends \BaseController {
$invitation = Invitation::with('user', 'invoice.account', 'invoice.invoice_items', 'invoice.client.account.account_gateways')->where('key', '=', $key)->firstOrFail(); $invitation = Invitation::with('user', 'invoice.account', 'invoice.invoice_items', 'invoice.client.account.account_gateways')->where('key', '=', $key)->firstOrFail();
$user = $invitation->user; $user = $invitation->user;
$invoice = $invitation->invoice;
$invitation->viewed_date = Carbon::now()->toDateTimeString(); $now = Carbon::now()->toDateTimeString();
$invitation->viewed_date = $now;
$invitation->save(); $invitation->save();
$client = $invoice->client;
$client->last_login = $now;
$client->save();
Activity::viewInvoice($invitation); Activity::viewInvoice($invitation);
return View::make('invoices.view')->with('invoice', $invitation->invoice); return View::make('invoices.view')->with('invoice', $invoice);
} }
private function createGateway($accountGateway) private function createGateway($accountGateway)
@ -201,7 +208,7 @@ class InvoiceController extends \BaseController {
public function edit($id) public function edit($id)
{ {
$invoice = Invoice::with('account.country', 'client', 'invoice_items')->find($id); $invoice = Invoice::scope()->with('account.country', 'client', 'invoice_items')->findOrFail($id);
trackViewed($invoice->invoice_number . ' - ' . $invoice->client->name); trackViewed($invoice->invoice_number . ' - ' . $invoice->client->name);
$data = array( $data = array(
@ -211,9 +218,9 @@ class InvoiceController extends \BaseController {
'url' => 'invoices/' . $id, 'url' => 'invoices/' . $id,
'title' => 'Edit', 'title' => 'Edit',
'account' => Auth::user()->account, 'account' => Auth::user()->account,
'products' => Product::getProducts()->get(), 'products' => Product::scope()->get(),
'client' => $invoice->client, 'client' => $invoice->client,
'clients' => Client::where('account_id','=',Auth::user()->account_id)->orderBy('name')->get()); 'clients' => Client::scope()->orderBy('name')->get());
return View::make('invoices.edit', $data); return View::make('invoices.edit', $data);
} }
@ -221,7 +228,11 @@ class InvoiceController extends \BaseController {
{ {
$client = null; $client = null;
$invoiceNumber = Auth::user()->account->getNextInvoiceNumber(); $invoiceNumber = Auth::user()->account->getNextInvoiceNumber();
$account = Account::with('country')->find(Auth::user()->account_id); $account = Account::with('country')->findOrFail(Auth::user()->account_id);
if ($clientId) {
$client = Client::scope()->findOrFail($clientId);
}
$data = array( $data = array(
'account' => $account, 'account' => $account,
@ -233,8 +244,8 @@ class InvoiceController extends \BaseController {
'client' => $client, 'client' => $client,
'items' => json_decode(Input::old('items')), 'items' => json_decode(Input::old('items')),
'account' => Auth::user()->account, 'account' => Auth::user()->account,
'products' => Product::getProducts()->get(), 'products' => Product::scope()->get(),
'clients' => Client::where('account_id','=',Auth::user()->account_id)->orderBy('name')->get()); 'clients' => Client::scope()->orderBy('name')->get());
return View::make('invoices.edit', $data); return View::make('invoices.edit', $data);
} }
@ -250,6 +261,17 @@ class InvoiceController extends \BaseController {
private function save($id = null) private function save($id = null)
{ {
$action = Input::get('action');
if ($action == 'archive')
{
return InvoiceController::archive($id);
}
else if ($action == 'delete')
{
return InvoiceController::delete($id);
}
$rules = array( $rules = array(
'client' => 'required', 'client' => 'required',
'invoice_number' => 'required', 'invoice_number' => 'required',
@ -279,12 +301,12 @@ class InvoiceController extends \BaseController {
} }
else else
{ {
$client = Client::with('contacts')->find($clientId); $client = Client::scope()->with('contacts')->findOrFail($clientId);
$contact = $client->contacts()->first(); $contact = $client->contacts()->first();
} }
if ($id) { if ($id) {
$invoice = Invoice::find($id); $invoice = Invoice::scope()->findOrFail($id);
$invoice->invoice_items()->forceDelete(); $invoice->invoice_items()->forceDelete();
} else { } else {
$invoice = new Invoice; $invoice = new Invoice;
@ -310,9 +332,14 @@ class InvoiceController extends \BaseController {
$item->qty = 0; $item->qty = 0;
} }
if (!$item->cost && !$item->qty && !$item->product_key && !$item->notes)
{
continue;
}
if ($item->product_key) if ($item->product_key)
{ {
$product = Product::findProduct($item->product_key); $product = Product::findProductByKey($item->product_key);
if (!$product) if (!$product)
{ {
@ -340,7 +367,7 @@ class InvoiceController extends \BaseController {
$invoice->invoice_items()->save($invoiceItem); $invoice->invoice_items()->save($invoiceItem);
} }
if (Input::get('send_email_checkBox')) if ($action == 'email')
{ {
$data = array('link' => URL::to('view') . '/' . $invoice->invoice_key); $data = array('link' => URL::to('view') . '/' . $invoice->invoice_key);
/* /*
@ -404,7 +431,7 @@ class InvoiceController extends \BaseController {
{ {
$action = Input::get('action'); $action = Input::get('action');
$ids = Input::get('ids'); $ids = Input::get('ids');
$invoices = Invoice::find($ids); $invoices = Invoice::scope()->findOrFail($ids);
foreach ($invoices as $invoice) { foreach ($invoices as $invoice) {
if ($action == 'archive') { if ($action == 'archive') {
@ -422,7 +449,7 @@ class InvoiceController extends \BaseController {
public function archive($id) public function archive($id)
{ {
$invoice = Invoice::find($id); $invoice = Invoice::scope()->findOrFail($id);
$invoice->delete(); $invoice->delete();
Session::flash('message', 'Successfully archived invoice ' . $invoice->invoice_number); Session::flash('message', 'Successfully archived invoice ' . $invoice->invoice_number);
@ -431,7 +458,7 @@ class InvoiceController extends \BaseController {
public function delete($id) public function delete($id)
{ {
$invoice = Invoice::find($id); $invoice = Invoice::scope()->findOrFail($id);
$invoice->forceDelete(); $invoice->forceDelete();
Session::flash('message', 'Successfully deleted invoice ' . $invoice->invoice_number); Session::flash('message', 'Successfully deleted invoice ' . $invoice->invoice_number);

View File

@ -9,7 +9,7 @@ class PaymentController extends \BaseController
public function getDatatable($clientId = null) public function getDatatable($clientId = null)
{ {
$collection = Payment::with('invoice.client')->where('account_id', '=', Auth::user()->account_id); $collection = Payment::scope()->with('invoice.client');
if ($clientId) { if ($clientId) {
$collection->where('client_id','=',$clientId); $collection->where('client_id','=',$clientId);
@ -42,7 +42,7 @@ class PaymentController extends \BaseController
public function archive($id) public function archive($id)
{ {
$payment = Payment::find($id); $payment = Payment::scope()->findOrFail($id);
$payment->delete(); $payment->delete();
Session::flash('message', 'Successfully archived payment'); Session::flash('message', 'Successfully archived payment');
@ -51,7 +51,7 @@ class PaymentController extends \BaseController
public function delete($id) public function delete($id)
{ {
$payment = Payment::find($id); $payment = Payment::scope()->findOrFail($id);
$payment->forceDelete(); $payment->forceDelete();
Session::flash('message', 'Successfully deleted payment'); Session::flash('message', 'Successfully deleted payment');

View File

@ -66,6 +66,7 @@ class ConfideSetupUsersTable extends Migration {
$t->string('ip'); $t->string('ip');
$t->string('logo_path'); $t->string('logo_path');
$t->string('key')->unique(); $t->string('key')->unique();
$t->timestamp('last_login');
$t->string('address1'); $t->string('address1');
$t->string('address2'); $t->string('address2');
@ -115,7 +116,7 @@ class ConfideSetupUsersTable extends Migration {
$t->string('last_name'); $t->string('last_name');
$t->string('phone'); $t->string('phone');
$t->string('username'); $t->string('username');
$t->string('email')->unique(); $t->string('email');
$t->string('password'); $t->string('password');
$t->string('confirmation_code'); $t->string('confirmation_code');
$t->boolean('registered')->default(false); $t->boolean('registered')->default(false);
@ -149,6 +150,7 @@ class ConfideSetupUsersTable extends Migration {
$t->string('work_phone'); $t->string('work_phone');
$t->text('notes'); $t->text('notes');
$t->decimal('balance', 10, 2); $t->decimal('balance', 10, 2);
$t->timestamp('last_login');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('country_id')->references('id')->on('countries'); $t->foreign('country_id')->references('id')->on('countries');

View File

@ -73,23 +73,8 @@ Route::filter('guest', function()
Route::filter('csrf', function() Route::filter('csrf', function()
{ {
if (!Input::get('_token')) $token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
{ if (Session::token() != $token) {
return;
}
$tokenInput = Input::get('_token');
$tokenSession = Session::token();
/*
if ($url = Session::get($tokenInput))
{
return Redirect::to($url);
}
*/
if ($tokenSession != $tokenInput)
{
throw new Illuminate\Session\TokenMismatchException; throw new Illuminate\Session\TokenMismatchException;
} }
}); });

View File

@ -18,6 +18,11 @@ define("ACTIVITY_TYPE_DELETE_CREDIT", 14);
class Activity extends Eloquent class Activity extends Eloquent
{ {
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
private static function getBlank() private static function getBlank()
{ {
$user = Auth::user(); $user = Auth::user();

View File

@ -14,6 +14,11 @@ class Client extends Eloquent implements iEntity
public static $fieldNotes = 'Client - Notes'; public static $fieldNotes = 'Client - Notes';
public static $fieldCountry = 'Client - Country'; public static $fieldCountry = 'Client - Country';
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
public function account() public function account()
{ {
return $this->belongsTo('Account'); return $this->belongsTo('Account');

View File

@ -4,6 +4,11 @@ class Credit extends Eloquent implements iEntity
{ {
protected $softDelete = true; protected $softDelete = true;
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
public function invoice() public function invoice()
{ {
return $this->belongsTo('Invoice'); return $this->belongsTo('Invoice');

View File

@ -4,6 +4,11 @@ class Invitation extends Eloquent
{ {
protected $softDelete = true; protected $softDelete = true;
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
public function invoice() public function invoice()
{ {
return $this->belongsTo('Invoice'); return $this->belongsTo('Invoice');

View File

@ -4,6 +4,11 @@ class Invoice extends Eloquent implements iEntity
{ {
protected $softDelete = true; protected $softDelete = true;
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
public function account() public function account()
{ {
return $this->belongsTo('Account'); return $this->belongsTo('Account');

View File

@ -4,6 +4,11 @@ class Payment extends Eloquent implements iEntity
{ {
protected $softDelete = true; protected $softDelete = true;
public function scopeScope($query)
{
return $query->whereAccountId(Auth::user()->account_id);
}
public function invoice() public function invoice()
{ {
return $this->belongsTo('Invoice'); return $this->belongsTo('Invoice');

View File

@ -4,14 +4,14 @@ class Product extends Eloquent
{ {
protected $softDelete = true; protected $softDelete = true;
public static function getProducts() public function scopeScope($query)
{ {
return Product::where('account_id','=',Auth::user()->account_id); return $query->whereAccountId(Auth::user()->account_id);
} }
public static function findProduct($key) public static function findProductByKey($key)
{ {
return Product::getProducts()->where('key','=',$key)->first(); return Product::scope()->where('key','=',$key)->first();
} }
public static function getProductKeys($products) public static function getProductKeys($products)

View File

@ -30,12 +30,13 @@ Route::filter('auth', function()
} }
}); });
Route::group(array('before' => array('auth', 'csrf')), function() Route::group(array('before' => 'auth'), function()
{ {
Route::get('home', function() { return View::make('header'); }); Route::get('home', function() { return View::make('header'); });
Route::get('account/{section?}', 'AccountController@showSection'); Route::get('account/{section?}', 'AccountController@showSection');
Route::post('account/{section?}', 'AccountController@doSection'); Route::post('account/{section?}', 'AccountController@doSection');
Route::post('signup/validate', 'AccountController@checkEmail');
Route::post('signup/submit', 'AccountController@submitSignup');
Route::resource('clients', 'ClientController'); Route::resource('clients', 'ClientController');
Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable')); Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable'));
@ -127,7 +128,16 @@ function toSpaceCase($camelStr)
return preg_replace('/([a-z])([A-Z])/s','$1 $2', $camelStr); return preg_replace('/([a-z])([A-Z])/s','$1 $2', $camelStr);
} }
/* function timestampToDateTimeString($timestamp) {
$tz = Session::get('tz');
if (!$tz) {
$tz = 'US/Eastern';
}
$date = new Carbon($timestamp);
$date->tz = $tz;
return $date->toDayDateTimeString();
}
function toDateString($date) function toDateString($date)
{ {
if ($date->year < 1900) { if ($date->year < 1900) {
@ -140,7 +150,7 @@ function toDateString($date)
$date->tz = $tz; $date->tz = $tz;
return $date->toFormattedDateString(); return $date->toFormattedDateString();
} }
*/
function toDateTimeString($date) function toDateTimeString($date)
{ {

View File

@ -1,14 +0,0 @@
@extends('header')
@section('content')
{{ Button::primary_link(URL::to('clients/create'), 'New Client', array('class' => 'pull-right')) }}
{{ Datatable::table()
->addColumn('Client', 'Contact', 'Balance', 'Last Login', 'Date Created', 'Email', 'Phone')
->setUrl(route('api.clients'))
->setOptions('sPaginationType', 'bootstrap')
->setOptions('bFilter', false)
->render() }}
@stop

View File

@ -4,11 +4,33 @@
<div class="pull-right"> <div class="pull-right">
{{ Button::link(URL::to('clients/' . $client->id . '/edit'), 'Edit Client') }} {{ Former::open('clients/bulk')->addClass('mainForm') }}
<div style="display:none">
{{ Former::text('action') }}
{{ Former::text('id')->value($client->id) }}
</div>
{{ DropdownButton::normal('Edit Client',
Navigation::links(
array(
array('Edit Client', URL::to('clients/' . $client->id . '/edit')),
array(Navigation::DIVIDER),
array('Archive Client', "javascript:onArchiveClick()"),
array('Delete Client', "javascript:onDeleteClick()"),
)
)
, array('id'=>'actionDropDown'))->split(); }}
{{ Button::primary_link(URL::to('invoices/create/' . $client->id), 'Create Invoice') }} {{ Button::primary_link(URL::to('invoices/create/' . $client->id), 'Create Invoice') }}
{{ Former::close() }}
</div> </div>
<h2>{{ $client->name }}</h2> <h2>{{ $client->name }}</h2>
@if ($client->last_login > 0)
<h3 style="margin-top:0px"><small>
Last logged in {{ timestampToDateTimeString($client->last_login); }}
</small></h3>
@endif
<div class="row"> <div class="row">
@ -90,9 +112,23 @@
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
$('#actionDropDown > button:first').click(function() {
window.location = '{{ URL::to('clients/' . $client->id . '/edit') }}';
});
}); });
function onArchiveClick() {
$('#action').val('archive');
$('.mainForm').submit();
}
function onDeleteClick() {
if (confirm('Are you sure you want to delete this client?')) {
$('#action').val('delete');
$('.mainForm').submit();
}
}
</script> </script>
@stop @stop

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Welcome</h2>
</body>
</html>

View File

@ -0,0 +1 @@
Welcome

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<meta name="csrf-token" content="<?= csrf_token() ?>">
<title>Invoice Ninja</title> <title>Invoice Ninja</title>
@ -54,7 +55,7 @@
body > div.container { body > div.container {
/*max-width: 850px;*/ min-height: 600px;
} }
label.control-label { label.control-label {
@ -62,6 +63,7 @@
} }
div.panel { div.panel {
padding-left: 0px !important; padding-left: 0px !important;
padding-right: 0px !important; padding-right: 0px !important;
@ -228,18 +230,29 @@
@endif @endif
<div class="container"> <div class="container">
<p/> <p/>
<div> <div>
<span style="font-size:30px">Invoice Ninja</span> <span style="font-size:30px">Invoice Ninja</span>
<div style="float:right;text-align:right"> <div style="float:right">
@if (Auth::user()->registered) @if (Auth::user()->registered)
{{ Auth::user()->email }} &nbsp;
@else @else
{{ Button::sm_primary('Sign up', array('data-toggle'=>'modal', 'data-target'=>'#signUpModal')); }} &nbsp; {{ Button::sm_primary('Sign up', array('data-toggle'=>'modal', 'data-target'=>'#signUpModal')); }}
{{ link_to('account/details', 'My Account'); }}
@endif @endif
<p class="text-danger">This is a sample site, the data is erased.</p>
<div class="btn-group">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
My Account <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>{{ link_to('account/details', 'Details'); }}</li>
<li>{{ link_to('account/settings', 'Settings'); }}</li>
<li>{{ link_to('account/import', 'Import'); }}</li>
<li>{{ link_to('account/export', 'Export'); }}</li>
<li class="divider"></li>
<li><a href="#">Logout</a></li>
</ul>
</div>
</div> </div>
</div> </div>
@ -293,6 +306,13 @@
@yield('content') @yield('content')
</div>
<div class="container">
<div class="footer">
Powered by {{ link_to('https://github.com/hillelcoren/invoice-ninja', 'InvoiceNinja', array('target'=>'_blank')) }}
<p class="text-danger">This is a demo site, the data is erased.</p>
</div>
</div> </div>
</div> </div>
@ -303,20 +323,29 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Sign Up</h4> <h4 class="modal-title" id="myModalLabel">Sign up</h4>
</div> </div>
<div style="padding-right:20px" onkeyup="validateSignUp()" onkeydown="checkForEnter(event)"> <div style="padding-right:20px" id="signUpDiv" onkeyup="validateSignUp()" onkeydown="checkForEnter(event)">
{{ Former::open(); }} {{ Former::open('signup/submit')->addClass('signUpForm') }}
{{ Former::populate(Auth::user()) }} {{ Former::populate(Auth::user()) }}
{{ Former::text('first_name'); }} {{ Former::hidden('path')->value(Request::path()) }}
{{ Former::text('last_name'); }} {{ Former::text('first_name') }}
{{ Former::text('email'); }} {{ Former::text('last_name') }}
{{ Former::password('password'); }} {{ Former::text('email') }}
{{ Former::close(); }} {{ Former::password('password') }}
{{ Former::close() }}
<center><div id="errorTaken" style="display:none">&nbsp;<br/>The email address is already regiestered</div></center>
</div> </div>
<div class="modal-footer"> <div style="padding-left:40px;padding-right:40px;display:none;min-height:130px" id="working">
<h3>Working...</h3>
<div class="progress progress-striped active">
<div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
</div>
<div class="modal-footer" id="signUpFooter">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="submitSignUp()">Save</button> <button type="button" class="btn btn-primary" onclick="submitSignUp()">Save</button>
</div> </div>
@ -334,26 +363,25 @@
@if (!Auth::user()->registered) @if (!Auth::user()->registered)
function validateSignUp(showError) function validateSignUp(showError)
{ {
var isValid = true; var isFormValid = true;
$(['first_name','last_name','email','password']).each(function(i, field) { $(['first_name','last_name','email','password']).each(function(i, field) {
var $input = $('#'+field), var $input = $('form.signUpForm #'+field),
val = $.trim($input.val()); val = $.trim($input.val());
var isValid = val && val.length > (field == 'password' ? 6 : 0); var isValid = val && val.length >= (field == 'password' ? 6 : 1);
if (isValid && field == 'email') { if (isValid && field == 'email') {
isValid = isValidEmailAddress(val); isValid = isValidEmailAddress(val);
} }
if (isValid) { if (isValid) {
$input.closest('div.form-group').removeClass('has-error'); $input.closest('div.form-group').removeClass('has-error').addClass('has-success');
$input.closest('div.form-group').addClass('has-success');
} else { } else {
isValid = false; isFormValid = false;
$input.closest('div.form-group').removeClass('has-success'); $input.closest('div.form-group').removeClass('has-success');
if (showError) { if (showError) {
$input.closest('div.form-group').addClass('has-error'); $input.closest('div.form-group').addClass('has-error');
} }
} }
}); });
return isValid; return isFormValid;
} }
function submitSignUp() function submitSignUp()
@ -361,6 +389,26 @@
if (!validateSignUp(true)) { if (!validateSignUp(true)) {
return; return;
} }
$('#signUpDiv, #signUpFooter').hide();
$('#working').show();
$.ajax({
type: 'POST',
url: '{{ URL::to('signup/validate') }}',
data: 'email=' + $('form.signUpForm #email').val() + '&path={{ Request::path() }}',
success: function(result) {
console.log(result)
if (result == 'available') {
$('.signUpForm').submit();
} else {
$('#errorTaken').show();
$('form.signUpForm #email').closest('div.form-group').removeClass('has-success').addClass('has-error');
$('#signUpDiv, #signUpFooter').show();
$('#working').hide();
}
}
});
} }
function checkForEnter(event) function checkForEnter(event)
@ -383,11 +431,21 @@
@if (!Auth::user()->registered) @if (!Auth::user()->registered)
validateSignUp(); validateSignUp();
$('#signUpModal').on('shown.bs.modal', function () {
$(['first_name','last_name','email','password']).each(function(i, field) {
var $input = $('form.signUpForm #'+field);
if (!$input.val()) {
console.log('focus: %s', field);
$input.focus();
return false;
}
});
})
@endif @endif
@yield('onReady') @yield('onReady')
}); });
</script> </script>
</html> </html>

View File

@ -4,6 +4,7 @@
<p>&nbsp;</p> <p>&nbsp;</p>
{{ Former::open($url)->method($method)->addClass('main_form')->rules(array( {{ Former::open($url)->method($method)->addClass('main_form')->rules(array(
'invoice_number' => 'required', 'invoice_number' => 'required',
'invoice_date' => 'required', 'invoice_date' => 'required',
@ -111,13 +112,26 @@
</tfoot> </tfoot>
</table> </table>
<input type="checkbox" name="send_email_checkBox" id="send_email_checkBox" value="true" style="display:none"/>
<p>&nbsp;</p> <p>&nbsp;</p>
<div class="form-actions"> <div class="form-actions">
{{ Button::primary('Download PDF', array('onclick' => 'onDownloadClick()')) }}
{{ Button::primary_submit('Save Invoice', array('onclick' => 'onSaveClick()')) }} @if ($invoice)
<div style="display:none">{{ Former::text('action') }}</div>
{{ DropdownButton::normal('Download PDF',
Navigation::links(
array(
array('Download PDF', "javascript:onDownloadClick()"),
array(Navigation::DIVIDER),
array('Archive Invoice', "javascript:onArchiveClick()"),
array('Delete Invoice', "javascript:onDeleteClick()"),
)
)
, array('id'=>'actionDropDown','style'=>'text-align:left'))->split(); }}
@else
{{ Button::normal('Download PDF', array('onclick' => 'onDownloadClick()')) }}
@endif
{{ Button::primary('Save Invoice', array('onclick' => 'onSaveClick()')) }}
{{ Button::primary('Send Email', array('onclick' => 'onEmailClick()')) }} {{ Button::primary('Send Email', array('onclick' => 'onEmailClick()')) }}
</div> </div>
<p>&nbsp;</p> <p>&nbsp;</p>
@ -160,8 +174,6 @@
{{ Former::close() }} {{ Former::close() }}
<script type="text/javascript"> <script type="text/javascript">
/* /*
@ -194,8 +206,31 @@
$input.combobox(); $input.combobox();
$('.combobox-container input.form-control').attr('name', 'client_combobox').on('change', function(e) { $('.combobox-container input.form-control').attr('name', 'client_combobox').on('change', function(e) {
refreshPDF(); refreshPDF();
}).mouseleave(function() {
$(this).css('text-decoration','none');
}).on('change keyup mouseenter', function(e) {
if ($(this).closest('.combobox-container').hasClass('combobox-selected')) {
$(this).css('text-decoration','underline');
$(this).css('cursor','pointer');
} else {
$(this).css('text-decoration','none');
$(this).css('cursor','text');
}
}).on('focusout mouseleave', function(e) {
$(this).css('text-decoration','none');
$(this).css('cursor','text');
}).on('click', function() {
var clientId = $('.combobox-container input[name=client]').val();
if ($(this).closest('.combobox-container').hasClass('combobox-selected')) {
if (parseInt(clientId) > 0) {
window.open('{{ URL::to('clients') }}' + '/' + clientId, '_blank');
} else {
$('#myModal').modal('show');
}
};
}); });
@if ($client) @if ($client)
$('input#invoice_number').focus(); $('input#invoice_number').focus();
@else @else
@ -214,6 +249,11 @@
$('#invoice_number').change(refreshPDF); $('#invoice_number').change(refreshPDF);
$('#actionDropDown > button:first').click(function() {
onDownloadClick();
});
applyComboboxListeners(); applyComboboxListeners();
refreshPDF(); refreshPDF();
}); });
@ -298,7 +338,7 @@
function onEmailClick() { function onEmailClick() {
if (confirm('Are you sure you want to email this invoice?')) { if (confirm('Are you sure you want to email this invoice?')) {
$('#send_email_checkBox').prop("checked",true); $('#action').val('email');
$('.main_form').submit(); $('.main_form').submit();
} }
} }
@ -307,6 +347,18 @@
$('.main_form').submit(); $('.main_form').submit();
} }
function onArchiveClick() {
$('#action').val('archive');
$('.main_form').submit();
}
function onDeleteClick() {
if (confirm('Are you sure you want to delete this invoice?')) {
$('#action').val('delete');
$('.main_form').submit();
}
}
function newClient() { function newClient() {
var name = $('#client_name').val(); var name = $('#client_name').val();
var email = $('#client_email').val(); var email = $('#client_email').val();
@ -361,20 +413,11 @@
item.qty("{{ $item->qty }}"); item.qty("{{ $item->qty }}");
self.items.push(item); self.items.push(item);
@endforeach @endforeach
@else
self.items.push(new ItemModel());
@endif @endif
@else
var model1 = new ItemModel();
/*
model1.item('TEST');
model1.notes('Some test text');
model1.cost(10);
model1.qty(1);
*/
self.items.push(model1);
@endif @endif
self.items.push(new ItemModel());
self.removeItem = function(item) { self.removeItem = function(item) {
self.items.remove(item); self.items.remove(item);
refreshPDF(); refreshPDF();

View File

@ -1,71 +0,0 @@
@extends('header')
@section('content')
{{ Former::open('invoices/action') }}
<div style="display:none">{{ Former::text('action') }}</div>
{{ DropdownButton::normal('Archive',
Navigation::links(
array(
array('Archive', "javascript:submitForm('archive')"),
array('Delete', "javascript:submitForm('delete')"),
)
)
, array('id'=>'archive'))->split(); }}
{{ Button::primary_link(URL::to('invoices/create'), 'New Invoice', array('class' => 'pull-right')) }}
{{ Datatable::table()
->addColumn('checkbox', 'Invoice Number', 'Client', 'Total', 'Amount Due', 'Invoice Date', 'Due Date', 'Status')
->setUrl(route('api.invoices'))
->setOptions('sPaginationType', 'bootstrap')
->setOptions('bFilter', false)
->render('datatable') }}
{{ Former::close() }}
<script type="text/javascript">
function submitForm(action) {
$('#action').val(action);
$('form').submit();
}
</script>
@stop
@section('onReady')
window.onDatatableReady = function() {
$(':checkbox').click(function() {
setArchiveEnabled();
});
$('tbody tr').click(function() {
$checkbox = $(this).closest('tr').find(':checkbox');
var checked = $checkbox.prop('checked');
$checkbox.prop('checked', !checked);
setArchiveEnabled();
});
}
$('#archive > button').prop('disabled', true);
$('#archive > button:first').click(function() {
submitForm('archive');
});
$('#selectAll').click(function() {
$(':checkbox').prop('checked', this.checked);
});
function setArchiveEnabled() {
var checked = $('tbody :checkbox:checked').length > 0;
$('#archive > button').prop('disabled', !checked);
}
@stop

View File

@ -2,7 +2,7 @@
@section('content') @section('content')
{{ Former::open($entityType . 's/bulk') }} {{ Former::open($entityType . 's/bulk')->addClass('listForm') }}
<div style="display:none">{{ Former::text('action') }}</div> <div style="display:none">{{ Former::text('action') }}</div>
{{ DropdownButton::normal('Archive', {{ DropdownButton::normal('Archive',
@ -37,7 +37,7 @@
} }
} }
$('#action').val(action); $('#action').val(action);
$('form').submit(); $('form.listForm').submit();
} }
function deleteEntity(id) { function deleteEntity(id) {

View File

@ -1,12 +0,0 @@
@extends('header')
@section('content')
{{ Datatable::table()
->addColumn('Client', 'Invoice', 'Amount', 'Date')
->setUrl(route('api.payments'))
->setOptions('sPaginationType', 'bootstrap')
->setOptions('bFilter', false)
->render() }}
@stop

View File

@ -64,11 +64,20 @@ function generatePDF(invoice) {
doc.setFontType("normal"); doc.setFontType("normal");
var line = 1; var line = 1;
var total = 0; var total = 0;
var shownItem = false;
for(var i=0; i<invoice.invoice_items.length; i++) { for(var i=0; i<invoice.invoice_items.length; i++) {
var item = invoice.invoice_items[i]; var item = invoice.invoice_items[i];
var cost = formatNumber(item.cost); var cost = formatNumber(item.cost);
var qty = item.qty ? parseInt(item.qty, 10) + '' : ''; var qty = item.qty ? parseInt(item.qty, 10) + '' : '';
var notes = item.notes;
var productKey = item.product_key;
// show at most one blank line
if (shownItem && !cost && !qty && !notes && !productKey) {
continue;
}
shownItem = true;
var lineTotal = item.cost * item.qty; var lineTotal = item.cost * item.qty;
if (lineTotal) total += lineTotal; if (lineTotal) total += lineTotal;
@ -79,8 +88,8 @@ function generatePDF(invoice) {
var totalX = lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize()); var totalX = lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
var x = tableTop + (line * rowHeight) + 6; var x = tableTop + (line * rowHeight) + 6;
doc.text(tableLeft, x, item.product_key); doc.text(tableLeft, x, productKey);
doc.text(descriptionLeft, x, item.notes); doc.text(descriptionLeft, x, notes);
doc.text(costX, x, cost); doc.text(costX, x, cost);
doc.text(qtyX, x, qty); doc.text(qtyX, x, qty);
doc.text(totalX, x, lineTotal); doc.text(totalX, x, lineTotal);
@ -89,7 +98,7 @@ function generatePDF(invoice) {
} }
/* table footer */ /* table footer */
var x = tableTop + (line * rowHeight) + 14; var x = tableTop + (line * rowHeight);
doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x); doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x);
x += 16; x += 16;
@ -362,3 +371,12 @@ function isValidEmailAddress(emailAddress) {
var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i); var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
return pattern.test(emailAddress); return pattern.test(emailAddress);
}; };
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
});