Bug fixes

This commit is contained in:
Hillel Coren 2015-06-10 11:34:20 +03:00
parent 1b39da734a
commit 1c1bef3abb
31 changed files with 193 additions and 84 deletions

View File

@ -1,5 +1,5 @@
APP_ENV=development APP_ENV=production
APP_DEBUG=true APP_DEBUG=false
APP_URL=http://ninja.dev APP_URL=http://ninja.dev
APP_CIPHER=rijndael-128 APP_CIPHER=rijndael-128
APP_KEY APP_KEY

View File

@ -108,6 +108,7 @@ module.exports = function(grunt) {
css_public: { css_public: {
src: [ src: [
'public/vendor/bootstrap/dist/css/bootstrap.min.css', 'public/vendor/bootstrap/dist/css/bootstrap.min.css',
'public/vendor/font-awesome/css/font-awesome.min.css',
/* /*
'public/css/bootstrap.splash.css', 'public/css/bootstrap.splash.css',
'public/css/splash.css', 'public/css/splash.css',

View File

@ -79,9 +79,8 @@ class AppController extends BaseController
return Redirect::to('/setup')->withInput(); return Redirect::to('/setup')->withInput();
} }
// == ENV Settings (Production) == // $config = "APP_ENV=production\n".
$config = "APP_ENV=development\n". "APP_DEBUG=false\n".
"APP_DEBUG=true\n".
"APP_URL={$app['url']}\n". "APP_URL={$app['url']}\n".
"APP_KEY={$app['key']}\n\n". "APP_KEY={$app['key']}\n\n".
"DB_TYPE={$dbType}\n". "DB_TYPE={$dbType}\n".

View File

@ -1,5 +1,6 @@
<?php namespace App\Http\Controllers; <?php namespace App\Http\Controllers;
use Response;
use Request; use Request;
use Redirect; use Redirect;
use Auth; use Auth;

View File

@ -293,8 +293,9 @@ class PaymentController extends BaseController
$useToken = false; $useToken = false;
if (!$paymentType) { if (!$paymentType) {
$paymentType = $account->account_gateways[0]->getPaymentType(); $paymentType = Session::get('payment_type', $account->account_gateways[0]->getPaymentType());
} else if ($paymentType == PAYMENT_TYPE_TOKEN) { }
if ($paymentType == PAYMENT_TYPE_TOKEN) {
$useToken = true; $useToken = true;
$paymentType = PAYMENT_TYPE_CREDIT_CARD; $paymentType = PAYMENT_TYPE_CREDIT_CARD;
} }
@ -324,7 +325,7 @@ class PaymentController extends BaseController
'gateway' => $gateway, 'gateway' => $gateway,
'acceptedCreditCardTypes' => $acceptedCreditCardTypes, 'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Cache::get('countries'), 'countries' => Cache::get('countries'),
'currencyId' => $client->currency_id, 'currencyId' => $client->getCurrencyId(),
'account' => $client->account, 'account' => $client->account,
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
]; ];
@ -514,7 +515,8 @@ class PaymentController extends BaseController
if ($validator->fails()) { if ($validator->fails()) {
Utils::logError('Payment Error [invalid]'); Utils::logError('Payment Error [invalid]');
return Redirect::to('payment/'.$invitationKey) return Redirect::to('payment/'.$invitationKey)
->withErrors($validator); ->withErrors($validator)
->withInput();
} }
} }

View File

@ -164,6 +164,7 @@ class TaskController extends BaseController
'method' => 'PUT', 'method' => 'PUT',
'url' => 'tasks/'.$publicId, 'url' => 'tasks/'.$publicId,
'title' => trans('texts.edit_task'), 'title' => trans('texts.edit_task'),
'duration' => time() - strtotime($task->start_time),
]; ];
$data = array_merge($data, self::getViewModel()); $data = array_merge($data, self::getViewModel());

View File

@ -51,6 +51,9 @@ class StartupCheck
'countries' => 'App\Models\Country', 'countries' => 'App\Models\Country',
]; ];
foreach ($cachedTables as $name => $class) { foreach ($cachedTables as $name => $class) {
if (Input::has('clear_cache')) {
Session::flash('message', 'Cache cleared');
}
if (Input::has('clear_cache') || !Cache::has($name)) { if (Input::has('clear_cache') || !Cache::has($name)) {
if ($name == 'paymentTerms') { if ($name == 'paymentTerms') {
$orderBy = 'num_days'; $orderBy = 'num_days';

View File

@ -233,7 +233,7 @@ class Utils
public static function formatMoney($value, $currencyId = false) public static function formatMoney($value, $currencyId = false)
{ {
if (!$currencyId) { if (!$currencyId) {
$currencyId = Session::get(SESSION_CURRENCY); $currencyId = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY);
} }
foreach (Cache::get('currencies') as $currency) { foreach (Cache::get('currencies') as $currency) {

View File

@ -168,7 +168,7 @@ class Account extends Eloquent
// confirm the invoice number isn't already taken // confirm the invoice number isn't already taken
do { do {
$number = $prefix.str_pad($counter, 4, "0", STR_PAD_LEFT); $number = $prefix.str_pad($counter, 4, "0", STR_PAD_LEFT);
$check = Invoice::scope()->whereInvoiceNumber($number)->withTrashed()->first(); $check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
$counter++; $counter++;
} while ($check); } while ($check);
@ -247,16 +247,23 @@ class Account extends Eloquent
'quote_number', 'quote_number',
'total', 'total',
'invoice_issued_to', 'invoice_issued_to',
'date',
'rate',
'hours',
]; ];
foreach ($fields as $field) { foreach ($fields as $field) {
if (isset($custom[$field]) && $custom[$field]) { if (isset($custom[$field]) && $custom[$field]) {
$data[$field] = $custom[$field]; $data[$field] = $custom[$field];
} else { } else {
$data[$field] = trans("texts.$field"); $data[$field] = uctrans("texts.$field");
} }
} }
foreach (['item', 'quantity', 'unit_cost'] as $field) {
$data["{$field}_orig"] = $data[$field];
}
return $data; return $data;
} }

View File

@ -406,7 +406,7 @@ class Activity extends Eloquent
public static function createCredit($credit) public static function createCredit($credit)
{ {
$activity = Activity::getBlank(); $activity = Activity::getBlank();
$activity->message = Utils::encodeActivity(Auth::user(), 'entered '.Utils::formatMoney($credit->amount, $credit->client->currency_id).' credit'); $activity->message = Utils::encodeActivity(Auth::user(), 'entered '.Utils::formatMoney($credit->amount, $credit->client->getCurrencyId()).' credit');
$activity->credit_id = $credit->id; $activity->credit_id = $credit->id;
$activity->client_id = $credit->client_id; $activity->client_id = $credit->client_id;
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT; $activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
@ -421,7 +421,7 @@ class Activity extends Eloquent
$activity->credit_id = $credit->id; $activity->credit_id = $credit->id;
$activity->client_id = $credit->client_id; $activity->client_id = $credit->client_id;
$activity->activity_type_id = ACTIVITY_TYPE_DELETE_CREDIT; $activity->activity_type_id = ACTIVITY_TYPE_DELETE_CREDIT;
$activity->message = Utils::encodeActivity(Auth::user(), 'deleted '.Utils::formatMoney($credit->balance, $credit->client->currency_id).' credit'); $activity->message = Utils::encodeActivity(Auth::user(), 'deleted '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
$activity->balance = $credit->client->balance; $activity->balance = $credit->client->balance;
$activity->save(); $activity->save();
} else { } else {
@ -460,7 +460,7 @@ class Activity extends Eloquent
$activity->client_id = $credit->client_id; $activity->client_id = $credit->client_id;
$activity->credit_id = $credit->id; $activity->credit_id = $credit->id;
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CREDIT; $activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CREDIT;
$activity->message = Utils::encodeActivity(Auth::user(), 'archived '.Utils::formatMoney($credit->balance, $credit->client->currency_id).' credit'); $activity->message = Utils::encodeActivity(Auth::user(), 'archived '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
$activity->balance = $credit->client->balance; $activity->balance = $credit->client->balance;
$activity->save(); $activity->save();
} }
@ -471,7 +471,7 @@ class Activity extends Eloquent
$activity->client_id = $credit->client_id; $activity->client_id = $credit->client_id;
$activity->credit_id = $credit->id; $activity->credit_id = $credit->id;
$activity->activity_type_id = ACTIVITY_TYPE_RESTORE_CREDIT; $activity->activity_type_id = ACTIVITY_TYPE_RESTORE_CREDIT;
$activity->message = Utils::encodeActivity(Auth::user(), 'restored '.Utils::formatMoney($credit->balance, $credit->client->currency_id).' credit'); $activity->message = Utils::encodeActivity(Auth::user(), 'restored '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
$activity->balance = $credit->client->balance; $activity->balance = $credit->client->balance;
$activity->save(); $activity->save();
} }

View File

@ -148,6 +148,15 @@ class Client extends EntityModel
$token = $this->getGatewayToken(); $token = $this->getGatewayToken();
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false; return $token ? "https://dashboard.stripe.com/customers/{$token}" : false;
} }
public function getCurrencyId()
{
if (!$this->account) {
$this->load('account');
}
return $this->currency_id ?: ($this->account->currency_id ?: DEFAULT_CURRENCY);
}
} }
/* /*

View File

@ -10,6 +10,7 @@ class Invoice extends EntityModel
protected $casts = [ protected $casts = [
'is_recurring' => 'boolean', 'is_recurring' => 'boolean',
'has_tasks' => 'boolean',
]; ];
public function account() public function account()
@ -121,6 +122,7 @@ class Invoice extends EntityModel
'custom_taxes1', 'custom_taxes1',
'custom_taxes2', 'custom_taxes2',
'partial', 'partial',
'has_tasks',
]); ]);
$this->client->setVisible([ $this->client->setVisible([

View File

@ -34,7 +34,7 @@ class Payment extends EntityModel
public function getAmount() public function getAmount()
{ {
return Utils::formatMoney($this->amount, $this->client->currency_id); return Utils::formatMoney($this->amount, $this->client->getCurrencyId());
} }
public function getName() public function getName()

View File

@ -19,13 +19,13 @@ class ContactMailer extends Mailer
$subject = trans("texts.{$entityType}_subject", ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]); $subject = trans("texts.{$entityType}_subject", ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]);
$accountName = $invoice->account->getDisplayName(); $accountName = $invoice->account->getDisplayName();
$emailTemplate = $invoice->account->getEmailTemplate($entityType); $emailTemplate = $invoice->account->getEmailTemplate($entityType);
$invoiceAmount = Utils::formatMoney($invoice->getRequestedAmount(), $invoice->client->currency_id); $invoiceAmount = Utils::formatMoney($invoice->getRequestedAmount(), $invoice->client->getCurrencyId());
foreach ($invoice->invitations as $invitation) { foreach ($invoice->invitations as $invitation) {
if (!$invitation->user || !$invitation->user->email) { if (!$invitation->user || !$invitation->user->email || $invitation->user->trashed()) {
return false; return false;
} }
if (!$invitation->contact || !$invitation->contact->email) { if (!$invitation->contact || !$invitation->contact->email || $invitation->contact->trashed()) {
return false; return false;
} }
@ -72,7 +72,7 @@ class ContactMailer extends Mailer
'$footer' => $payment->account->getEmailFooter(), '$footer' => $payment->account->getEmailFooter(),
'$client' => $payment->client->getDisplayName(), '$client' => $payment->client->getDisplayName(),
'$account' => $accountName, '$account' => $accountName,
'$amount' => Utils::formatMoney($payment->amount, $payment->client->currency_id) '$amount' => Utils::formatMoney($payment->amount, $payment->client->getCurrencyId())
]; ];
$data = ['body' => str_replace(array_keys($variables), array_values($variables), $emailTemplate)]; $data = ['body' => str_replace(array_keys($variables), array_values($variables), $emailTemplate)];

View File

@ -47,13 +47,13 @@ class UserMailer extends Mailer
'clientName' => $invoice->client->getDisplayName(), 'clientName' => $invoice->client->getDisplayName(),
'accountName' => $invoice->account->getDisplayName(), 'accountName' => $invoice->account->getDisplayName(),
'userName' => $user->getDisplayName(), 'userName' => $user->getDisplayName(),
'invoiceAmount' => Utils::formatMoney($invoice->amount, $invoice->client->currency_id), 'invoiceAmount' => Utils::formatMoney($invoice->amount, $invoice->client->getCurrencyId()),
'invoiceNumber' => $invoice->invoice_number, 'invoiceNumber' => $invoice->invoice_number,
'invoiceLink' => SITE_URL."/{$entityType}s/{$invoice->public_id}", 'invoiceLink' => SITE_URL."/{$entityType}s/{$invoice->public_id}",
]; ];
if ($payment) { if ($payment) {
$data['paymentAmount'] = Utils::formatMoney($payment->amount, $invoice->client->currency_id); $data['paymentAmount'] = Utils::formatMoney($payment->amount, $invoice->client->getCurrencyId());
} }
$subject = trans("texts.notification_{$entityType}_{$notificationType}_subject", ['invoice' => $invoice->invoice_number, 'client' => $invoice->client->getDisplayName()]); $subject = trans("texts.notification_{$entityType}_{$notificationType}_subject", ['invoice' => $invoice->invoice_number, 'client' => $invoice->client->getDisplayName()]);

View File

@ -272,6 +272,7 @@ class InvoiceRepository
$invoice->invoice_number = trim($data['invoice_number']); $invoice->invoice_number = trim($data['invoice_number']);
$invoice->partial = round(Utils::parseFloat($data['partial']), 2); $invoice->partial = round(Utils::parseFloat($data['partial']), 2);
$invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']); $invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']);
$invoice->has_tasks = isset($data['has_tasks']) ? $data['has_tasks'] : false;
if (!$publicId) { if (!$publicId) {
$invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false; $invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;

View File

@ -102,8 +102,12 @@ class PaymentRepository
$payment = Payment::createNew(); $payment = Payment::createNew();
} }
$paymentTypeId = false;
if (isset($input['payment_type_id'])) {
$paymentTypeId = $input['payment_type_id'] ? $input['payment_type_id'] : null; $paymentTypeId = $input['payment_type_id'] ? $input['payment_type_id'] : null;
$payment->payment_type_id = $paymentTypeId; $payment->payment_type_id = $paymentTypeId;
}
$payment->payment_date = Utils::toSqlDate($input['payment_date']); $payment->payment_date = Utils::toSqlDate($input['payment_date']);
$payment->transaction_reference = trim($input['transaction_reference']); $payment->transaction_reference = trim($input['transaction_reference']);

View File

@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddHasTasksToInvoices extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->boolean('has_tasks')->default(false);
});
$invoices = DB::table('invoices')
->join('tasks', 'tasks.invoice_id', '=', 'invoices.id')
->selectRaw('DISTINCT invoices.id')
->get();
foreach ($invoices as $invoice) {
DB::table('invoices')
->where('id', $invoice->id)
->update(['has_tasks' => true]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropColumn('has_tasks');
});
}
}

View File

@ -2449,9 +2449,11 @@ table.dataTable thead > tr > th, table.invoice-table thead > tr > th {
background-color: #e37329 !important; background-color: #e37329 !important;
color:#fff; color:#fff;
} }
/*
table.dataTable tr:hover { table.dataTable tr:hover {
background-color: #F2F5FE !important; background-color: #F2F5FE !important;
} }
*/
th:first-child { th:first-child {
border-radius: 3px 0 0 0; border-radius: 3px 0 0 0;
border-left: none; border-left: none;
@ -2472,7 +2474,7 @@ border-bottom: none;
} }
.table-striped>tbody>tr:nth-child(odd)>tr, .table-striped>tbody>tr:nth-child(odd)>tr,
.table-striped>tbody>tr:nth-child(odd)>th { .table-striped>tbody>tr:nth-child(odd)>th {
/*background-color: #FDFDFD;*/ background-color: #FDFDFD;
} }
table.table thead .sorting_asc { table.table thead .sorting_asc {
background: url('../images/sort_asc.png') no-repeat 90% 50%; background: url('../images/sort_asc.png') no-repeat 90% 50%;

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@ If you'd like to use our code to sell your own invoicing app we have an affiliat
To setup the site you can either use the [zip file](https://www.invoiceninja.com/knowledgebase/self-host/) (easier to run) or checkout the code from GitHub (easier to make changes). To setup the site you can either use the [zip file](https://www.invoiceninja.com/knowledgebase/self-host/) (easier to run) or checkout the code from GitHub (easier to make changes).
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the application please use our [forum](http://www.invoiceninja.com/forums/). For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the app please use our [new forum](http://www.invoiceninja.com/forums).
If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files. If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files.

View File

@ -48,7 +48,7 @@
@if (file_exists($account->getLogoPath())) @if (file_exists($account->getLogoPath()))
<center> <center>
{!! HTML::image($account->getLogoPath(), "Logo") !!} &nbsp; {!! HTML::image($account->getLogoPath().'?no_cache='.time(), "Logo") !!} &nbsp;
<a href="#" onclick="deleteLogo()">{{ trans('texts.remove_logo') }}</a> <a href="#" onclick="deleteLogo()">{{ trans('texts.remove_logo') }}</a>
</center><br/> </center><br/>
@endif @endif

View File

@ -122,16 +122,16 @@
<table class="table" style="width:300px"> <table class="table" style="width:300px">
<tr> <tr>
<td><small>{{ trans('texts.paid_to_date') }}</small></td> <td><small>{{ trans('texts.paid_to_date') }}</small></td>
<td style="text-align: right">{{ Utils::formatMoney($client->paid_to_date, $client->currency_id) }}</td> <td style="text-align: right">{{ Utils::formatMoney($client->paid_to_date, $client->getCurrencyId()) }}</td>
</tr> </tr>
<tr> <tr>
<td><small>{{ trans('texts.balance') }}</small></td> <td><small>{{ trans('texts.balance') }}</small></td>
<td style="text-align: right">{{ Utils::formatMoney($client->balance, $client->currency_id) }}</td> <td style="text-align: right">{{ Utils::formatMoney($client->balance, $client->getCurrencyId()) }}</td>
</tr> </tr>
@if ($credit > 0) @if ($credit > 0)
<tr> <tr>
<td><small>{{ trans('texts.credit') }}</small></td> <td><small>{{ trans('texts.credit') }}</small></td>
<td style="text-align: right">{{ Utils::formatMoney($credit, $client->currency_id) }}</td> <td style="text-align: right">{{ Utils::formatMoney($credit, $client->getCurrencyId()) }}</td>
</tr> </tr>
@endif @endif
</table> </table>

View File

@ -98,7 +98,7 @@
<td>{!! $invoice->getLink() !!}</td> <td>{!! $invoice->getLink() !!}</td>
<td>{{ $invoice->client->getDisplayName() }}</td> <td>{{ $invoice->client->getDisplayName() }}</td>
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td> <td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
<td>{{ Utils::formatMoney($invoice->balance, $invoice->client->currency_id) }}</td> <td>{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }}</td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
@ -125,7 +125,7 @@
<td>{!! $invoice->getLink() !!}</td> <td>{!! $invoice->getLink() !!}</td>
<td>{{ $invoice->client->getDisplayName() }}</td> <td>{{ $invoice->client->getDisplayName() }}</td>
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td> <td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
<td>{{ Utils::formatMoney($invoice->balance, $invoice->client->currency_id) }}</td> <td>{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }}</td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>

View File

@ -151,10 +151,10 @@
<thead> <thead>
<tr> <tr>
<th style="min-width:32px;" class="hide-border"></th> <th style="min-width:32px;" class="hide-border"></th>
<th style="min-width:160px">{{ $invoiceLabels['item'] }}</th> <th style="min-width:160px" data-bind="text: productLabel"></th>
<th style="width:100%">{{ $invoiceLabels['description'] }}</th> <th style="width:100%">{{ $invoiceLabels['description'] }}</th>
<th style="min-width:120px">{{ $invoiceLabels['unit_cost'] }}</th> <th style="min-width:120px" data-bind="text: costLabel"></th>
<th style="{{ $account->hide_quantity ? 'display:none' : 'min-width:120px' }}">{{ $invoiceLabels['quantity'] }}</th> <th style="{{ $account->hide_quantity ? 'display:none' : 'min-width:120px' }}" data-bind="text: qtyLabel"></th>
<th style="min-width:120px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th> <th style="min-width:120px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th>
<th style="min-width:120px;">{{ trans('texts.line_total') }}</th> <th style="min-width:120px;">{{ trans('texts.line_total') }}</th>
<th style="min-width:32px;" class="hide-border"></th> <th style="min-width:32px;" class="hide-border"></th>
@ -699,6 +699,10 @@
invoice.imageHeight = {{ $account->getLogoHeight() }}; invoice.imageHeight = {{ $account->getLogoHeight() }};
@endif @endif
invoiceLabels.item = invoice.has_tasks ? invoiceLabels.date : invoiceLabels.item_orig;
invoiceLabels.quantity = invoice.has_tasks ? invoiceLabels.hours : invoiceLabels.quantity_orig;
invoiceLabels.unit_cost = invoice.has_tasks ? invoiceLabels.rate : invoiceLabels.unit_cost_orig;
return invoice; return invoice;
} }
@ -1090,7 +1094,6 @@
self.discount = ko.observable(''); self.discount = ko.observable('');
self.is_amount_discount = ko.observable(0); self.is_amount_discount = ko.observable(0);
self.frequency_id = ko.observable(''); self.frequency_id = ko.observable('');
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
self.terms = ko.observable(''); self.terms = ko.observable('');
self.default_terms = ko.observable({{ !$invoice && $account->invoice_terms ? 'true' : 'false' }} ? wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) !!}', 300) : ''); self.default_terms = ko.observable({{ !$invoice && $account->invoice_terms ? 'true' : 'false' }} ? wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) !!}', 300) : '');
self.set_default_terms = ko.observable(false); self.set_default_terms = ko.observable(false);
@ -1113,6 +1116,7 @@
self.balance = ko.observable(0); self.balance = ko.observable(0);
self.invoice_design_id = ko.observable({{ $account->utf8_invoices ? 1 : $account->invoice_design_id }}); self.invoice_design_id = ko.observable({{ $account->utf8_invoices ? 1 : $account->invoice_design_id }});
self.partial = ko.observable(0); self.partial = ko.observable(0);
self.has_tasks = ko.observable(false);
self.custom_value1 = ko.observable(0); self.custom_value1 = ko.observable(0);
self.custom_value2 = ko.observable(0); self.custom_value2 = ko.observable(0);
@ -1153,6 +1157,18 @@
self.addItem(); self.addItem();
} }
self.productLabel = ko.computed(function() {
return self.has_tasks() ? invoiceLabels['date'] : invoiceLabels['item'];
}, this);
self.qtyLabel = ko.computed(function() {
return self.has_tasks() ? invoiceLabels['hours'] : invoiceLabels['quantity'];
}, this);
self.costLabel = ko.computed(function() {
return self.has_tasks() ? invoiceLabels['rate'] : invoiceLabels['unit_cost'];
}, this);
self._tax = ko.observable(); self._tax = ko.observable();
this.tax = ko.computed({ this.tax = ko.computed({
read: function () { read: function () {
@ -1268,7 +1284,7 @@
var tax = roundToTwo(total * (taxRate/100)); var tax = roundToTwo(total * (taxRate/100));
return formatMoney(tax, self.client().currency_id()); return formatMoney(tax, self.client().currency_id());
} else { } else {
return formatMoney(0); return formatMoney(0, self.client().currency_id());
} }
}); });
@ -1716,6 +1732,7 @@
item.task_public_id(task.publicId); item.task_public_id(task.publicId);
} }
model.invoice().invoice_items.push(blank); model.invoice().invoice_items.push(blank);
model.invoice().has_tasks(true);
@endif @endif
@endif @endif
@endif @endif

View File

@ -77,6 +77,12 @@
var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!}; var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!};
if (window.invoice) {
invoiceLabels.item = invoice.has_tasks ? invoiceLabels.date : invoiceLabels.item_orig;
invoiceLabels.quantity = invoice.has_tasks ? invoiceLabels.hours : invoiceLabels.quantity_orig;
invoiceLabels.unit_cost = invoice.has_tasks ? invoiceLabels.rate : invoiceLabels.unit_cost_orig;
}
var isRefreshing = false; var isRefreshing = false;
var needsRefresh = false; var needsRefresh = false;

View File

@ -25,8 +25,10 @@
{!! Former::text('amount') !!} {!! Former::text('amount') !!}
@endif @endif
{!! Former::select('payment_type_id')->addOption('','') @if (!$payment || !$payment->account_gateway_id)
->fromQuery($paymentTypes, 'name', 'id') !!} {!! Former::select('payment_type_id')->addOption('','')->fromQuery($paymentTypes, 'name', 'id') !!}
@endif
{!! Former::text('payment_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar"></i>') !!} {!! Former::text('payment_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar"></i>') !!}
{!! Former::text('transaction_reference') !!} {!! Former::text('transaction_reference') !!}

View File

@ -191,16 +191,16 @@ header h3 em {
<h3>{{ trans('texts.contact_information') }}</h3> <h3>{{ trans('texts.contact_information') }}</h3>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('first_name')->placeholder(trans('texts.first_name'))->raw() !!} {!! Former::text('first_name')->placeholder(trans('texts.first_name'))->label('') !!}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('last_name')->placeholder(trans('texts.last_name'))->raw() !!} {!! Former::text('last_name')->placeholder(trans('texts.last_name'))->label('') !!}
</div> </div>
</div> </div>
@if (isset($paymentTitle)) @if (isset($paymentTitle))
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
{!! Former::text('email')->placeholder(trans('texts.email'))->raw() !!} {!! Former::text('email')->placeholder(trans('texts.email'))->label('') !!}
</div> </div>
</div> </div>
@endif @endif
@ -210,26 +210,26 @@ header h3 em {
<h3>{{ trans('texts.billing_address') }} &nbsp;<span class="help">{{ trans('texts.payment_footer1') }}</span></h3> <h3>{{ trans('texts.billing_address') }} &nbsp;<span class="help">{{ trans('texts.payment_footer1') }}</span></h3>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('address1')->placeholder(trans('texts.address1'))->raw() !!} {!! Former::text('address1')->placeholder(trans('texts.address1'))->label('') !!}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('address2')->placeholder(trans('texts.address2'))->raw() !!} {!! Former::text('address2')->placeholder(trans('texts.address2'))->label('') !!}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('city')->placeholder(trans('texts.city'))->raw() !!} {!! Former::text('city')->placeholder(trans('texts.city'))->label('') !!}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('state')->placeholder(trans('texts.state'))->raw() !!} {!! Former::text('state')->placeholder(trans('texts.state'))->label('') !!}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{!! Former::text('postal_code')->placeholder(trans('texts.postal_code'))->raw() !!} {!! Former::text('postal_code')->placeholder(trans('texts.postal_code'))->label('') !!}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
{!! Former::select('country_id')->placeholder(trans('texts.country_id'))->fromQuery($countries, 'name', 'id')->raw() !!} {!! Former::select('country_id')->placeholder(trans('texts.country_id'))->fromQuery($countries, 'name', 'id')->label('') !!}
</div> </div>
</div> </div>
@ -238,10 +238,10 @@ header h3 em {
<h3>{{ trans('texts.billing_method') }}</h3> <h3>{{ trans('texts.billing_method') }}</h3>
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
{!! Former::text('card_number')->placeholder(trans('texts.card_number'))->raw() !!} {!! Former::text('card_number')->placeholder(trans('texts.card_number'))->label('') !!}
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
{!! Former::text('cvv')->placeholder(trans('texts.cvv'))->raw() !!} {!! Former::text('cvv')->placeholder(trans('texts.cvv'))->label('') !!}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -258,7 +258,7 @@ header h3 em {
->addOption('09 - September', '9') ->addOption('09 - September', '9')
->addOption('10 - October', '10') ->addOption('10 - October', '10')
->addOption('11 - November', '11') ->addOption('11 - November', '11')
->addOption('12 - December', '12')->raw() ->addOption('12 - December', '12')->label('')
!!} !!}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
@ -273,7 +273,7 @@ header h3 em {
->addOption('2022', '2022') ->addOption('2022', '2022')
->addOption('2023', '2023') ->addOption('2023', '2023')
->addOption('2024', '2024') ->addOption('2024', '2024')
->addOption('2025', '2025')->raw() ->addOption('2025', '2025')->label('')
!!} !!}
</div> </div>
</div> </div>

View File

@ -101,7 +101,7 @@ header h3 em {
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
trackEvent('license', 'product_{{ $productId }}'); trackEvent('/license', '/product_{{ $productId }}');
}) })
</script> </script>

View File

@ -100,6 +100,9 @@
</div> </div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
$('#main-container').height($(window).height() - ($('.navbar').height() + $('footer').height() + 20)); $('#main-container').height($(window).height() - ($('.navbar').height() + $('footer').height() + 20));

View File

@ -129,7 +129,7 @@
var clients = {!! $clients !!}; var clients = {!! $clients !!};
function tock() { function tock(duration) {
var timeLabels = {}; var timeLabels = {};
@foreach (['hour', 'minute', 'second'] as $period) @foreach (['hour', 'minute', 'second'] as $period)
timeLabels['{{ $period }}'] = '{{ trans("texts.{$period}") }}'; timeLabels['{{ $period }}'] = '{{ trans("texts.{$period}") }}';
@ -137,14 +137,14 @@
@endforeach @endforeach
var now = Math.floor(Date.now() / 1000); var now = Math.floor(Date.now() / 1000);
var duration = secondsToTime(now - NINJA.startTime);
var data = []; var data = [];
var periods = ['hour', 'minute', 'second']; var periods = ['hour', 'minute', 'second'];
var parts = secondsToTime(duration);
for (var i=0; i<periods.length; i++) { for (var i=0; i<periods.length; i++) {
var period = periods[i]; var period = periods[i];
var letter = period.charAt(0); var letter = period.charAt(0);
var value = duration[letter]; var value = parts[letter];
if (!value && !data.length) { if (!value && !data.length) {
continue; continue;
} }
@ -155,7 +155,7 @@
$('#duration-text').html(data.length ? data.join(', ') : '0 ' + timeLabels['seconds']); $('#duration-text').html(data.length ? data.join(', ') : '0 ' + timeLabels['seconds']);
setTimeout(function() { setTimeout(function() {
tock(); tock(duration+1);
}, 1000); }, 1000);
} }
@ -237,7 +237,7 @@
@if ($task) @if ($task)
NINJA.startTime = {{ strtotime($task->start_time) }}; NINJA.startTime = {{ strtotime($task->start_time) }};
@if ($task->duration == -1) @if ($task->duration == -1)
tock(); tock({{ $duration }});
@else @else
var date = new Date(NINJA.startTime * 1000); var date = new Date(NINJA.startTime * 1000);
var hours = date.getHours(); var hours = date.getHours();