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

Merge branch 'develop' of github.com:invoiceninja/invoiceninja into develop

This commit is contained in:
Hillel Coren 2017-11-06 09:58:12 +02:00
commit fed2e57891
15 changed files with 157 additions and 31 deletions

View File

@ -51,6 +51,7 @@ class ProjectController extends BaseController
public function create(ProjectRequest $request)
{
$data = [
'account' => auth()->user()->account,
'project' => null,
'method' => 'POST',
'url' => 'projects',
@ -67,6 +68,7 @@ class ProjectController extends BaseController
$project = $request->entity();
$data = [
'account' => auth()->user()->account,
'project' => $project,
'method' => 'PUT',
'url' => 'projects/' . $project->public_id,

View File

@ -11,7 +11,7 @@ class TwoFactorController extends Controller
{
$user = auth()->user();
if ($user->google_2fa_secret || ! $user->phone) {
if ($user->google_2fa_secret || ! $user->phone || ! $user->confirmed) {
return redirect('/settings/user_details');
}
@ -39,7 +39,7 @@ class TwoFactorController extends Controller
$user = auth()->user();
$secret = session()->pull('2fa:secret');
if ($secret && ! $user->google_2fa_secret && $user->phone) {
if ($secret && ! $user->google_2fa_secret && $user->phone && $user->confirmed) {
$user->google_2fa_secret = Crypt::encrypt($secret);
$user->save();

View File

@ -89,6 +89,11 @@ class Utils
return env('NINJA_DEV') == 'true';
}
public static function isTimeTracker()
{
return array_get($_SERVER, 'HTTP_USER_AGENT') == TIME_TRACKER_USER_AGENT;
}
public static function requireHTTPS()
{
if (Request::root() === 'http://ninja.dev' || Request::root() === 'http://ninja.dev:8000') {

View File

@ -126,7 +126,7 @@ class Activity extends Eloquent
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : e($user->getDisplayName()),
'invoice' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null,
'quote' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null,
'contact' => $contactId ? e($client->getDisplayName()) : e($user->getDisplayName()),
'contact' => $contactId ? link_to($client->getRoute(), $client->getDisplayName()) : e($user->getDisplayName()),
'payment' => $payment ? e($payment->transaction_reference) : null,
'payment_amount' => $payment ? $account->formatMoney($payment->amount, $payment) : null,
'adjustment' => $this->adjustment ? $account->formatMoney($this->adjustment, $this) : null,

View File

@ -15,8 +15,17 @@ class ActivityDatatable extends EntityDatatable
'activities.id',
function ($model) {
$str = Utils::timestampToDateTimeString(strtotime($model->created_at));
$activityTypes = [
ACTIVITY_TYPE_VIEW_INVOICE,
ACTIVITY_TYPE_VIEW_QUOTE,
ACTIVITY_TYPE_CREATE_PAYMENT,
ACTIVITY_TYPE_APPROVE_QUOTE,
];
if ($model->contact_id && ! in_array($model->ip, ['127.0.0.1', '192.168.255.33'])) {
if ($model->contact_id
&& ! $model->is_system
&& in_array($model->activity_type_id, $activityTypes)
&& ! in_array($model->ip, ['127.0.0.1', '192.168.255.33'])) {
$ipLookUpLink = IP_LOOKUP_URL . $model->ip;
$str .= sprintf(' &nbsp; <i class="fa fa-globe" style="cursor:pointer" title="%s" onclick="openUrl(\'%s\', \'IP Lookup\')"></i>', $model->ip, $ipLookUpLink);
}

View File

@ -52,6 +52,18 @@ class AccountPresenter extends Presenter
return Utils::addHttp($this->entity->website);
}
/**
* @return string
*/
public function taskRate()
{
if ($this->entity->task_rate) {
return Utils::roundSignificant($this->entity->task_rate);
} else {
return '';
}
}
/**
* @return mixed
*/

View File

@ -50,4 +50,16 @@ class ClientPresenter extends EntityPresenter
return sprintf('%s: %s %s', trans('texts.payment_terms'), trans('texts.payment_terms_net'), $client->defaultDaysDue());
}
/**
* @return string
*/
public function taskRate()
{
if ($this->entity->task_rate) {
return Utils::roundSignificant($this->entity->task_rate);
} else {
return '';
}
}
}

View File

@ -2519,6 +2519,9 @@ $LANG = array(
'add_product' => 'Add Product',
'email_will_be_sent_on' => 'Note: the email will be sent on :date.',
'invoice_product' => 'Invoice Product',
'self_host_login' => 'Self-Host Login',
'set_self_hoat_url' => 'Self-Host URL',
'local_storage_required' => 'Error: local storage is not available.',
);

View File

@ -50,21 +50,22 @@
!!}
@endif
@if ($user->google_2fa_secret)
{!! Former::checkbox('enable_two_factor')
->help(trans('texts.enable_two_factor_help'))
->text(trans('texts.enable'))
->value(1) !!}
@elseif ($user->phone)
{!! Former::plaintext('enable_two_factor')->value(
Button::primary(trans('texts.enable'))->asLinkTo(url('settings/enable_two_factor'))->small()
)->help('enable_two_factor_help') !!}
@else
{!! Former::plaintext('enable_two_factor')
->value('<span class="text-muted">' . trans('texts.set_phone_for_two_factor') . '</span>') !!}
@if ($user->confirmed)
@if ($user->google_2fa_secret)
{!! Former::checkbox('enable_two_factor')
->help(trans('texts.enable_two_factor_help'))
->text(trans('texts.enable'))
->value(1) !!}
@elseif ($user->phone)
{!! Former::plaintext('enable_two_factor')->value(
Button::primary(trans('texts.enable'))->asLinkTo(url('settings/enable_two_factor'))->small()
)->help('enable_two_factor_help') !!}
@else
{!! Former::plaintext('enable_two_factor')
->value('<span class="text-muted">' . trans('texts.set_phone_for_two_factor') . '</span>') !!}
@endif
@endif
{!! Former::checkbox('dark_mode')
->help(trans('texts.dark_mode_help'))
->text(trans('texts.enable'))

View File

@ -83,7 +83,11 @@
{!! link_to('/recover_password', trans('texts.recover_password')) !!}
</div>
<div class="col-md-5 col-sm-12">
{!! link_to(NINJA_WEB_URL.'/knowledgebase/', trans('texts.knowledge_base'), ['target' => '_blank']) !!}
@if (Utils::isTimeTracker())
{!! link_to('#', trans('texts.self_host_login'), ['onclick' => 'setSelfHostUrl()']) !!}
@else
{!! link_to(NINJA_WEB_URL.'/knowledgebase/', trans('texts.knowledge_base'), ['target' => '_blank']) !!}
@endif
</div>
@endif
</div>
@ -111,8 +115,13 @@
$('#email').focus();
}
@if (array_get($_SERVER, 'HTTP_USER_AGENT') == TIME_TRACKER_USER_AGENT)
@if (Utils::isTimeTracker())
if (isStorageSupported()) {
var selfHostUrl = localStorage.getItem('last:time_tracker:url');
if (selfHostUrl) {
location.href = selfHostUrl;
return;
}
$('#email').change(function() {
localStorage.setItem('last:time_tracker:email', $('#email').val());
})
@ -124,6 +133,29 @@
}
@endif
})
@if (Utils::isTimeTracker())
function setSelfHostUrl() {
if (! isStorageSupported()) {
swal("{{ trans('texts.local_storage_required') }}");
return;
}
swal({
title: "{{ trans('texts.set_self_hoat_url') }}",
input: 'text',
showCancelButton: true,
confirmButtonText: 'Save',
}).then(function (value) {
if (!value) {
return;
}
value = value.replace(/\/+$/, '') + '/time_tracker';
localStorage.setItem('last:time_tracker:url', value);
location.reload();
})
}
@endif
</script>
@endsection

View File

@ -158,6 +158,7 @@
->help(trans('texts.payment_terms_help')) !!}
@if ($account->isModuleEnabled(ENTITY_TASK))
{!! Former::text('task_rate')
->placeholder($account->present()->taskRate)
->help('task_rate_help') !!}
@endif
{!! Former::select('size_id')->addOption('','')

View File

@ -536,7 +536,10 @@
@if ($invoice->isClientTrashed())
<!-- do nothing -->
@elseif ($invoice->isSent() && config('ninja.lock_sent_invoices'))
<!-- do nothing -->
@if (! $invoice->trashed())
{!! Button::info(trans("texts.email_{$entityType}"))->withAttributes(array('id' => 'emailButton', 'onclick' => 'onEmailClick()'))->appendIcon(Icon::create('send')) !!}
@endif
@else
@if (!$invoice->is_deleted)
@if ($invoice->isSent())
@ -1188,6 +1191,8 @@
}
var origInvoiceNumber = false;
var checkedInvoiceBalances = false;
function getPDFString(cb, force) {
@if (! $invoice->id && $account->credit_number_counter > 0)
var total = model.invoice().totals.rawTotal();
@ -1201,13 +1206,30 @@
}
@endif
var invoice = createInvoiceModel();
var design = getDesignJavascript();
/*
@if ($invoice->exists)
if (! checkedInvoiceBalances) {
checkedInvoiceBalances = true;
var phpBalance = roundSignificant(invoice.balance);
var koBalance = roundSignificant(model.invoice().totals.rawTotal());
var jsBalance = roundSignificant(calculateAmounts(invoice).total_amount);
if (phpBalance == koBalance && koBalance == jsBalance) {
// do nothing
} else {
var invitationKey = invoice.invitations[0].invitation_key;
window.onerror(invitationKey + ': Balances do not match | PHP: ' + phpBalance + ', JS: ' + jsBalance + ', KO: ' + koBalance);
}
}
@endif
*/
@if ( ! $account->live_preview)
return;
@endif
var invoice = createInvoiceModel();
var design = getDesignJavascript();
if (! design) {
return;
}
@ -1421,10 +1443,6 @@
return false;
}
@if ($invoice->isSent() && config('ninja.lock_sent_invoices'))
return false;
@endif
@if ($invoice->is_deleted || $invoice->isClientTrashed())
if ($('#bulk_action').val() != 'restore') {
return false;
@ -1569,7 +1587,6 @@
submitBulkAction('delete');
});
}
function formEnterClick(event) {
if (event.keyCode === 13){
if (event.target.type == 'textarea') {

View File

@ -18,7 +18,14 @@
<div class="panel panel-default">
<div class="panel-body">
{!! Former::open('/bluevine/signup')->id('bluevineSignup') !!}
{!! trans('texts.bluevine_modal_text') !!}<br/>
<div class="pull-left">
{!! trans('texts.bluevine_modal_text') !!}
</div>
<div class="pull-right">
<br/>
<a class='btn btn-primary btn-sm' href='https://www.invoiceninja.com/blue-vine-invoice-factoring/' target="_blank">{{ trans('texts.learn_more') }}</a>
</div>
<div class="clearfix"></div>
<h3>{!! trans('texts.bluevine_create_account') !!}</h3>
{!! Former::text('name')->id('bluevine_name')->placeholder(trans('texts.name'))->value($user->first_name . ' ' . $user->last_name)->required() !!}
{!! Former::text('email')->id('bluevine_email')->placeholder(trans('texts.email'))->value($user->email)->required() !!}

View File

@ -41,6 +41,7 @@
{!! Former::text('name') !!}
{!! Former::text('task_rate')
->placeholder($project && $project->client->task_rate ? $project->client->present()->taskRate : $account->present()->taskRate)
->help('task_rate_help') !!}
</div>
@ -65,11 +66,13 @@
<script>
var clients = {!! $clients !!};
var clientMap = {};
$(function() {
var $clientSelect = $('select#client_id');
for (var i=0; i<clients.length; i++) {
var client = clients[i];
clientMap[client.public_id] = client;
var clientName = getClientDisplayName(client);
if (!clientName) {
continue;
@ -80,7 +83,15 @@
$clientSelect.val({{ $clientPublicId }});
@endif
$clientSelect.combobox({highlighter: comboboxHighlighter});
$clientSelect.combobox({highlighter: comboboxHighlighter}).change(function() {
var client = clientMap[$('#client_id').val()];
if (client && parseFloat(client.task_rate)) {
var rate = client.task_rate;
} else {
var rate = {{ $account->present()->taskRate }};
}
$('#task_rate').attr('placeholder', roundSignificant(rate));
});
@if ($clientPublicId)
$('#name').focus();

View File

@ -41,7 +41,7 @@
{!! Former::text('time_log') !!}
</div>
<div class="row">
<div class="row" onkeypress="formEnterClick(event)">
<div class="col-md-12">
<div class="panel panel-default">
@ -490,6 +490,20 @@
}
}
function formEnterClick(event) {
if (event.keyCode === 13){
if (event.target.type == 'textarea') {
return;
}
event.preventDefault();
@if ($task && $task->trashed())
return;
@endif
submitAction('');
return false;
}
}
$(function() {
$('input[type=radio]').change(function() {
onTaskTypeChange();