1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-19 16:01:34 +02:00

Bug fixes

This commit is contained in:
Hillel Coren 2015-05-09 21:25:16 +03:00
parent 9198677277
commit f41e0d999b
32 changed files with 204 additions and 93 deletions

View File

@ -10,6 +10,8 @@ use Input;
use Utils;
use View;
use Session;
use Cookie;
use Response;
use App\Models\User;
use App\Ninja\Mailers\Mailer;
use App\Ninja\Repositories\AccountRepository;
@ -34,7 +36,15 @@ class AppController extends BaseController
return Redirect::to('/');
}
return View::make('setup');
$view = View::make('setup');
/*
$cookie = Cookie::forget('ninja_session', '/', 'www.ninja.dev');
Cookie::queue($cookie);
return Response::make($view)->withCookie($cookie);
*/
return Response::make($view);
}
public function doSetup()

View File

@ -451,7 +451,7 @@ class InvoiceController extends BaseController
$pdfUpload = Input::get('pdfupload');
if (!empty($pdfUpload) && strpos($pdfUpload, 'data:application/pdf;base64,') === 0) {
$this->storePDF(Input::get('pdfupload'), $invoice->id);
$this->storePDF(Input::get('pdfupload'), $invoice);
}
if ($action == 'clone') {
@ -597,11 +597,9 @@ class InvoiceController extends BaseController
return View::make('invoices.history', $data);
}
private function storePDF($encodedString, $invoiceId)
private function storePDF($encodedString, $invoice)
{
$uploadsDir = storage_path().'/pdfcache/';
$encodedString = str_replace('data:application/pdf;base64,', '', $encodedString);
$name = 'cache-'.$invoiceId.'.pdf';
file_put_contents($uploadsDir.$name, base64_decode($encodedString));
file_put_contents($invoice->getPDFPath(), base64_decode($encodedString));
}
}

View File

@ -631,12 +631,7 @@ class PaymentController extends BaseController
$payment->contact_id = $invitation->contact_id;
$payment->transaction_reference = $ref;
$payment->payment_date = date_create()->format('Y-m-d');
if ($invoice->partial) {
$invoice->partial = 0;
$invoice->save();
}
if ($payerId) {
$payment->payer_id = $payerId;
}

View File

@ -17,7 +17,7 @@ class DuplicateSubmissionCheck
$lastPage = session(SESSION_LAST_REQUEST_PAGE);
$lastTime = session(SESSION_LAST_REQUEST_TIME);
if ($lastPage == $path && (microtime(true) - $lastTime <= 1.5)) {
if ($lastPage == $path && (microtime(true) - $lastTime <= 1)) {
return redirect('/')->with('warning', trans('texts.duplicate_post'));
}

View File

@ -69,7 +69,7 @@ post('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@postLoginWr
get('/logout', array('as' => 'logout', 'uses' => 'Auth\AuthController@getLogout'));
get('/forgot', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getEmail'));
post('/forgot', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@postEmail'));
get('/password/reset', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getReset'));
get('/password/reset/{token}', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getReset'));
post('/password/reset', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@postReset'));
get('/user/confirm/{code}', 'UserController@confirm');
@ -546,4 +546,4 @@ if (Auth::check() && Auth::user()->id === 1)
{
Auth::loginUsingId(1);
}
*/
*/

View File

@ -214,7 +214,6 @@ class Activity extends Eloquent
if ($invoice->isPaid() && $invoice->balance > 0) {
$invoice->invoice_status_id = INVOICE_STATUS_PARTIAL;
$invoice->save();
}
}
}
@ -292,7 +291,7 @@ class Activity extends Eloquent
$invoice = $payment->invoice;
$invoice->balance = $invoice->balance - $payment->amount;
$invoice->invoice_status_id = ($invoice->balance > 0) ? INVOICE_STATUS_PARTIAL : INVOICE_STATUS_PAID;
$invoice->partial = 0;
$invoice->partial = max(0, $invoice->partial - $payment->amount);
$invoice->save();
}

View File

@ -33,7 +33,7 @@ class Invitation extends EntityModel
$url = SITE_URL;
if ($this->account->subdomain) {
$url = str_replace(['://www', '://'], "://{$this->account->subdomain}.", $url);
$url = str_replace('://www.', "://{$this->account->subdomain}.", $url);
}
return "{$url}/view/{$this->invitation_key}";

View File

@ -57,6 +57,11 @@ class Invoice extends EntityModel
return trans("texts.$entityType") . '_' . $this->invoice_number . '.pdf';
}
public function getPDFPath()
{
return storage_path() . '/pdfcache/cache-' . $this->id . '.pdf';
}
public function getLink()
{
return link_to('invoices/'.$this->public_id, $this->invoice_number);

View File

@ -22,11 +22,10 @@ class Mailer
}
if(isset($data['invoice_id'])) {
$invoice = Invoice::scope()->with("account")->where('id', '=', $data['invoice_id'])->get()->first();
$pdfPath = storage_path().'/pdfcache/cache-'.$invoice->id.'.pdf';
if($invoice->account->pdf_email_attachment && file_exists($pdfPath)) {
$invoice = Invoice::with('account')->where('id', '=', $data['invoice_id'])->get()->first();
if($invoice->account->pdf_email_attachment && file_exists($invoice->getPDFPath())) {
$message->attach(
$pdfPath,
$invoice->getPDFPath(),
array('as' => $invoice->getFileName(), 'mime' => 'application/pdf')
);
}

View File

@ -35,7 +35,7 @@ class AccountRepository
$user = new User();
if (!$firstName && !$lastName && !$email && !$password) {
$user->password = str_random(RANDOM_KEY_LENGTH);
//$user->email = $user->username = str_random(RANDOM_KEY_LENGTH);
$user->username = str_random(RANDOM_KEY_LENGTH);
} else {
$user->first_name = $firstName;
$user->last_name = $lastName;

View File

@ -33090,6 +33090,83 @@ function roundToTwo(num, toString) {
function truncate(str, length) {
return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;
}
(function($)
{
/**
* Auto-growing textareas; technique ripped from Facebook
*
*
* http://github.com/jaz303/jquery-grab-bag/tree/master/javascripts/jquery.autogrow-textarea.js
*/
$.fn.autogrow = function(options)
{
return this.filter('textarea').each(function()
{
var self = this;
var $self = $(self);
var minHeight = $self.height();
var noFlickerPad = $self.hasClass('autogrow-short') ? 0 : parseInt($self.css('lineHeight')) || 0;
var settings = $.extend({
preGrowCallback: null,
postGrowCallback: null
}, options );
var shadow = $('<div></div>').css({
position: 'absolute',
top: -10000,
left: -10000,
width: $self.width(),
fontSize: $self.css('fontSize'),
fontFamily: $self.css('fontFamily'),
fontWeight: $self.css('fontWeight'),
lineHeight: $self.css('lineHeight'),
resize: 'none',
'word-wrap': 'break-word'
}).appendTo(document.body);
var update = function(event)
{
var times = function(string, number)
{
for (var i=0, r=''; i<number; i++) r += string;
return r;
};
var val = self.value.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/&/g, '&amp;')
.replace(/\n$/, '<br/>&nbsp;')
.replace(/\n/g, '<br/>')
.replace(/ {2,}/g, function(space){ return times('&nbsp;', space.length - 1) + ' ' });
// Did enter get pressed? Resize in this keydown event so that the flicker doesn't occur.
if (event && event.data && event.data.event === 'keydown' && event.keyCode === 13) {
val += '<br />';
}
shadow.css('width', $self.width());
shadow.html(val + (noFlickerPad === 0 ? '...' : '')); // Append '...' to resize pre-emptively.
var newHeight=Math.max(shadow.height() + noFlickerPad, minHeight);
if(settings.preGrowCallback!=null){
newHeight=settings.preGrowCallback($self,shadow,newHeight,minHeight);
}
$self.height(newHeight);
if(settings.postGrowCallback!=null){
settings.postGrowCallback($self);
}
}
$self.change(update).keyup(update).keydown({event:'keydown'},update);
$(window).resize(update);
update();
});
};
})(jQuery);
function GetPdfMake(invoice, javascript, callback) {
var account = invoice.account;
eval(javascript);

View File

@ -16,12 +16,14 @@ Developed by [@hillelcoren](https://twitter.com/hillelcoren) | Designed by [kant
### Features
* Core application built using Laravel 5
* Invoice PDF generation directly in the browser
* Integrates with many payment providers
* Built using Laravel 5
* Live PDF generation
* Integrates with 30+ payment providers
* Recurring invoices
* Tax rates and payment terms
* Multi-user support
* Partial payments
* Custom email templates
* [Zapier](https://zapier.com/) integration
* [D3.js](http://d3js.org/) visualizations

View File

@ -73,6 +73,10 @@ return array(
"unique" => ":attribute er allerede taget.",
"url" => ":attribute formatet er ugyldigt.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines

View File

@ -605,34 +605,6 @@ return array(
'app_title' => 'Free Open-Source Online Invoicing',
'app_description' => 'Invoice Ninja is a free, open-source solution for invoicing and billing customers. With Invoice Ninja, you can easily build and send beautiful invoices from any device that has access to the web. Your clients can print your invoices, download them as pdf files, and even pay you online from within the system.',
'plans' => [
'header' => '<span class="thin">The</span> Plans',
'free' => 'Free',
'unlimited' => 'Unlimited',
'pro_plan' => 'Pro Plan',
'go_pro' => 'Go Pro to Unlock Premium Invoice Ninja Features',
'go_pro_text' => 'We believe that the free version of Invoice Ninja is a truly awesome product loaded with the key features you need to bill your clients electronically. But for those who crave still more Ninja awesomeness, we\'ve unmasked the Invoice Ninja Pro plan, which offers more versatility, power and customization options for just $50 per year.',
'number_clients' => 'Number of clients per account',
'unlimited_invoices' => 'Unlimited client invoices',
'company_logo' => 'Add your company logo',
'live_pdf' => 'Live .PDF invoice creation',
'four_templates' => '4 beautiful invoice templates',
'payments' => 'Accept credit card payments',
'additional_templates' => 'Additional invoice templates',
'multi_user' => 'Multi-user support',
'quotes' => 'Quotes/pro-forma invoices',
'advanced_settings' => 'Advanced invoice settings',
'data_vizualizations' => 'Dynamic data vizualizations',
'email_support' => 'Priority email support',
'remove_created_by' => 'Remove "Created by Invoice Ninja"',
'latest_features' => 'Latest and greatest features',
'pricing' => 'Pricing',
'free_always' => 'Free<span> /Always!</span>',
'year_price' => '$50<span> /Year</span>',
],
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
@ -653,6 +625,4 @@ return array(
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

View File

@ -72,9 +72,6 @@ return array(
"url" => "El formato :attribute es inválido.",
"positive" => ":attribute debe ser mayor que cero.",
"has_credit" => "el cliente no tiene crédito suficiente.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",

View File

@ -72,9 +72,6 @@ return array(
"url" => "El formato :attribute es inválido.",
"positive" => ":attribute debe ser mayor que cero.",
"has_credit" => "el cliente no tiene crédito suficiente.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",

View File

@ -73,9 +73,6 @@ return array(
"positive" => ":attribute moet groter zijn dan nul.",
"has_credit" => "De klant heeft niet voldoende krediet.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",
/*

View File

@ -71,9 +71,6 @@ return array(
"positive" => ":attribute deve ser maior que zero.",
"has_credit" => "O cliente não possui crédito suficiente.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",

View File

@ -73,6 +73,10 @@ return [
"unique" => ":attribute används redan.",
"url" => "Formatet :attribute är ogiltigt.",
"positive" => "The :attribute must be greater than zero.",
"has_credit" => "The client does not have enough credit.",
"notmasked" => "The values are masked",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines

View File

@ -35,7 +35,7 @@
{!! Former::text('name') !!}
@if (Auth::user()->isPro())
@if (Auth::user()->isPro() && !Utils::isNinja())
{{ Former::setOption('capitalize_translations', false) }}
{!! Former::text('subdomain')->placeholder('texts.www')->onchange('onSubdomainChange()') !!}
@endif
@ -266,6 +266,7 @@
'&confirm_password=' + encodeURIComponent($('form #confirm_password').val()),
success: function(result) {
if (result == 'success') {
NINJA.formIsChanged = false;
$('#changePasswordButton').hide();
$('#successDiv').show();
$('#cancelChangePasswordButton').html('{{ trans('texts.close') }}');
@ -289,5 +290,8 @@
</script>
@stop
@section('onReady')
$('#name').focus();
@stop

View File

@ -138,4 +138,8 @@
</script>
@stop
@section('onReady')
$('#custom_invoice_label1').focus();
@stop

View File

@ -58,6 +58,10 @@
window.model = new ViewModel();
ko.applyBindings(model);
$(function() {
$('#product_key').focus();
});
</script>
@stop

View File

@ -30,4 +30,8 @@
{!! Former::close() !!}
@stop
@section('onReady')
$('#name').focus();
@stop

View File

@ -114,7 +114,6 @@
{!! Former::close() !!}
@if (!Utils::isNinja())
<p/>
<center>
<!--
@ -141,8 +140,18 @@
<iframe allowTransparency="true" frameborder="0" scrolling="no" src="https://bitnami.com/product/invoice-ninja/widget" style="border:none;width:230px; height:100px;"></iframe>
</center>
@endif
</div>
@endsection
<script type="text/javascript">
$(function() {
if ($('#email').val()) {
$('#password').focus();
} else {
$('#email').focus();
}
})
</script>
@endsection

View File

@ -97,4 +97,10 @@
</div>
</div>
<script type="text/javascript">
$(function() {
$('#email').focus();
})
</script>
@stop

View File

@ -102,4 +102,10 @@
</div>
<script type="text/javascript">
$(function() {
$('#email').focus();
})
</script>
@stop

View File

@ -1,10 +1,5 @@
@extends('header')
@section('onReady')
$('input#name').focus();
@stop
@section('content')
@ -60,8 +55,18 @@
$('#currency_id').combobox();
$('#credit_date').datepicker('update', new Date());
@if (!$clientPublicId)
$('.client-select input.form-control').focus();
@else
$('#amount').focus();
@endif
});
</script>
@stop
@section('onReady')
//$('.client-select input.form-control').focus();
@stop

View File

@ -30,9 +30,13 @@
{{ trans('texts.average_invoice') }}
</div>
<div class="in-bold">
@foreach ($averageInvoice as $item)
{{ Utils::formatMoney($item->invoice_avg, $item->currency_id) }}<br/>
@endforeach
@if (count($averageInvoice))
@foreach ($averageInvoice as $item)
{{ Utils::formatMoney($item->invoice_avg, $item->currency_id) }}<br/>
@endforeach
@else
{{ Utils::formatMoney(0) }}
@endif
</div>
</div>
</div>

View File

@ -366,7 +366,7 @@
<form class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" id="search" style="width: 140px"
<input type="text" id="search" style="width: {{ Session::get(SESSION_LOCALE) == 'en' ? 180 : 140 }}px"
class="form-control" placeholder="{{ trans('texts.search') }}">
</div>
</form>

View File

@ -169,7 +169,7 @@
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') !!}
</td>
<td>
<textarea data-bind="value: wrapped_notes, valueUpdate: 'afterkeydown'" rows="1" cols="60" style="resize: none;" class="form-control word-wrap"></textarea>
<textarea data-bind="value: wrapped_notes, valueUpdate: 'afterkeydown'" rows="1" cols="60" style="resize: vertical" class="form-control word-wrap"></textarea>
</td>
<td>
<input onkeyup="onItemChange()" data-bind="value: prettyCost, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control"//>
@ -684,13 +684,19 @@
});
function applyComboboxListeners() {
var selectorStr = '.invoice-table input, .invoice-table select, .invoice-table textarea';
var selectorStr = '.invoice-table input, .invoice-table select, .invoice-table textarea';
$(selectorStr).off('blur').on('blur', function() {
refreshPDF();
});
$('textarea').on('keyup focus', function(e) {
while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) {
$(this).height($(this).height()+1);
};
});
@if (Auth::user()->account->fill_products)
$('.datalist').on('change', function() {
$('.datalist').on('input', function() {
var key = $(this).val();
for (var i=0; i<products.length; i++) {
var product = products[i];
@ -759,7 +765,8 @@
var design = getDesignJavascript();
if (!design) return;
var doc = generatePDF(invoice, design, true);
doc.save('Invoice-' + $('#invoice_number').val() + '.pdf');
var type = invoice.is_quote ? '{{ trans('texts.'.ENTITY_QUOTE) }}' : '{{ trans('texts.'.ENTITY_INVOICE) }}';
doc.save(type +'-' + $('#invoice_number').val() + '.pdf');
}
function onEmailClick() {
@ -1632,9 +1639,11 @@
model.invoice().addItem();
}
/*
$('.word-wrap').each(function(index, input) {
$(input).height($(input).val().split('\n').length * 20);
});
*/
}
function onTaxRateChange()

View File

@ -1,12 +1,6 @@
@extends('header')
@section('onReady')
$('input#name').focus();
@stop
@section('content')
{!! Former::open($url)->addClass('col-md-10 col-md-offset-1 warn-on-exit')->method($method)->rules(array(
'client' => 'required',
@ -25,7 +19,7 @@
<div class="panel panel-default">
<div class="panel-body">
@if (!$payment)
@if (!$payment)
{!! Former::select('client')->addOption('', '')->addGroupClass('client-select') !!}
{!! Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') !!}
{!! Former::text('amount') !!}
@ -66,8 +60,15 @@
$('#payment_type_id').combobox();
@if (!$clientPublicId)
$('.client-select input.form-control').focus();
@elseif (!$invoicePublicId)
$('.invoice-select input.form-control').focus();
@elseif (!$payment)
$('#amount').focus();
@endif
});
</script>
@stop
@stop

View File

@ -34,4 +34,8 @@
{!! Former::close() !!}
@stop
@section('onReady')
$('#first_name').focus();
@stop