mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 12:42:36 +01:00
Starting to work on reports
This commit is contained in:
parent
19abec6f09
commit
374e34e733
@ -56,4 +56,5 @@ Configure config/database.php and then initialize the database
|
||||
* [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+
|
||||
* [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);
|
||||
Session::put('tz', 'US/Eastern');
|
||||
Event::fire('user.login');
|
||||
|
||||
return Redirect::to('invoices/create');
|
||||
}
|
||||
@ -51,9 +51,8 @@ class AccountController extends \BaseController {
|
||||
{
|
||||
$account = Account::with('users')->findOrFail(Auth::user()->account_id);
|
||||
$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)
|
||||
{
|
||||
@ -71,7 +70,10 @@ class AccountController extends \BaseController {
|
||||
'account' => $account,
|
||||
'accountGateway' => $accountGateway,
|
||||
'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)
|
||||
@ -383,6 +385,12 @@ class AccountController extends \BaseController {
|
||||
$account = Account::findOrFail(Auth::user()->account_id);
|
||||
$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->save();
|
||||
|
||||
@ -431,7 +439,6 @@ class AccountController extends \BaseController {
|
||||
$account->state = trim(Input::get('state'));
|
||||
$account->postal_code = trim(Input::get('postal_code'));
|
||||
$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();
|
||||
|
||||
$user = $account->users()->first();
|
||||
|
@ -179,11 +179,12 @@ class ClientController extends \BaseController {
|
||||
$client->address2 = trim(Input::get('address2'));
|
||||
$client->city = trim(Input::get('city'));
|
||||
$client->state = trim(Input::get('state'));
|
||||
$client->notes = trim(Input::get('notes'));
|
||||
$client->postal_code = trim(Input::get('postal_code'));
|
||||
$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_industry_id = Input::get('client_industry_id') ? Input::get('client_industry_id') : null;
|
||||
$client->website = trim(Input::get('website'));
|
||||
|
||||
$client->save();
|
||||
|
||||
@ -238,15 +239,15 @@ class ClientController extends \BaseController {
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$clients = Client::scope($ids)->get();
|
||||
|
||||
foreach ($clients as $client) {
|
||||
if ($action == 'archive') {
|
||||
$client->delete();
|
||||
} else if ($action == 'delete') {
|
||||
$client->forceDelete();
|
||||
foreach ($clients as $client) {
|
||||
if ($action == 'delete') {
|
||||
$client->is_deleted = true;
|
||||
$client->save();
|
||||
}
|
||||
$client->delete();
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? client', count($ids));
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? client', count($clients));
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('clients');
|
||||
|
@ -22,6 +22,7 @@ class CreditController extends \BaseController {
|
||||
->join('clients', 'clients.id', '=','credits.client_id')
|
||||
->where('clients.account_id', '=', Auth::user()->account_id)
|
||||
->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');
|
||||
|
||||
if ($clientPublicId) {
|
||||
@ -55,7 +56,7 @@ class CreditController extends \BaseController {
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('credits/'.$model->public_id.'/edit') . '">Edit Credit</a></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>
|
||||
</ul>
|
||||
</div>';
|
||||
@ -65,7 +66,7 @@ class CreditController extends \BaseController {
|
||||
}
|
||||
|
||||
|
||||
public function create($clientPublicId)
|
||||
public function create($clientPublicId = null)
|
||||
{
|
||||
$client = null;
|
||||
if ($clientPublicId) {
|
||||
@ -144,14 +145,14 @@ class CreditController extends \BaseController {
|
||||
$credits = Credit::scope($ids)->get();
|
||||
|
||||
foreach ($credits as $credit) {
|
||||
if ($action == 'archive') {
|
||||
$credit->delete();
|
||||
} else if ($action == 'delete') {
|
||||
$credit->forceDelete();
|
||||
if ($action == 'delete') {
|
||||
$credit->is_deleted = true;
|
||||
$credit->save();
|
||||
}
|
||||
$credit->delete();
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? credit', count($ids));
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? credit', count($credits));
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('credits');
|
||||
|
@ -37,6 +37,7 @@ class InvoiceController extends \BaseController {
|
||||
->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id')
|
||||
->where('invoices.account_id', '=', Auth::user()->account_id)
|
||||
->where('invoices.deleted_at', '=', null)
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->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');
|
||||
|
||||
@ -81,7 +82,7 @@ class InvoiceController extends \BaseController {
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></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>
|
||||
</ul>
|
||||
</div>';
|
||||
@ -138,7 +139,7 @@ class InvoiceController extends \BaseController {
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></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>
|
||||
</ul>
|
||||
</div>';
|
||||
@ -150,12 +151,22 @@ class InvoiceController extends \BaseController {
|
||||
|
||||
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();
|
||||
|
||||
$user = $invitation->user;
|
||||
$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) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_VIEWED;
|
||||
$invoice->save();
|
||||
@ -438,6 +449,10 @@ class InvoiceController extends \BaseController {
|
||||
$client->state = trim($inputClient->state);
|
||||
$client->postal_code = trim($inputClient->postal_code);
|
||||
$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();
|
||||
|
||||
$isPrimary = true;
|
||||
@ -498,7 +513,7 @@ class InvoiceController extends \BaseController {
|
||||
$invoice->frequency_id = $input->frequency_id ? $input->frequency_id : 0;
|
||||
$invoice->start_date = Utils::toSqlDate($input->start_date);
|
||||
$invoice->end_date = Utils::toSqlDate($input->end_date);
|
||||
$invoice->notes = $input->notes;
|
||||
$invoice->terms = $input->terms;
|
||||
$invoice->po_number = $input->po_number;
|
||||
|
||||
|
||||
@ -587,6 +602,7 @@ class InvoiceController extends \BaseController {
|
||||
/*
|
||||
*/
|
||||
|
||||
$message = $clientPublicId == "-1" ? ' and created client' : '';
|
||||
if ($action == 'clone')
|
||||
{
|
||||
return InvoiceController::cloneInvoice($publicId);
|
||||
@ -595,9 +611,9 @@ class InvoiceController extends \BaseController {
|
||||
{
|
||||
$this->mailer->sendInvoice($invoice);
|
||||
|
||||
Session::flash('message', 'Successfully emailed invoice');
|
||||
Session::flash('message', 'Successfully emailed invoice'.$message);
|
||||
} else {
|
||||
Session::flash('message', 'Successfully saved invoice');
|
||||
Session::flash('message', 'Successfully saved invoice'.$message);
|
||||
}
|
||||
|
||||
$url = 'invoices/' . $invoice->public_id . '/edit';
|
||||
@ -640,14 +656,14 @@ class InvoiceController extends \BaseController {
|
||||
$invoices = Invoice::scope($ids)->get();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
if ($action == 'archive') {
|
||||
$invoice->delete();
|
||||
} else if ($action == 'delete') {
|
||||
$invoice->forceDelete();
|
||||
if ($action == 'delete') {
|
||||
$invoice->is_deleted = true;
|
||||
$invoice->save();
|
||||
}
|
||||
$invoice->delete();
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? invoice', count($ids));
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? invoice', count($invoices));
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('invoices');
|
||||
|
@ -18,6 +18,7 @@ class PaymentController extends \BaseController
|
||||
->leftJoin('invoices', 'invoices.id', '=','payments.invoice_id')
|
||||
->where('payments.account_id', '=', Auth::user()->account_id)
|
||||
->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');
|
||||
|
||||
if ($clientPublicId) {
|
||||
@ -57,7 +58,7 @@ class PaymentController extends \BaseController
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('payments/'.$model->public_id.'/edit') . '">Edit Payment</a></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>
|
||||
</ul>
|
||||
</div>';
|
||||
@ -152,15 +153,15 @@ class PaymentController extends \BaseController
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$payments = Payment::scope($ids)->get();
|
||||
|
||||
foreach ($payments as $payment) {
|
||||
if ($action == 'archive') {
|
||||
$payment->delete();
|
||||
} else if ($action == 'delete') {
|
||||
$payment->forceDelete();
|
||||
foreach ($payments as $payment) {
|
||||
if ($action == 'delete') {
|
||||
$payment->is_deleted = true;
|
||||
$payment->save();
|
||||
}
|
||||
$payment->delete();
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? payment', count($ids));
|
||||
$message = Utils::pluralize('Successfully '.$action.'d ? payment', count($payments));
|
||||
Session::flash('message', $message);
|
||||
|
||||
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() )
|
||||
{
|
||||
Event::fire('user.login');
|
||||
return Redirect::to('/clients');
|
||||
}
|
||||
else
|
||||
@ -101,10 +102,7 @@ class UserController extends BaseController {
|
||||
// Get the value from the config file instead of changing the controller
|
||||
if ( Confide::logAttempt( $input, Config::get('confide::signup_confirm') ) )
|
||||
{
|
||||
$account = Account::findOrFail(Auth::user()->account_id);
|
||||
$account->last_login = Carbon::now()->toDateTimeString();
|
||||
$account->save();
|
||||
|
||||
Event::fire('user.login');
|
||||
// Redirect the user to the URL they were trying to access before
|
||||
// caught by the authentication filter IE Redirect::guest('user/login').
|
||||
// Otherwise fallback to '/'
|
||||
|
@ -31,6 +31,8 @@ class ConfideSetupUsersTable extends Migration {
|
||||
Schema::dropIfExists('countries');
|
||||
Schema::dropIfExists('timezones');
|
||||
Schema::dropIfExists('frequencies');
|
||||
Schema::dropIfExists('date_formats');
|
||||
Schema::dropIfExists('datetime_formats');
|
||||
|
||||
Schema::create('countries', function($table)
|
||||
{
|
||||
@ -63,10 +65,26 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$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)
|
||||
{
|
||||
$t->increments('id');
|
||||
$t->unsignedInteger('timezone_id')->nullable();
|
||||
$t->unsignedInteger('date_format_id')->nullable();
|
||||
$t->unsignedInteger('datetime_format_id')->nullable();
|
||||
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
@ -85,19 +103,20 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->text('invoice_terms');
|
||||
|
||||
$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');
|
||||
});
|
||||
|
||||
Schema::create('gateways', function($t)
|
||||
{
|
||||
$t->increments('id');
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
$t->timestamps();
|
||||
|
||||
$t->string('name');
|
||||
$t->string('provider');
|
||||
$t->boolean('visible')->default(true);
|
||||
});
|
||||
});
|
||||
|
||||
Schema::create('account_gateways', function($t)
|
||||
{
|
||||
@ -105,8 +124,7 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->unsignedInteger('account_id');
|
||||
$t->unsignedInteger('gateway_id');
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
|
||||
|
||||
$t->text('config');
|
||||
|
||||
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
@ -175,10 +193,12 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->string('work_phone');
|
||||
$t->text('notes');
|
||||
$t->decimal('balance', 10, 2);
|
||||
$t->decimal('paid_to_date', 10, 2);
|
||||
$t->timestamp('last_login');
|
||||
$t->string('website');
|
||||
$t->unsignedInteger('client_industry_id')->nullable();
|
||||
$t->unsignedInteger('client_size_id')->nullable();
|
||||
$t->boolean('is_deleted');
|
||||
|
||||
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$t->foreign('user_id')->references('id')->on('users');
|
||||
@ -240,8 +260,8 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->string('po_number');
|
||||
$t->date('invoice_date')->nullable();
|
||||
$t->date('due_date')->nullable();
|
||||
$t->text('notes');
|
||||
|
||||
$t->text('terms');
|
||||
$t->boolean('is_deleted');
|
||||
$t->boolean('is_recurring');
|
||||
$t->unsignedInteger('frequency_id');
|
||||
$t->date('start_date')->nullable();
|
||||
@ -341,7 +361,8 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->unsignedInteger('user_id')->nullable();
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
|
||||
|
||||
$t->boolean('is_deleted');
|
||||
$t->decimal('amount', 10, 2);
|
||||
$t->date('payment_date');
|
||||
$t->string('transaction_reference');
|
||||
@ -367,8 +388,9 @@ class ConfideSetupUsersTable extends Migration {
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
|
||||
$t->boolean('is_deleted');
|
||||
$t->decimal('amount', 10, 2);
|
||||
$t->date('credit_date');
|
||||
$t->date('credit_date')->nullable();
|
||||
$t->string('credit_number');
|
||||
|
||||
$t->foreign('account_id')->references('id')->on('accounts');
|
||||
@ -432,5 +454,7 @@ class ConfideSetupUsersTable extends Migration {
|
||||
Schema::dropIfExists('countries');
|
||||
Schema::dropIfExists('timezones');
|
||||
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' => '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 = [
|
||||
array('name'=>'Authorize.Net AIM', 'provider'=>'AuthorizeNet_AIM'),
|
||||
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) {
|
||||
$tz = Session::get('tz');
|
||||
if (!$tz) {
|
||||
$tz = 'US/Eastern';
|
||||
}
|
||||
$date = new Carbon($timestamp);
|
||||
$date->tz = $tz;
|
||||
if ($date->year < 1900) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $date->format('D M jS, Y g:ia');
|
||||
$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
|
||||
$format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT);
|
||||
return Utils::timestampToString($timestamp, $timezone, $format);
|
||||
}
|
||||
|
||||
public static function timestampToDateString($timestamp) {
|
||||
$tz = Session::get('tz');
|
||||
if (!$tz) {
|
||||
$tz = 'US/Eastern';
|
||||
}
|
||||
$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
|
||||
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
|
||||
return Utils::timestampToString($timestamp, $timezone, $format);
|
||||
}
|
||||
|
||||
public static function timestampToString($timestamp, $timzone, $format)
|
||||
{
|
||||
$date = new Carbon($timestamp);
|
||||
$date->tz = $tz;
|
||||
$date->tz = $timzone;
|
||||
if ($date->year < 1900) {
|
||||
return '';
|
||||
}
|
||||
return $date->toFormattedDateString();
|
||||
return $date->format($format);
|
||||
}
|
||||
|
||||
public static function toSqlDate($date)
|
||||
|
@ -35,6 +35,17 @@ class Account extends Eloquent
|
||||
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)
|
||||
{
|
||||
if ($gatewayId)
|
||||
|
@ -131,6 +131,16 @@ class Client extends EntityModel
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function getWebsite()
|
||||
{
|
||||
if (!$this->website)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return link_to($this->website, $this->website);
|
||||
}
|
||||
|
||||
public function getDateCreated()
|
||||
{
|
||||
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
|
||||
{
|
||||
protected $softDelete = true;
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
//dd(DB::getQueryLog());
|
||||
//dd(Client::getPrivateId(1));
|
||||
//dd(new DateTime());
|
||||
|
||||
//Event::fire('user.signup');
|
||||
|
||||
Route::get('/send_emails', function() {
|
||||
Artisan::call('ninja:send-invoices');
|
||||
@ -80,9 +80,9 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::resource('credits', 'CreditController');
|
||||
Route::get('credits/create/{client_id?}', 'CreditController@create');
|
||||
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');
|
||||
});
|
||||
|
||||
|
||||
@ -160,4 +160,12 @@ define('FREQUENCY_FOUR_WEEKS', 3);
|
||||
define('FREQUENCY_MONTHLY', 4);
|
||||
define('FREQUENCY_THREE_MONTHS', 5);
|
||||
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().'/database/seeds',
|
||||
app_path().'/libraries',
|
||||
app_path().'/handlers',
|
||||
|
||||
));
|
||||
|
||||
@ -70,6 +71,11 @@ App::down(function()
|
||||
return Response::make("Be right back!", 503);
|
||||
});
|
||||
|
||||
|
||||
|
||||
Event::subscribe('UserEventHandler');
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Require The Filters File
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
{{ Former::legend('Account') }}
|
||||
{{ 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') }}
|
||||
|
||||
@if (file_exists($account->getLogoPath()))
|
||||
|
@ -3,7 +3,7 @@
|
||||
@section('content')
|
||||
@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::legend('Payment Gateway') }}
|
||||
@ -36,6 +36,15 @@
|
||||
@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::textarea('invoice_terms') }}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
{{ Former::legend('Organization') }}
|
||||
{{ Former::text('name') }}
|
||||
{{ Former::text('website') }}
|
||||
{{ Former::text('work_phone')->label('Phone') }}
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
<p>{{ $client->getPhone() }}</p>
|
||||
<p>{{ $client->getNotes() }}</p>
|
||||
<p>{{ $client->getIndustry() }}</p>
|
||||
<p>{{ $client->getWebsite() }}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
|
@ -273,7 +273,7 @@
|
||||
{{ HTML::menu_link('invoice') }}
|
||||
{{ HTML::menu_link('payment') }}
|
||||
{{ HTML::menu_link('credit') }}
|
||||
{{-- HTML::nav_link('reports', 'Reports') --}}
|
||||
{{ HTML::nav_link('reports', 'Reports') }}
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<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') }}
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{ 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 class="col-md-4" id="col_2">
|
||||
@ -94,7 +94,7 @@
|
||||
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
|
||||
</td>
|
||||
<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 style="width:100px">
|
||||
<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::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') }}
|
||||
|
||||
|
||||
@ -437,9 +438,10 @@
|
||||
this.client = new ClientModel();
|
||||
self.discount = ko.observable('');
|
||||
self.frequency_id = ko.observable('');
|
||||
self.notes = ko.observable('');
|
||||
self.terms = ko.observable('');
|
||||
self.po_number = ko.observable('');
|
||||
self.invoice_date = ko.observable('');
|
||||
self.invoice_number = ko.observable('');
|
||||
self.due_date = ko.observable('');
|
||||
self.start_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() {
|
||||
return self.client.public_id() ? 'Edit client details' : 'Create new client';
|
||||
});
|
||||
|
||||
|
||||
self.showClientForm = function() {
|
||||
if (self.client.public_id() == 0) {
|
||||
$('#myModal input').val('');
|
||||
@ -552,6 +565,7 @@
|
||||
self.country_id = ko.observable('');
|
||||
self.client_size_id = ko.observable('');
|
||||
self.client_industry_id = ko.observable('');
|
||||
self.website = ko.observable('');
|
||||
self.contacts = ko.observableArray();
|
||||
|
||||
self.mapping = {
|
||||
@ -617,6 +631,18 @@
|
||||
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() {
|
||||
var cost = parseFloat(self.cost());
|
||||
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()
|
||||
{
|
||||
var hasEmpty = false;
|
||||
@ -688,6 +684,10 @@
|
||||
if (!hasEmpty) {
|
||||
model.addItem();
|
||||
}
|
||||
|
||||
$('.word-wrap').each(function(index, input) {
|
||||
$(input).height($(input).val().split('\n').length * 22);
|
||||
});
|
||||
}
|
||||
|
||||
var products = {{ $products }};
|
||||
@ -696,8 +696,8 @@
|
||||
|
||||
for (var i=0; i<clients.length; i++) {
|
||||
var client = clients[i];
|
||||
for (var i=0; i<client.contacts.length; i++) {
|
||||
var contact = client.contacts[i];
|
||||
for (var j=0; j<client.contacts.length; j++) {
|
||||
var contact = client.contacts[j];
|
||||
contact.send_invoice = contact.is_primary;
|
||||
}
|
||||
clientMap[client.public_id] = client;
|
||||
@ -716,7 +716,8 @@
|
||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||
}
|
||||
@else
|
||||
model.invoice_number = '{{ $invoiceNumber }}';
|
||||
model.invoice_number('{{ $invoiceNumber }}');
|
||||
model.terms(wordWrapText('{{ $account->invoice_terms }}', 250));
|
||||
@endif
|
||||
model.invoice_items.push(new ItemModel());
|
||||
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,12 +139,16 @@ function generatePDF(invoice) {
|
||||
var x = tableTop + (line * rowHeight);
|
||||
doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x);
|
||||
|
||||
|
||||
doc.text(tableLeft, x+16, invoice.terms);
|
||||
|
||||
x += 16;
|
||||
doc.text(footerLeft, x, 'Subtotal');
|
||||
var total = formatNumber(total);
|
||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||
doc.text(totalX, x, total);
|
||||
|
||||
if (invoice.discount > 0) {
|
||||
x += 16;
|
||||
doc.text(footerLeft, x, 'Subtotal');
|
||||
var total = formatNumber(total);
|
||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||
doc.text(totalX, x, total);
|
||||
|
||||
x += 16;
|
||||
doc.text(footerLeft, x, 'Discount');
|
||||
@ -154,6 +158,13 @@ function generatePDF(invoice) {
|
||||
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;
|
||||
doc.setFontType("bold");
|
||||
doc.text(footerLeft, x, 'Total');
|
||||
@ -229,15 +240,6 @@ function generatePDF(invoice) {
|
||||
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) */
|
||||
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 */
|
||||
$.extend( true, $.fn.dataTable.defaults, {
|
||||
"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 = {};
|
||||
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user