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
baea73f8c6
commit
63a6b88e20
@ -1,8 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use ninja\mailers\Mailer;
|
||||||
|
|
||||||
class HomeController extends BaseController {
|
class HomeController extends BaseController {
|
||||||
|
|
||||||
protected $layout = 'master';
|
protected $layout = 'master';
|
||||||
|
protected $mailer;
|
||||||
|
|
||||||
|
public function __construct(Mailer $mailer)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->mailer = $mailer;
|
||||||
|
}
|
||||||
|
|
||||||
public function showWelcome()
|
public function showWelcome()
|
||||||
{
|
{
|
||||||
@ -19,6 +29,24 @@ class HomeController extends BaseController {
|
|||||||
return View::make('contact_us');
|
return View::make('contact_us');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function doContactUs()
|
||||||
|
{
|
||||||
|
$email = Input::get('email');
|
||||||
|
$name = Input::get('name');
|
||||||
|
$message = Input::get('message');
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $name,
|
||||||
|
'email' => $email,
|
||||||
|
'text' => $message
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->mailer->sendTo('contact@invoiceninja.com', 'contact@invoiceninja.com', 'Invoice Ninja Feedback', 'contact', $data);
|
||||||
|
|
||||||
|
Session::flash('message', 'Successfully sent message');
|
||||||
|
return Redirect::to('/contact');
|
||||||
|
}
|
||||||
|
|
||||||
public function showComingSoon()
|
public function showComingSoon()
|
||||||
{
|
{
|
||||||
return View::make('coming_soon');
|
return View::make('coming_soon');
|
||||||
|
@ -254,6 +254,8 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
if ($errors = $this->invoiceRepo->getErrors($invoice))
|
if ($errors = $this->invoiceRepo->getErrors($invoice))
|
||||||
{
|
{
|
||||||
|
Session::flash('error', 'Please make sure to select a client and correct any errors');
|
||||||
|
|
||||||
return Redirect::to('invoices/create')
|
return Redirect::to('invoices/create')
|
||||||
->withInput()->withErrors($errors);
|
->withInput()->withErrors($errors);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ class AddSupportForInvoiceDesigns extends Migration {
|
|||||||
DB::table('invoice_designs')->insert(['name' => 'Clean']);
|
DB::table('invoice_designs')->insert(['name' => 'Clean']);
|
||||||
DB::table('invoice_designs')->insert(['name' => 'Bold']);
|
DB::table('invoice_designs')->insert(['name' => 'Bold']);
|
||||||
DB::table('invoice_designs')->insert(['name' => 'Modern']);
|
DB::table('invoice_designs')->insert(['name' => 'Modern']);
|
||||||
|
DB::table('invoice_designs')->insert(['name' => 'Plain']);
|
||||||
|
|
||||||
Schema::table('invoices', function($table)
|
Schema::table('invoices', function($table)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,8 @@ class Utils
|
|||||||
'url' => Input::get('url', Request::url()),
|
'url' => Input::get('url', Request::url()),
|
||||||
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
||||||
'ip' => Request::getClientIp(),
|
'ip' => Request::getClientIp(),
|
||||||
'count' => Session::get('error_count', 0)
|
'count' => Session::get('error_count', 0),
|
||||||
|
'input' => Input::all()
|
||||||
];
|
];
|
||||||
|
|
||||||
Log::error('\n'.$error, $data);
|
Log::error('\n'.$error, $data);
|
||||||
|
@ -54,7 +54,7 @@ class Invoice extends EntityModel
|
|||||||
|
|
||||||
public function hidePrivateFields()
|
public function hidePrivateFields()
|
||||||
{
|
{
|
||||||
$this->setVisible(['invoice_number', 'discount', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'amount', 'balance', 'invoice_items', 'client', 'tax_name', 'tax_rate', 'account']);
|
$this->setVisible(['invoice_number', 'discount', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'amount', 'balance', 'invoice_items', 'client', 'tax_name', 'tax_rate', 'account', 'invoice_design_id']);
|
||||||
|
|
||||||
$this->client->setVisible(['name', 'address1', 'address2', 'city', 'state', 'postal_code', 'work_phone', 'payment_terms', 'contacts', 'country', 'currency_id' ]);
|
$this->client->setVisible(['name', 'address1', 'address2', 'city', 'state', 'postal_code', 'work_phone', 'payment_terms', 'contacts', 'country', 'currency_id' ]);
|
||||||
$this->account->setVisible(['name', 'address1', 'address2', 'city', 'state', 'postal_code', 'work_phone', 'work_email', 'country', 'currency_id']);
|
$this->account->setVisible(['name', 'address1', 'address2', 'city', 'state', 'postal_code', 'work_phone', 'work_email', 'country', 'currency_id']);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use Mail;
|
use Mail;
|
||||||
|
|
||||||
abstract class Mailer {
|
class Mailer {
|
||||||
|
|
||||||
public function sendTo($toEmail, $fromEmail, $subject, $view, $data = [])
|
public function sendTo($toEmail, $fromEmail, $subject, $view, $data = [])
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ class InvoiceRepository
|
|||||||
|
|
||||||
$invoice = (array) $input;
|
$invoice = (array) $input;
|
||||||
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
|
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
|
||||||
$rules = ['invoice_number' => 'unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
|
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
|
||||||
|
|
||||||
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
|
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
|
||||||
{
|
{
|
||||||
|
@ -56,8 +56,9 @@ Route::get('/send_emails', function() {
|
|||||||
|
|
||||||
Route::get('/', 'HomeController@showWelcome');
|
Route::get('/', 'HomeController@showWelcome');
|
||||||
Route::get('/rocksteady', 'HomeController@showWelcome');
|
Route::get('/rocksteady', 'HomeController@showWelcome');
|
||||||
Route::get('/about_us', 'HomeController@showAboutUs');
|
Route::get('/about', 'HomeController@showAboutUs');
|
||||||
Route::get('/contact_us', 'HomeController@showContactUs');
|
Route::get('/contact', 'HomeController@showContactUs');
|
||||||
|
Route::post('/contact', 'HomeController@doContactUs');
|
||||||
|
|
||||||
Route::get('log_error', 'HomeController@logError');
|
Route::get('log_error', 'HomeController@logError');
|
||||||
Route::post('get_started', 'AccountController@getStarted');
|
Route::post('get_started', 'AccountController@getStarted');
|
||||||
|
@ -9,83 +9,108 @@
|
|||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
||||||
|
{{ Form::hidden('guest_key') }}
|
||||||
|
{{ Form::close() }}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
|
||||||
|
if (isStorageSupported()) {
|
||||||
|
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
|
||||||
|
}
|
||||||
|
|
||||||
var $window = $(window);
|
var $window = $(window);
|
||||||
$('section[data-type="background"]').each(function () {
|
$('section[data-type="background"]').each(function () {
|
||||||
var $bgobj = $(this);
|
var $bgobj = $(this);
|
||||||
$(window).scroll(function () {
|
$(window).scroll(function () {
|
||||||
var yPos = -($window.scrollTop() / $bgobj.data('speed'));
|
var yPos = -($window.scrollTop() / $bgobj.data('speed'));
|
||||||
var coords = '50% ' + yPos + 'px';
|
var coords = '50% ' + yPos + 'px';
|
||||||
$bgobj.css({ backgroundPosition: coords });
|
$bgobj.css({ backgroundPosition: coords });
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function isStorageSupported() {
|
||||||
|
try {
|
||||||
|
return 'localStorage' in window && window['localStorage'] !== null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStarted() {
|
||||||
|
$('#startForm').submit();
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<a class="brand" href="#"><img src=
|
<a class="brand" href="/"><img src=
|
||||||
"images/invoiceninja-logo.png"></a>
|
"images/invoiceninja-logo.png"></a>
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<li>{{ link_to('about_us', 'About Us' ) }}</li>
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
<li>{{ link_to('contact_us', 'Contact Us' ) }}</li>
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="hero3" data-speed="2" data-type="background">
|
<section class="hero3" data-speed="2" data-type="background">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<h1>WHY INVOICE NINJA?
|
<h1>WHY INVOICE NINJA?
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="about center">
|
<section class="about center">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<h2>Open Source Platform</h2>
|
<h2>Open Source Platform</h2>
|
||||||
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being open source allows us fast app development, security audits by the open-course community, and we can keep it <span style="color:#2299c0"><strong>FREE!</strong></span></p>
|
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being open source allows us fast app development, security audits by the open-course community, and we can keep it <span style="color:#2299c0"><strong>FREE!</strong></span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="about white-bg">
|
<section class="about white-bg">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<div class="screendump">
|
<div class="screendump">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-7">
|
|
||||||
<h2>Live PDF Creation</h2>
|
|
||||||
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and it’s awesome!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
<section class="about">
|
<div class="col-md-7">
|
||||||
<div class="container">
|
<h2>Live PDF Creation</h2>
|
||||||
<div class="row">
|
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and it’s awesome!
|
||||||
<div class="col-md-7">
|
</p>
|
||||||
<h2>Online Payments</h2>
|
</div>
|
||||||
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we don’t yet support, please contact us! We’re happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5">
|
</section>
|
||||||
<div class="screendump">
|
<section class="about">
|
||||||
</div>
|
<div class="container">
|
||||||
</div>
|
<div class="row">
|
||||||
</div>
|
<div class="col-md-7">
|
||||||
|
<h2>Online Payments</h2>
|
||||||
|
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we don’t yet support, please contact us! We’re happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="screendump">
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--
|
||||||
<section class="about center white-bg">
|
<section class="about center white-bg">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -100,24 +125,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="upper-footer">
|
-->
|
||||||
<div class="container">
|
<section class="upper-footer">
|
||||||
<div class="row">
|
<div class="container">
|
||||||
<div class="col-md-3 center-block">
|
<div class="row">
|
||||||
<a href="#">
|
<div class="col-md-3 center-block">
|
||||||
<div class="cta">
|
<a href="#">
|
||||||
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
|
<div class="cta">
|
||||||
</div>
|
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="social">
|
<div class="social">
|
||||||
<!--
|
<!--
|
||||||
<a href="http://twitter.com/eas_id"><span class=
|
<a href="http://twitter.com/eas_id"><span class=
|
||||||
"socicon">c</span></a>
|
"socicon">c</span></a>
|
||||||
@ -132,7 +158,9 @@
|
|||||||
|
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@ -148,4 +176,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
@stop
|
@stop
|
@ -10,6 +10,11 @@
|
|||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
|
|
||||||
|
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
||||||
|
{{ Form::hidden('guest_key') }}
|
||||||
|
{{ Form::close() }}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
var $window = $(window);
|
var $window = $(window);
|
||||||
@ -27,7 +32,7 @@
|
|||||||
|
|
||||||
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
|
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
|
||||||
var hasErrors = false;
|
var hasErrors = false;
|
||||||
$('#feedbackForm input,textarea').each(function() {
|
$('.feedbackForm input,textarea').each(function() {
|
||||||
if (!$(this).val()) {
|
if (!$(this).val()) {
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
contactForm.addError($(this));
|
contactForm.addError($(this));
|
||||||
@ -44,23 +49,6 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//send the feedback e-mail
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "library/sendmail.php",
|
|
||||||
data: $("#feedbackForm").serialize(),
|
|
||||||
success: function(data)
|
|
||||||
{
|
|
||||||
contactForm.addAjaxMessage(data.message, false);
|
|
||||||
//get new Captcha on success
|
|
||||||
$('#captcha').attr('src', '/vendor/securimage/securimage_show.php?' + Math.random());
|
|
||||||
},
|
|
||||||
error: function(response)
|
|
||||||
{
|
|
||||||
contactForm.addAjaxMessage(response.responseJSON.message, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -73,8 +61,8 @@ var contactForm = {
|
|||||||
},
|
},
|
||||||
clearErrors: function () {
|
clearErrors: function () {
|
||||||
$('#emailAlert').remove();
|
$('#emailAlert').remove();
|
||||||
$('#feedbackForm .help-block').hide();
|
$('.feedbackForm .help-block').hide();
|
||||||
$('#feedbackForm .form-group').removeClass('has-error');
|
$('.feedbackForm .form-group').removeClass('has-error');
|
||||||
},
|
},
|
||||||
addError: function ($input) {
|
addError: function ($input) {
|
||||||
$input.siblings('.help-block').show();
|
$input.siblings('.help-block').show();
|
||||||
@ -84,16 +72,29 @@ var contactForm = {
|
|||||||
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
|
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isStorageSupported() {
|
||||||
|
try {
|
||||||
|
return 'localStorage' in window && window['localStorage'] !== null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStarted() {
|
||||||
|
$('#startForm').submit();
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<a class="brand" href="#"><img src=
|
<a class="brand" href="/"><img src=
|
||||||
"images/invoiceninja-logo.png"></a>
|
"images/invoiceninja-logo.png"></a>
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<li>{{ link_to('about_us', 'About Us' ) }}</li>
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
<li>{{ link_to('contact_us', 'Contact Us' ) }}</li>
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -113,12 +114,22 @@ var contactForm = {
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div id="contact_form" class="row">
|
<div id="contact_form" class="row">
|
||||||
|
|
||||||
|
|
||||||
|
@if (Session::has('message'))
|
||||||
|
<div class="alert alert-info">{{ Session::get('message') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (Session::has('error'))
|
||||||
|
<div class="alert alert-danger">{{ Session::get('error') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
<h2>Have a question or just want to say hi?</h2>
|
<h2>Have a question or just want to say hi?</h2>
|
||||||
<p>Fill in the form below and we'll get back to you as soon as possible (within 24 hours). Hope to hear from you.</p>
|
<p>Fill in the form below and we'll get back to you as soon as possible (within 24 hours). Hope to hear from you.</p>
|
||||||
|
|
||||||
<form role="form" id="feedbackForm">
|
{{ Former::open('contact')->addClass('feedbackForm') }}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
|
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
|
||||||
<span class="help-block" style="display: none;">Please enter your name.</span>
|
<span class="help-block" style="display: none;">Please enter your name.</span>
|
||||||
@ -136,17 +147,18 @@ var contactForm = {
|
|||||||
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
|
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
{{ Former::close() }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 col-md-offset-1 address">
|
<div class="col-md-4 col-md-offset-1 address">
|
||||||
<h2>Other ways to reach us</h2>
|
<h2>Other ways to reach us</h2>
|
||||||
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:hello@invoiceninja.com">hello@invoiceninja.com</a></p>
|
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a></p>
|
||||||
<p><span class="glyphicon glyphicon-earphone"></span>+524 975 502</p>
|
<p><span class="glyphicon glyphicon-earphone"></span>+524 975 502</p>
|
||||||
<address>
|
<address>
|
||||||
<span class="glyphicon glyphicon-pencil"></span><strong>InvoiceNinja</strong><br>
|
<span class="glyphicon glyphicon-pencil"></span><strong>InvoiceNinja</strong><br>
|
||||||
<span class="push">795 Folsom Ave, Suite 600<br></span>
|
<span class="push">795 Folsom Ave, Suite 600<br></span>
|
||||||
<span class="push">San Francisco, CA 94107<br></span>
|
<span class="push">San Francisco, CA 94107<br></span>
|
||||||
<span class="push">Isarel</span>
|
|
||||||
</address>
|
</address>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -191,7 +203,9 @@ var contactForm = {
|
|||||||
|
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
3
app/views/emails/contact_html.blade.php
Normal file
3
app/views/emails/contact_html.blade.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Name: {{ $name }}<br/>
|
||||||
|
Email: {{ $email }}<p/>
|
||||||
|
Message: {{ $text }}
|
4
app/views/emails/contact_text.blade.php
Normal file
4
app/views/emails/contact_text.blade.php
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Name: {{ $name }}
|
||||||
|
Email: {{ $email }}
|
||||||
|
|
||||||
|
Message: {{ $text }}
|
@ -30,7 +30,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="client" class="control-label col-lg-4 col-sm-4">Client</label>
|
<label for="client" class="control-label col-lg-4 col-sm-4">Client</label>
|
||||||
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
||||||
<a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm">{{ $client->getDisplayName() }}</a>
|
<a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm, text: getClientDisplayName(ko.toJS(client()))"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
@ -217,9 +217,9 @@
|
|||||||
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
||||||
@if ($invoice)
|
@if ($invoice)
|
||||||
|
|
||||||
<div id="primaryActions" style="text-align:left" data-bind="css: $root.enable.save" class="btn-group">
|
<div id="primaryActions" style="text-align:left" class="btn-group">
|
||||||
<button class="btn-success btn" type="button" data-bind="css: $root.enable.save">Save Invoice</button>
|
<button class="btn-success btn" type="button">Save Invoice</button>
|
||||||
<button class="btn-success btn dropdown-toggle" type="button" data-toggle="dropdown" data-bind="css: $root.enable.save">
|
<button class="btn-success btn dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
@ -255,10 +255,10 @@
|
|||||||
)
|
)
|
||||||
, array('id'=>'primaryActions', 'style'=>'text-align:left', 'data-bind'=>'css: $root.enable.save'))->split(); --}}
|
, array('id'=>'primaryActions', 'style'=>'text-align:left', 'data-bind'=>'css: $root.enable.save'))->split(); --}}
|
||||||
@else
|
@else
|
||||||
{{ Button::success_submit('Save Invoice', array('data-bind'=>'css: $root.enable.save', 'id' => 'saveButton')) }}
|
{{ Button::success_submit('Save Invoice', array('id' => 'saveButton')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ Button::normal('Email Invoice', array('id' => 'email_button', 'onclick' => 'onEmailClick()', 'data-bind' => 'css: $root.enable.email'))->append_with_icon('send'); }}
|
{{ Button::normal('Email Invoice', array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->append_with_icon('send'); }}
|
||||||
|
|
||||||
@if ($invoice)
|
@if ($invoice)
|
||||||
{{ Button::primary('Enter Payment', array('onclick' => 'onPaymentClick()'))->append_with_icon('usd'); }}
|
{{ Button::primary('Enter Payment', array('onclick' => 'onPaymentClick()'))->append_with_icon('usd'); }}
|
||||||
@ -684,9 +684,6 @@
|
|||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (model.enable.save() != 'enabled') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.main_form').submit();
|
$('.main_form').submit();
|
||||||
return false;
|
return false;
|
||||||
@ -893,40 +890,6 @@
|
|||||||
$('#invoice_number').focus();
|
$('#invoice_number').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.enable = {};
|
|
||||||
self.enable.save = ko.computed(function() {
|
|
||||||
var isValid = false;
|
|
||||||
for (var i=0; i<self.invoice().client().contacts().length; i++) {
|
|
||||||
var contact = self.invoice().client().contacts()[i];
|
|
||||||
if (isValidEmailAddress(contact.email())) {
|
|
||||||
isValid = true;
|
|
||||||
} else {
|
|
||||||
isValid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isValid ? "enabled" : "disabled";
|
|
||||||
});
|
|
||||||
|
|
||||||
self.enable.email = ko.computed(function() {
|
|
||||||
var isValid = false;
|
|
||||||
var sendTo = false;
|
|
||||||
var client = self.invoice().client();
|
|
||||||
for (var i=0; i<client.contacts().length; i++) {
|
|
||||||
var contact = client.contacts()[i];
|
|
||||||
if (isValidEmailAddress(contact.email())) {
|
|
||||||
isValid = true;
|
|
||||||
if (contact.send_invoice() || client.contacts().length == 1) {
|
|
||||||
sendTo = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
isValid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isValid && sendTo ? "enabled" : "disabled";
|
|
||||||
});
|
|
||||||
|
|
||||||
self.clientLinkText = ko.computed(function() {
|
self.clientLinkText = ko.computed(function() {
|
||||||
if (self.invoice().client().public_id())
|
if (self.invoice().client().public_id())
|
||||||
{
|
{
|
||||||
|
@ -46,15 +46,21 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
@if (App::environment() == ENV_PRODUCTION)
|
@if (App::environment() == ENV_PRODUCTION)
|
||||||
<script>
|
<script>
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
ga('create', 'UA-46031341-1');
|
ga('create', 'UA-46031341-1');
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
|
@else
|
||||||
|
<style>
|
||||||
|
.navbar {
|
||||||
|
background-color: #006600 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@yield('body')
|
@yield('body')
|
||||||
|
@ -48,12 +48,12 @@
|
|||||||
<div class="navbar" style="margin-bottom:0px">
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<a class="brand" href="#"><img src=
|
<a class="brand" href="/"><img src=
|
||||||
"images/invoiceninja-logo.png"></a>
|
"images/invoiceninja-logo.png"></a>
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<!--<li>{{ link_to('about_us', 'About Us' ) }}</li>-->
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
<!--<li>{{ link_to('contact_us', 'Contact Us' ) }}</li>-->
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -184,7 +184,9 @@
|
|||||||
|
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<ul class="navbar-list">
|
<ul class="navbar-list">
|
||||||
<li>{{ link_to('login', Auth::check() ? 'Continue' : 'Login' ) }}</li>
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -8,6 +8,381 @@ var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function GetReportTemplate4(invoice,checkMath) {
|
||||||
|
|
||||||
|
var client = invoice.client;
|
||||||
|
var account = invoice.account;
|
||||||
|
var currencyId = client.currency_id;
|
||||||
|
var invoiceNumber = invoice.invoice_number;
|
||||||
|
var invoiceDate = invoice.invoice_date ? invoice.invoice_date : '';
|
||||||
|
var dueDate = invoice.due_date ? invoice.due_date : '';
|
||||||
|
|
||||||
|
var marginLeft = 50;
|
||||||
|
var accountTop = 30;
|
||||||
|
var headerTop = 140;
|
||||||
|
var headerLeft = 360;
|
||||||
|
var headerRight = 550;
|
||||||
|
var rowHeight = 15;
|
||||||
|
var tableRowHeight = 20;
|
||||||
|
var footerLeft = 420;
|
||||||
|
var tablePadding = 6;
|
||||||
|
|
||||||
|
var tableTop = 240;
|
||||||
|
var tableLeft = 50;
|
||||||
|
var descriptionLeft = 162;
|
||||||
|
var unitCostRight = 410;
|
||||||
|
var qtyRight = 480;
|
||||||
|
var taxRight = 480;
|
||||||
|
var lineTotalRight = 550;
|
||||||
|
|
||||||
|
|
||||||
|
var hasTaxes = false;
|
||||||
|
for (var i=0; i<invoice.invoice_items.length; i++)
|
||||||
|
{
|
||||||
|
var item = invoice.invoice_items[i];
|
||||||
|
if ((item.tax && item.tax.rate > 0) || (item.tax_rate && parseFloat(item.tax_rate) > 0)) {
|
||||||
|
hasTaxes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasTaxes)
|
||||||
|
{
|
||||||
|
descriptionLeft -= 20;
|
||||||
|
unitCostRight -= 40;
|
||||||
|
qtyRight -= 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var doc = new jsPDF('p', 'pt');
|
||||||
|
doc.setFont('Helvetica','');
|
||||||
|
doc.setFontSize(10);
|
||||||
|
|
||||||
|
if (invoice.image)
|
||||||
|
{
|
||||||
|
var left = headerRight - invoice.imageWidth;
|
||||||
|
doc.addImage(invoice.image, 'JPEG', left, 30, invoice.imageWidth, invoice.imageHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* table header */
|
||||||
|
doc.setDrawColor(200,200,200);
|
||||||
|
doc.setFillColor(230,230,230);
|
||||||
|
var x1 = headerLeft - tablePadding;
|
||||||
|
var y1 = headerTop + rowHeight + 4;
|
||||||
|
var x2 = headerRight - headerLeft + 11;
|
||||||
|
var y2 = rowHeight + 1;
|
||||||
|
if (invoice.po_number) {
|
||||||
|
y1 += rowHeight;
|
||||||
|
}
|
||||||
|
if (dueDate) {
|
||||||
|
y1 += rowHeight;
|
||||||
|
}
|
||||||
|
doc.rect(x1, y1, x2, y2, 'FD');
|
||||||
|
|
||||||
|
var invoiceNumberX = headerRight - (doc.getStringUnitWidth(invoiceNumber, false) * doc.internal.getFontSize());
|
||||||
|
var invoiceDateX = headerRight - (doc.getStringUnitWidth(invoiceDate) * doc.internal.getFontSize());
|
||||||
|
var dueDateX = headerRight - (doc.getStringUnitWidth(dueDate) * doc.internal.getFontSize());
|
||||||
|
var poNumberX = headerRight - (doc.getStringUnitWidth(invoice.po_number) * doc.internal.getFontSize());
|
||||||
|
|
||||||
|
doc.setFontType("normal");
|
||||||
|
|
||||||
|
var y = accountTop;
|
||||||
|
var left = marginLeft;
|
||||||
|
|
||||||
|
if (account.name) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(left, y, account.name);
|
||||||
|
}
|
||||||
|
if (account.address1) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(left, y, account.address1);
|
||||||
|
}
|
||||||
|
if (account.address2) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(left, y, account.address2);
|
||||||
|
}
|
||||||
|
if (account.city || account.state || account.postal_code) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(left, y, account.city + ', ' + account.state + ' ' + account.postal_code);
|
||||||
|
}
|
||||||
|
if (account.country) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(left, y, account.country.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client) {
|
||||||
|
var y = headerTop;
|
||||||
|
doc.text(marginLeft, y, getClientDisplayName(client));
|
||||||
|
if (client.address1) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(marginLeft, y, client.address1);
|
||||||
|
}
|
||||||
|
if (client.address2) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(marginLeft, y, client.address2);
|
||||||
|
}
|
||||||
|
if (client.city || client.state || client.postal_code) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(marginLeft, y, client.city + ', ' + client.state + ' ' + client.postal_code);
|
||||||
|
}
|
||||||
|
if (client.country) {
|
||||||
|
y += rowHeight;
|
||||||
|
doc.text(marginLeft, y, client.country.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var headerY = headerTop;
|
||||||
|
doc.text(headerLeft, headerY, 'Invoice Number');
|
||||||
|
doc.text(invoiceNumberX, headerY, invoiceNumber);
|
||||||
|
|
||||||
|
if (invoice.po_number) {
|
||||||
|
headerY += rowHeight;
|
||||||
|
doc.text(headerLeft, headerY, 'PO Number');
|
||||||
|
doc.text(poNumberX, headerY, invoice.po_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
headerY += rowHeight;
|
||||||
|
doc.text(headerLeft, headerY, 'Invoice Date');
|
||||||
|
doc.text(invoiceDateX, headerY, invoiceDate);
|
||||||
|
|
||||||
|
if (dueDate) {
|
||||||
|
headerY += rowHeight;
|
||||||
|
doc.text(headerLeft, headerY, 'Due Date');
|
||||||
|
doc.text(dueDateX, headerY, dueDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
headerY += rowHeight;
|
||||||
|
doc.setFontType("bold");
|
||||||
|
doc.text(headerLeft, headerY, 'Balance Due');
|
||||||
|
|
||||||
|
var total = 0;
|
||||||
|
|
||||||
|
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||||
|
var item = invoice.invoice_items[i];
|
||||||
|
var tax = 0;
|
||||||
|
if (item.tax && parseFloat(item.tax.rate)) {
|
||||||
|
tax = parseFloat(item.tax.rate);
|
||||||
|
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||||
|
tax = parseFloat(item.tax_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||||||
|
if (tax) {
|
||||||
|
lineTotal += lineTotal * tax / 100;
|
||||||
|
}
|
||||||
|
if (lineTotal) {
|
||||||
|
total += lineTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invoice.discount > 0) {
|
||||||
|
|
||||||
|
var discount = total * (invoice.discount/100);
|
||||||
|
total -= discount;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tax = 0;
|
||||||
|
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||||||
|
tax = parseFloat(invoice.tax.rate);
|
||||||
|
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||||
|
tax = parseFloat(invoice.tax_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tax) {
|
||||||
|
var tax = total * (tax/100);
|
||||||
|
total = parseFloat(total) + parseFloat(tax);
|
||||||
|
}
|
||||||
|
|
||||||
|
total = formatMoney(total - (invoice.amount - invoice.balance), currencyId);
|
||||||
|
|
||||||
|
var balance = formatMoney(total, currencyId);
|
||||||
|
balanceX = headerRight - (doc.getStringUnitWidth(balance) * doc.internal.getFontSize());
|
||||||
|
doc.text(balanceX, headerY, balance);
|
||||||
|
|
||||||
|
|
||||||
|
doc.setDrawColor(200,200,200);
|
||||||
|
doc.setFillColor(230,230,230);
|
||||||
|
doc.rect(tableLeft - tablePadding, tableTop - 12, headerRight - tableLeft + 12, rowHeight + 2, 'FD');
|
||||||
|
|
||||||
|
var costX = unitCostRight - (doc.getStringUnitWidth('Unit Cost') * doc.internal.getFontSize());
|
||||||
|
var qtyX = qtyRight - (doc.getStringUnitWidth('Quantity') * doc.internal.getFontSize());
|
||||||
|
var taxX = taxRight - (doc.getStringUnitWidth('Tax') * doc.internal.getFontSize());
|
||||||
|
var totalX = lineTotalRight - (doc.getStringUnitWidth('Line Total') * doc.internal.getFontSize());
|
||||||
|
|
||||||
|
doc.text(tableLeft, tableTop, 'Item');
|
||||||
|
doc.text(descriptionLeft, tableTop, 'Description');
|
||||||
|
doc.text(costX, tableTop, 'Unit Cost');
|
||||||
|
doc.text(qtyX, tableTop, 'Quantity');
|
||||||
|
doc.text(totalX, tableTop, 'Line Total');
|
||||||
|
|
||||||
|
if (hasTaxes)
|
||||||
|
{
|
||||||
|
doc.text(taxX, tableTop, 'Tax');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* line items */
|
||||||
|
doc.setFontType("normal");
|
||||||
|
var line = 1;
|
||||||
|
var total = 0;
|
||||||
|
var shownItem = false;
|
||||||
|
|
||||||
|
doc.setFontSize(7);
|
||||||
|
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||||
|
var item = invoice.invoice_items[i];
|
||||||
|
var cost = formatMoney(item.cost, currencyId, true);
|
||||||
|
var qty = NINJA.parseFloat(item.qty) ? NINJA.parseFloat(item.qty) + '' : '';
|
||||||
|
var notes = item.notes;
|
||||||
|
var productKey = item.product_key;
|
||||||
|
var tax = 0;
|
||||||
|
if (item.tax && parseFloat(item.tax.rate)) {
|
||||||
|
tax = parseFloat(item.tax.rate);
|
||||||
|
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||||
|
tax = parseFloat(item.tax_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show at most one blank line
|
||||||
|
if (shownItem && (!cost || cost == '0.00') && !qty && !notes && !productKey) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
shownItem = true;
|
||||||
|
|
||||||
|
// process date variables
|
||||||
|
notes = processVariables(notes);
|
||||||
|
productKey = processVariables(productKey);
|
||||||
|
|
||||||
|
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||||||
|
if (tax) {
|
||||||
|
lineTotal += lineTotal * tax / 100;
|
||||||
|
}
|
||||||
|
if (lineTotal) {
|
||||||
|
total += lineTotal;
|
||||||
|
}
|
||||||
|
lineTotal = formatMoney(lineTotal, currencyId, true);
|
||||||
|
|
||||||
|
var costX = unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize());
|
||||||
|
var qtyX = qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
||||||
|
var taxX = taxRight - (doc.getStringUnitWidth(tax+'%') * doc.internal.getFontSize());
|
||||||
|
var totalX = lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
|
||||||
|
var x = tableTop + (line * tableRowHeight) + 6;
|
||||||
|
if (i==0) x -= 4;
|
||||||
|
|
||||||
|
doc.text(tableLeft, x, productKey);
|
||||||
|
doc.text(descriptionLeft, x, notes);
|
||||||
|
doc.text(costX, x, cost);
|
||||||
|
doc.text(qtyX, x, qty);
|
||||||
|
doc.text(totalX, x, lineTotal);
|
||||||
|
|
||||||
|
if (tax) {
|
||||||
|
doc.text(taxX, x, tax+'%');
|
||||||
|
}
|
||||||
|
|
||||||
|
line += (doc.splitTextToSize(item.notes, 200).length * .6) + .4;
|
||||||
|
|
||||||
|
if (i < invoice.invoice_items.length - 2) {
|
||||||
|
doc.setLineWidth(0.5);
|
||||||
|
doc.setDrawColor(220,220,220);
|
||||||
|
doc.line(tableLeft - tablePadding, tableTop + (line * tableRowHeight) - 8,
|
||||||
|
lineTotalRight+tablePadding, tableTop + (line * tableRowHeight) - 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line > 20) {
|
||||||
|
line = 0;
|
||||||
|
tableTop = 60;
|
||||||
|
doc.addPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doc.setFontSize(10);
|
||||||
|
|
||||||
|
/* table footer */
|
||||||
|
doc.setDrawColor(200,200,200);
|
||||||
|
var x = tableTop + (line * tableRowHeight) - 6;
|
||||||
|
|
||||||
|
doc.setLineWidth(1);
|
||||||
|
doc.line(tableLeft - tablePadding, x, lineTotalRight+tablePadding, x);
|
||||||
|
//console.log('%s %s %s', lineTotalRight, tableLeft, (lineTotalRight-tableLeft));
|
||||||
|
|
||||||
|
doc.text(tableLeft, x+16, invoice.public_notes);
|
||||||
|
if (invoice.terms) {
|
||||||
|
var termsX = x+16 + (doc.splitTextToSize(invoice.public_notes, 340).length * rowHeight) + (rowHeight/2);
|
||||||
|
doc.setFontType("bold");
|
||||||
|
doc.text(tableLeft, termsX, "Terms");
|
||||||
|
doc.setFontType("normal");
|
||||||
|
doc.text(tableLeft, termsX + rowHeight, invoice.terms);
|
||||||
|
}
|
||||||
|
|
||||||
|
x += 16;
|
||||||
|
doc.text(footerLeft, x, 'Subtotal');
|
||||||
|
var prettyTotal = formatMoney(total, currencyId, true);
|
||||||
|
var totalX = headerRight - (doc.getStringUnitWidth(prettyTotal) * doc.internal.getFontSize());
|
||||||
|
doc.text(totalX, x, prettyTotal);
|
||||||
|
|
||||||
|
if (invoice.discount > 0) {
|
||||||
|
|
||||||
|
x += 16;
|
||||||
|
doc.text(footerLeft, x, 'Discount');
|
||||||
|
var discount = total * (invoice.discount/100);
|
||||||
|
total -= discount;
|
||||||
|
discount = formatMoney(discount, currencyId, true);
|
||||||
|
var discountX = headerRight - (doc.getStringUnitWidth(discount) * doc.internal.getFontSize());
|
||||||
|
doc.text(discountX, x, discount);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tax = 0;
|
||||||
|
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||||||
|
tax = parseFloat(invoice.tax.rate);
|
||||||
|
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||||
|
tax = parseFloat(invoice.tax_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tax) {
|
||||||
|
x += 16;
|
||||||
|
doc.text(footerLeft, x, 'Tax ' + tax + '%');
|
||||||
|
var tax = total * (tax/100);
|
||||||
|
total = parseFloat(total) + parseFloat(tax);
|
||||||
|
tax = formatMoney(tax, currencyId, true);
|
||||||
|
var taxX = headerRight - (doc.getStringUnitWidth(tax) * doc.internal.getFontSize());
|
||||||
|
doc.text(taxX, x, tax);
|
||||||
|
}
|
||||||
|
|
||||||
|
x += 16;
|
||||||
|
doc.text(footerLeft, x, 'Paid to Date');
|
||||||
|
var paid = formatMoney(invoice.amount - invoice.balance, currencyId, true);
|
||||||
|
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
||||||
|
doc.text(paidX, x, paid);
|
||||||
|
|
||||||
|
x += 16;
|
||||||
|
|
||||||
|
if (checkMath && NINJA.parseFloat(total).toFixed(4) != NINJA.parseFloat(invoice.amount).toFixed(4))
|
||||||
|
{
|
||||||
|
var doc = new jsPDF('p', 'pt');
|
||||||
|
doc.setFont('Helvetica','');
|
||||||
|
doc.setFontSize(10);
|
||||||
|
doc.text(100, 100, "An error occurred, please try again later.");
|
||||||
|
onerror('Failed to generate PDF ' + total + ', ' + invoice.amount );
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
doc.setDrawColor(200,200,200);
|
||||||
|
doc.setFillColor(230,230,230);
|
||||||
|
var x1 = footerLeft - tablePadding;
|
||||||
|
var y1 = x - 11;
|
||||||
|
var x2 = headerRight - footerLeft + 11;
|
||||||
|
var y2 = 16;
|
||||||
|
doc.rect(x1, y1, x2, y2, 'FD');
|
||||||
|
|
||||||
|
doc.setFontType("bold");
|
||||||
|
doc.text(footerLeft, x, 'Balance Due');
|
||||||
|
|
||||||
|
total = formatMoney(total - (invoice.amount - invoice.balance), currencyId);
|
||||||
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
|
doc.text(totalX, x, total);
|
||||||
|
|
||||||
|
|
||||||
|
doc.setFontType("normal");
|
||||||
|
doc.text(marginLeft, 790, "Created by InvoiceNinja.com");
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function generatePDF(invoice, checkMath) {
|
function generatePDF(invoice, checkMath) {
|
||||||
@ -386,7 +761,7 @@ ko.bindingHandlers.datePicker = {
|
|||||||
|
|
||||||
function wordWrapText(value, width)
|
function wordWrapText(value, width)
|
||||||
{
|
{
|
||||||
if (!width) width = 200;
|
if (!width) width = 280;
|
||||||
var doc = new jsPDF('p', 'pt');
|
var doc = new jsPDF('p', 'pt');
|
||||||
doc.setFont('Helvetica','');
|
doc.setFont('Helvetica','');
|
||||||
doc.setFontSize(10);
|
doc.setFontSize(10);
|
||||||
@ -416,6 +791,7 @@ function wordWrapText(value, width)
|
|||||||
|
|
||||||
function getClientDisplayName(client)
|
function getClientDisplayName(client)
|
||||||
{
|
{
|
||||||
|
console.log(client);
|
||||||
var contact = client.contacts[0];
|
var contact = client.contacts[0];
|
||||||
if (client.name) {
|
if (client.name) {
|
||||||
return client.name;
|
return client.name;
|
||||||
@ -538,7 +914,7 @@ function GetPdf(invoice,checkMath,report_id){
|
|||||||
if (report_id==1) return GetReportTemplate1(invoice,checkMath);
|
if (report_id==1) return GetReportTemplate1(invoice,checkMath);
|
||||||
if (report_id==2) return GetReportTemplate2(invoice,checkMath);
|
if (report_id==2) return GetReportTemplate2(invoice,checkMath);
|
||||||
if (report_id==3) return GetReportTemplate3(invoice,checkMath);
|
if (report_id==3) return GetReportTemplate3(invoice,checkMath);
|
||||||
|
if (report_id==4) return GetReportTemplate4(invoice,checkMath);
|
||||||
|
|
||||||
alert('report template not implemented yet');
|
alert('report template not implemented yet');
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user