mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
bug fixes
This commit is contained in:
parent
ef24ac2c36
commit
2b5f42e5ac
@ -40,7 +40,8 @@ class SendRecurringInvoices extends Command {
|
|||||||
$invoice->client_id = $recurInvoice->client_id;
|
$invoice->client_id = $recurInvoice->client_id;
|
||||||
$invoice->recurring_invoice_id = $recurInvoice->id;
|
$invoice->recurring_invoice_id = $recurInvoice->id;
|
||||||
$invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber();
|
$invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber();
|
||||||
$invoice->total = $recurInvoice->total;
|
$invoice->amount = $recurInvoice->amount;
|
||||||
|
$invoice->currency_id = $recurInvoice->currency_id;
|
||||||
$invoice->invoice_date = new DateTime();
|
$invoice->invoice_date = new DateTime();
|
||||||
$invoice->due_date = new DateTime();
|
$invoice->due_date = new DateTime();
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
|
@ -4,12 +4,18 @@ class ActivityController extends \BaseController {
|
|||||||
|
|
||||||
public function getDatatable($clientPublicId)
|
public function getDatatable($clientPublicId)
|
||||||
{
|
{
|
||||||
$clientId = Client::getPrivateId($clientPublicId);
|
$query = DB::table('activities')
|
||||||
|
->join('clients', 'clients.id', '=', 'activities.client_id')
|
||||||
|
->where('clients.public_id', '=', $clientPublicId)
|
||||||
|
->where('activities.account_id', '=', Auth::user()->account_id)
|
||||||
|
->select('activities.message', 'activities.created_at', 'activities.currency_id', 'activities.balance', 'activities.adjustment');
|
||||||
|
|
||||||
return Datatable::collection(Activity::scope()->where('client_id','=',$clientId)->get())
|
|
||||||
|
return Datatable::query($query)
|
||||||
->addColumn('date', function($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
->addColumn('date', function($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||||
->addColumn('message', function($model) { return $model->message; })
|
->addColumn('message', function($model) { return $model->message; })
|
||||||
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->account->currency_id); })
|
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||||
|
->addColumn('adjustment', function($model) { return $model->adjustment != 0 ? Utils::formatMoney($model->adjustment, $model->currency_id) : ''; })
|
||||||
->orderColumns('date')
|
->orderColumns('date')
|
||||||
->make();
|
->make();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class ClientController extends \BaseController {
|
|||||||
return View::make('list', array(
|
return View::make('list', array(
|
||||||
'entityType'=>ENTITY_CLIENT,
|
'entityType'=>ENTITY_CLIENT,
|
||||||
'title' => '- Clients',
|
'title' => '- Clients',
|
||||||
'columns'=>['checkbox', 'Client', 'Contact', 'Date Created', 'Email', 'Phone', 'Last Login', 'Balance', 'Action']
|
'columns'=>['checkbox', 'Client', 'Contact', 'Email', 'Date Created', 'Phone', 'Last Login', 'Balance', 'Action']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ class ClientController extends \BaseController {
|
|||||||
return Datatable::query($query)
|
return Datatable::query($query)
|
||||||
->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; })
|
->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; })
|
||||||
->addColumn('name', function($model) { return link_to('clients/' . $model->public_id, $model->name); })
|
->addColumn('name', function($model) { return link_to('clients/' . $model->public_id, $model->name); })
|
||||||
->addColumn('first_name', function($model) { return $model->first_name . ' ' . $model->last_name; })
|
->addColumn('first_name', function($model) { return link_to('clients/' . $model->public_id, $model->first_name . ' ' . $model->last_name); })
|
||||||
|
->addColumn('email', function($model) { return link_to('clients/' . $model->public_id, $model->email); })
|
||||||
->addColumn('created_at', function($model) { return Utils::timestampToDateString(strtotime($model->created_at)); })
|
->addColumn('created_at', function($model) { return Utils::timestampToDateString(strtotime($model->created_at)); })
|
||||||
->addColumn('email', function($model) { return $model->email ? HTML::mailto($model->email, $model->email) : ''; })
|
|
||||||
->addColumn('work_phone', function($model) { return Utils::formatPhoneNumber($model->work_phone); })
|
->addColumn('work_phone', function($model) { return Utils::formatPhoneNumber($model->work_phone); })
|
||||||
->addColumn('last_login', function($model) { return Utils::timestampToDateString($model->last_login); })
|
->addColumn('last_login', function($model) { return Utils::timestampToDateString($model->last_login); })
|
||||||
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||||
@ -88,6 +88,7 @@ class ClientController extends \BaseController {
|
|||||||
'title' => '- New Client',
|
'title' => '- New Client',
|
||||||
'clientSizes' => ClientSize::orderBy('id')->get(),
|
'clientSizes' => ClientSize::orderBy('id')->get(),
|
||||||
'clientIndustries' => ClientIndustry::orderBy('name')->get(),
|
'clientIndustries' => ClientIndustry::orderBy('name')->get(),
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'countries' => Country::orderBy('name')->get());
|
'countries' => Country::orderBy('name')->get());
|
||||||
|
|
||||||
return View::make('clients.edit', $data);
|
return View::make('clients.edit', $data);
|
||||||
@ -117,7 +118,7 @@ class ClientController extends \BaseController {
|
|||||||
$data = array(
|
$data = array(
|
||||||
'client' => $client,
|
'client' => $client,
|
||||||
'title' => '- ' . $client->name,
|
'title' => '- ' . $client->name,
|
||||||
'hasRecurringInvoices' => Invoice::scope()->where('frequency_id', '>', '0')->whereClientId($client->id)->count() > 0
|
'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0
|
||||||
);
|
);
|
||||||
|
|
||||||
return View::make('clients.show', $data);
|
return View::make('clients.show', $data);
|
||||||
@ -158,7 +159,7 @@ class ClientController extends \BaseController {
|
|||||||
private function save($publicId = null)
|
private function save($publicId = null)
|
||||||
{
|
{
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'name' => 'required'
|
'email' => 'required'
|
||||||
);
|
);
|
||||||
$validator = Validator::make(Input::all(), $rules);
|
$validator = Validator::make(Input::all(), $rules);
|
||||||
|
|
||||||
@ -182,7 +183,7 @@ class ClientController extends \BaseController {
|
|||||||
$client->state = trim(Input::get('state'));
|
$client->state = trim(Input::get('state'));
|
||||||
$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->private_notes = trim(Input::get('private_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->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
$client->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
||||||
|
@ -20,10 +20,12 @@ class CreditController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$query = DB::table('credits')
|
$query = DB::table('credits')
|
||||||
->join('clients', 'clients.id', '=','credits.client_id')
|
->join('clients', 'clients.id', '=','credits.client_id')
|
||||||
|
->join('contacts', 'contacts.client_id', '=', 'clients.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)
|
->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', 'credits.currency_id');
|
->where('contacts.is_primary', '=', true)
|
||||||
|
->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.credit_date', 'credits.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -42,7 +44,7 @@ class CreditController extends \BaseController {
|
|||||||
|
|
||||||
if (!$clientPublicId) {
|
if (!$clientPublicId) {
|
||||||
$table->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; })
|
$table->addColumn('checkbox', function($model) { return '<input type="checkbox" name="ids[]" value="' . $model->public_id . '">'; })
|
||||||
->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('amount', function($model){ return Utils::formatMoney($model->amount, $model->currency_id); })
|
return $table->addColumn('amount', function($model){ return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||||
@ -68,19 +70,14 @@ class CreditController extends \BaseController {
|
|||||||
|
|
||||||
public function create($clientPublicId = null)
|
public function create($clientPublicId = null)
|
||||||
{
|
{
|
||||||
$client = null;
|
|
||||||
if ($clientPublicId) {
|
|
||||||
$client = Client::scope($clientPublicId)->firstOrFail();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'client' => $client,
|
'clientPublicId' => $clientPublicId,
|
||||||
'credit' => null,
|
'credit' => null,
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'credits',
|
'url' => 'credits',
|
||||||
'title' => '- New Credit',
|
'title' => '- New Credit',
|
||||||
'currencies' => Currency::orderBy('name')->get(),
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
|
||||||
|
|
||||||
return View::make('credits.edit', $data);
|
return View::make('credits.edit', $data);
|
||||||
}
|
}
|
||||||
@ -95,7 +92,7 @@ class CreditController extends \BaseController {
|
|||||||
'url' => 'credits/' . $publicId,
|
'url' => 'credits/' . $publicId,
|
||||||
'title' => '- Edit Credit',
|
'title' => '- Edit Credit',
|
||||||
'currencies' => Currency::orderBy('name')->get(),
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
|
||||||
return View::make('credit.edit', $data);
|
return View::make('credit.edit', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$table->addColumn('invoice_number', function($model) { return link_to('invoices/' . $model->public_id . '/edit', $model->invoice_number); });
|
$table->addColumn('invoice_number', function($model) { return link_to('invoices/' . $model->public_id . '/edit', $model->invoice_number); });
|
||||||
|
|
||||||
if (!$clientPublicId) {
|
if (!$clientPublicId) {
|
||||||
$table->addColumn('client', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
$table->addColumn('client', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
||||||
@ -89,7 +89,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$table->addColumn('frequency', function($model) { return link_to('invoices/' . $model->public_id, $model->frequency); });
|
$table->addColumn('frequency', function($model) { return link_to('invoices/' . $model->public_id, $model->frequency); });
|
||||||
|
|
||||||
if (!$clientPublicId) {
|
if (!$clientPublicId) {
|
||||||
$table->addColumn('client', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
$table->addColumn('client', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
||||||
@ -385,10 +385,8 @@ class InvoiceController extends \BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$input = json_decode(Input::get('data'));
|
$input = json_decode(Input::get('data'));
|
||||||
$inputClient = $input->client;
|
|
||||||
$inputClient->name = trim($inputClient->name);
|
|
||||||
|
|
||||||
if (!$inputClient->name)
|
if (!$input->client->contacts[0]->email)
|
||||||
{
|
{
|
||||||
return Redirect::to('invoices/create')
|
return Redirect::to('invoices/create')
|
||||||
->withInput();
|
->withInput();
|
||||||
@ -521,7 +519,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
|
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
|
||||||
|
|
||||||
$clone = Invoice::createNew();
|
$clone = Invoice::createNew();
|
||||||
foreach (['client_id', 'discount', 'invoice_date', 'due_date', 'is_recurring', 'frequency_id', 'start_date', 'end_date', 'notes'] as $field)
|
foreach (['client_id', 'discount', 'invoice_date', 'due_date', 'is_recurring', 'frequency_id', 'start_date', 'end_date', 'terms', 'currency_id'] as $field)
|
||||||
{
|
{
|
||||||
$clone->$field = $invoice->$field;
|
$clone->$field = $invoice->$field;
|
||||||
}
|
}
|
||||||
@ -537,7 +535,7 @@ class InvoiceController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$cloneItem = InvoiceItem::createNew();
|
$cloneItem = InvoiceItem::createNew();
|
||||||
|
|
||||||
foreach (['product_id', 'product_key', 'notes', 'cost', 'qty'] as $field)
|
foreach (['product_id', 'product_key', 'notes', 'cost', 'qty', 'tax_name', 'tax_rate'] as $field)
|
||||||
{
|
{
|
||||||
$cloneItem->$field = $item->$field;
|
$cloneItem->$field = $item->$field;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,12 @@ class PaymentController extends \BaseController
|
|||||||
$query = DB::table('payments')
|
$query = DB::table('payments')
|
||||||
->join('clients', 'clients.id', '=','payments.client_id')
|
->join('clients', 'clients.id', '=','payments.client_id')
|
||||||
->leftJoin('invoices', 'invoices.id', '=','payments.invoice_id')
|
->leftJoin('invoices', 'invoices.id', '=','payments.invoice_id')
|
||||||
|
->join('contacts', 'contacts.client_id', '=', 'clients.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)
|
->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', 'payments.currency_id');
|
->where('contacts.is_primary', '=', true)
|
||||||
|
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'payments.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -43,7 +45,7 @@ class PaymentController extends \BaseController
|
|||||||
$table->addColumn('transaction_reference', function($model) { return $model->transaction_reference ? $model->transaction_reference : '<i>Manual entry</i>'; });
|
$table->addColumn('transaction_reference', function($model) { return $model->transaction_reference ? $model->transaction_reference : '<i>Manual entry</i>'; });
|
||||||
|
|
||||||
if (!$clientPublicId) {
|
if (!$clientPublicId) {
|
||||||
$table->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
$table->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
||||||
@ -70,21 +72,16 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
public function create($clientPublicId = 0)
|
public function create($clientPublicId = 0)
|
||||||
{
|
{
|
||||||
$client = null;
|
|
||||||
if ($clientPublicId) {
|
|
||||||
$client = Client::scope($clientPublicId)->firstOrFail();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'client' => $client,
|
'clientPublicId' => $clientPublicId,
|
||||||
'invoice' => null,
|
'invoice' => null,
|
||||||
'invoices' => Invoice::with('client')->scope()->orderBy('invoice_number')->get(),
|
'invoices' => Invoice::scope()->with('client')->orderBy('invoice_number')->get(),
|
||||||
'payment' => null,
|
'payment' => null,
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'payments',
|
'url' => 'payments',
|
||||||
'title' => '- New Payment',
|
'title' => '- New Payment',
|
||||||
'currencies' => Currency::orderBy('name')->get(),
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
|
||||||
|
|
||||||
return View::make('payments.edit', $data);
|
return View::make('payments.edit', $data);
|
||||||
}
|
}
|
||||||
@ -95,13 +92,13 @@ class PaymentController extends \BaseController
|
|||||||
$data = array(
|
$data = array(
|
||||||
'client' => null,
|
'client' => null,
|
||||||
'invoice' => null,
|
'invoice' => null,
|
||||||
'invoices' => Invoice::scope()->orderBy('invoice_number')->get(array('public_id','invoice_number')),
|
'invoices' => Invoice::scope()->with('client')->orderBy('invoice_number')->get(array('public_id','invoice_number')),
|
||||||
'payment' => $payment,
|
'payment' => $payment,
|
||||||
'method' => 'PUT',
|
'method' => 'PUT',
|
||||||
'url' => 'payments/' . $publicId,
|
'url' => 'payments/' . $publicId,
|
||||||
'title' => '- Edit Payment',
|
'title' => '- Edit Payment',
|
||||||
'currencies' => Currency::orderBy('name')->get(),
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
|
||||||
return View::make('payments.edit', $data);
|
return View::make('payments.edit', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->boolean('confirmed')->default(false);
|
$t->boolean('confirmed')->default(false);
|
||||||
$t->integer('theme_id');
|
$t->integer('theme_id');
|
||||||
|
|
||||||
$t->boolean('notify_sent')->default(false);
|
$t->boolean('notify_sent')->default(true);
|
||||||
$t->boolean('notify_viewed')->default(false);
|
$t->boolean('notify_viewed')->default(false);
|
||||||
$t->boolean('notify_paid')->default(true);
|
$t->boolean('notify_paid')->default(true);
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->string('postal_code');
|
$t->string('postal_code');
|
||||||
$t->unsignedInteger('country_id')->nullable();
|
$t->unsignedInteger('country_id')->nullable();
|
||||||
$t->string('work_phone');
|
$t->string('work_phone');
|
||||||
$t->text('notes');
|
$t->text('private_notes');
|
||||||
$t->decimal('balance', 13, 4);
|
$t->decimal('balance', 13, 4);
|
||||||
$t->decimal('paid_to_date', 13, 4);
|
$t->decimal('paid_to_date', 13, 4);
|
||||||
$t->timestamp('last_login')->nullable();
|
$t->timestamp('last_login')->nullable();
|
||||||
@ -285,6 +285,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->date('invoice_date')->nullable();
|
$t->date('invoice_date')->nullable();
|
||||||
$t->date('due_date')->nullable();
|
$t->date('due_date')->nullable();
|
||||||
$t->text('terms');
|
$t->text('terms');
|
||||||
|
$t->text('public_notes');
|
||||||
$t->boolean('is_deleted');
|
$t->boolean('is_deleted');
|
||||||
$t->boolean('is_recurring');
|
$t->boolean('is_recurring');
|
||||||
$t->unsignedInteger('frequency_id');
|
$t->unsignedInteger('frequency_id');
|
||||||
|
@ -246,4 +246,20 @@ class Utils
|
|||||||
return ucwords(str_replace('_', ' ', $entityType));
|
return ucwords(str_replace('_', ' ', $entityType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getClientDisplayName($model)
|
||||||
|
{
|
||||||
|
if ($model->client_name)
|
||||||
|
{
|
||||||
|
return $model->client_name;
|
||||||
|
}
|
||||||
|
else if ($model->first_name || $model->last_name)
|
||||||
|
{
|
||||||
|
return $model->first_name . ' ' . $model->last_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $model->email;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,16 +5,17 @@ define("ACTIVITY_TYPE_CREATE_CLIENT", 1);
|
|||||||
define("ACTIVITY_TYPE_ARCHIVE_CLIENT", 2);
|
define("ACTIVITY_TYPE_ARCHIVE_CLIENT", 2);
|
||||||
define("ACTIVITY_TYPE_DELETE_CLIENT", 3);
|
define("ACTIVITY_TYPE_DELETE_CLIENT", 3);
|
||||||
define("ACTIVITY_TYPE_CREATE_INVOICE", 4);
|
define("ACTIVITY_TYPE_CREATE_INVOICE", 4);
|
||||||
define("ACTIVITY_TYPE_EMAIL_INVOICE", 5);
|
define("ACTIVITY_TYPE_UPDATE_INVOICE", 5);
|
||||||
define("ACTIVITY_TYPE_VIEW_INVOICE", 6);
|
define("ACTIVITY_TYPE_EMAIL_INVOICE", 6);
|
||||||
define("ACTIVITY_TYPE_ARCHIVE_INVOICE", 7);
|
define("ACTIVITY_TYPE_VIEW_INVOICE", 7);
|
||||||
define("ACTIVITY_TYPE_DELETE_INVOICE", 8);
|
define("ACTIVITY_TYPE_ARCHIVE_INVOICE", 8);
|
||||||
define("ACTIVITY_TYPE_CREATE_PAYMENT", 9);
|
define("ACTIVITY_TYPE_DELETE_INVOICE", 9);
|
||||||
define("ACTIVITY_TYPE_ARCHIVE_PAYMENT", 10);
|
define("ACTIVITY_TYPE_CREATE_PAYMENT", 10);
|
||||||
define("ACTIVITY_TYPE_DELETE_PAYMENT", 11);
|
define("ACTIVITY_TYPE_ARCHIVE_PAYMENT", 11);
|
||||||
define("ACTIVITY_TYPE_CREATE_CREDIT", 12);
|
define("ACTIVITY_TYPE_DELETE_PAYMENT", 12);
|
||||||
define("ACTIVITY_TYPE_ARCHIVE_CREDIT", 13);
|
define("ACTIVITY_TYPE_CREATE_CREDIT", 13);
|
||||||
define("ACTIVITY_TYPE_DELETE_CREDIT", 14);
|
define("ACTIVITY_TYPE_ARCHIVE_CREDIT", 14);
|
||||||
|
define("ACTIVITY_TYPE_DELETE_CREDIT", 15);
|
||||||
|
|
||||||
|
|
||||||
class Activity extends Eloquent
|
class Activity extends Eloquent
|
||||||
@ -55,7 +56,6 @@ class Activity extends Eloquent
|
|||||||
$activity->client_id = $client->id;
|
$activity->client_id = $client->id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CLIENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CLIENT;
|
||||||
$activity->message = Auth::user()->getFullName() . ' created client ' . link_to('clients/'.$client->public_id, $client->name);
|
$activity->message = Auth::user()->getFullName() . ' created client ' . link_to('clients/'.$client->public_id, $client->name);
|
||||||
|
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ class Activity extends Eloquent
|
|||||||
$activity->client_id = $client->id;
|
$activity->client_id = $client->id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CLIENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CLIENT;
|
||||||
$activity->message = Auth::user()->getFullName() . ' archived client ' . $client->name;
|
$activity->message = Auth::user()->getFullName() . ' archived client ' . $client->name;
|
||||||
|
$activity->balance = $client->balance;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +73,12 @@ class Activity extends Eloquent
|
|||||||
{
|
{
|
||||||
$userName = Auth::check() ? Auth::user()->getFullName() : '<i>System</i>';
|
$userName = Auth::check() ? Auth::user()->getFullName() : '<i>System</i>';
|
||||||
|
|
||||||
if ($invoice->is_recurring) {
|
if ($invoice->is_recurring)
|
||||||
|
{
|
||||||
$message = $userName . ' created ' . link_to('invoices/'.$invoice->public_id, 'recuring invoice');
|
$message = $userName . ' created ' . link_to('invoices/'.$invoice->public_id, 'recuring invoice');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$message = $userName . ' created invoice ' . link_to('invoices/'.$invoice->public_id, $invoice->invoice_number);
|
$message = $userName . ' created invoice ' . link_to('invoices/'.$invoice->public_id, $invoice->invoice_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +88,7 @@ class Activity extends Eloquent
|
|||||||
$activity->currency_id = $invoice->currency_id;
|
$activity->currency_id = $invoice->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE;
|
||||||
$activity->message = $message;
|
$activity->message = $message;
|
||||||
|
$activity->balance = $invoice->client->balance;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,11 +99,22 @@ class Activity extends Eloquent
|
|||||||
$activity->client_id = $invoice->client_id;
|
$activity->client_id = $invoice->client_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_INVOICE;
|
||||||
$activity->message = Auth::user()->getFullName() . ' archived invoice ' . $invoice->invoice_number;
|
$activity->message = Auth::user()->getFullName() . ' archived invoice ' . $invoice->invoice_number;
|
||||||
|
$activity->balance = $invoice->client->balance;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailInvoice($invitation)
|
public static function emailInvoice($invitation)
|
||||||
{
|
{
|
||||||
|
$adjustment = 0;
|
||||||
|
|
||||||
|
if (!$invitation->invoice->isSent())
|
||||||
|
{
|
||||||
|
$adjustment = $invitation->invoice->amount;
|
||||||
|
$client = $invitation->invoice->client;
|
||||||
|
$client->balance = $client->balance + $adjustment;
|
||||||
|
$client->save();
|
||||||
|
}
|
||||||
|
|
||||||
$userName = Auth::check() ? Auth::user()->getFullName() : '<i>System</i>';
|
$userName = Auth::check() ? Auth::user()->getFullName() : '<i>System</i>';
|
||||||
$activity = Activity::getBlank($invitation);
|
$activity = Activity::getBlank($invitation);
|
||||||
$activity->client_id = $invitation->invoice->client_id;
|
$activity->client_id = $invitation->invoice->client_id;
|
||||||
@ -106,11 +122,45 @@ class Activity extends Eloquent
|
|||||||
$activity->contact_id = $invitation->contact_id;
|
$activity->contact_id = $invitation->contact_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE;
|
||||||
$activity->message = $userName . ' emailed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number) . ' to ' . $invitation->contact->getFullName();
|
$activity->message = $userName . ' emailed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number) . ' to ' . $invitation->contact->getFullName();
|
||||||
|
$activity->balance = $invitation->invoice->client->balance;
|
||||||
|
$activity->adjustment = $adjustment;
|
||||||
|
$activity->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateInvoice($invoice)
|
||||||
|
{
|
||||||
|
if ($invoice->invoice_status_id < INVOICE_STATUS_SENT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
|
||||||
|
|
||||||
|
if ($diff == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$client = $invoice->client;
|
||||||
|
$client->balance = $client->balance + $diff;
|
||||||
|
$client->save();
|
||||||
|
|
||||||
|
$activity = Activity::getBlank($invoice);
|
||||||
|
$activity->client_id = $invoice->client_id;
|
||||||
|
$activity->invoice_id = $invoice->id;
|
||||||
|
$activity->activity_type_id = ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||||
|
$activity->message = Auth::user()->getFullName() . ' updated invoice ' . link_to('invoices/'.$invoice->public_id, $invoice->invoice_number);
|
||||||
|
$activity->balance = $client->balance;
|
||||||
|
$activity->adjustment = $diff;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function createPayment($payment)
|
public static function createPayment($payment)
|
||||||
{
|
{
|
||||||
|
$client = $payment->client;
|
||||||
|
$client->balance = $client->balance - $payment->amount;
|
||||||
|
$client->save();
|
||||||
|
|
||||||
if (Auth::check())
|
if (Auth::check())
|
||||||
{
|
{
|
||||||
$activity = Activity::getBlank();
|
$activity = Activity::getBlank();
|
||||||
@ -130,23 +180,28 @@ class Activity extends Eloquent
|
|||||||
$activity->client_id = $payment->client_id;
|
$activity->client_id = $payment->client_id;
|
||||||
$activity->currency_id = $payment->currency_id;
|
$activity->currency_id = $payment->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
||||||
|
$activity->balance = $client->balance;
|
||||||
|
$activity->adjustment = $payment->amount * -1;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function createCredit($credit)
|
public static function createCredit($credit)
|
||||||
{
|
{
|
||||||
|
$client = $credit->client;
|
||||||
|
$client->balance = $client->balance - $credit->amount;
|
||||||
|
$client->save();
|
||||||
|
|
||||||
$activity = Activity::getBlank();
|
$activity = Activity::getBlank();
|
||||||
$activity->message = Auth::user()->getFullName() . ' created credit';
|
$activity->message = Auth::user()->getFullName() . ' created credit';
|
||||||
$activity->credit_id = $credit->id;
|
$activity->credit_id = $credit->id;
|
||||||
$activity->client_id = $credit->client_id;
|
$activity->client_id = $credit->client_id;
|
||||||
$activity->currency_id = $credit->currency_id;
|
$activity->currency_id = $credit->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
||||||
|
$activity->balance = $client->balance;
|
||||||
|
$activity->adjustment = $credit->amount * -1;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function archivePayment($payment)
|
public static function archivePayment($payment)
|
||||||
{
|
{
|
||||||
$activity = Activity::getBlank();
|
$activity = Activity::getBlank();
|
||||||
@ -154,6 +209,7 @@ class Activity extends Eloquent
|
|||||||
$activity->client_id = $invoice->client_id;
|
$activity->client_id = $invoice->client_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_PAYMENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_PAYMENT;
|
||||||
$activity->message = Auth::user()->getFullName() . ' archived payment';
|
$activity->message = Auth::user()->getFullName() . ' archived payment';
|
||||||
|
$activity->balance = $payment->client->balance;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +224,7 @@ class Activity extends Eloquent
|
|||||||
$activity->invoice_id = $invitation->invoice_id;
|
$activity->invoice_id = $invitation->invoice_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_VIEW_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_VIEW_INVOICE;
|
||||||
$activity->message = $invitation->contact->getFullName() . ' viewed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number);
|
$activity->message = $invitation->contact->getFullName() . ' viewed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number);
|
||||||
|
$activity->balance = $invitation->invoice->client->balance;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class Client extends EntityModel
|
class Client extends EntityModel
|
||||||
{
|
{
|
||||||
protected $hidden = array('id', 'account_id', 'created_at', 'updated_at', 'deleted_at', 'notes', 'last_login');
|
protected $hidden = array('id', 'account_id', 'created_at', 'updated_at', 'deleted_at', 'private_notes', 'last_login');
|
||||||
|
|
||||||
public static $fieldName = 'Client - Name';
|
public static $fieldName = 'Client - Name';
|
||||||
public static $fieldPhone = 'Client - Phone';
|
public static $fieldPhone = 'Client - Phone';
|
||||||
|
@ -35,6 +35,11 @@ class Contact extends EntityModel
|
|||||||
|
|
||||||
public function getFullName()
|
public function getFullName()
|
||||||
{
|
{
|
||||||
|
if (!$this->first_name && !$this->last_name)
|
||||||
|
{
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
$fullName = $this->first_name . ' ' . $this->last_name;
|
$fullName = $this->first_name . ' ' . $this->last_name;
|
||||||
|
|
||||||
if ($fullName == ' ')
|
if ($fullName == ' ')
|
||||||
|
@ -19,8 +19,3 @@ class Invitation extends EntityModel
|
|||||||
return $this->belongsTo('User');
|
return $this->belongsTo('User');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Invitation::created(function($invitation)
|
|
||||||
{
|
|
||||||
Activity::emailInvoice($invitation);
|
|
||||||
});
|
|
@ -96,3 +96,8 @@ Invoice::created(function($invoice)
|
|||||||
{
|
{
|
||||||
Activity::createInvoice($invoice);
|
Activity::createInvoice($invoice);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Invoice::updating(function($invoice)
|
||||||
|
{
|
||||||
|
Activity::updateInvoice($invoice);
|
||||||
|
});
|
@ -5,6 +5,7 @@ use Contact;
|
|||||||
use Invitation;
|
use Invitation;
|
||||||
use URL;
|
use URL;
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use Activity;
|
||||||
|
|
||||||
class ContactMailer extends Mailer {
|
class ContactMailer extends Mailer {
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ class ContactMailer extends Mailer {
|
|||||||
$invitation->save();
|
$invitation->save();
|
||||||
|
|
||||||
$this->sendTo($invitation->contact->email, $subject, $view, $data);
|
$this->sendTo($invitation->contact->email, $subject, $view, $data);
|
||||||
|
|
||||||
|
Activity::emailInvoice($invitation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$invoice->isSent())
|
if (!$invoice->isSent())
|
||||||
|
@ -9,13 +9,14 @@ class AccountRepository
|
|||||||
{
|
{
|
||||||
$clients = \DB::table('clients')
|
$clients = \DB::table('clients')
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
|
->whereRaw("clients.name <> ''")
|
||||||
->select(\DB::raw("'Clients' as type, clients.public_id, clients.name, '' as token"));
|
->select(\DB::raw("'Clients' as type, clients.public_id, clients.name, '' as token"));
|
||||||
|
|
||||||
$contacts = \DB::table('clients')
|
$contacts = \DB::table('clients')
|
||||||
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->whereRaw("CONCAT(contacts.first_name, contacts.last_name) <> ''")
|
->whereRaw("CONCAT(contacts.first_name, contacts.last_name, contacts.email) <> ''")
|
||||||
->select(\DB::raw("'Contacts' as type, clients.public_id, CONCAT(contacts.first_name, ' ', contacts.last_name, ': ', clients.name) as name, '' as token"));
|
->select(\DB::raw("'Contacts' as type, clients.public_id, CONCAT(contacts.first_name, ' ', contacts.last_name, ' ', contacts.email) as name, '' as token"));
|
||||||
|
|
||||||
$invoices = \DB::table('clients')
|
$invoices = \DB::table('clients')
|
||||||
->join('invoices', 'invoices.client_id', '=', 'clients.id')
|
->join('invoices', 'invoices.client_id', '=', 'clients.id')
|
||||||
|
@ -27,7 +27,7 @@ class ClientRepository
|
|||||||
$client->state = trim($data['state']);
|
$client->state = trim($data['state']);
|
||||||
$client->postal_code = trim($data['postal_code']);
|
$client->postal_code = trim($data['postal_code']);
|
||||||
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
|
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
|
||||||
$client->notes = trim($data['notes']);
|
$client->private_notes = trim($data['private_notes']);
|
||||||
$client->client_size_id = $data['client_size_id'] ? $data['client_size_id'] : null;
|
$client->client_size_id = $data['client_size_id'] ? $data['client_size_id'] : null;
|
||||||
$client->client_industry_id = $data['client_industry_id'] ? $data['client_industry_id'] : null;
|
$client->client_industry_id = $data['client_industry_id'] ? $data['client_industry_id'] : null;
|
||||||
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : null;
|
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : null;
|
||||||
|
@ -13,11 +13,13 @@ class InvoiceRepository
|
|||||||
$query = \DB::table('invoices')
|
$query = \DB::table('invoices')
|
||||||
->join('clients', 'clients.id', '=','invoices.client_id')
|
->join('clients', 'clients.id', '=','invoices.client_id')
|
||||||
->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id')
|
->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id')
|
||||||
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->where('invoices.account_id', '=', $accountId)
|
->where('invoices.account_id', '=', $accountId)
|
||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('clients.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', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'invoices.currency_id');
|
->where('contacts.is_primary', '=', true)
|
||||||
|
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'invoices.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
||||||
|
|
||||||
if ($clientPublicId)
|
if ($clientPublicId)
|
||||||
{
|
{
|
||||||
@ -42,10 +44,12 @@ class InvoiceRepository
|
|||||||
$query = \DB::table('invoices')
|
$query = \DB::table('invoices')
|
||||||
->join('clients', 'clients.id', '=','invoices.client_id')
|
->join('clients', 'clients.id', '=','invoices.client_id')
|
||||||
->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id')
|
->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id')
|
||||||
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->where('invoices.account_id', '=', $accountId)
|
->where('invoices.account_id', '=', $accountId)
|
||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', true)
|
->where('invoices.is_recurring', '=', true)
|
||||||
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date', 'invoices.currency_id');
|
->where('contacts.is_primary', '=', true)
|
||||||
|
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date', 'invoices.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
||||||
|
|
||||||
if ($clientPublicId)
|
if ($clientPublicId)
|
||||||
{
|
{
|
||||||
@ -87,6 +91,7 @@ class InvoiceRepository
|
|||||||
$invoice->start_date = Utils::toSqlDate($data['start_date']);
|
$invoice->start_date = Utils::toSqlDate($data['start_date']);
|
||||||
$invoice->end_date = Utils::toSqlDate($data['end_date']);
|
$invoice->end_date = Utils::toSqlDate($data['end_date']);
|
||||||
$invoice->terms = trim($data['terms']);
|
$invoice->terms = trim($data['terms']);
|
||||||
|
$invoice->public_notes = trim($data['public_notes']);
|
||||||
$invoice->po_number = trim($data['po_number']);
|
$invoice->po_number = trim($data['po_number']);
|
||||||
$invoice->currency_id = $data['currency_id'];
|
$invoice->currency_id = $data['currency_id'];
|
||||||
|
|
||||||
@ -108,6 +113,7 @@ class InvoiceRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
$invoice->amount = $total;
|
$invoice->amount = $total;
|
||||||
|
$invoice->balance = $total;
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
|
|
||||||
foreach ($data['invoice_items'] as $item)
|
foreach ($data['invoice_items'] as $item)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
@section('onReady')
|
@section('onReady')
|
||||||
$('input#name').focus();
|
$('input#first_name').focus();
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@ -10,8 +10,7 @@
|
|||||||
<!--<h3>{{ $title }} Client</h3>-->
|
<!--<h3>{{ $title }} Client</h3>-->
|
||||||
|
|
||||||
{{ Former::open($url)->addClass('col-md-10 col-md-offset-1 main_form')->method($method)->rules(array(
|
{{ Former::open($url)->addClass('col-md-10 col-md-offset-1 main_form')->method($method)->rules(array(
|
||||||
'name' => 'required',
|
'email' => 'email|required'
|
||||||
'email' => 'email'
|
|
||||||
)); }}
|
)); }}
|
||||||
|
|
||||||
@if ($client)
|
@if ($client)
|
||||||
@ -20,25 +19,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
{{ Former::legend('Organization') }}
|
|
||||||
{{ Former::text('name') }}
|
|
||||||
{{ Former::text('website') }}
|
|
||||||
{{ Former::text('work_phone')->label('Phone') }}
|
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Address') }}
|
|
||||||
{{ Former::text('address1')->label('Street') }}
|
|
||||||
{{ Former::text('address2')->label('Apt/Floor') }}
|
|
||||||
{{ Former::text('city') }}
|
|
||||||
{{ Former::text('state') }}
|
|
||||||
{{ Former::text('postal_code') }}
|
|
||||||
{{ Former::select('country_id')->addOption('','')->label('Country')
|
|
||||||
->fromQuery($countries, 'name', 'id')->select($client ? $client->country_id : '') }}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
||||||
{{ Former::legend('Contacts') }}
|
{{ Former::legend('Contacts') }}
|
||||||
@ -70,7 +50,28 @@
|
|||||||
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
||||||
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')
|
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')
|
||||||
->fromQuery($clientIndustries, 'name', 'id')->select($client ? $client->client_industry_id : '') }}
|
->fromQuery($clientIndustries, 'name', 'id')->select($client ? $client->client_industry_id : '') }}
|
||||||
{{ Former::textarea('notes') }}
|
{{ Former::textarea('private_notes') }}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
|
||||||
|
{{ Former::legend('Organization') }}
|
||||||
|
{{ Former::text('name') }}
|
||||||
|
{{ Former::text('website') }}
|
||||||
|
{{ Former::text('work_phone')->label('Phone') }}
|
||||||
|
|
||||||
|
|
||||||
|
{{ Former::legend('Address') }}
|
||||||
|
{{ Former::text('address1')->label('Street') }}
|
||||||
|
{{ Former::text('address2')->label('Apt/Floor') }}
|
||||||
|
{{ Former::text('city') }}
|
||||||
|
{{ Former::text('state') }}
|
||||||
|
{{ Former::text('postal_code') }}
|
||||||
|
{{ Former::select('country_id')->addOption('','')->label('Country')
|
||||||
|
->fromQuery($countries, 'name', 'id')->select($client ? $client->country_id : '') }}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,8 +62,8 @@
|
|||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h3>Standing</h3>
|
<h3>Standing</h3>
|
||||||
<h3>$0.00 <small>Paid to Date USD</small></h3>
|
<h3>{{ Utils::formatMoney($client->paid_to_date, $client->currency_id); }} <small>Paid to Date USD</small></h3>
|
||||||
<h3>$0.00 <small>Balance USD</small></h3>
|
<h3>{{ Utils::formatMoney($client->balance, $client->currency_id); }} <small>Balance USD</small></h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<div class="tab-pane active" id="activity">
|
<div class="tab-pane active" id="activity">
|
||||||
|
|
||||||
{{ Datatable::table()
|
{{ Datatable::table()
|
||||||
->addColumn('Date', 'Message', 'Balance')
|
->addColumn('Date', 'Message', 'Balance', 'Adjustment')
|
||||||
->setUrl(url('api/activities/'. $client->public_id))
|
->setUrl(url('api/activities/'. $client->public_id))
|
||||||
->setOptions('sPaginationType', 'bootstrap')
|
->setOptions('sPaginationType', 'bootstrap')
|
||||||
->setOptions('bFilter', false)
|
->setOptions('bFilter', false)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
@if ($credit)
|
@if ($credit)
|
||||||
{{ Former::populate($credit) }}
|
{{ Former::populate($credit) }}
|
||||||
|
@else
|
||||||
|
{{ Former::populateField('credit_date', date('Y-m-d')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
@ -27,11 +29,11 @@
|
|||||||
{{ Former::legend('New Credit') }}
|
{{ Former::legend('New Credit') }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ Former::select('client')->fromQuery($clients, 'name', 'public_id')->select($client ? $client->public_id : '')->addOption('', '')->addGroupClass('client-select') }}
|
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
|
||||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
|
||||||
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
|
||||||
{{ Former::text('amount') }}
|
{{ Former::text('amount') }}
|
||||||
{{ Former::text('credit_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('credit_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@ -48,10 +50,20 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var clients = {{ $clients }};
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
var $input = $('select#client');
|
var $input = $('select#client');
|
||||||
|
for (var i=0; i<clients.length; i++) {
|
||||||
|
var client = clients[i];
|
||||||
|
$input.append(new Option(getClientDisplayName(client), client.public_id));
|
||||||
|
}
|
||||||
|
@if ($clientPublicId)
|
||||||
|
$('select#client').val({{ $clientPublicId }});
|
||||||
|
@endif
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
|
|
||||||
$('#currency_id').combobox();
|
$('#currency_id').combobox();
|
||||||
|
|
||||||
$('#credit_date').datepicker({
|
$('#credit_date').datepicker({
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
jQuery('.{{ $class }}').dataTable({
|
jQuery('.{{ $class }}').dataTable({
|
||||||
// Disable sorting on the first column
|
// Disable sorting on the first column
|
||||||
"aaSorting": [],
|
"aaSorting": [],
|
||||||
|
"bAutoWidth": false,
|
||||||
@if (isset($hasCheckboxes) && $hasCheckboxes)
|
@if (isset($hasCheckboxes) && $hasCheckboxes)
|
||||||
"aoColumnDefs" : [ {
|
"aoColumnDefs" : [ {
|
||||||
'bSortable' : false,
|
'bSortable' : false,
|
||||||
|
@ -13,12 +13,13 @@
|
|||||||
|
|
||||||
{{ Former::open($url)->method($method)->addClass('main_form')->rules(array(
|
{{ Former::open($url)->method($method)->addClass('main_form')->rules(array(
|
||||||
'client' => 'required',
|
'client' => 'required',
|
||||||
|
'email' => 'required',
|
||||||
'product_key' => 'max:14',
|
'product_key' => 'max:14',
|
||||||
)); }}
|
)); }}
|
||||||
|
|
||||||
<div class="row" style="min-height:195px" onkeypress="formEnterClick(event)">
|
<div class="row" style="min-height:195px" onkeypress="formEnterClick(event)">
|
||||||
<div class="col-md-5" id="col_1">
|
<div class="col-md-5" id="col_1">
|
||||||
{{ Former::select('client')->addOption('', '')->fromQuery($clients, 'name', 'public_id')->data_bind("dropdown: client")
|
{{ Former::select('client')->addOption('', '')->data_bind("dropdown: client")
|
||||||
->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">
|
||||||
@ -38,6 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'") }}
|
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'") }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4" id="col_2">
|
<div class="col-md-4" id="col_2">
|
||||||
@ -51,13 +53,14 @@
|
|||||||
{{ Former::text('start_date')->data_bind("value: start_date, valueUpdate: 'afterkeydown'")->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('start_date')->data_bind("value: start_date, valueUpdate: 'afterkeydown'")->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
{{ Former::text('end_date')->data_bind("value: end_date, valueUpdate: 'afterkeydown'")->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('end_date')->data_bind("value: end_date, valueUpdate: 'afterkeydown'")->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
</div>
|
</div>
|
||||||
|
@if ($invoice && $invoice->recurring_invoice_id)
|
||||||
|
<div class="pull-right" style="padding-top: 6px">
|
||||||
|
Created by a {{ link_to('/invoices/'.$invoice->recurring_invoice_id, 'recurring invoice') }}
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
<div data-bind="visible: invoice_status_id() < CONSTS.INVOICE_STATUS_SENT">
|
<div data-bind="visible: invoice_status_id() < CONSTS.INVOICE_STATUS_SENT">
|
||||||
{{ Former::checkbox('recurring')->text('Enable | <a href="#" rel="tooltip" data-toggle="tooltip" title="Recurring invoices are automatically sent. Use :MONTH, :QUARTER or :YEAR for dynamic dates. Basic math works as well. ie, :MONTH-1.">Learn more</a>')->data_bind("checked: is_recurring")
|
{{ Former::checkbox('recurring')->text('Enable | <a href="#" rel="tooltip" data-toggle="tooltip" title="Recurring invoices are automatically sent. Use :MONTH, :QUARTER or :YEAR for dynamic dates. Basic math works as well. ie, :MONTH-1.">Learn more</a>')->data_bind("checked: is_recurring")
|
||||||
->inlineHelp($invoice && $invoice->last_sent_date ? 'Last invoice sent ' . Utils::timestampToDateString($invoice->last_sent_date) : '') }}
|
->inlineHelp($invoice && $invoice->last_sent_date ? 'Last invoice sent ' . Utils::dateToString($invoice->last_sent_date) : '') }}
|
||||||
</div>
|
|
||||||
@if ($invoice && $invoice->recurring_invoice_id)
|
|
||||||
<div style="padding-top: 6px">
|
|
||||||
Created by a {{ link_to('/invoices/'.$invoice->recurring_invoice_id, 'recurring invoice') }}
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@ -131,16 +134,16 @@
|
|||||||
<td colspan="2">Subtotal</td>
|
<td colspan="2">Subtotal</td>
|
||||||
<td style="text-align: right"><span data-bind="text: subtotal"/></td>
|
<td style="text-align: right"><span data-bind="text: subtotal"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
|
||||||
<td colspan="2">Paid to Date</td>
|
|
||||||
<td style="text-align: right"></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-bind="visible: discount() > 0">
|
<tr data-bind="visible: discount() > 0">
|
||||||
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
||||||
<td colspan="2">Discount</td>
|
<td colspan="2">Discount</td>
|
||||||
<td style="text-align: right"><span data-bind="text: discounted"/></td>
|
<td style="text-align: right"><span data-bind="text: discounted"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
||||||
|
<td colspan="2">Paid to Date</td>
|
||||||
|
<td style="text-align: right"></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
<td class="hide-border" data-bind="attr: {colspan: tax_rates().length > 1 ? 4 : 3}"/>
|
||||||
<td colspan="2"><b>Balance Due</b></td>
|
<td colspan="2"><b>Balance Due</b></td>
|
||||||
@ -200,23 +203,6 @@
|
|||||||
<div style="background-color: #F6F6F6" class="row" data-bind="with: client" onkeypress="clientModalEnterClick(event)">
|
<div style="background-color: #F6F6F6" class="row" data-bind="with: client" onkeypress="clientModalEnterClick(event)">
|
||||||
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
||||||
|
|
||||||
{{ 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') }}
|
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Address') }}
|
|
||||||
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
|
||||||
{{ Former::text('address2')->label('Apt/Floor')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
|
||||||
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
|
|
||||||
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
|
||||||
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
|
|
||||||
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
|
|
||||||
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
|
||||||
|
|
||||||
{{ Former::legend('Contacts') }}
|
{{ Former::legend('Contacts') }}
|
||||||
<div data-bind='template: { foreach: contacts,
|
<div data-bind='template: { foreach: contacts,
|
||||||
@ -247,14 +233,33 @@
|
|||||||
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
||||||
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')->data_bind('value: client_industry_id')
|
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')->data_bind('value: client_industry_id')
|
||||||
->fromQuery($clientIndustries, 'name', 'id')->select($client ? $client->client_industry_id : '') }}
|
->fromQuery($clientIndustries, 'name', 'id')->select($client ? $client->client_industry_id : '') }}
|
||||||
{{ Former::textarea('notes') }}
|
{{ Former::textarea('private_notes')->data_bind('value: private_notes') }}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
||||||
|
|
||||||
|
{{ 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') }}
|
||||||
|
|
||||||
|
|
||||||
|
{{ Former::legend('Address') }}
|
||||||
|
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::text('address2')->label('Apt/Floor')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
|
||||||
|
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
|
||||||
|
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
<div class="modal-footer" style="margin-top: 0px">
|
||||||
<span class="error-block" id="nameError" style="display:none;float:left">Please provide a value for the name field.</span><span> </span>
|
<span class="error-block" id="emailError" style="display:none;float:left">Please provide a valid email address.</span><span> </span>
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
<button type="button" class="btn btn-primary" data-bind="click: clientFormComplete">Done</button>
|
<button type="button" class="btn btn-primary" data-bind="click: clientFormComplete">Done</button>
|
||||||
</div>
|
</div>
|
||||||
@ -316,7 +321,7 @@
|
|||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
$('form').change(refreshPDF);
|
//$('form').change(refreshPDF);
|
||||||
|
|
||||||
$('#country_id').combobox();
|
$('#country_id').combobox();
|
||||||
$('[rel=tooltip]').tooltip();
|
$('[rel=tooltip]').tooltip();
|
||||||
@ -344,8 +349,12 @@
|
|||||||
} else {
|
} else {
|
||||||
model.client.public_id(0); // TODO_FIX
|
model.client.public_id(0); // TODO_FIX
|
||||||
}
|
}
|
||||||
|
refreshPDF();
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
|
|
||||||
|
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discout, #currency_id').change(function() {
|
||||||
|
refreshPDF();
|
||||||
|
});
|
||||||
|
|
||||||
$('.country_select input.form-control').on('change', function(e) {
|
$('.country_select input.form-control').on('change', function(e) {
|
||||||
var countryId = parseInt($('input[name=country_id]').val(), 10);
|
var countryId = parseInt($('input[name=country_id]').val(), 10);
|
||||||
@ -360,7 +369,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
$('#clientModal').on('shown.bs.modal', function () {
|
$('#clientModal').on('shown.bs.modal', function () {
|
||||||
$('#name').focus();
|
$('#first_name').focus();
|
||||||
}).on('hidden.bs.modal', function () {
|
}).on('hidden.bs.modal', function () {
|
||||||
if (model.clientBackup) {
|
if (model.clientBackup) {
|
||||||
model.loadClient(model.clientBackup);
|
model.loadClient(model.clientBackup);
|
||||||
@ -521,6 +530,7 @@
|
|||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
||||||
self.terms = ko.observable('');
|
self.terms = ko.observable('');
|
||||||
|
self.public_notes = 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.invoice_number = ko.observable('');
|
||||||
@ -548,12 +558,26 @@
|
|||||||
|
|
||||||
self.wrapped_terms = ko.computed({
|
self.wrapped_terms = ko.computed({
|
||||||
read: function() {
|
read: function() {
|
||||||
|
$('#terms').height(this.terms().split('\n').length * 36);
|
||||||
return this.terms();
|
return this.terms();
|
||||||
},
|
},
|
||||||
write: function(value) {
|
write: function(value) {
|
||||||
value = wordWrapText(value, 250);
|
value = wordWrapText(value, 340);
|
||||||
self.terms(value);
|
self.terms(value);
|
||||||
$('#terms').height(value.split('\n').length * 22);
|
$('#terms').height(value.split('\n').length * 36);
|
||||||
|
},
|
||||||
|
owner: this
|
||||||
|
});
|
||||||
|
|
||||||
|
self.wrapped_notes = ko.computed({
|
||||||
|
read: function() {
|
||||||
|
$('#public_notes').height(this.public_notes().split('\n').length * 36);
|
||||||
|
return this.public_notes();
|
||||||
|
},
|
||||||
|
write: function(value) {
|
||||||
|
value = wordWrapText(value, 340);
|
||||||
|
self.public_notes(value);
|
||||||
|
$('#public_notes').height(value.split('\n').length * 36);
|
||||||
},
|
},
|
||||||
owner: this
|
owner: this
|
||||||
});
|
});
|
||||||
@ -584,14 +608,17 @@
|
|||||||
$('#clientModal #country_id').val('');
|
$('#clientModal #country_id').val('');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#nameError').css( "display", "none" );
|
$('#emailError').css( "display", "none" );
|
||||||
$('#clientModal').modal('show');
|
$('#clientModal').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
self.clientFormComplete = function() {
|
self.clientFormComplete = function() {
|
||||||
|
var email = $('#email').val();
|
||||||
|
var firstName = $('#first_name').val();
|
||||||
|
var lastName = $('#last_name').val();
|
||||||
var name = $('#name').val();
|
var name = $('#name').val();
|
||||||
if (!name) {
|
if (!email || !isValidEmailAddress(email)) {
|
||||||
if (!name) $('#nameError').css( "display", "inline" );
|
$('#emailError').css( "display", "inline" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,10 +626,19 @@
|
|||||||
if (self.client.public_id() == 0) {
|
if (self.client.public_id() == 0) {
|
||||||
self.client.public_id(-1);
|
self.client.public_id(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
//
|
||||||
|
} else if (firstName || lastName) {
|
||||||
|
name = firstName + ' ' + lastName;
|
||||||
|
} else {
|
||||||
|
name = email;
|
||||||
|
}
|
||||||
|
|
||||||
$('.client_select input.form-control').val(name);
|
$('.client_select input.form-control').val(name);
|
||||||
$('.client_select .combobox-container').addClass('combobox-selected');
|
$('.client_select .combobox-container').addClass('combobox-selected');
|
||||||
|
|
||||||
$('#nameError').css( "display", "none" );
|
$('#emailError').css( "display", "none" );
|
||||||
$('.client_select input.form-control').focus();
|
$('.client_select input.form-control').focus();
|
||||||
|
|
||||||
refreshPDF();
|
refreshPDF();
|
||||||
@ -673,7 +709,7 @@
|
|||||||
self.public_id = ko.observable(0);
|
self.public_id = ko.observable(0);
|
||||||
self.name = ko.observable('');
|
self.name = ko.observable('');
|
||||||
self.work_phone = ko.observable('');
|
self.work_phone = ko.observable('');
|
||||||
self.notes = ko.observable('');
|
self.private_notes = ko.observable('');
|
||||||
self.address1 = ko.observable('');
|
self.address1 = ko.observable('');
|
||||||
self.address2 = ko.observable('');
|
self.address2 = ko.observable('');
|
||||||
self.city = ko.observable('');
|
self.city = ko.observable('');
|
||||||
@ -711,6 +747,16 @@
|
|||||||
self.contacts.remove(this);
|
self.contacts.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.placeholderName = ko.computed(function() {
|
||||||
|
if (self.contacts().length == 0) return;
|
||||||
|
var contact = self.contacts()[0];
|
||||||
|
if (contact.first_name() || contact.last_name()) {
|
||||||
|
return contact.first_name() + ' ' + contact.last_name();
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, {}, this);
|
ko.mapping.fromJS(data, {}, this);
|
||||||
} else {
|
} else {
|
||||||
@ -905,6 +951,7 @@
|
|||||||
var products = {{ $products }};
|
var products = {{ $products }};
|
||||||
var clients = {{ $clients }};
|
var clients = {{ $clients }};
|
||||||
var clientMap = {};
|
var clientMap = {};
|
||||||
|
var $clientSelect = $('select#client');
|
||||||
|
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
var client = clients[i];
|
var client = clients[i];
|
||||||
@ -913,9 +960,9 @@
|
|||||||
contact.send_invoice = contact.is_primary;
|
contact.send_invoice = contact.is_primary;
|
||||||
}
|
}
|
||||||
clientMap[client.public_id] = client;
|
clientMap[client.public_id] = client;
|
||||||
|
$clientSelect.append(new Option(getClientDisplayName(client), client.public_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.model = new InvoiceModel();
|
window.model = new InvoiceModel();
|
||||||
@foreach ($taxRates as $taxRate)
|
@foreach ($taxRates as $taxRate)
|
||||||
model.addTaxRate({{ $taxRate }});
|
model.addTaxRate({{ $taxRate }});
|
||||||
@ -932,8 +979,9 @@
|
|||||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||||
}
|
}
|
||||||
@else
|
@else
|
||||||
|
model.invoice_date('{{ date('Y-m-d') }}');
|
||||||
model.invoice_number('{{ $invoiceNumber }}');
|
model.invoice_number('{{ $invoiceNumber }}');
|
||||||
model.terms(wordWrapText('{{ $account->invoice_terms }}', 250));
|
model.terms(wordWrapText('{{ $account->invoice_terms }}', 340));
|
||||||
@endif
|
@endif
|
||||||
model.addItem();
|
model.addItem();
|
||||||
ko.applyBindings(model);
|
ko.applyBindings(model);
|
||||||
|
@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
{{ Former::open($url)->addClass('col-md-10 col-md-offset-1 main_form')->method($method)->rules(array(
|
{{ Former::open($url)->addClass('col-md-10 col-md-offset-1 main_form')->method($method)->rules(array(
|
||||||
'client' => 'required',
|
'client' => 'required',
|
||||||
|
'invoice' => 'required',
|
||||||
'amount' => 'required',
|
'amount' => 'required',
|
||||||
)); }}
|
)); }}
|
||||||
|
|
||||||
@if ($payment)
|
@if ($payment)
|
||||||
{{-- Former::populate($payment) --}}
|
{{-- Former::populate($payment) --}}
|
||||||
|
@else
|
||||||
|
{{ Former::populateField('payment_date', date('Y-m-d')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
@ -29,10 +32,10 @@
|
|||||||
|
|
||||||
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
|
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
|
||||||
{{ Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') }}
|
{{ Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') }}
|
||||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
|
||||||
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
|
||||||
{{ Former::text('amount') }}
|
{{ Former::text('amount') }}
|
||||||
{{ Former::text('payment_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('payment_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@ -53,7 +56,7 @@
|
|||||||
var clients = {{ $clients }};
|
var clients = {{ $clients }};
|
||||||
var clientMap = {};
|
var clientMap = {};
|
||||||
var invoiceMap = {};
|
var invoiceMap = {};
|
||||||
|
var invoicesForClientMap = {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function compareClient(a,b) {
|
function compareClient(a,b) {
|
||||||
@ -73,23 +76,29 @@
|
|||||||
var invoice = invoices[i];
|
var invoice = invoices[i];
|
||||||
var client = invoice.client;
|
var client = invoice.client;
|
||||||
|
|
||||||
if (!invoiceMap.hasOwnProperty(client.public_id)) {
|
if (!invoicesForClientMap.hasOwnProperty(client.public_id)) {
|
||||||
invoiceMap[client.public_id] = [];
|
invoicesForClientMap[client.public_id] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
invoiceMap[client.public_id].push(invoice);
|
invoicesForClientMap[client.public_id].push(invoice);
|
||||||
clientMap[invoice.public_id] = invoice.client;
|
invoiceMap[invoice.public_id] = invoice;
|
||||||
|
//clientMap[invoice.public_id] = invoice.client;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<clients.length; i++) {
|
||||||
|
var client = clients[i];
|
||||||
|
clientMap[client.public_id] = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
//clients.sort(compareClient);
|
//clients.sort(compareClient);
|
||||||
$input.append(new Option('', ''));
|
$input.append(new Option('', ''));
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
var client = clients[i];
|
var client = clients[i];
|
||||||
$input.append(new Option(client.name, client.public_id));
|
$input.append(new Option(getClientDisplayName(client), client.public_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@if ($client)
|
@if ($clientPublicId)
|
||||||
$('select#client').val({{ $client->public_id }});
|
$('select#client').val({{ $clientPublicId }});
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
@ -97,7 +106,8 @@
|
|||||||
console.log('client change');
|
console.log('client change');
|
||||||
var clientId = $('input[name=client]').val();
|
var clientId = $('input[name=client]').val();
|
||||||
var invoiceId = $('input[name=invoice]').val();
|
var invoiceId = $('input[name=invoice]').val();
|
||||||
if (clientMap.hasOwnProperty(invoiceId) && clientMap[invoiceId].public_id == clientId) {
|
var invoice = invoiceMap[invoiceId];
|
||||||
|
if (invoice && invoice.client.public_id == clientId) {
|
||||||
console.log('values the same:' + $('select#client').prop('selected'))
|
console.log('values the same:' + $('select#client').prop('selected'))
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
@ -106,10 +116,11 @@
|
|||||||
$invoiceCombobox = $('select#invoice');
|
$invoiceCombobox = $('select#invoice');
|
||||||
$invoiceCombobox.find('option').remove().end().combobox('refresh');
|
$invoiceCombobox.find('option').remove().end().combobox('refresh');
|
||||||
$invoiceCombobox.append(new Option('', ''));
|
$invoiceCombobox.append(new Option('', ''));
|
||||||
var list = clientId ? (invoiceMap.hasOwnProperty(clientId) ? invoiceMap[clientId] : []) : invoices;
|
var list = clientId ? (invoicesForClientMap.hasOwnProperty(clientId) ? invoicesForClientMap[clientId] : []) : invoices;
|
||||||
for (var i=0; i<list.length; i++) {
|
for (var i=0; i<list.length; i++) {
|
||||||
var invoice = list[i];
|
var invoice = list[i];
|
||||||
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.client.name, invoice.public_id));
|
var client = clientMap[invoice.client.public_id];
|
||||||
|
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(client), invoice.public_id));
|
||||||
}
|
}
|
||||||
$('select#invoice').combobox('refresh');
|
$('select#invoice').combobox('refresh');
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
@ -118,8 +129,9 @@
|
|||||||
$clientCombobox = $('select#client');
|
$clientCombobox = $('select#client');
|
||||||
var invoiceId = $('input[name=invoice]').val();
|
var invoiceId = $('input[name=invoice]').val();
|
||||||
if (invoiceId) {
|
if (invoiceId) {
|
||||||
var client = clientMap[invoiceId];
|
var invoice = invoiceMap[invoiceId];
|
||||||
setComboboxValue($('.client-select'), client.public_id, client.name);
|
var client = clientMap[invoice.client.public_id];
|
||||||
|
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
|
@ -9,6 +9,7 @@ function generatePDF(invoice) {
|
|||||||
var headerLeft = 360;
|
var headerLeft = 360;
|
||||||
var headerRight = 540;
|
var headerRight = 540;
|
||||||
var rowHeight = 15;
|
var rowHeight = 15;
|
||||||
|
var tableRowHeight = 20;
|
||||||
var footerLeft = 420;
|
var footerLeft = 420;
|
||||||
|
|
||||||
var tableTop = 240;
|
var tableTop = 240;
|
||||||
@ -20,16 +21,15 @@ function generatePDF(invoice) {
|
|||||||
var lineTotalRight = 540;
|
var lineTotalRight = 540;
|
||||||
|
|
||||||
|
|
||||||
var hasTaxes = true;
|
var hasTaxes = false;
|
||||||
for (var i=0; i<invoice.invoice_items.length; i++)
|
for (var i=0; i<invoice.invoice_items.length; i++)
|
||||||
{
|
{
|
||||||
var item = invoice.invoice_items[i];
|
var item = invoice.invoice_items[i];
|
||||||
if (item.tax_rate > 0) {
|
if (item.tax && item.tax.rate > 0) {
|
||||||
hasTaxes = true;
|
hasTaxes = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasTaxes)
|
if (hasTaxes)
|
||||||
{
|
{
|
||||||
descriptionLeft -= 20;
|
descriptionLeft -= 20;
|
||||||
@ -66,7 +66,7 @@ function generatePDF(invoice) {
|
|||||||
doc.setFontType("normal");
|
doc.setFontType("normal");
|
||||||
if (invoice.client) {
|
if (invoice.client) {
|
||||||
var y = headerTop;
|
var y = headerTop;
|
||||||
doc.text(marginLeft, y, invoice.client.name);
|
doc.text(marginLeft, y, getClientDisplayName(invoice.client));
|
||||||
y += rowHeight;
|
y += rowHeight;
|
||||||
doc.text(marginLeft, y, invoice.client.address1);
|
doc.text(marginLeft, y, invoice.client.address1);
|
||||||
if (invoice.client.address2) {
|
if (invoice.client.address2) {
|
||||||
@ -126,6 +126,7 @@ function generatePDF(invoice) {
|
|||||||
var line = 1;
|
var line = 1;
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var shownItem = false;
|
var shownItem = false;
|
||||||
|
doc.setDrawColor(220,220,220);
|
||||||
|
|
||||||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||||
var item = invoice.invoice_items[i];
|
var item = invoice.invoice_items[i];
|
||||||
@ -158,7 +159,8 @@ function generatePDF(invoice) {
|
|||||||
var qtyX = qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
var qtyX = qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
||||||
var taxX = taxRight - (doc.getStringUnitWidth(tax) * doc.internal.getFontSize());
|
var taxX = taxRight - (doc.getStringUnitWidth(tax) * doc.internal.getFontSize());
|
||||||
var totalX = lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
|
var totalX = lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
|
||||||
var x = tableTop + (line * rowHeight) + 6;
|
var x = tableTop + (line * tableRowHeight) + 6;
|
||||||
|
if (i==0) x -= 4;
|
||||||
|
|
||||||
doc.text(tableLeft, x, productKey);
|
doc.text(tableLeft, x, productKey);
|
||||||
doc.text(descriptionLeft, x, notes);
|
doc.text(descriptionLeft, x, notes);
|
||||||
@ -171,14 +173,21 @@ function generatePDF(invoice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
line += doc.splitTextToSize(item.notes, 200).length;
|
line += doc.splitTextToSize(item.notes, 200).length;
|
||||||
|
|
||||||
|
if (i < invoice.invoice_items.length - 2) {
|
||||||
|
doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, tableTop + (line * tableRowHeight) - 8);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* table footer */
|
/* table footer */
|
||||||
var x = tableTop + (line * rowHeight);
|
doc.setDrawColor(200,200,200);
|
||||||
|
var x = tableTop + (line * tableRowHeight);
|
||||||
doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x);
|
doc.lines([[0,0],[headerRight-tableLeft+5,0]],tableLeft - 8, x);
|
||||||
|
|
||||||
|
|
||||||
doc.text(tableLeft, x+16, invoice.terms);
|
doc.text(tableLeft, x+16, invoice.terms);
|
||||||
|
doc.text(tableLeft, x+16 + (doc.splitTextToSize(invoice.terms, 340).length * rowHeight), invoice.public_notes);
|
||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Subtotal');
|
doc.text(footerLeft, x, 'Subtotal');
|
||||||
@ -205,7 +214,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(footerLeft, x, 'Total');
|
doc.text(footerLeft, x, 'Balance Due');
|
||||||
|
|
||||||
var total = formatMoney(total, currencyId);
|
var total = formatMoney(total, currencyId);
|
||||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
@ -652,12 +661,33 @@ function wordWrapText(value, width)
|
|||||||
while (j++ < lines[i].length) {
|
while (j++ < lines[i].length) {
|
||||||
if (lines[i].charAt(j) === " ") space = j;
|
if (lines[i].charAt(j) === " ") space = j;
|
||||||
}
|
}
|
||||||
lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
|
lines[i + 1] = lines[i].substring(space + 1) + ' ' + (lines[i + 1] || "");
|
||||||
lines[i] = lines[i].substring(0, space);
|
lines[i] = lines[i].substring(0, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines.slice(0, 6).join("\n");
|
var newValue = (lines.join("\n")).trim();
|
||||||
|
|
||||||
|
if (value == newValue) {
|
||||||
|
return newValue;
|
||||||
|
} else {
|
||||||
|
return wordWrapText(newValue, width);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getClientDisplayName(client)
|
||||||
|
{
|
||||||
|
var contact = client.contacts[0];
|
||||||
|
if (client.name) {
|
||||||
|
return client.name;
|
||||||
|
} else if (contact.first_name || contact.last_name) {
|
||||||
|
return contact.first_name + ' ' + contact.last_name;
|
||||||
|
} else {
|
||||||
|
return contact.email;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var CONSTS = {};
|
var CONSTS = {};
|
||||||
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user