mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Starting to work on reports
This commit is contained in:
parent
19abec6f09
commit
374e34e733
@ -57,3 +57,4 @@ Configure config/database.php and then initialize the database
|
|||||||
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+
|
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+
|
||||||
* [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap
|
* [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap
|
||||||
* [mozilla/pdf.js)](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
* [mozilla/pdf.js)](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
||||||
|
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
@ -40,7 +40,7 @@ class AccountController extends \BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Auth::login($user, true);
|
Auth::login($user, true);
|
||||||
Session::put('tz', 'US/Eastern');
|
Event::fire('user.login');
|
||||||
|
|
||||||
return Redirect::to('invoices/create');
|
return Redirect::to('invoices/create');
|
||||||
}
|
}
|
||||||
@ -51,9 +51,8 @@ class AccountController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$account = Account::with('users')->findOrFail(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();
|
|
||||||
|
|
||||||
return View::make('accounts.details', array('account'=>$account, 'countries'=>$countries, 'timezones'=>$timezones));
|
return View::make('accounts.details', array('account'=>$account, 'countries'=>$countries));
|
||||||
}
|
}
|
||||||
else if ($section == ACCOUNT_SETTINGS)
|
else if ($section == ACCOUNT_SETTINGS)
|
||||||
{
|
{
|
||||||
@ -71,7 +70,10 @@ class AccountController extends \BaseController {
|
|||||||
'account' => $account,
|
'account' => $account,
|
||||||
'accountGateway' => $accountGateway,
|
'accountGateway' => $accountGateway,
|
||||||
'config' => json_decode($config),
|
'config' => json_decode($config),
|
||||||
'gateways' => Gateway::all()
|
'gateways' => Gateway::all(),
|
||||||
|
'timezones' => Timezone::orderBy('location')->get(),
|
||||||
|
'dateFormats' => DateFormat::all(),
|
||||||
|
'datetimeFormats' => DatetimeFormat::all(),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($data['gateways'] as $gateway)
|
foreach ($data['gateways'] as $gateway)
|
||||||
@ -383,6 +385,12 @@ class AccountController extends \BaseController {
|
|||||||
$account = Account::findOrFail(Auth::user()->account_id);
|
$account = Account::findOrFail(Auth::user()->account_id);
|
||||||
$account->account_gateways()->forceDelete();
|
$account->account_gateways()->forceDelete();
|
||||||
|
|
||||||
|
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
||||||
|
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
|
||||||
|
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
|
||||||
|
|
||||||
|
Event::fire('user.refresh');
|
||||||
|
|
||||||
$account->invoice_terms = Input::get('invoice_terms');
|
$account->invoice_terms = Input::get('invoice_terms');
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
@ -431,7 +439,6 @@ class AccountController extends \BaseController {
|
|||||||
$account->state = trim(Input::get('state'));
|
$account->state = trim(Input::get('state'));
|
||||||
$account->postal_code = trim(Input::get('postal_code'));
|
$account->postal_code = trim(Input::get('postal_code'));
|
||||||
$account->country_id = Input::get('country_id') ? Input::get('country_id') : null;
|
$account->country_id = Input::get('country_id') ? Input::get('country_id') : null;
|
||||||
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
$user = $account->users()->first();
|
$user = $account->users()->first();
|
||||||
|
@ -179,11 +179,12 @@ class ClientController extends \BaseController {
|
|||||||
$client->address2 = trim(Input::get('address2'));
|
$client->address2 = trim(Input::get('address2'));
|
||||||
$client->city = trim(Input::get('city'));
|
$client->city = trim(Input::get('city'));
|
||||||
$client->state = trim(Input::get('state'));
|
$client->state = trim(Input::get('state'));
|
||||||
$client->notes = trim(Input::get('notes'));
|
|
||||||
$client->postal_code = trim(Input::get('postal_code'));
|
$client->postal_code = trim(Input::get('postal_code'));
|
||||||
$client->country_id = Input::get('country_id') ? Input::get('country_id') : null;
|
$client->country_id = Input::get('country_id') ? Input::get('country_id') : null;
|
||||||
|
$client->notes = trim(Input::get('notes'));
|
||||||
$client->client_size_id = Input::get('client_size_id') ? Input::get('client_size_id') : null;
|
$client->client_size_id = Input::get('client_size_id') ? Input::get('client_size_id') : null;
|
||||||
$client->client_industry_id = Input::get('client_industry_id') ? Input::get('client_industry_id') : null;
|
$client->client_industry_id = Input::get('client_industry_id') ? Input::get('client_industry_id') : null;
|
||||||
|
$client->website = trim(Input::get('website'));
|
||||||
|
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
@ -239,14 +240,14 @@ class ClientController extends \BaseController {
|
|||||||
$clients = Client::scope($ids)->get();
|
$clients = Client::scope($ids)->get();
|
||||||
|
|
||||||
foreach ($clients as $client) {
|
foreach ($clients as $client) {
|
||||||
if ($action == 'archive') {
|
if ($action == 'delete') {
|
||||||
$client->delete();
|
$client->is_deleted = true;
|
||||||
} else if ($action == 'delete') {
|
$client->save();
|
||||||
$client->forceDelete();
|
|
||||||
}
|
}
|
||||||
|
$client->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = Utils::pluralize('Successfully '.$action.'d ? client', count($ids));
|
$message = Utils::pluralize('Successfully '.$action.'d ? client', count($clients));
|
||||||
Session::flash('message', $message);
|
Session::flash('message', $message);
|
||||||
|
|
||||||
return Redirect::to('clients');
|
return Redirect::to('clients');
|
||||||
|
@ -22,6 +22,7 @@ class CreditController extends \BaseController {
|
|||||||
->join('clients', 'clients.id', '=','credits.client_id')
|
->join('clients', 'clients.id', '=','credits.client_id')
|
||||||
->where('clients.account_id', '=', Auth::user()->account_id)
|
->where('clients.account_id', '=', Auth::user()->account_id)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
|
->where('credits.deleted_at', '=', null)
|
||||||
->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.credit_date');
|
->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.credit_date');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
@ -55,7 +56,7 @@ class CreditController extends \BaseController {
|
|||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('credits/'.$model->public_id.'/edit') . '">Edit Credit</a></li>
|
<li><a href="' . URL::to('credits/'.$model->public_id.'/edit') . '">Edit Credit</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="' . URL::to('credits/'.$model->public_id.'/archive') . '">Archive Credit</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">Archive Credit</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Credit</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Credit</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
@ -65,7 +66,7 @@ class CreditController extends \BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function create($clientPublicId)
|
public function create($clientPublicId = null)
|
||||||
{
|
{
|
||||||
$client = null;
|
$client = null;
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
@ -144,14 +145,14 @@ class CreditController extends \BaseController {
|
|||||||
$credits = Credit::scope($ids)->get();
|
$credits = Credit::scope($ids)->get();
|
||||||
|
|
||||||
foreach ($credits as $credit) {
|
foreach ($credits as $credit) {
|
||||||
if ($action == 'archive') {
|
if ($action == 'delete') {
|
||||||
$credit->delete();
|
$credit->is_deleted = true;
|
||||||
} else if ($action == 'delete') {
|
$credit->save();
|
||||||
$credit->forceDelete();
|
|
||||||
}
|
}
|
||||||
|
$credit->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = Utils::pluralize('Successfully '.$action.'d ? credit', count($ids));
|
$message = Utils::pluralize('Successfully '.$action.'d ? credit', count($credits));
|
||||||
Session::flash('message', $message);
|
Session::flash('message', $message);
|
||||||
|
|
||||||
return Redirect::to('credits');
|
return Redirect::to('credits');
|
||||||
|
@ -37,6 +37,7 @@ class InvoiceController extends \BaseController {
|
|||||||
->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id')
|
->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id')
|
||||||
->where('invoices.account_id', '=', Auth::user()->account_id)
|
->where('invoices.account_id', '=', Auth::user()->account_id)
|
||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', false)
|
->where('invoices.is_recurring', '=', false)
|
||||||
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'total', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name');
|
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'total', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name');
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ class InvoiceController extends \BaseController {
|
|||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/archive') . '">Archive Invoice</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">Archive Invoice</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
@ -138,7 +139,7 @@ class InvoiceController extends \BaseController {
|
|||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/archive') . '">Archive Invoice</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">Archive Invoice</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
@ -150,12 +151,22 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
public function view($invitationKey)
|
public function view($invitationKey)
|
||||||
{
|
{
|
||||||
$invitation = Invitation::with('user', 'invoice.account', 'invoice.invoice_items', 'invoice.client.account.account_gateways')
|
$invitation = Invitation::with('user', 'invoice.account', 'invoice.client', 'invoice.invoice_items', 'invoice.client.account.account_gateways')
|
||||||
->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
|
|
||||||
$user = $invitation->user;
|
$user = $invitation->user;
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
|
if (!$invoice || $invoice->is_deleted) {
|
||||||
|
return View::make('invoices.deleted');
|
||||||
|
}
|
||||||
|
|
||||||
|
$client = $invoice->client;
|
||||||
|
|
||||||
|
if (!$client || $client->is_deleted) {
|
||||||
|
return View::make('invoices.deleted');
|
||||||
|
}
|
||||||
|
|
||||||
if ($invoice->invoice_status_id < INVOICE_STATUS_VIEWED) {
|
if ($invoice->invoice_status_id < INVOICE_STATUS_VIEWED) {
|
||||||
$invoice->invoice_status_id = INVOICE_STATUS_VIEWED;
|
$invoice->invoice_status_id = INVOICE_STATUS_VIEWED;
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
@ -438,6 +449,10 @@ class InvoiceController extends \BaseController {
|
|||||||
$client->state = trim($inputClient->state);
|
$client->state = trim($inputClient->state);
|
||||||
$client->postal_code = trim($inputClient->postal_code);
|
$client->postal_code = trim($inputClient->postal_code);
|
||||||
$client->country_id = $inputClient->country_id ? $inputClient->country_id : null;
|
$client->country_id = $inputClient->country_id ? $inputClient->country_id : null;
|
||||||
|
$client->notes = trim($inputClient->notes);
|
||||||
|
$client->client_size_id = $inputClient->client_size_id ? $inputClient->client_size_id : null;
|
||||||
|
$client->client_industry_id = $inputClient->client_industry_id ? $inputClient->client_industry_id : null;
|
||||||
|
$client->website = trim($inputClient->website);
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
$isPrimary = true;
|
$isPrimary = true;
|
||||||
@ -498,7 +513,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$invoice->frequency_id = $input->frequency_id ? $input->frequency_id : 0;
|
$invoice->frequency_id = $input->frequency_id ? $input->frequency_id : 0;
|
||||||
$invoice->start_date = Utils::toSqlDate($input->start_date);
|
$invoice->start_date = Utils::toSqlDate($input->start_date);
|
||||||
$invoice->end_date = Utils::toSqlDate($input->end_date);
|
$invoice->end_date = Utils::toSqlDate($input->end_date);
|
||||||
$invoice->notes = $input->notes;
|
$invoice->terms = $input->terms;
|
||||||
$invoice->po_number = $input->po_number;
|
$invoice->po_number = $input->po_number;
|
||||||
|
|
||||||
|
|
||||||
@ -587,6 +602,7 @@ class InvoiceController extends \BaseController {
|
|||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
$message = $clientPublicId == "-1" ? ' and created client' : '';
|
||||||
if ($action == 'clone')
|
if ($action == 'clone')
|
||||||
{
|
{
|
||||||
return InvoiceController::cloneInvoice($publicId);
|
return InvoiceController::cloneInvoice($publicId);
|
||||||
@ -595,9 +611,9 @@ class InvoiceController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$this->mailer->sendInvoice($invoice);
|
$this->mailer->sendInvoice($invoice);
|
||||||
|
|
||||||
Session::flash('message', 'Successfully emailed invoice');
|
Session::flash('message', 'Successfully emailed invoice'.$message);
|
||||||
} else {
|
} else {
|
||||||
Session::flash('message', 'Successfully saved invoice');
|
Session::flash('message', 'Successfully saved invoice'.$message);
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = 'invoices/' . $invoice->public_id . '/edit';
|
$url = 'invoices/' . $invoice->public_id . '/edit';
|
||||||
@ -640,14 +656,14 @@ class InvoiceController extends \BaseController {
|
|||||||
$invoices = Invoice::scope($ids)->get();
|
$invoices = Invoice::scope($ids)->get();
|
||||||
|
|
||||||
foreach ($invoices as $invoice) {
|
foreach ($invoices as $invoice) {
|
||||||
if ($action == 'archive') {
|
if ($action == 'delete') {
|
||||||
$invoice->delete();
|
$invoice->is_deleted = true;
|
||||||
} else if ($action == 'delete') {
|
$invoice->save();
|
||||||
$invoice->forceDelete();
|
|
||||||
}
|
}
|
||||||
|
$invoice->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = Utils::pluralize('Successfully '.$action.'d ? invoice', count($ids));
|
$message = Utils::pluralize('Successfully '.$action.'d ? invoice', count($invoices));
|
||||||
Session::flash('message', $message);
|
Session::flash('message', $message);
|
||||||
|
|
||||||
return Redirect::to('invoices');
|
return Redirect::to('invoices');
|
||||||
|
@ -18,6 +18,7 @@ class PaymentController extends \BaseController
|
|||||||
->leftJoin('invoices', 'invoices.id', '=','payments.invoice_id')
|
->leftJoin('invoices', 'invoices.id', '=','payments.invoice_id')
|
||||||
->where('payments.account_id', '=', Auth::user()->account_id)
|
->where('payments.account_id', '=', Auth::user()->account_id)
|
||||||
->where('payments.deleted_at', '=', null)
|
->where('payments.deleted_at', '=', null)
|
||||||
|
->where('clients.deleted_at', '=', null)
|
||||||
->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');
|
->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');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
@ -57,7 +58,7 @@ class PaymentController extends \BaseController
|
|||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('payments/'.$model->public_id.'/edit') . '">Edit Payment</a></li>
|
<li><a href="' . URL::to('payments/'.$model->public_id.'/edit') . '">Edit Payment</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="' . URL::to('payments/'.$model->public_id.'/archive') . '">Archive Payment</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">Archive Payment</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Payment</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Payment</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
@ -153,14 +154,14 @@ class PaymentController extends \BaseController
|
|||||||
$payments = Payment::scope($ids)->get();
|
$payments = Payment::scope($ids)->get();
|
||||||
|
|
||||||
foreach ($payments as $payment) {
|
foreach ($payments as $payment) {
|
||||||
if ($action == 'archive') {
|
if ($action == 'delete') {
|
||||||
$payment->delete();
|
$payment->is_deleted = true;
|
||||||
} else if ($action == 'delete') {
|
$payment->save();
|
||||||
$payment->forceDelete();
|
|
||||||
}
|
}
|
||||||
|
$payment->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = Utils::pluralize('Successfully '.$action.'d ? payment', count($ids));
|
$message = Utils::pluralize('Successfully '.$action.'d ? payment', count($payments));
|
||||||
Session::flash('message', $message);
|
Session::flash('message', $message);
|
||||||
|
|
||||||
return Redirect::to('payments');
|
return Redirect::to('payments');
|
||||||
|
46
app/controllers/ReportController.php
Executable file
46
app/controllers/ReportController.php
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ReportController extends \BaseController {
|
||||||
|
|
||||||
|
public function monthly()
|
||||||
|
{
|
||||||
|
$records = DB::table('invoices')
|
||||||
|
->select(DB::raw('sum(total) as total, month(invoice_date) as month'))
|
||||||
|
->where('invoices.deleted_at', '=', null)
|
||||||
|
->where('invoices.invoice_date', '>', 0)
|
||||||
|
->groupBy('month');
|
||||||
|
|
||||||
|
$totals = $records->lists('total');
|
||||||
|
$dates = $records->lists('month');
|
||||||
|
$data = array_combine($dates, $totals);
|
||||||
|
|
||||||
|
$startDate = date_create('2013-06-30');
|
||||||
|
$endDate = date_create('2013-12-30');
|
||||||
|
$endDate = $endDate->modify('+1 month');
|
||||||
|
$interval = new DateInterval('P1M');
|
||||||
|
$period = new DatePeriod($startDate, $interval, $endDate);
|
||||||
|
|
||||||
|
$totals = [];
|
||||||
|
$dates = [];
|
||||||
|
|
||||||
|
foreach ($period as $d)
|
||||||
|
{
|
||||||
|
$date = $d->format('Y-m-d');
|
||||||
|
$month = $d->format('n');
|
||||||
|
|
||||||
|
$dates[] = $date;
|
||||||
|
$totals[] = isset($data[$month]) ? $data[$month] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$width = (ceil( max($totals) / 100 ) * 100) / 10;
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'dates' => $dates,
|
||||||
|
'totals' => $totals,
|
||||||
|
'scaleStepWidth' => $width,
|
||||||
|
];
|
||||||
|
|
||||||
|
return View::make('reports.monthly', $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -74,6 +74,7 @@ class UserController extends BaseController {
|
|||||||
{
|
{
|
||||||
if( Confide::user() )
|
if( Confide::user() )
|
||||||
{
|
{
|
||||||
|
Event::fire('user.login');
|
||||||
return Redirect::to('/clients');
|
return Redirect::to('/clients');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -101,10 +102,7 @@ class UserController extends BaseController {
|
|||||||
// Get the value from the config file instead of changing the controller
|
// Get the value from the config file instead of changing the controller
|
||||||
if ( Confide::logAttempt( $input, Config::get('confide::signup_confirm') ) )
|
if ( Confide::logAttempt( $input, Config::get('confide::signup_confirm') ) )
|
||||||
{
|
{
|
||||||
$account = Account::findOrFail(Auth::user()->account_id);
|
Event::fire('user.login');
|
||||||
$account->last_login = Carbon::now()->toDateTimeString();
|
|
||||||
$account->save();
|
|
||||||
|
|
||||||
// Redirect the user to the URL they were trying to access before
|
// Redirect the user to the URL they were trying to access before
|
||||||
// caught by the authentication filter IE Redirect::guest('user/login').
|
// caught by the authentication filter IE Redirect::guest('user/login').
|
||||||
// Otherwise fallback to '/'
|
// Otherwise fallback to '/'
|
||||||
|
@ -31,6 +31,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
Schema::dropIfExists('countries');
|
Schema::dropIfExists('countries');
|
||||||
Schema::dropIfExists('timezones');
|
Schema::dropIfExists('timezones');
|
||||||
Schema::dropIfExists('frequencies');
|
Schema::dropIfExists('frequencies');
|
||||||
|
Schema::dropIfExists('date_formats');
|
||||||
|
Schema::dropIfExists('datetime_formats');
|
||||||
|
|
||||||
Schema::create('countries', function($table)
|
Schema::create('countries', function($table)
|
||||||
{
|
{
|
||||||
@ -63,10 +65,26 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->string('location');
|
$t->string('location');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::create('date_formats', function($t)
|
||||||
|
{
|
||||||
|
$t->increments('id');
|
||||||
|
$t->string('format');
|
||||||
|
$t->string('label');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('datetime_formats', function($t)
|
||||||
|
{
|
||||||
|
$t->increments('id');
|
||||||
|
$t->string('format');
|
||||||
|
$t->string('label');
|
||||||
|
});
|
||||||
|
|
||||||
Schema::create('accounts', function($t)
|
Schema::create('accounts', function($t)
|
||||||
{
|
{
|
||||||
$t->increments('id');
|
$t->increments('id');
|
||||||
$t->unsignedInteger('timezone_id')->nullable();
|
$t->unsignedInteger('timezone_id')->nullable();
|
||||||
|
$t->unsignedInteger('date_format_id')->nullable();
|
||||||
|
$t->unsignedInteger('datetime_format_id')->nullable();
|
||||||
|
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
@ -85,6 +103,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->text('invoice_terms');
|
$t->text('invoice_terms');
|
||||||
|
|
||||||
$t->foreign('timezone_id')->references('id')->on('timezones');
|
$t->foreign('timezone_id')->references('id')->on('timezones');
|
||||||
|
$t->foreign('date_format_id')->references('id')->on('date_formats');
|
||||||
|
$t->foreign('datetime_format_id')->references('id')->on('datetime_formats');
|
||||||
$t->foreign('country_id')->references('id')->on('countries');
|
$t->foreign('country_id')->references('id')->on('countries');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,7 +112,6 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
{
|
{
|
||||||
$t->increments('id');
|
$t->increments('id');
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
|
||||||
|
|
||||||
$t->string('name');
|
$t->string('name');
|
||||||
$t->string('provider');
|
$t->string('provider');
|
||||||
@ -105,7 +124,6 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('account_id');
|
$t->unsignedInteger('account_id');
|
||||||
$t->unsignedInteger('gateway_id');
|
$t->unsignedInteger('gateway_id');
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
|
||||||
|
|
||||||
$t->text('config');
|
$t->text('config');
|
||||||
|
|
||||||
@ -175,10 +193,12 @@ 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->decimal('paid_to_date', 10, 2);
|
||||||
$t->timestamp('last_login');
|
$t->timestamp('last_login');
|
||||||
$t->string('website');
|
$t->string('website');
|
||||||
$t->unsignedInteger('client_industry_id')->nullable();
|
$t->unsignedInteger('client_industry_id')->nullable();
|
||||||
$t->unsignedInteger('client_size_id')->nullable();
|
$t->unsignedInteger('client_size_id')->nullable();
|
||||||
|
$t->boolean('is_deleted');
|
||||||
|
|
||||||
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
@ -240,8 +260,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->string('po_number');
|
$t->string('po_number');
|
||||||
$t->date('invoice_date')->nullable();
|
$t->date('invoice_date')->nullable();
|
||||||
$t->date('due_date')->nullable();
|
$t->date('due_date')->nullable();
|
||||||
$t->text('notes');
|
$t->text('terms');
|
||||||
|
$t->boolean('is_deleted');
|
||||||
$t->boolean('is_recurring');
|
$t->boolean('is_recurring');
|
||||||
$t->unsignedInteger('frequency_id');
|
$t->unsignedInteger('frequency_id');
|
||||||
$t->date('start_date')->nullable();
|
$t->date('start_date')->nullable();
|
||||||
@ -342,6 +362,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
|
$t->boolean('is_deleted');
|
||||||
$t->decimal('amount', 10, 2);
|
$t->decimal('amount', 10, 2);
|
||||||
$t->date('payment_date');
|
$t->date('payment_date');
|
||||||
$t->string('transaction_reference');
|
$t->string('transaction_reference');
|
||||||
@ -367,8 +388,9 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
|
$t->boolean('is_deleted');
|
||||||
$t->decimal('amount', 10, 2);
|
$t->decimal('amount', 10, 2);
|
||||||
$t->date('credit_date');
|
$t->date('credit_date')->nullable();
|
||||||
$t->string('credit_number');
|
$t->string('credit_number');
|
||||||
|
|
||||||
$t->foreign('account_id')->references('id')->on('accounts');
|
$t->foreign('account_id')->references('id')->on('accounts');
|
||||||
@ -432,5 +454,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
Schema::dropIfExists('countries');
|
Schema::dropIfExists('countries');
|
||||||
Schema::dropIfExists('timezones');
|
Schema::dropIfExists('timezones');
|
||||||
Schema::dropIfExists('frequencies');
|
Schema::dropIfExists('frequencies');
|
||||||
|
Schema::dropIfExists('date_formats');
|
||||||
|
Schema::dropIfExists('datetime_formats');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,13 @@ class ConstantsSeeder extends Seeder
|
|||||||
ClientSize::create(array('name' => '101 - 500'));
|
ClientSize::create(array('name' => '101 - 500'));
|
||||||
ClientSize::create(array('name' => '500+'));
|
ClientSize::create(array('name' => '500+'));
|
||||||
|
|
||||||
|
DatetimeFormat::create(array('format' => 'F j, Y, g:i a', 'label' => 'March 10, 2013, 6:15 pm'));
|
||||||
|
DatetimeFormat::create(array('format' => 'D M jS, Y g:ia', 'label' => 'Mon March 10th, 2013, 6:15 pm'));
|
||||||
|
|
||||||
|
DateFormat::create(array('format' => 'F j, Y', 'label' => 'March 10, 2013'));
|
||||||
|
DateFormat::create(array('format' => 'D M jS', 'label' => 'Mon March 10th, 2013'));
|
||||||
|
|
||||||
|
|
||||||
$gateways = [
|
$gateways = [
|
||||||
array('name'=>'Authorize.Net AIM', 'provider'=>'AuthorizeNet_AIM'),
|
array('name'=>'Authorize.Net AIM', 'provider'=>'AuthorizeNet_AIM'),
|
||||||
array('name'=>'Authorize.Net SIM', 'provider'=>'AuthorizeNet_SIM'),
|
array('name'=>'Authorize.Net SIM', 'provider'=>'AuthorizeNet_SIM'),
|
||||||
|
36
app/handlers/UserEventHandler.php
Executable file
36
app/handlers/UserEventHandler.php
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class UserEventHandler
|
||||||
|
{
|
||||||
|
public function subscribe($events)
|
||||||
|
{
|
||||||
|
$events->listen('user.signup', 'UserEventHandler@onSignup');
|
||||||
|
$events->listen('user.login', 'UserEventHandler@onLogin');
|
||||||
|
|
||||||
|
$events->listen('user.refresh', 'UserEventHandler@onRefresh');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSignup()
|
||||||
|
{
|
||||||
|
dd('user signed up');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onLogin()
|
||||||
|
{
|
||||||
|
$account = Account::findOrFail(Auth::user()->account_id);
|
||||||
|
$account->last_login = Carbon::now()->toDateTimeString();
|
||||||
|
$account->save();
|
||||||
|
|
||||||
|
Event::fire('user.refresh');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onRefresh()
|
||||||
|
{
|
||||||
|
$user = User::whereId(Auth::user()->id)->with('account', 'account.date_format', 'account.datetime_format', 'account.timezone')->firstOrFail();
|
||||||
|
$account = $user->account;
|
||||||
|
|
||||||
|
Session::put(SESSION_TIMEZONE, $account->timezone ? $account->timezone->name : DEFAULT_TIMEZONE);
|
||||||
|
Session::put(SESSION_DATE_FORMAT, $account->date_format ? $account->date_format->format : DEFAULT_DATE_FORMAT);
|
||||||
|
Session::put(SESSION_DATETIME_FORMAT, $account->datetime_format ? $account->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
||||||
|
}
|
||||||
|
}
|
@ -52,30 +52,25 @@ class Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function timestampToDateTimeString($timestamp) {
|
public static function timestampToDateTimeString($timestamp) {
|
||||||
$tz = Session::get('tz');
|
$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
|
||||||
if (!$tz) {
|
$format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT);
|
||||||
$tz = 'US/Eastern';
|
return Utils::timestampToString($timestamp, $timezone, $format);
|
||||||
}
|
|
||||||
$date = new Carbon($timestamp);
|
|
||||||
$date->tz = $tz;
|
|
||||||
if ($date->year < 1900) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $date->format('D M jS, Y g:ia');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function timestampToDateString($timestamp) {
|
public static function timestampToDateString($timestamp) {
|
||||||
$tz = Session::get('tz');
|
$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
|
||||||
if (!$tz) {
|
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
|
||||||
$tz = 'US/Eastern';
|
return Utils::timestampToString($timestamp, $timezone, $format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function timestampToString($timestamp, $timzone, $format)
|
||||||
|
{
|
||||||
$date = new Carbon($timestamp);
|
$date = new Carbon($timestamp);
|
||||||
$date->tz = $tz;
|
$date->tz = $timzone;
|
||||||
if ($date->year < 1900) {
|
if ($date->year < 1900) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return $date->toFormattedDateString();
|
return $date->format($format);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function toSqlDate($date)
|
public static function toSqlDate($date)
|
||||||
|
@ -35,6 +35,17 @@ class Account extends Eloquent
|
|||||||
return $this->belongsTo('Timezone');
|
return $this->belongsTo('Timezone');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function date_format()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('DateFormat');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function datetime_format()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('DatetimeFormat');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function isGatewayConfigured($gatewayId = 0)
|
public function isGatewayConfigured($gatewayId = 0)
|
||||||
{
|
{
|
||||||
if ($gatewayId)
|
if ($gatewayId)
|
||||||
|
@ -131,6 +131,16 @@ class Client extends EntityModel
|
|||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getWebsite()
|
||||||
|
{
|
||||||
|
if (!$this->website)
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return link_to($this->website, $this->website);
|
||||||
|
}
|
||||||
|
|
||||||
public function getDateCreated()
|
public function getDateCreated()
|
||||||
{
|
{
|
||||||
if ($this->created_at == '0000-00-00 00:00:00')
|
if ($this->created_at == '0000-00-00 00:00:00')
|
||||||
|
7
app/models/DateFormat.php
Executable file
7
app/models/DateFormat.php
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class DateFormat extends Eloquent
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $softDelete = false;
|
||||||
|
}
|
7
app/models/DatetimeFormat.php
Executable file
7
app/models/DatetimeFormat.php
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class DatetimeFormat extends Eloquent
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $softDelete = false;
|
||||||
|
}
|
@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
class Gateway extends Eloquent
|
class Gateway extends Eloquent
|
||||||
{
|
{
|
||||||
protected $softDelete = true;
|
|
||||||
}
|
}
|
@ -14,7 +14,7 @@
|
|||||||
//dd(DB::getQueryLog());
|
//dd(DB::getQueryLog());
|
||||||
//dd(Client::getPrivateId(1));
|
//dd(Client::getPrivateId(1));
|
||||||
//dd(new DateTime());
|
//dd(new DateTime());
|
||||||
|
//Event::fire('user.signup');
|
||||||
|
|
||||||
Route::get('/send_emails', function() {
|
Route::get('/send_emails', function() {
|
||||||
Artisan::call('ninja:send-invoices');
|
Artisan::call('ninja:send-invoices');
|
||||||
@ -80,9 +80,9 @@ Route::group(array('before' => 'auth'), function()
|
|||||||
Route::resource('credits', 'CreditController');
|
Route::resource('credits', 'CreditController');
|
||||||
Route::get('credits/create/{client_id?}', 'CreditController@create');
|
Route::get('credits/create/{client_id?}', 'CreditController@create');
|
||||||
Route::get('api/credits/{client_id?}', array('as'=>'api.credits', 'uses'=>'CreditController@getDatatable'));
|
Route::get('api/credits/{client_id?}', array('as'=>'api.credits', 'uses'=>'CreditController@getDatatable'));
|
||||||
Route::post('credits/bulk', 'PaymentController@bulk');
|
Route::post('credits/bulk', 'CreditController@bulk');
|
||||||
|
|
||||||
Route::get('reports', function() { return View::make('header'); });
|
Route::get('reports', 'ReportController@monthly');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -161,3 +161,11 @@ define('FREQUENCY_MONTHLY', 4);
|
|||||||
define('FREQUENCY_THREE_MONTHS', 5);
|
define('FREQUENCY_THREE_MONTHS', 5);
|
||||||
define('FREQUENCY_SIX_MONTHS', 6);
|
define('FREQUENCY_SIX_MONTHS', 6);
|
||||||
define('FREQUENCY_ANNUALLY', 7);
|
define('FREQUENCY_ANNUALLY', 7);
|
||||||
|
|
||||||
|
define('SESSION_TIMEZONE', 'timezone');
|
||||||
|
define('SESSION_DATE_FORMAT', 'dateFormat');
|
||||||
|
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
|
||||||
|
|
||||||
|
define('DEFAULT_TIMEZONE', 'US/Eastern');
|
||||||
|
define('DEFAULT_DATE_FORMAT', 'F j, Y');
|
||||||
|
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
||||||
|
@ -18,6 +18,7 @@ ClassLoader::addDirectories(array(
|
|||||||
app_path().'/models',
|
app_path().'/models',
|
||||||
app_path().'/database/seeds',
|
app_path().'/database/seeds',
|
||||||
app_path().'/libraries',
|
app_path().'/libraries',
|
||||||
|
app_path().'/handlers',
|
||||||
|
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -70,6 +71,11 @@ App::down(function()
|
|||||||
return Response::make("Be right back!", 503);
|
return Response::make("Be right back!", 503);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Event::subscribe('UserEventHandler');
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Require The Filters File
|
| Require The Filters File
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
{{ Former::legend('Account') }}
|
{{ Former::legend('Account') }}
|
||||||
{{ Former::text('name') }}
|
{{ Former::text('name') }}
|
||||||
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
|
||||||
->fromQuery($timezones, 'location', 'id')->select($account->timezone_id) }}
|
|
||||||
{{ Former::file('logo')->max(2, 'MB')->accept('image')->wrap('test') }}
|
{{ Former::file('logo')->max(2, 'MB')->accept('image')->wrap('test') }}
|
||||||
|
|
||||||
@if (file_exists($account->getLogoPath()))
|
@if (file_exists($account->getLogoPath()))
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
@parent
|
@parent
|
||||||
|
|
||||||
{{ Former::open()->addClass('col-md-10 col-md-offset-1') }}
|
{{ Former::open()->addClass('col-md-8 col-md-offset-2') }}
|
||||||
{{ Former::populate($account) }}
|
{{ Former::populate($account) }}
|
||||||
|
|
||||||
{{ Former::legend('Payment Gateway') }}
|
{{ Former::legend('Payment Gateway') }}
|
||||||
@ -36,6 +36,15 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
{{ Former::legend('Date and Time') }}
|
||||||
|
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
||||||
|
->fromQuery($timezones, 'location', 'id')->select($account->timezone_id) }}
|
||||||
|
{{ Former::select('date_format_id')->addOption('','')->label('Date Format')
|
||||||
|
->fromQuery($dateFormats, 'label', 'id')->select($account->date_format_id) }}
|
||||||
|
{{ Former::select('datetime_format_id')->addOption('','')->label('Date/Time Format')
|
||||||
|
->fromQuery($datetimeFormats, 'label', 'id')->select($account->datetime_format_id) }}
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Invoices') }}
|
{{ Former::legend('Invoices') }}
|
||||||
{{ Former::textarea('invoice_terms') }}
|
{{ Former::textarea('invoice_terms') }}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
{{ Former::legend('Organization') }}
|
{{ Former::legend('Organization') }}
|
||||||
{{ Former::text('name') }}
|
{{ Former::text('name') }}
|
||||||
|
{{ Former::text('website') }}
|
||||||
{{ Former::text('work_phone')->label('Phone') }}
|
{{ Former::text('work_phone')->label('Phone') }}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<p>{{ $client->getPhone() }}</p>
|
<p>{{ $client->getPhone() }}</p>
|
||||||
<p>{{ $client->getNotes() }}</p>
|
<p>{{ $client->getNotes() }}</p>
|
||||||
<p>{{ $client->getIndustry() }}</p>
|
<p>{{ $client->getIndustry() }}</p>
|
||||||
|
<p>{{ $client->getWebsite() }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
@ -273,7 +273,7 @@
|
|||||||
{{ HTML::menu_link('invoice') }}
|
{{ HTML::menu_link('invoice') }}
|
||||||
{{ HTML::menu_link('payment') }}
|
{{ HTML::menu_link('payment') }}
|
||||||
{{ HTML::menu_link('credit') }}
|
{{ HTML::menu_link('credit') }}
|
||||||
{{-- HTML::nav_link('reports', 'Reports') --}}
|
{{ HTML::nav_link('reports', 'Reports') }}
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
|
7
app/views/invoices/deleted.blade.php
Executable file
7
app/views/invoices/deleted.blade.php
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
@extends('header')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
The requested invoice is no longer available.
|
||||||
|
|
||||||
|
@stop
|
@ -22,7 +22,7 @@
|
|||||||
->addGroupClass('client_select closer-row') }}
|
->addGroupClass('client_select closer-row') }}
|
||||||
|
|
||||||
<div class="form-group" style="margin-bottom: 8px">
|
<div class="form-group" style="margin-bottom: 8px">
|
||||||
<div class="col-lg-8 col-lg-offset-4">
|
<div class="col-lg-8 col-sm-8 col-lg-offset-4 col-sm-offset-4">
|
||||||
<a href="#" data-bind="click: showClientForm, text: showClientText"></a>
|
<a href="#" data-bind="click: showClientForm, text: showClientText"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::textarea('notes')->data_bind("value: notes, valueUpdate: 'afterkeydown'") }}
|
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'") }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4" id="col_2">
|
<div class="col-md-4" id="col_2">
|
||||||
@ -94,7 +94,7 @@
|
|||||||
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
|
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
|
||||||
</td>
|
</td>
|
||||||
<td style="width:300px">
|
<td style="width:300px">
|
||||||
<textarea onkeyup="checkWordWrap(event)" data-bind="value: notes, valueUpdate: 'afterkeydown'" rows="1" cols="60" style="resize: none;" class="form-control" onchange="refreshPDF()"></textarea>
|
<textarea data-bind="value: wrapped_notes, valueUpdate: 'afterkeydown'" rows="1" cols="60" style="resize: none;" class="form-control word-wrap" onchange="refreshPDF()"></textarea>
|
||||||
</td>
|
</td>
|
||||||
<td style="width:100px">
|
<td style="width:100px">
|
||||||
<input onkeyup="onChange()" data-bind="value: cost, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
<input onkeyup="onChange()" data-bind="value: cost, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
||||||
@ -195,6 +195,7 @@
|
|||||||
|
|
||||||
{{ Former::legend('Organization') }}
|
{{ Former::legend('Organization') }}
|
||||||
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
|
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
|
||||||
|
|
||||||
|
|
||||||
@ -437,9 +438,10 @@
|
|||||||
this.client = new ClientModel();
|
this.client = new ClientModel();
|
||||||
self.discount = ko.observable('');
|
self.discount = ko.observable('');
|
||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
self.notes = ko.observable('');
|
self.terms = ko.observable('');
|
||||||
self.po_number = ko.observable('');
|
self.po_number = ko.observable('');
|
||||||
self.invoice_date = ko.observable('');
|
self.invoice_date = ko.observable('');
|
||||||
|
self.invoice_number = ko.observable('');
|
||||||
self.due_date = ko.observable('');
|
self.due_date = ko.observable('');
|
||||||
self.start_date = ko.observable('');
|
self.start_date = ko.observable('');
|
||||||
self.end_date = ko.observable('');
|
self.end_date = ko.observable('');
|
||||||
@ -455,11 +457,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.wrapped_terms = ko.computed({
|
||||||
|
read: function() {
|
||||||
|
return this.terms();
|
||||||
|
},
|
||||||
|
write: function(value) {
|
||||||
|
value = wordWrapText(value, 250);
|
||||||
|
self.terms(value);
|
||||||
|
$('#terms').height(value.split('\n').length * 22);
|
||||||
|
},
|
||||||
|
owner: this
|
||||||
|
});
|
||||||
|
|
||||||
self.showClientText = ko.computed(function() {
|
self.showClientText = ko.computed(function() {
|
||||||
return self.client.public_id() ? 'Edit client details' : 'Create new client';
|
return self.client.public_id() ? 'Edit client details' : 'Create new client';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
self.showClientForm = function() {
|
self.showClientForm = function() {
|
||||||
if (self.client.public_id() == 0) {
|
if (self.client.public_id() == 0) {
|
||||||
$('#myModal input').val('');
|
$('#myModal input').val('');
|
||||||
@ -552,6 +565,7 @@
|
|||||||
self.country_id = ko.observable('');
|
self.country_id = ko.observable('');
|
||||||
self.client_size_id = ko.observable('');
|
self.client_size_id = ko.observable('');
|
||||||
self.client_industry_id = ko.observable('');
|
self.client_industry_id = ko.observable('');
|
||||||
|
self.website = ko.observable('');
|
||||||
self.contacts = ko.observableArray();
|
self.contacts = ko.observableArray();
|
||||||
|
|
||||||
self.mapping = {
|
self.mapping = {
|
||||||
@ -617,6 +631,18 @@
|
|||||||
ko.mapping.fromJS(data, {}, this);
|
ko.mapping.fromJS(data, {}, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.wrapped_notes = ko.computed({
|
||||||
|
read: function() {
|
||||||
|
return this.notes();
|
||||||
|
},
|
||||||
|
write: function(value) {
|
||||||
|
value = wordWrapText(value);
|
||||||
|
self.notes(value);
|
||||||
|
onChange();
|
||||||
|
},
|
||||||
|
owner: this
|
||||||
|
});
|
||||||
|
|
||||||
this.rawTotal = ko.computed(function() {
|
this.rawTotal = ko.computed(function() {
|
||||||
var cost = parseFloat(self.cost());
|
var cost = parseFloat(self.cost());
|
||||||
var qty = parseFloat(self.qty());
|
var qty = parseFloat(self.qty());
|
||||||
@ -646,36 +672,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkWordWrap(event)
|
|
||||||
{
|
|
||||||
var doc = new jsPDF('p', 'pt');
|
|
||||||
doc.setFont('Helvetica','');
|
|
||||||
doc.setFontSize(10);
|
|
||||||
|
|
||||||
var $textarea = $(event.target || event.srcElement);
|
|
||||||
var lines = $textarea.val().split("\n");
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
|
||||||
var numLines = doc.splitTextToSize(lines[i], 200).length;
|
|
||||||
if (numLines <= 1) continue;
|
|
||||||
var j = 0; space = lines[i].length;
|
|
||||||
while (j++ < lines[i].length) {
|
|
||||||
if (lines[i].charAt(j) === " ") space = j;
|
|
||||||
}
|
|
||||||
lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
|
|
||||||
lines[i] = lines[i].substring(0, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = lines.slice(0, 6).join("\n");
|
|
||||||
if (val != $textarea.val())
|
|
||||||
{
|
|
||||||
var model = ko.dataFor($textarea[0]);
|
|
||||||
model.notes(val);
|
|
||||||
refreshPDF();
|
|
||||||
}
|
|
||||||
$textarea.height(val.split('\n').length * 22);
|
|
||||||
onChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange()
|
function onChange()
|
||||||
{
|
{
|
||||||
var hasEmpty = false;
|
var hasEmpty = false;
|
||||||
@ -688,6 +684,10 @@
|
|||||||
if (!hasEmpty) {
|
if (!hasEmpty) {
|
||||||
model.addItem();
|
model.addItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.word-wrap').each(function(index, input) {
|
||||||
|
$(input).height($(input).val().split('\n').length * 22);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var products = {{ $products }};
|
var products = {{ $products }};
|
||||||
@ -696,8 +696,8 @@
|
|||||||
|
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
var client = clients[i];
|
var client = clients[i];
|
||||||
for (var i=0; i<client.contacts.length; i++) {
|
for (var j=0; j<client.contacts.length; j++) {
|
||||||
var contact = client.contacts[i];
|
var contact = client.contacts[j];
|
||||||
contact.send_invoice = contact.is_primary;
|
contact.send_invoice = contact.is_primary;
|
||||||
}
|
}
|
||||||
clientMap[client.public_id] = client;
|
clientMap[client.public_id] = client;
|
||||||
@ -716,7 +716,8 @@
|
|||||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||||
}
|
}
|
||||||
@else
|
@else
|
||||||
model.invoice_number = '{{ $invoiceNumber }}';
|
model.invoice_number('{{ $invoiceNumber }}');
|
||||||
|
model.terms(wordWrapText('{{ $account->invoice_terms }}', 250));
|
||||||
@endif
|
@endif
|
||||||
model.invoice_items.push(new ItemModel());
|
model.invoice_items.push(new ItemModel());
|
||||||
ko.applyBindings(model);
|
ko.applyBindings(model);
|
||||||
|
39
app/views/reports/monthly.blade.php
Executable file
39
app/views/reports/monthly.blade.php
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
@extends('header')
|
||||||
|
|
||||||
|
@section('head')
|
||||||
|
@parent
|
||||||
|
|
||||||
|
<script src="{{ asset('js/chart.js') }}" type="text/javascript"></script>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<center style="padding-top: 40px">
|
||||||
|
<canvas id="monthly-reports" width="800" height="300"></canvas>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var ctx = document.getElementById('monthly-reports').getContext('2d');
|
||||||
|
var chart = {
|
||||||
|
labels: {{ json_encode($dates)}},
|
||||||
|
datasets: [{
|
||||||
|
data: {{ json_encode($totals) }},
|
||||||
|
fillColor : "rgba(151,187,205,0.5)",
|
||||||
|
strokeColor : "rgba(151,187,205,1)",
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
scaleOverride: true,
|
||||||
|
scaleSteps: 10,
|
||||||
|
scaleStepWidth: {{ $scaleStepWidth }},
|
||||||
|
scaleStartValue: 0,
|
||||||
|
scaleLabel : "<%=formatMoney(value)%>",
|
||||||
|
};
|
||||||
|
|
||||||
|
new Chart(ctx).Bar(chart, options);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@stop
|
1426
public/js/Chart.js
vendored
Executable file
1426
public/js/Chart.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
@ -139,13 +139,17 @@ function generatePDF(invoice) {
|
|||||||
var x = tableTop + (line * rowHeight);
|
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);
|
||||||
|
|
||||||
if (invoice.discount > 0) {
|
|
||||||
|
doc.text(tableLeft, x+16, invoice.terms);
|
||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Subtotal');
|
doc.text(footerLeft, x, 'Subtotal');
|
||||||
var total = formatNumber(total);
|
var total = formatNumber(total);
|
||||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, x, total);
|
doc.text(totalX, x, total);
|
||||||
|
|
||||||
|
if (invoice.discount > 0) {
|
||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Discount');
|
doc.text(footerLeft, x, 'Discount');
|
||||||
var discount = formatNumber(total * (invoice.discount/100));
|
var discount = formatNumber(total * (invoice.discount/100));
|
||||||
@ -154,6 +158,13 @@ function generatePDF(invoice) {
|
|||||||
doc.text(discountX, x, discount);
|
doc.text(discountX, x, discount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x += 16;
|
||||||
|
doc.text(footerLeft, x, 'Paid to Date');
|
||||||
|
var paid = formatNumber(0);
|
||||||
|
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
||||||
|
doc.text(paidX, x, paid);
|
||||||
|
|
||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(footerLeft, x, 'Total');
|
doc.text(footerLeft, x, 'Total');
|
||||||
@ -229,15 +240,6 @@ function generatePDF(invoice) {
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatNumber(num) {
|
|
||||||
num = parseFloat(num);
|
|
||||||
if (!num) return '';
|
|
||||||
var p = num.toFixed(2).split(".");
|
|
||||||
return p[0].split("").reverse().reduce(function(acc, num, i, orig) {
|
|
||||||
return num + (i && !(i % 3) ? "," : "") + acc;
|
|
||||||
}, "") + "." + p[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle converting variables in the invoices (ie, MONTH+1) */
|
/* Handle converting variables in the invoices (ie, MONTH+1) */
|
||||||
function processVariables(str) {
|
function processVariables(str) {
|
||||||
@ -316,6 +318,16 @@ function formatMoney(num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function formatNumber(num) {
|
||||||
|
num = parseFloat(num);
|
||||||
|
if (!num) num = 0;
|
||||||
|
var p = num.toFixed(2).split(".");
|
||||||
|
return p[0].split("").reverse().reduce(function(acc, num, i, orig) {
|
||||||
|
return num + (i && !(i % 3) ? "," : "") + acc;
|
||||||
|
}, "") + "." + p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the defaults for DataTables initialisation */
|
/* Set the defaults for DataTables initialisation */
|
||||||
$.extend( true, $.fn.dataTable.defaults, {
|
$.extend( true, $.fn.dataTable.defaults, {
|
||||||
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
||||||
@ -590,6 +602,28 @@ ko.bindingHandlers.dropdown = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function wordWrapText(value, width)
|
||||||
|
{
|
||||||
|
if (!width) width = 200;
|
||||||
|
var doc = new jsPDF('p', 'pt');
|
||||||
|
doc.setFont('Helvetica','');
|
||||||
|
doc.setFontSize(10);
|
||||||
|
|
||||||
|
var lines = value.split("\n");
|
||||||
|
for (var i = 0; i < lines.length; i++) {
|
||||||
|
var numLines = doc.splitTextToSize(lines[i], width).length;
|
||||||
|
if (numLines <= 1) continue;
|
||||||
|
var j = 0; space = lines[i].length;
|
||||||
|
while (j++ < lines[i].length) {
|
||||||
|
if (lines[i].charAt(j) === " ") space = j;
|
||||||
|
}
|
||||||
|
lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
|
||||||
|
lines[i] = lines[i].substring(0, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.slice(0, 6).join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var CONSTS = {};
|
var CONSTS = {};
|
||||||
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user