1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 16:31:33 +02:00

Merge pull request #7 from hillelcoren/master

Update from Master
This commit is contained in:
Paul-Vincent Roll 2015-05-10 21:58:04 +02:00
commit 1865880d5d
163 changed files with 5948 additions and 4357 deletions

3
.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "./public/vendor"
}

View File

@ -2,18 +2,18 @@ APP_ENV=development
APP_DEBUG=true
APP_URL=http://ninja.dev
APP_CIPHER=rijndael-128
APP_KEY=
APP_KEY
DB_TYPE=mysql
DB_HOST=localhost
DB_DATABASE=ninja
DB_USERNAME=
DB_PASSWORD=
DB_USERNAME
DB_PASSWORD
MAIL_DRIVER=smtp
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_HOST=
MAIL_USERNAME=
MAIL_FROM_NAME=
MAIL_PASSWORD=
MAIL_HOST
MAIL_USERNAME
MAIL_FROM_NAME
MAIL_PASSWORD

4
.gitignore vendored
View File

@ -8,6 +8,7 @@
/public/build
/public/packages
/public/vendor
/storage
/bootstrap/compiled.php
/bootstrap/environment.php
/vendor
@ -24,3 +25,6 @@ public/error_log
/ninja.sublime-project
/ninja.sublime-workspace
auth.json
.phpstorm.meta.php
_ide_helper.php

View File

@ -57,9 +57,14 @@ module.exports = function(grunt) {
'public/vendor/spectrum/spectrum.js',
'public/vendor/jspdf/dist/jspdf.min.js',
//'public/vendor/handsontable/dist/jquery.handsontable.full.min.js',
//'public/vendor/pdfmake/build/pdfmake.min.js',
//'public/vendor/pdfmake/build/vfs_fonts.js',
//'public/js/vfs_fonts.js',
'public/js/lightbox.min.js',
'public/js/bootstrap-combobox.js',
'public/js/script.js',
'public/js/pdf.pdfmake.js',
],
dest: 'public/js/built.js',
nonull: true
@ -73,6 +78,7 @@ module.exports = function(grunt) {
'public/js/simpleexpand.js',
*/
'public/vendor/bootstrap/dist/js/bootstrap.min.js',
'public/js/bootstrap-combobox.js',
],
dest: 'public/js/built.public.js',
@ -84,7 +90,7 @@ module.exports = function(grunt) {
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
'public/vendor/font-awesome/css/font-awesome.min.css',
'public/vendor/bootstrap-datepicker/css/datepicker.css',
'public/vendor/bootstrap-datepicker/css/datepicker3.css',
'public/vendor/spectrum/spectrum.css',
'public/css/bootstrap-combobox.css',
'public/css/typeahead.js-bootstrap.css',
@ -105,6 +111,7 @@ module.exports = function(grunt) {
'public/css/bootstrap.splash.css',
'public/css/splash.css',
*/
'public/css/bootstrap-combobox.css',
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
],

40
LICENSE Normal file
View File

@ -0,0 +1,40 @@
Attribution Assurance License
Copyright (c) 2014 by Hillel Coren
http://www.hillelcoren.com
All Rights Reserved
ATTRIBUTION ASSURANCE LICENSE (adapted from the original BSD license)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the conditions below are met.
These conditions require a modest attribution to InvoiceNinja.com. The hope
is that its promotional value may help justify the thousands of dollars in
otherwise billable time invested in writing this and other freely available,
open-source software.
1. Redistributions of source code, in whole or part and with or without
modification requires the express permission of the author and must prominently
display "Powered by InvoiceNinja" or the Invoice Ninja logo in verifiable form
with hyperlink to said site.
2. Neither the name nor any trademark of the Author may be used to
endorse or promote products derived from this software without specific
prior written permission.
3. Users are entirely responsible, to the exclusion of the Author and
any other persons, for compliance with (1) regulations set by owners or
administrators of employed equipment, (2) licensing terms of any other
software, and (3) local regulations regarding use, including those
regarding import, export, and use of encryption software.
THIS FREE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR OR ANY CONTRIBUTOR BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
EFFECTS OF UNAUTHORIZED OR MALICIOUS NETWORK ACCESS;
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,5 +1,8 @@
<?php namespace App\Console\Commands;
use DB;
use DateTime;
use Carbon;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
@ -10,7 +13,7 @@ use Symfony\Component\Console\Input\InputArgument;
WARNING: Please backup your database before running this script
##################################################################
Since the application was released a number of bugs have (inevitably) been found.
Since the application was released a number of bugs have inevitably been found.
Although the bugs have always been fixed in some cases they've caused the client's
balance, paid to date and/or activity records to become inaccurate. This script will
check for errors and correct the data.
@ -100,13 +103,15 @@ class CheckData extends Command {
$clients = $clients->groupBy('clients.id', 'clients.balance', 'clients.created_at')
->orderBy('clients.id', 'DESC')
->get(['clients.id', 'clients.balance', 'clients.paid_to_date']);
->get(['clients.account_id', 'clients.id', 'clients.balance', 'clients.paid_to_date', DB::raw('sum(invoices.balance) actual_balance')]);
$this->info(count($clients) . ' clients with incorrect balance/activities');
foreach ($clients as $client) {
$this->info("=== Client:{$client->id} Balance:{$client->balance} ===");
$this->info("=== Client:{$client->id} Balance:{$client->balance} Actual Balance:{$client->actual_balance} ===");
$foundProblem = false;
$lastBalance = 0;
$lastAdjustment = 0;
$lastCreatedAt = null;
$clientFix = false;
$activities = DB::table('activities')
->where('client_id', '=', $client->id)
@ -195,6 +200,11 @@ class CheckData extends Command {
$foundProblem = true;
$clientFix -= $activity->adjustment;
$activityFix = 0;
} else if ((strtotime($activity->created_at) - strtotime($lastCreatedAt) <= 1) && $activity->adjustment > 0 && $activity->adjustment == $lastAdjustment) {
$this->info("Duplicate adjustment for updated invoice adjustment:{$activity->adjustment}");
$foundProblem = true;
$clientFix -= $activity->adjustment;
$activityFix = 0;
}
} elseif ($activity->activity_type_id == ACTIVITY_TYPE_UPDATE_QUOTE) {
// **Fix for updating balance when updating a quote**
@ -231,18 +241,32 @@ class CheckData extends Command {
}
$lastBalance = $activity->balance;
$lastAdjustment = $activity->adjustment;
$lastCreatedAt = $activity->created_at;
}
if ($clientFix !== false) {
$balance = $activity->balance + $clientFix;
$data = ['balance' => $balance];
$this->info("Corrected balance:{$balance}");
if ($activity->balance + $clientFix != $client->actual_balance) {
$this->info("** Creating 'recovered update' activity **");
if ($this->option('fix') == 'true') {
DB::table('clients')
->where('id', $client->id)
->update($data);
DB::table('activities')->insert([
'created_at' => new Carbon,
'updated_at' => new Carbon,
'account_id' => $client->account_id,
'client_id' => $client->id,
'message' => 'Recovered update to invoice [<a href="https://github.com/hillelcoren/invoice-ninja/releases/tag/v1.7.1" target="_blank">details</a>]',
'adjustment' => $client->actual_balance - $activity->balance,
'balance' => $client->actual_balance,
]);
}
}
$data = ['balance' => $client->actual_balance];
$this->info("Corrected balance:{$client->actual_balance}");
if ($this->option('fix') == 'true') {
DB::table('clients')
->where('id', $client->id)
->update($data);
}
}
$this->info('Done');

View File

@ -69,8 +69,12 @@ class SendRecurringInvoices extends Command
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
$invoice->is_amount_discount = $recurInvoice->is_amount_discount;
if ($invoice->client->payment_terms) {
$invoice->due_date = date_create()->modify($invoice->client->payment_terms.' day')->format('Y-m-d');
if ($invoice->client->payment_terms != 0) {
$days = $invoice->client->payment_terms;
if ($days == -1) {
$days = 0;
}
$invoice->due_date = date_create()->modify($days.' day')->format('Y-m-d');
}
$invoice->save();

View File

@ -0,0 +1,57 @@
<?php namespace App\Console\Commands;
use DB;
use DateTime;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use App\Models\Account;
use App\Ninja\Mailers\ContactMailer as Mailer;
use App\Ninja\Repositories\AccountRepository;
class SendRenewalInvoices extends Command
{
protected $name = 'ninja:send-renewals';
protected $description = 'Send renewal invoices';
protected $mailer;
protected $accountRepo;
public function __construct(Mailer $mailer, AccountRepository $repo)
{
parent::__construct();
$this->mailer = $mailer;
$this->accountRepo = $repo;
}
public function fire()
{
$this->info(date('Y-m-d').' Running SendRenewalInvoices...');
$today = new DateTime();
$accounts = Account::whereRaw('datediff(curdate(), pro_plan_paid) = 355')->get();
$this->info(count($accounts).' accounts found');
dd(0);
foreach ($accounts as $account) {
$client = $this->accountRepo->getNinjaClient($account);
$invitation = $this->accountRepo->createNinjaInvoice($client);
$this->mailer->sendInvoice($invitation->invoice);
}
$this->info('Done');
}
protected function getArguments()
{
return array(
//array('example', InputArgument::REQUIRED, 'An example argument.'),
);
}
protected function getOptions()
{
return array(
//array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null),
);
}
}

View File

@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel {
'App\Console\Commands\ResetData',
'App\Console\Commands\ImportTimesheetData',
'App\Console\Commands\CheckData',
'App\Console\Commands\SendRenewalInvoices',
];
/**

View File

@ -27,6 +27,7 @@ class Handler extends ExceptionHandler {
{
Utils::logError(Utils::getErrorString($e));
return false;
//return parent::report($e);
}
@ -39,6 +40,15 @@ class Handler extends ExceptionHandler {
*/
public function render($request, Exception $e)
{
return parent::render($request, $e);
if (Utils::isNinjaProd()) {
$data = [
'error' => get_class($e),
'hideHeader' => true,
];
return response()->view('error', $data);
} else {
return parent::render($request, $e);
}
}
}

View File

@ -12,9 +12,20 @@ use Validator;
use View;
use stdClass;
use Cache;
use Response;
use parseCSV;
use Request;
use App\Models\Affiliate;
use App\Models\License;
use App\Models\User;
use App\Models\Client;
use App\Models\Contact;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Activity;
use App\Models\Payment;
use App\Models\Credit;
use App\Models\Account;
use App\Models\Country;
use App\Models\Currency;
@ -90,7 +101,7 @@ class AccountController extends BaseController
Auth::login($user, true);
Event::fire(new UserLoggedIn());
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
}
@ -153,7 +164,7 @@ class AccountController extends BaseController
if ($count == 0) {
return Redirect::to('gateways/create');
} else {
return View::make('accounts.payments', ['showAdd' => $count < 2]);
return View::make('accounts.payments', ['showAdd' => $count < 3]);
}
} elseif ($section == ACCOUNT_NOTIFICATIONS) {
$data = [
@ -197,7 +208,7 @@ class AccountController extends BaseController
$invoice->invoice_items = [$invoiceItem];
$data['invoice'] = $invoice;
$data['invoiceDesigns'] = InvoiceDesign::where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
$data['invoiceDesigns'] = InvoiceDesign::availableDesigns();
} else if ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
$data['invoiceEmail'] = $account->getEmailTemplate(ENTITY_INVOICE);
$data['quoteEmail'] = $account->getEmailTemplate(ENTITY_QUOTE);
@ -291,6 +302,8 @@ class AccountController extends BaseController
$account->share_counter = Input::get('share_counter') ? true : false;
$account->pdf_email_attachment = Input::get('pdf_email_attachment') ? true : false;
$account->utf8_invoices = Input::get('utf8_invoices') ? true : false;
$account->auto_wrap = Input::get('auto_wrap') ? true : false;
if (!$account->share_counter) {
$account->quote_number_counter = Input::get('quote_number_counter');
@ -333,40 +346,27 @@ class AccountController extends BaseController
header('Content-Disposition:attachment;filename=export.csv');
$clients = Client::scope()->get();
AccountController::exportData($output, $clients->toArray());
Utils::exportData($output, $clients->toArray());
$contacts = Contact::scope()->get();
AccountController::exportData($output, $contacts->toArray());
Utils::exportData($output, $contacts->toArray());
$invoices = Invoice::scope()->get();
AccountController::exportData($output, $invoices->toArray());
Utils::exportData($output, $invoices->toArray());
$invoiceItems = InvoiceItem::scope()->get();
AccountController::exportData($output, $invoiceItems->toArray());
Utils::exportData($output, $invoiceItems->toArray());
$payments = Payment::scope()->get();
AccountController::exportData($output, $payments->toArray());
Utils::exportData($output, $payments->toArray());
$credits = Credit::scope()->get();
AccountController::exportData($output, $credits->toArray());
Utils::exportData($output, $credits->toArray());
fclose($output);
exit;
}
private function exportData($output, $data)
{
if (count($data) > 0) {
fputcsv($output, array_keys($data[0]));
}
foreach ($data as $record) {
fputcsv($output, $record);
}
fwrite($output, "\n");
}
private function importFile()
{
$data = Session::get('data');
@ -574,6 +574,14 @@ class AccountController extends BaseController
$rules['email'] = 'email|required|unique:users,email,'.$user->id.',id';
}
$subdomain = preg_replace('/[^a-zA-Z0-9_\-]/', '', substr(strtolower(Input::get('subdomain')), 0, MAX_SUBDOMAIN_LENGTH));
if (!$subdomain || in_array($subdomain, ['www', 'app', 'mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner'])) {
$subdomain = null;
}
if ($subdomain) {
$rules['subdomain'] = "unique:accounts,subdomain,{$user->account_id},id";
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
@ -583,6 +591,7 @@ class AccountController extends BaseController
} else {
$account = Auth::user()->account;
$account->name = trim(Input::get('name'));
$account->subdomain = $subdomain;
$account->id_number = trim(Input::get('id_number'));
$account->vat_number = trim(Input::get('vat_number'));
$account->work_email = trim(Input::get('work_email'));

View File

@ -25,10 +25,11 @@ class AccountGatewayController extends BaseController
->join('gateways', 'gateways.id', '=', 'account_gateways.gateway_id')
->where('account_gateways.deleted_at', '=', null)
->where('account_gateways.account_id', '=', Auth::user()->account_id)
->select('account_gateways.public_id', 'gateways.name', 'account_gateways.deleted_at');
->select('account_gateways.public_id', 'gateways.name', 'account_gateways.deleted_at', 'account_gateways.gateway_id');
return Datatable::query($query)
->addColumn('name', function ($model) { return link_to('gateways/'.$model->public_id.'/edit', $model->name); })
->addColumn('payment_type', function ($model) { return Gateway::getPrettyPaymentType($model->gateway_id); })
->addColumn('dropdown', function ($model) {
$actions = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
@ -68,6 +69,9 @@ class AccountGatewayController extends BaseController
$data['method'] = 'PUT';
$data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name;
$data['config'] = $configFields;
$data['paymentTypeId'] = $accountGateway->getPaymentType();
$data['selectGateways'] = Gateway::where('id', '=', $accountGateway->gateway_id)->get();
return View::make('accounts.account_gateway', $data);
}
@ -92,6 +96,7 @@ class AccountGatewayController extends BaseController
$data['url'] = 'gateways';
$data['method'] = 'POST';
$data['title'] = trans('texts.add_gateway');
$data['selectGateways'] = Gateway::where('payment_library_id', '=', 1)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->orderBy('name')->get();
return View::make('accounts.account_gateway', $data);
}
@ -101,6 +106,17 @@ class AccountGatewayController extends BaseController
$selectedCards = $accountGateway ? $accountGateway->accepted_credit_cards : 0;
$account = Auth::user()->account;
$paymentTypes = [];
foreach ([PAYMENT_TYPE_CREDIT_CARD, PAYMENT_TYPE_PAYPAL, PAYMENT_TYPE_BITCOIN] as $type) {
if ($accountGateway || !$account->getGatewayByType($type)) {
$paymentTypes[$type] = trans('texts.'.strtolower($type));
if ($type == PAYMENT_TYPE_BITCOIN) {
$paymentTypes[$type] .= ' - BitPay';
}
}
}
$creditCardsArray = unserialize(CREDIT_CARDS);
$creditCards = [];
foreach ($creditCardsArray as $card => $name) {
@ -113,25 +129,10 @@ class AccountGatewayController extends BaseController
$account->load('account_gateways');
$currentGateways = $account->account_gateways;
$gateways = Gateway::where('payment_library_id', '=', 1)->orderBy('name');
$onlyPayPal = false;
if (!$accountGateway) {
if (count($currentGateways) > 0) {
$currentGateway = $currentGateways[0];
if ($currentGateway->isPayPal()) {
$gateways->where('id', '!=', GATEWAY_PAYPAL_EXPRESS);
} else {
$gateways->where('id', '=', GATEWAY_PAYPAL_EXPRESS);
$onlyPayPal = true;
}
}
}
$gateways = $gateways->get();
$gateways = Gateway::where('payment_library_id', '=', 1)->orderBy('name')->get();
foreach ($gateways as $gateway) {
$paymentLibrary = $gateway->paymentlibrary;
$gateway->fields = $gateway->getFields();
if ($accountGateway && $accountGateway->gateway_id == $gateway->id) {
$accountGateway->fields = $gateway->fields;
}
@ -143,6 +144,7 @@ class AccountGatewayController extends BaseController
}
return [
'paymentTypes' => $paymentTypes,
'account' => $account,
'accountGateway' => $accountGateway,
'config' => false,
@ -150,7 +152,6 @@ class AccountGatewayController extends BaseController
'creditCardTypes' => $creditCards,
'tokenBillingOptions' => $tokenBillingOptions,
'showBreadcrumbs' => false,
'onlyPayPal' => $onlyPayPal,
'countGateways' => count($currentGateways)
];
}
@ -174,8 +175,15 @@ class AccountGatewayController extends BaseController
public function save($accountGatewayPublicId = false)
{
$rules = array();
$paymentType = Input::get('payment_type_id');
$gatewayId = Input::get('gateway_id');
if ($paymentType == PAYMENT_TYPE_PAYPAL) {
$gatewayId = GATEWAY_PAYPAL_EXPRESS;
} elseif ($paymentType == PAYMENT_TYPE_BITCOIN) {
$gatewayId = GATEWAY_BITPAY;
}
if (!$gatewayId) {
Session::flash('error', trans('validation.required', ['attribute' => 'gateway']));
return Redirect::to('gateways/create')
@ -183,7 +191,6 @@ class AccountGatewayController extends BaseController
}
$gateway = Gateway::findOrFail($gatewayId);
$paymentLibrary = $gateway->paymentlibrary;
$fields = $gateway->getFields();
foreach ($fields as $field => $details) {
@ -207,25 +214,28 @@ class AccountGatewayController extends BaseController
->withInput();
} else {
$account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id);
$oldConfig = null;
if ($accountGatewayPublicId) {
$accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail();
$oldConfig = json_decode($accountGateway->config);
} else {
$accountGateway = AccountGateway::createNew();
$accountGateway->gateway_id = $gatewayId;
}
$isMasked = false;
$config = new stdClass();
foreach ($fields as $field => $details) {
$value = trim(Input::get($gateway->id.'_'.$field));
// if the new value is masked use the original value
if ($value && $value === str_repeat('*', strlen($value))) {
$isMasked = true;
$value = $oldConfig->$field;
}
if (!$value && ($field == 'testMode' || $field == 'developerMode')) {
// do nothing
} else {
$config->$field = $value;
}
$config->$field = $value;
}
$cardCount = 0;
@ -235,19 +245,12 @@ class AccountGatewayController extends BaseController
}
}
// if the values haven't changed don't update the config
if ($isMasked && $accountGatewayPublicId) {
$accountGateway->accepted_credit_cards = $cardCount;
$accountGateway->accepted_credit_cards = $cardCount;
$accountGateway->config = json_encode($config);
if ($accountGatewayPublicId) {
$accountGateway->save();
// if there's an existing config for this gateway update it
} elseif (!$isMasked && $accountGatewayPublicId && $accountGateway->gateway_id == $gatewayId) {
$accountGateway->accepted_credit_cards = $cardCount;
$accountGateway->config = json_encode($config);
$accountGateway->save();
// otherwise, create a new gateway config
} else {
$accountGateway->config = json_encode($config);
$accountGateway->accepted_credit_cards = $cardCount;
$account->account_gateways()->save($accountGateway);
}

View File

@ -4,6 +4,7 @@ use Auth;
use DB;
use Datatable;
use Utils;
use View;
class ActivityController extends BaseController
{
@ -19,7 +20,14 @@ class ActivityController extends BaseController
->addColumn('id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
->addColumn('message', function ($model) { return Utils::decodeActivity($model->message); })
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::formatMoney($model->adjustment, $model->currency_id) : ''; })
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? self::wrapAdjustment($model->adjustment, $model->currency_id) : ''; })
->make();
}
private function wrapAdjustment($adjustment, $currencyId)
{
$class = $adjustment <= 0 ? 'success' : 'default';
$adjustment = Utils::formatMoney($adjustment, $currencyId);
return "<h4><div class=\"label label-{$class}\">$adjustment</div></h4>";
}
}

View File

@ -9,6 +9,9 @@ use Exception;
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;
@ -33,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()
@ -95,6 +106,7 @@ class AppController extends BaseController
// Artisan::call('migrate:rollback', array('--force' => true)); // Debug Purposes
Artisan::call('migrate', array('--force' => true));
Artisan::call('db:seed', array('--force' => true));
Artisan::call('optimize', array('--force' => true));
$firstName = trim(Input::get('first_name'));
$lastName = trim(Input::get('last_name'));
@ -159,6 +171,7 @@ class AppController extends BaseController
try {
Artisan::call('migrate', array('--force' => true));
Artisan::call('db:seed', array('--force' => true));
Artisan::call('optimize', array('--force' => true));
} catch (Exception $e) {
Response::make($e->getMessage(), 500);
}
@ -172,7 +185,10 @@ class AppController extends BaseController
if (!Utils::isNinja()) {
try {
Artisan::call('migrate', array('--force' => true));
Artisan::call('db:seed', array('--force' => true, '--class' => 'PaymentLibrariesSeeder'));
Artisan::call('optimize', array('--force' => true));
Cache::flush();
Session::flash('message', trans('texts.processed_updates'));
} catch (Exception $e) {
Response::make($e->getMessage(), 500);
}

View File

@ -2,8 +2,9 @@
use Auth;
use Event;
use Utils;
use Illuminate\Http\Request;
use App\Models\User;
use App\Events\UserLoggedIn;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
@ -43,6 +44,15 @@ class AuthController extends Controller {
$this->middleware('guest', ['except' => 'getLogout']);
}
public function getLoginWrapper()
{
if (!Utils::isNinja() && !User::count()) {
return redirect()->to('invoice_now');
}
return self::getLogin();
}
public function postLoginWrapper(Request $request)
{
$response = self::postLogin($request);

View File

@ -44,6 +44,7 @@ class ClientController extends BaseController
return View::make('list', array(
'entityType' => ENTITY_CLIENT,
'title' => trans('texts.clients'),
'sortCol' => '4',
'columns' => Utils::trans(['checkbox', 'client', 'contact', 'email', 'date_created', 'last_login', 'balance', 'action']),
));
}
@ -204,7 +205,8 @@ class ClientController extends BaseController
private function save($publicId = null)
{
$rules = array(
'email' => 'required',
'email' => 'email|required_without:first_name',
'first_name' => 'required_without:email',
);
$validator = Validator::make(Input::all(), $rules);

View File

@ -32,6 +32,7 @@ class CreditController extends BaseController
return View::make('list', array(
'entityType' => ENTITY_CREDIT,
'title' => trans('texts.credits'),
'sortCol' => '4',
'columns' => Utils::trans(['checkbox', 'client', 'credit_amount', 'credit_balance', 'credit_date', 'private_notes', 'action']),
));
}

View File

@ -51,7 +51,8 @@ class DashboardController extends BaseController
$activities = Activity::where('activities.account_id', '=', Auth::user()->account_id)
->orderBy('created_at', 'desc')->take(6)->get();
->where('activity_type_id', '>', 0)
->orderBy('created_at', 'desc')->take(14)->get();
$pastDue = Invoice::scope()
->where('due_date', '<', date('Y-m-d'))
@ -72,7 +73,7 @@ class DashboardController extends BaseController
$data = [
'paidToDate' => $paidToDate,
'averageInvoice' => $averageInvoice,
'billedClients' => $metrics ? $metrics->billed_clients : 0,
//'billedClients' => $metrics ? $metrics->billed_clients : 0,
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
'activeClients' => $metrics ? $metrics->active_clients : 0,
'activities' => $activities,

View File

@ -22,10 +22,14 @@ class HomeController extends BaseController
public function showIndex()
{
Session::reflash();
if (!Utils::isDatabaseSetup()) {
return Redirect::to('/setup');
} elseif (Account::count() == 0) {
return Redirect::to('/invoice_now');
} elseif (Auth::check()) {
return Redirect::to('/dashboard');
} else {
return Redirect::to('/login');
}

View File

@ -1,6 +1,10 @@
<?php namespace App\Http\Controllers;
use Utils;
use Response;
use Auth;
use Input;
use App\Models\Subscription;
class IntegrationController extends Controller
{

View File

@ -6,8 +6,10 @@ use Response;
use Input;
use App\Models\Invoice;
use App\Models\Client;
use App\Models\Contact;
use App\Models\Product;
use App\Models\Invitation;
use App\Ninja\Repositories\ClientRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Mailers\ContactMailer as Mailer;
@ -15,9 +17,10 @@ class InvoiceApiController extends Controller
{
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo, Mailer $mailer)
public function __construct(InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, Mailer $mailer)
{
$this->invoiceRepo = $invoiceRepo;
$this->clientRepo = $clientRepo;
$this->mailer = $mailer;
}
@ -56,21 +59,46 @@ class InvoiceApiController extends Controller
}
}
// check the client id is set and exists
if (!isset($data['client_id'])) {
$error = trans('validation.required', ['attribute' => 'client_id']);
} else {
if (isset($data['email'])) {
$contact = Contact::scope()->with('client')->whereEmail($data['email'])->first();
if ($contact) {
$client = $contact->client;
} else {
$clientData = ['contact' => ['email' => $data['email']]];
foreach (['name', 'private_notes'] as $field) {
if (isset($data[$field])) {
$clientData[$field] = $data[$field];
}
}
foreach (['first_name', 'last_name'] as $field) {
if (isset($data[$field])) {
$clientData[$field] = $data[$field];
}
}
$error = $this->clientRepo->getErrors($clientData);
if (!$error) {
$client = $this->clientRepo->save(false, $clientData, false);
}
}
} else if (isset($data['client_id'])) {
$client = Client::scope($data['client_id'])->first();
if (!$client) {
}
if (!$error) {
if (!isset($data['client_id']) && !isset($data['email'])) {
$error = trans('validation.', ['attribute' => 'client_id or email']);
} else if (!$client) {
$error = trans('validation.not_in', ['attribute' => 'client_id']);
}
}
if ($error) {
$response = json_encode($error, JSON_PRETTY_PRINT);
} else {
$data = self::prepareData($data);
$data['client_id'] = $client->id;
$invoice = $this->invoiceRepo->save(false, $data, false);
$invoice->load('invoice_items');
$invitation = Invitation::createNew();
$invitation->invoice_id = $invoice->id;
@ -78,8 +106,11 @@ class InvoiceApiController extends Controller
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
$invitation->save();
if (isset($data['email_invoice']) && $data['email_invoice']) {
$this->mailer->sendInvoice($invoice);
}
// prepare the return data
$invoice->load('invoice_items');
$invoice = $invoice->toArray();
$invoice['link'] = $invitation->getLink();
unset($invoice['account']);
@ -114,6 +145,7 @@ class InvoiceApiController extends Controller
'custom_value2' => 0,
'custom_taxes1' => false,
'custom_taxes2' => false,
'partial' => 0
];
if (!isset($data['invoice_date'])) {

View File

@ -10,7 +10,9 @@ use Redirect;
use DB;
use Event;
use URL;
use Datatable;
use finfo;
use Request;
use App\Models\Invoice;
use App\Models\Invitation;
use App\Models\Client;
@ -25,7 +27,6 @@ use App\Models\PaymentTerm;
use App\Models\InvoiceDesign;
use App\Models\AccountGateway;
use App\Models\Activity;
use App\Ninja\Mailers\ContactMailer as Mailer;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\ClientRepository;
@ -176,11 +177,21 @@ class InvoiceController extends BaseController
$invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country');
$client = $invoice->client;
$account = $client->account;
if (!$client || $client->is_deleted) {
return View::make('invoices.deleted');
}
if ($account->subdomain) {
$server = explode('.', Request::server('HTTP_HOST'));
$subdomain = $server[0];
if (!in_array($subdomain, ['app', 'www']) && $subdomain != $account->subdomain) {
return View::make('invoices.deleted');
}
}
if (!Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
Activity::viewInvoice($invitation);
Event::fire(new InvoiceViewed($invoice));
@ -188,13 +199,13 @@ class InvoiceController extends BaseController
Session::set($invitationKey, true);
Session::set('invitation_key', $invitationKey);
Session::set('white_label', $client->account->isWhiteLabel());
Session::set('white_label', $account->isWhiteLabel());
$client->account->loadLocalizationSettings();
$account->loadLocalizationSettings();
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = $client->account->isPro();
$invoice->is_pro = $account->isPro();
$contact = $invitation->contact;
$contact->setVisible([
@ -203,16 +214,30 @@ class InvoiceController extends BaseController
'email',
'phone', ]);
// Determine payment options
$paymentTypes = [];
if ($client->getGatewayToken()) {
$paymentTypes[] = [
'url' => URL::to("payment/{$invitation->invitation_key}/".PAYMENT_TYPE_TOKEN), 'label' => trans('texts.use_card_on_file')
];
}
foreach([PAYMENT_TYPE_CREDIT_CARD, PAYMENT_TYPE_PAYPAL, PAYMENT_TYPE_BITCOIN] as $type) {
if ($account->getGatewayByType($type)) {
$paymentTypes[] = [
'url' => URL::to("/payment/{$invitation->invitation_key}/{$type}"), 'label' => trans('texts.'.strtolower($type))
];
}
}
$data = array(
'isConverted' => $invoice->quote_invoice_id ? true : false,
'showBreadcrumbs' => false,
'hideLogo' => $client->account->isWhiteLabel(),
'hideLogo' => $account->isWhiteLabel(),
'invoice' => $invoice->hidePrivateFields(),
'invitation' => $invitation,
'invoiceLabels' => $client->account->getInvoiceLabels(),
'invoiceLabels' => $account->getInvoiceLabels(),
'contact' => $contact,
'hasToken' => $client->getGatewayToken(),
'countGateways' => AccountGateway::scope(false, $client->account->id)->count(),
'paymentTypes' => $paymentTypes
);
return View::make('invoices.view', $data);
@ -331,7 +356,7 @@ class InvoiceController extends BaseController
'sizes' => Cache::get('sizes'),
'paymentTerms' => Cache::get('paymentTerms'),
'industries' => Cache::get('industries'),
'invoiceDesigns' => InvoiceDesign::where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
'invoiceDesigns' => InvoiceDesign::availableDesigns(),
'frequencies' => array(
1 => 'Weekly',
2 => 'Two weeks',
@ -423,13 +448,12 @@ class InvoiceController extends BaseController
$url = URL::to('clients/'.$client->public_id);
Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT, $url);
}
/*
This causes an error message. Commenting out. will return later.
if (!empty(Input::get('pdfupload')) && strpos(Input::get('pdfupload'), 'data:application/pdf;base64,') === 0) {
$this->storePDF(Input::get('pdfupload'), $invoice->id);
$pdfUpload = Input::get('pdfupload');
if (!empty($pdfUpload) && strpos($pdfUpload, 'data:application/pdf;base64,') === 0) {
$this->storePDF(Input::get('pdfupload'), $invoice);
}
*/
if ($action == 'clone') {
return $this->cloneInvoice($publicId);
} elseif ($action == 'convert') {
@ -567,23 +591,15 @@ class InvoiceController extends BaseController
'invoice' => $invoice,
'versionsJson' => json_encode($versionsJson),
'versionsSelect' => $versionsSelect,
'invoiceDesigns' => InvoiceDesign::where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
'invoiceDesigns' => InvoiceDesign::availableDesigns(),
];
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';
if (file_put_contents($uploadsDir.$name, base64_decode($encodedString)) !== false) {
$finfo = new finfo(FILEINFO_MIME);
if ($finfo->file($uploadsDir.$name) !== 'application/pdf; charset=binary') {
unlink($uploadsDir.$name);
}
}
file_put_contents($invoice->getPDFPath(), base64_decode($encodedString));
}
}

View File

@ -3,6 +3,7 @@
use Datatable;
use Input;
use Redirect;
use Request;
use Session;
use Utils;
use View;
@ -11,13 +12,18 @@ use Omnipay;
use CreditCard;
use URL;
use Cache;
use Event;
use DateTime;
use App\Models\Account;
use App\Models\Invoice;
use App\Models\Invitation;
use App\Models\Client;
use App\Models\PaymentType;
use App\Models\Country;
use App\Models\License;
use App\Models\Payment;
use App\Models\Affiliate;
use App\Models\AccountGatewayToken;
use App\Ninja\Repositories\PaymentRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\AccountRepository;
@ -142,12 +148,18 @@ class PaymentController extends BaseController
public function create($clientPublicId = 0, $invoicePublicId = 0)
{
$invoices = Invoice::scope()
->where('is_recurring', '=', false)
->where('is_quote', '=', false)
->where('invoices.balance', '>', 0)
->with('client', 'invoice_status')
->orderBy('invoice_number')->get();
$data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
'invoice' => null,
'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false)
->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'invoices' => $invoices,
'payment' => null,
'method' => 'POST',
'url' => "payments",
@ -220,6 +232,8 @@ class PaymentController extends BaseController
private function convertInputForOmnipay($input)
{
$country = Country::find($input['country_id']);
return [
'firstName' => $input['first_name'],
'lastName' => $input['last_name'],
@ -232,144 +246,85 @@ class PaymentController extends BaseController
'billingCity' => $input['city'],
'billingState' => $input['state'],
'billingPostcode' => $input['postal_code'],
'billingCountry' => $country->iso_3166_2,
'shippingAddress1' => $input['address1'],
'shippingAddress2' => $input['address2'],
'shippingCity' => $input['city'],
'shippingState' => $input['state'],
'shippingPostcode' => $input['postal_code']
'shippingPostcode' => $input['postal_code'],
'shippingCountry' => $country->iso_3166_2
];
}
private function getPaymentDetails($invitation, $input = null)
{
$invoice = $invitation->invoice;
$key = $invoice->invoice_number.'_details';
$gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$key = $invoice->account_id.'-'.$invoice->invoice_number;
$currencyCode = $invoice->client->currency ? $invoice->client->currency->code : ($invoice->account->currency ? $invoice->account->currency->code : 'USD');
if ($input && $paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
if ($input) {
$data = self::convertInputForOmnipay($input);
Session::put($key, $data);
} elseif ($input && $paymentLibrary->id == PAYMENT_LIBRARY_PHP_PAYMENTS) {
$input = Input::all();
$data = [
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'cc_number' => $input['card_number'],
'cc_exp' => $input['expiration_month'].$input['expiration_year'],
'cc_code' => $input['cvv'],
'street' => $input['address1'],
'street2' => $input['address2'],
'city' => $input['city'],
'state' => $input['state'],
'postal_code' => $input['postal_code'],
'amt' => $invoice->balance,
'ship_to_street' => $input['address1'],
'ship_to_city' => $input['city'],
'ship_to_state' => $input['state'],
'ship_to_postal_code' => $input['postal_code'],
'currency_code' => $currencyCode,
];
switch ($gateway->id) {
case GATEWAY_BEANSTREAM:
$data['phone'] = $input['phone'];
$data['email'] = $input['email'];
$data['country'] = $input['country'];
$data['ship_to_country'] = $input['country'];
break;
case GATEWAY_BRAINTREE:
$data['ship_to_state'] = 'Ohio'; //$input['state'];
break;
}
if (strlen($data['cc_exp']) == 5) {
$data['cc_exp'] = '0'.$data['cc_exp'];
}
Session::put($key, $data);
return $data;
} elseif (Session::get($key)) {
$data = Session::get($key);
} else {
$data = [];
}
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$card = new CreditCard($data);
$card = new CreditCard($data);
return [
'amount' => $invoice->balance,
'card' => $card,
'currency' => $currencyCode,
'returnUrl' => URL::to('complete'),
'cancelUrl' => $invitation->getLink(),
'description' => trans('texts.' . $invoice->getEntityType()) . " {$invoice->invoice_number}",
];
} else {
return $data;
}
return [
'amount' => $invoice->getRequestedAmount(),
'card' => $card,
'currency' => $currencyCode,
'returnUrl' => URL::to('complete'),
'cancelUrl' => $invitation->getLink(),
'description' => trans('texts.' . $invoice->getEntityType()) . " {$invoice->invoice_number}",
];
}
public function show_payment($invitationKey)
{
// Handle token billing
if (Input::get('use_token') == 'true') {
return self::do_payment($invitationKey, false, true);
}
public function show_payment($invitationKey, $paymentType = false)
{
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
$client = $invoice->client;
$account = $client->account;
$useToken = false;
if (Input::has('use_paypal')) {
Session::put('payment_type', Input::get('use_paypal') == 'true' ? PAYMENT_TYPE_PAYPAL : PAYMENT_TYPE_CREDIT_CARD);
} elseif (!Session::has('payment_type')) {
Session::put('payment_type', PAYMENT_TYPE_ANY);
if (!$paymentType) {
$paymentType = $account->account_gateways[0]->getPaymentType();
} else if ($paymentType == PAYMENT_TYPE_TOKEN) {
$useToken = true;
$paymentType = PAYMENT_TYPE_CREDIT_CARD;
}
Session::put('payment_type', $paymentType);
// For PayPal we redirect straight to their site
$usePayPal = false;
if ($usePayPal = Input::get('use_paypal')) {
$usePayPal = $usePayPal == 'true';
} else {
$invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$account = $invitation->invoice->client->account;
if (count($account->account_gateways) == 1 && $account->getGatewayByType(PAYMENT_TYPE_PAYPAL)) {
$usePayPal = true;
}
}
if ($usePayPal) {
// Handle offsite payments
if ($useToken || $paymentType != PAYMENT_TYPE_CREDIT_CARD) {
if (Session::has('error')) {
Session::reflash();
return Redirect::to('view/'.$invitationKey);
} else {
return self::do_payment($invitationKey, false);
return self::do_payment($invitationKey, false, $useToken);
}
} else {
Session::put('payment_type', PAYMENT_TYPE_ANY);
}
}
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
$client = $invoice->client;
$accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
$gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$accountGateway = $invoice->client->account->getGatewayByType($paymentType);
$gateway = $accountGateway->gateway;
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
$data = [
'showBreadcrumbs' => false,
'url' => 'payment/'.$invitationKey,
'amount' => $invoice->balance,
'amount' => $invoice->getRequestedAmount(),
'invoiceNumber' => $invoice->invoice_number,
'client' => $client,
'contact' => $invitation->contact,
'paymentLibrary' => $paymentLibrary,
'gateway' => $gateway,
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Cache::get('countries'),
'currencyId' => $client->currency_id,
'account' => $client->account
'account' => $client->account,
];
return View::make('payments.payment', $data);
@ -401,7 +356,6 @@ class PaymentController extends BaseController
$account->load('account_gateways.gateway');
$accountGateway = $account->getGatewayByType(Session::get('payment_type'));
$gateway = $accountGateway->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
$affiliate = Affiliate::find(Session::get('affiliate_id'));
@ -413,7 +367,6 @@ class PaymentController extends BaseController
'amount' => $affiliate->price,
'client' => false,
'contact' => false,
'paymentLibrary' => $paymentLibrary,
'gateway' => $gateway,
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Cache::get('countries'),
@ -440,6 +393,7 @@ class PaymentController extends BaseController
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
'country_id' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
@ -519,13 +473,13 @@ class PaymentController extends BaseController
$productId = Input::get('product_id', PRODUCT_ONE_CLICK_INSTALL);
$license = License::where('license_key', '=', $licenseKey)
->where('is_claimed', '=', false)
->where('is_claimed', '<', 3)
->where('product_id', '=', $productId)
->first();
if ($license) {
if ($license->transaction_reference != 'TEST_MODE') {
$license->is_claimed = true;
$license->is_claimed = $license->is_claimed + 1;
$license->save();
}
@ -548,6 +502,7 @@ class PaymentController extends BaseController
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
'country_id' => 'required',
);
if ($onSite) {
@ -564,8 +519,8 @@ class PaymentController extends BaseController
$client = $invoice->client;
$account = $client->account;
$accountGateway = $account->getGatewayByType(Session::get('payment_type'));
$paymentLibrary = $accountGateway->gateway->paymentlibrary;
/*
if ($onSite) {
$client->address1 = trim(Input::get('address1'));
$client->address2 = trim(Input::get('address2'));
@ -574,18 +529,20 @@ class PaymentController extends BaseController
$client->postal_code = trim(Input::get('postal_code'));
$client->save();
}
*/
try {
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$gateway = self::createGateway($accountGateway);
$details = self::getPaymentDetails($invitation, $useToken || !$onSite ? false : Input::all());
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
if ($useToken) {
$details['cardReference'] = $client->getGatewayToken();
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
$tokenResponse = $gateway->createCard($details)->send();
$cardReference = $tokenResponse->getCardReference();
$gateway = self::createGateway($accountGateway);
$details = self::getPaymentDetails($invitation, $useToken || !$onSite ? false : Input::all());
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
if ($useToken) {
$details['cardReference'] = $client->getGatewayToken();
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
$tokenResponse = $gateway->createCard($details)->send();
$cardReference = $tokenResponse->getCardReference();
if ($cardReference) {
$details['cardReference'] = $cardReference;
$token = AccountGatewayToken::where('client_id', '=', $client->id)
@ -598,43 +555,44 @@ class PaymentController extends BaseController
$token->account_gateway_id = $accountGateway->id;
$token->client_id = $client->id;
}
$token->token = $cardReference;
$token->save();
}
}
}
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
if (!$ref) {
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
Session::flash('error', $response->getMessage());
if (!$ref) {
Session::flash('error', $response->getMessage());
if ($onSite) {
return Redirect::to('payment/'.$invitationKey)->withInput();
} else {
return Redirect::to('view/'.$invitationKey);
}
}
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref);
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$payment->invitation->invitation_key);
} elseif ($response->isRedirect()) {
$invitation->transaction_reference = $ref;
$invitation->save();
Session::save();
$response->redirect();
if ($onSite) {
return Redirect::to('payment/'.$invitationKey)->withInput();
} else {
Session::flash('error', $response->getMessage());
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
return Redirect::to('view/'.$invitationKey);
}
}
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref);
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$payment->invitation->invitation_key);
} elseif ($response->isRedirect()) {
$invitation->transaction_reference = $ref;
$invitation->save();
Session::put('transaction_reference', $ref);
Session::save();
$response->redirect();
} else {
Session::flash('error', $response->getMessage());
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
}
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage."<p>".$e->getMessage());
@ -655,7 +613,12 @@ class PaymentController extends BaseController
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY) {
$account = Account::find($invoice->client->public_id);
$account->pro_plan_paid = date_create()->format('Y-m-d');
if ($account->pro_plan_paid && $account->pro_plan_paid != '0000-00-00') {
$date = DateTime::createFromFormat('Y-m-d', $account->pro_plan_paid);
$account->pro_plan_paid = $date->modify('+1 year')->format('Y-m-d');
} else {
$account->pro_plan_paid = date_create()->format('Y-m-d');
}
$account->save();
}
@ -663,12 +626,12 @@ class PaymentController extends BaseController
$payment->invitation_id = $invitation->id;
$payment->account_gateway_id = $accountGateway->id;
$payment->invoice_id = $invoice->id;
$payment->amount = $invoice->balance;
$payment->amount = $invoice->getRequestedAmount();
$payment->client_id = $invoice->client_id;
$payment->contact_id = $invitation->contact_id;
$payment->transaction_reference = $ref;
$payment->payment_date = date_create()->format('Y-m-d');
if ($payerId) {
$payment->payer_id = $payerId;
}
@ -685,6 +648,14 @@ class PaymentController extends BaseController
$payerId = Request::query('PayerID');
$token = Request::query('token');
if (!$token) {
$token = Session::pull('transaction_reference');
}
if (!$token) {
return redirect(NINJA_WEB_URL);
}
$invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
$invoice = $invitation->invoice;
@ -692,20 +663,26 @@ class PaymentController extends BaseController
$gateway = self::createGateway($accountGateway);
try {
$details = self::getPaymentDetails($invitation);
$response = $gateway->completePurchase($details)->send();
$ref = $response->getTransactionReference();
if (method_exists($gateway, 'completePurchase')) {
$details = self::getPaymentDetails($invitation);
$response = $gateway->completePurchase($details)->send();
$ref = $response->getTransactionReference();
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref, $payerId);
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref, $payerId);
Session::flash('message', trans('texts.applied_payment'));
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$invitation->invitation_key);
} else {
$errorMessage = trans('texts.payment_error')."\n\n".$response->getMessage();
Session::flash('error', $errorMessage);
Utils::logError($errorMessage);
return Redirect::to('view/'.$invitation->invitation_key);
return Redirect::to('view/'.$invitation->invitation_key);
}
} else {
$errorMessage = trans('texts.payment_error')."\n\n".$response->getMessage();
Session::flash('error', $errorMessage);
Utils::logError($errorMessage);
$payment = self::createPayment($invitation, $token, $payerId);
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$invitation->invitation_key);
}

View File

@ -155,7 +155,7 @@ class QuoteController extends BaseController
'sizes' => Cache::get('sizes'),
'paymentTerms' => Cache::get('paymentTerms'),
'industries' => Cache::get('industries'),
'invoiceDesigns' => InvoiceDesign::where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
'invoiceDesigns' => InvoiceDesign::availableDesigns(),
'invoiceLabels' => Auth::user()->account->getInvoiceLabels()
];
}

View File

@ -37,76 +37,175 @@ class ReportController extends BaseController
return View::make('reports.d3', $data);
}
public function report()
public function showReports()
{
$action = Input::get('action');
if (Input::all()) {
$groupBy = Input::get('group_by');
$chartType = Input::get('chart_type');
$reportType = Input::get('report_type');
$startDate = Utils::toSqlDate(Input::get('start_date'), false);
$endDate = Utils::toSqlDate(Input::get('end_date'), false);
$enableReport = Input::get('enable_report') ? true : false;
$enableChart = Input::get('enable_chart') ? true : false;
} else {
$groupBy = 'MONTH';
$chartType = 'Bar';
$reportType = '';
$startDate = Utils::today(false)->modify('-3 month');
$endDate = Utils::today(false);
$enableReport = true;
$enableChart = true;
}
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
$endDate->modify('+1 '.$padding);
$datasets = [];
$labels = [];
$maxTotals = 0;
$width = 10;
$displayData = [];
$exportData = [];
$reportTotals = [
'amount' => [],
'balance' => [],
'paid' => []
];
if ($reportType) {
$columns = ['client', 'amount', 'paid', 'balance'];
} else {
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance'];
}
if (Auth::user()->account->isPro()) {
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) {
$records = DB::table($entityType.'s')
->select(DB::raw('sum(amount) as total, '.$groupBy.'('.$entityType.'_date) as '.$groupBy))
->where('account_id', '=', Auth::user()->account_id)
->where($entityType.'s.is_deleted', '=', false)
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
->groupBy($groupBy);
if ($entityType == ENTITY_INVOICE) {
$records->where('is_quote', '=', false)
->where('is_recurring', '=', false);
if ($enableReport) {
$query = DB::table('invoices')
->join('clients', 'clients.id', '=', 'invoices.client_id')
->join('contacts', 'contacts.client_id', '=', 'clients.id')
->where('invoices.account_id', '=', Auth::user()->account_id)
->where('invoices.is_deleted', '=', false)
->where('clients.is_deleted', '=', false)
->where('contacts.deleted_at', '=', null)
->where('invoices.invoice_date', '>=', $startDate->format('Y-m-d'))
->where('invoices.invoice_date', '<=', $endDate->format('Y-m-d'))
->where('invoices.is_quote', '=', false)
->where('invoices.is_recurring', '=', false)
->where('contacts.is_primary', '=', true);
$select = ['clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'clients.name as client_name', 'clients.public_id as client_public_id', 'invoices.public_id as invoice_public_id'];
if ($reportType) {
$query->groupBy('clients.id');
array_push($select, DB::raw('sum(invoices.amount) amount'), DB::raw('sum(invoices.balance) balance'), DB::raw('sum(invoices.amount - invoices.balance) paid'));
} else {
array_push($select, 'invoices.invoice_number', 'invoices.amount', 'invoices.balance', 'invoices.invoice_date', DB::raw('(invoices.amount - invoices.balance) paid'));
$query->orderBy('invoices.id');
}
$query->select($select);
$data = $query->get();
$totals = $records->lists('total');
$dates = $records->lists($groupBy);
$data = array_combine($dates, $totals);
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
$period = new DatePeriod($startDate, $interval, $endDate);
$totals = [];
foreach ($period as $d) {
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
$date = $d->format($dateFormat);
$totals[] = isset($data[$date]) ? $data[$date] : 0;
if ($entityType == ENTITY_INVOICE) {
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
$label = $d->format($labelFormat);
$labels[] = $label;
foreach ($data as $record) {
// web display data
$displayRow = [link_to('/clients/'.$record->client_public_id, Utils::getClientDisplayName($record))];
if (!$reportType) {
array_push($displayRow,
link_to('/invoices/'.$record->invoice_public_id, $record->invoice_number),
Utils::fromSqlDate($record->invoice_date, true)
);
}
array_push($displayRow,
Utils::formatMoney($record->amount, $record->currency_id),
Utils::formatMoney($record->paid, $record->currency_id),
Utils::formatMoney($record->balance, $record->currency_id)
);
// export data
$exportRow = [trans('texts.client') => Utils::getClientDisplayName($record)];
if (!$reportType) {
$exportRow[trans('texts.invoice_number')] = $record->invoice_number;
$exportRow[trans('texts.invoice_date')] = Utils::fromSqlDate($record->invoice_date, true);
}
$exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id);
$exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id);
$exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id);
$displayData[] = $displayRow;
$exportData[] = $exportRow;
$accountCurrencyId = Auth::user()->account->currency_id;
$currencyId = $record->currency_id ? $record->currency_id : ($accountCurrencyId ? $accountCurrencyId : DEFAULT_CURRENCY);
if (!isset($reportTotals['amount'][$currencyId])) {
$reportTotals['amount'][$currencyId] = 0;
$reportTotals['balance'][$currencyId] = 0;
$reportTotals['paid'][$currencyId] = 0;
}
$reportTotals['amount'][$currencyId] += $record->amount;
$reportTotals['paid'][$currencyId] += $record->paid;
$reportTotals['balance'][$currencyId] += $record->balance;
}
$max = max($totals);
if ($max > 0) {
$datasets[] = [
'totals' => $totals,
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'),
];
$maxTotals = max($max, $maxTotals);
if ($action == 'export') {
self::export($exportData, $reportTotals);
}
}
$width = (ceil($maxTotals / 100) * 100) / 10;
$width = max($width, 10);
if ($enableChart) {
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) {
$records = DB::table($entityType.'s')
->select(DB::raw('sum(amount) as total, concat(YEAR('.$entityType.'_date), '.$groupBy.'('.$entityType.'_date)) as '.$groupBy))
->where('account_id', '=', Auth::user()->account_id)
->where($entityType.'s.is_deleted', '=', false)
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
->groupBy($groupBy);
if ($entityType == ENTITY_INVOICE) {
$records->where('is_quote', '=', false)
->where('is_recurring', '=', false);
}
$totals = $records->lists('total');
$dates = $records->lists($groupBy);
$data = array_combine($dates, $totals);
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
$endDate->modify('+1 '.$padding);
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
$period = new DatePeriod($startDate, $interval, $endDate);
$endDate->modify('-1 '.$padding);
$totals = [];
foreach ($period as $d) {
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
$date = $d->format('Y'.$dateFormat);
$totals[] = isset($data[$date]) ? $data[$date] : 0;
if ($entityType == ENTITY_INVOICE) {
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
$label = $d->format($labelFormat);
$labels[] = $label;
}
}
$max = max($totals);
if ($max > 0) {
$datasets[] = [
'totals' => $totals,
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'),
];
$maxTotals = max($max, $maxTotals);
}
}
$width = (ceil($maxTotals / 100) * 100) / 10;
$width = max($width, 10);
}
}
$dateTypes = [
@ -120,6 +219,11 @@ class ReportController extends BaseController
'Line' => 'Line',
];
$reportTypes = [
'' => '',
'Client' => trans('texts.client')
];
$params = [
'labels' => $labels,
'datasets' => $datasets,
@ -128,11 +232,38 @@ class ReportController extends BaseController
'chartTypes' => $chartTypes,
'chartType' => $chartType,
'startDate' => $startDate->format(Session::get(SESSION_DATE_FORMAT)),
'endDate' => $endDate->modify('-1'.$padding)->format(Session::get(SESSION_DATE_FORMAT)),
'endDate' => $endDate->format(Session::get(SESSION_DATE_FORMAT)),
'groupBy' => $groupBy,
'feature' => ACCOUNT_CHART_BUILDER,
'displayData' => $displayData,
'columns' => $columns,
'reportTotals' => $reportTotals,
'reportTypes' => $reportTypes,
'reportType' => $reportType,
'enableChart' => $enableChart,
'enableReport' => $enableReport,
];
return View::make('reports.report_builder', $params);
return View::make('reports.chart_builder', $params);
}
private function export($data, $totals)
{
$output = fopen('php://output', 'w') or Utils::fatalError();
header('Content-Type:application/csv');
header('Content-Disposition:attachment;filename=ninja-report.csv');
Utils::exportData($output, $data);
foreach (['amount', 'paid', 'balance'] as $type) {
$csv = trans("texts.{$type}") . ',';
foreach ($totals[$type] as $currencyId => $amount) {
$csv .= Utils::formatMoney($amount, $currencyId) . ',';
}
fwrite($output, $csv . "\n");
}
fclose($output);
exit;
}
}

View File

@ -16,6 +16,7 @@ class Kernel extends HttpKernel {
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\DuplicateSubmissionCheck',
'App\Http\Middleware\StartupCheck',
];

View File

@ -0,0 +1,30 @@
<?php namespace app\Http\Middleware;
use Closure;
class DuplicateSubmissionCheck
{
// Prevent users from submitting forms twice
public function handle($request, Closure $next)
{
$path = $request->path();
if (strpos($path, 'charts_and_reports') !== false) {
return $next($request);
}
if (in_array($request->method(), ['POST', 'PUT', 'DELETE'])) {
$lastPage = session(SESSION_LAST_REQUEST_PAGE);
$lastTime = session(SESSION_LAST_REQUEST_TIME);
if ($lastPage == $path && (microtime(true) - $lastTime <= 1)) {
return redirect('/')->with('warning', trans('texts.duplicate_post'));
}
session([SESSION_LAST_REQUEST_PAGE => $request->path()]);
session([SESSION_LAST_REQUEST_TIME => microtime(true)]);
}
return $next($request);
}
}

View File

@ -1,6 +1,8 @@
<?php namespace App\Http\Middleware;
use Session;
use Closure;
use App\Models\Client;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\RedirectResponse;
@ -33,8 +35,10 @@ class RedirectIfAuthenticated {
*/
public function handle($request, Closure $next)
{
if ($this->auth->check())
if ($this->auth->check() && Client::scope()->count() > 0)
{
Session::reflash();
return new RedirectResponse(url('/dashboard'));
}

View File

@ -9,6 +9,8 @@ use Redirect;
use Cache;
use Session;
use Event;
use App\Models\Language;
use App\Models\InvoiceDesign;
use App\Events\UserSettingsChanged;
class StartupCheck
@ -45,17 +47,17 @@ class StartupCheck
'languages' => 'App\Models\Language',
'paymentTerms' => 'App\Models\PaymentTerm',
'paymentTypes' => 'App\Models\PaymentType',
'countries' => 'App\Models\Country',
];
foreach ($cachedTables as $name => $class) {
if (!Cache::has($name)) {
$orderBy = 'id';
if ($name == 'paymentTerms') {
$orderBy = 'num_days';
} elseif (property_exists($class, 'name') && $name != 'paymentTypes') {
} elseif (in_array($name, ['currencies', 'sizes', 'industries', 'languages', 'countries'])) {
$orderBy = 'name';
} else {
$orderBy = 'id';
}
Cache::forever($name, $class::orderBy($orderBy)->get());
}
}
@ -74,12 +76,12 @@ class StartupCheck
$data = @json_decode($file);
}
if ($data) {
if ($data->version != NINJA_VERSION) {
if (version_compare(NINJA_VERSION, $data->version, '<')) {
$params = [
'user_version' => NINJA_VERSION,
'latest_version' => $data->version,
'releases_link' => link_to(RELEASES_URL, 'Invoice Ninja', ['target' => '_blank']),
];
'user_version' => NINJA_VERSION,
'latest_version' => $data->version,
'releases_link' => link_to(RELEASES_URL, 'Invoice Ninja', ['target' => '_blank']),
];
Session::put('news_feed_id', NEW_VERSION_AVAILABLE);
Session::put('news_feed_message', trans('texts.new_version_available', $params));
} else {
@ -123,7 +125,7 @@ class StartupCheck
$licenseKey = Input::get('license_key');
$productId = Input::get('product_id');
$data = trim(file_get_contents((Utils::isNinjaDev() ? 'http://ninja.dev' : NINJA_APP_URL)."/claim_license?license_key={$licenseKey}&product_id={$productId}"));
$data = trim(file_get_contents((Utils::isNinjaDev() ? 'http://www.ninja.dev' : NINJA_APP_URL)."/claim_license?license_key={$licenseKey}&product_id={$productId}"));
if ($productId == PRODUCT_INVOICE_DESIGNS) {
if ($data = json_decode($data)) {

View File

@ -6,11 +6,13 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier {
private $openRoutes = [
'signup/register',
'api/v1/clients',
'api/v1/invoices',
'api/v1/quotes',
'api/v1/payments',
'api/v1/email_invoice',
'api/v1/hooks',
];
/**

View File

@ -1,5 +1,6 @@
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
@ -36,7 +37,7 @@ Route::post('get_started', 'AccountController@getStarted');
// Client visible pages
Route::get('view/{invitation_key}', 'InvoiceController@view');
Route::get('approve/{invitation_key}', 'QuoteController@approve');
Route::get('payment/{invitation_key}', 'PaymentController@show_payment');
Route::get('payment/{invitation_key}/{payment_type?}', 'PaymentController@show_payment');
Route::post('payment/{invitation_key}', 'PaymentController@do_payment');
Route::get('complete', 'PaymentController@offsite_payment');
Route::get('client/quotes', 'QuoteController@clientIndex');
@ -64,12 +65,12 @@ Route::controllers([
get('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@getRegister'));
post('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@postRegister'));
get('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@getLogin'));
get('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@getLoginWrapper'));
post('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@postLoginWrapper'));
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');
@ -84,7 +85,7 @@ Route::post('user/reset', 'UserController@do_reset_password');
Route::get('logout', 'UserController@logout');
*/
if (\App\Libraries\Utils::isNinja()) {
if (Utils::isNinja()) {
Route::post('/signup/register', 'AccountController@doRegister');
Route::get('/news_feed/{user_type}/{version}/', 'HomeController@newsFeed');
Route::get('/demo', 'AccountController@demo');
@ -112,8 +113,8 @@ Route::group(['middleware' => 'auth'], function() {
Route::get('products/{product_id}/archive', 'ProductController@archive');
Route::get('company/advanced_settings/data_visualizations', 'ReportController@d3');
Route::get('company/advanced_settings/chart_builder', 'ReportController@report');
Route::post('company/advanced_settings/chart_builder', 'ReportController@report');
Route::get('company/advanced_settings/charts_and_reports', 'ReportController@showReports');
Route::post('company/advanced_settings/charts_and_reports', 'ReportController@showReports');
Route::post('company/cancel_account', 'AccountController@cancelAccount');
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
@ -179,10 +180,37 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
Route::resource('invoices', 'InvoiceApiController');
Route::resource('quotes', 'QuoteApiController');
Route::resource('payments', 'PaymentApiController');
Route::post('api/hooks', 'IntegrationController@subscribe');
Route::post('hooks', 'IntegrationController@subscribe');
Route::post('email_invoice', 'InvoiceApiController@emailInvoice');
});
// Redirects for legacy links
Route::get('/rocksteady', function() {
return Redirect::to(NINJA_WEB_URL, 301);
});
Route::get('/about', function() {
return Redirect::to(NINJA_WEB_URL, 301);
});
Route::get('/contact', function() {
return Redirect::to(NINJA_WEB_URL.'/contact', 301);
});
Route::get('/plans', function() {
return Redirect::to(NINJA_WEB_URL.'/pricing', 301);
});
Route::get('/faq', function() {
return Redirect::to(NINJA_WEB_URL.'/how-it-works', 301);
});
Route::get('/features', function() {
return Redirect::to(NINJA_WEB_URL.'/features', 301);
});
Route::get('/testimonials', function() {
return Redirect::to(NINJA_WEB_URL, 301);
});
Route::get('/compare-online-invoicing{sites?}', function() {
return Redirect::to(NINJA_WEB_URL, 301);
});
define('CONTACT_EMAIL', Config::get('mail.from.address'));
define('CONTACT_NAME', Config::get('mail.from.name'));
define('SITE_URL', Config::get('app.url'));
@ -260,6 +288,7 @@ define('RANDOM_KEY_LENGTH', 32);
define('MAX_NUM_CLIENTS', 500);
define('MAX_NUM_CLIENTS_PRO', 20000);
define('MAX_NUM_USERS', 20);
define('MAX_SUBDOMAIN_LENGTH', 30);
define('INVOICE_STATUS_DRAFT', 1);
define('INVOICE_STATUS_SENT', 2);
@ -285,6 +314,9 @@ define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
define('SESSION_COUNTER', 'sessionCounter');
define('SESSION_LOCALE', 'sessionLocale');
define('SESSION_LAST_REQUEST_PAGE', 'SESSION_LAST_REQUEST_PAGE');
define('SESSION_LAST_REQUEST_TIME', 'SESSION_LAST_REQUEST_TIME');
define('DEFAULT_TIMEZONE', 'US/Eastern');
define('DEFAULT_CURRENCY', 1); // US Dollar
define('DEFAULT_DATE_FORMAT', 'M j, Y');
@ -309,6 +341,7 @@ define('GATEWAY_TWO_CHECKOUT', 27);
define('GATEWAY_BEANSTREAM', 29);
define('GATEWAY_PSIGATE', 30);
define('GATEWAY_MOOLAH', 31);
define('GATEWAY_BITPAY', 42);
define('EVENT_CREATE_CLIENT', 1);
define('EVENT_CREATE_INVOICE', 2);
@ -318,14 +351,15 @@ define('EVENT_CREATE_PAYMENT', 4);
define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN');
define('DEMO_ACCOUNT_ID', 'DEMO_ACCOUNT_ID');
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET);
define('NINJA_GATEWAY_CONFIG', '{"apiLoginId":"626vWcD5","transactionKey":"4bn26TgL9r4Br4qJ","testMode":"","developerMode":""}');
define('NINJA_GATEWAY_ID', GATEWAY_STRIPE);
define('NINJA_GATEWAY_CONFIG', '');
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
define('NINJA_VERSION', '1.7.2');
define('NINJA_VERSION', '2.0.1');
define('NINJA_DATE', '2000-01-01');
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
define('RELEASES_URL', 'https://github.com/hillelcoren/invoice-ninja/releases/');
define('ZAPIER_URL', 'https://zapier.com/developer/invite/11276/85cf0ee4beae8e802c6c579eb4e351f1/');
define('COUNT_FREE_DESIGNS', 4);
define('PRODUCT_ONE_CLICK_INSTALL', 1);
@ -351,6 +385,8 @@ define('TOKEN_BILLING_ALWAYS', 4);
define('PAYMENT_TYPE_PAYPAL', 'PAYMENT_TYPE_PAYPAL');
define('PAYMENT_TYPE_CREDIT_CARD', 'PAYMENT_TYPE_CREDIT_CARD');
define('PAYMENT_TYPE_BITCOIN', 'PAYMENT_TYPE_BITCOIN');
define('PAYMENT_TYPE_TOKEN', 'PAYMENT_TYPE_TOKEN');
define('PAYMENT_TYPE_ANY', 'PAYMENT_TYPE_ANY');
/*
@ -472,7 +508,7 @@ Validator::extend('has_credit', function($attribute, $value, $parameters) {
$publicClientId = $parameters[0];
$amount = $parameters[1];
$client = Client::scope($publicClientId)->firstOrFail();
$client = \App\Models\Client::scope($publicClientId)->firstOrFail();
$credit = $client->getTotalCredit();
return $credit >= $amount;
@ -511,4 +547,4 @@ if (Auth::check() && Auth::user()->id === 1)
{
Auth::loginUsingId(1);
}
*/
*/

View File

@ -146,7 +146,9 @@ class Utils
public static function getErrorString($exception)
{
return "{$exception->getFile()} [Line {$exception->getLine()}] => {$exception->getMessage()}";
$class = get_class($exception);
$code = method_exists($exception, 'getStatusCode') ? $exception->getStatusCode() : $exception->getCode();
return "***{$class}*** [{$code}] : {$exception->getFile()} [Line {$exception->getLine()}] => {$exception->getMessage()}";
}
public static function logError($error, $context = 'PHP')
@ -234,9 +236,13 @@ class Utils
$currencyId = Session::get(SESSION_CURRENCY);
}
$currency = Currency::find($currencyId);
if(!$currency){
foreach (Cache::get('currencies') as $currency) {
if ($currency->id == $currencyId) {
break;
}
}
if (!$currency) {
$currency = Currency::find(1);
}
@ -484,7 +490,7 @@ class Utils
public static function encodeActivity($person = null, $action, $entity = null, $otherPerson = null)
{
$person = $person ? $person->getDisplayName() : '<i>System</i>';
$entity = $entity ? '['.$entity->getActivityKey().']' : '';
$entity = $entity ? $entity->getActivityKey() : '';
$otherPerson = $otherPerson ? 'to '.$otherPerson->getDisplayName() : '';
$token = Session::get('token_id') ? ' ('.trans('texts.token').')' : '';
@ -621,4 +627,17 @@ class Utils
return $str;
}
public static function exportData($output, $data)
{
if (count($data) > 0) {
fputcsv($output, array_keys($data[0]));
}
foreach ($data as $record) {
fputcsv($output, $record);
}
fwrite($output, "\n");
}
}

View File

@ -31,8 +31,10 @@ class HandleInvoicePaid {
*/
public function handle(InvoicePaid $event)
{
$this->contactMailer->sendPaymentConfirmation($payment);
$payment = $event->payment;
$invoice = $payment->invoice;
$this->contactMailer->sendPaymentConfirmation($payment);
foreach ($invoice->account->users as $user)
{

View File

@ -34,7 +34,7 @@ class HandleInvoiceViewed {
{
if ($user->{'notify_viewed'})
{
$this->userMailer->sendNotification($user, $invoice, 'viewed', $payment);
$this->userMailer->sendNotification($user, $invoice, 'viewed');
}
}
}

View File

@ -3,6 +3,7 @@
use Eloquent;
use Utils;
use Session;
use DateTime;
use Illuminate\Database\Eloquent\SoftDeletes;
@ -113,9 +114,7 @@ class Account extends Eloquent
foreach ($this->account_gateways as $gateway) {
if (!$type || $type == PAYMENT_TYPE_ANY) {
return $gateway;
} elseif ($gateway->isPayPal() && $type == PAYMENT_TYPE_PAYPAL) {
return $gateway;
} elseif (!$gateway->isPayPal() && $type == PAYMENT_TYPE_CREDIT_CARD) {
} elseif ($gateway->isPaymentType($type)) {
return $gateway;
}
}
@ -230,6 +229,7 @@ class Account extends Eloquent
'subtotal',
'paid_to_date',
'balance_due',
'amount_due',
'terms',
'your_invoice',
'quote',
@ -356,7 +356,8 @@ class Account extends Eloquent
public function getEmailFooter()
{
if ($this->email_footer) {
return $this->email_footer;
// Add line breaks if HTML isn't already being used
return strip_tags($this->email_footer) == $this->email_footer ? nl2br($this->email_footer) : $this->email_footer;
} else {
return "<p>" . trans('texts.email_signature') . "<br>\$account</p>";
}
@ -377,3 +378,10 @@ class Account extends Eloquent
return $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;
}
}
Account::updating(function ($account) {
// Lithuanian requires UTF8 support
if (!Utils::isPro()) {
$account->utf8_invoices = ($account->language_id == 13) ? 1 : 0;
}
});

View File

@ -1,5 +1,6 @@
<?php namespace App\Models;
use App\Models\Gateway;
use Illuminate\Database\Eloquent\SoftDeletes;
class AccountGateway extends EntityModel
@ -26,8 +27,12 @@ class AccountGateway extends EntityModel
return $arrayOfImages;
}
public function isPayPal() {
return $this->gateway_id == GATEWAY_PAYPAL_EXPRESS;
public function getPaymentType() {
return Gateway::getPaymentType($this->gateway_id);
}
public function isPaymentType($type) {
return $this->getPaymentType() == $type;
}
}

View File

@ -1,5 +1,6 @@
<?php namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class AccountGatewayToken extends Eloquent

View File

@ -187,7 +187,7 @@ class Activity extends Eloquent
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
$fieldChanged = false;
foreach (['invoice_number', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'invoice_footer'] as $field) {
foreach (['invoice_number', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'invoice_footer', 'partial'] as $field) {
if ($invoice->$field != $invoice->getOriginal($field)) {
$fieldChanged = true;
break;
@ -214,7 +214,6 @@ class Activity extends Eloquent
if ($invoice->isPaid() && $invoice->balance > 0) {
$invoice->invoice_status_id = INVOICE_STATUS_PARTIAL;
$invoice->save();
}
}
}
@ -292,6 +291,9 @@ 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;
if ($invoice->partial > 0) {
$invoice->partial = max(0, $invoice->partial - $payment->amount);
}
$invoice->save();
}

View File

@ -1,5 +1,7 @@
<?php namespace App\Models;
use Eloquent;
class Affiliate extends Eloquent
{
public $timestamps = true;

View File

@ -44,7 +44,7 @@ class EntityModel extends Eloquent
public function getActivityKey()
{
return $this->getEntityType().':'.$this->public_id.':'.$this->getName();
return '[' . $this->getEntityType().':'.$this->public_id.':'.$this->getName() . ']';
}
/*

View File

@ -7,11 +7,6 @@ class Gateway extends Eloquent
{
public $timestamps = true;
public function paymentlibrary()
{
return $this->belongsTo('\App\Models\PaymentLibrary', 'payment_library_id');
}
public function getLogoUrl()
{
return '/images/gateways/logo_'.$this->provider.'.png';
@ -27,6 +22,8 @@ class Gateway extends Eloquent
$link = 'https://www.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run';
} elseif ($this->id == GATEWAY_TWO_CHECKOUT) {
$link = 'https://www.2checkout.com/referral?r=2c37ac2298';
} elseif ($this->id == GATEWAY_BITPAY) {
$link = 'https://bitpay.com/dashboard/signup';
}
$key = 'texts.gateway_help_'.$this->id;
@ -37,18 +34,20 @@ class Gateway extends Eloquent
public function getFields()
{
$paymentLibrary = $this->paymentlibrary;
return Omnipay::create($this->provider)->getDefaultParameters();
}
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$fields = Omnipay::create($this->provider)->getDefaultParameters();
public static function getPaymentType($gatewayId) {
if ($gatewayId == GATEWAY_PAYPAL_EXPRESS) {
return PAYMENT_TYPE_PAYPAL;
} else if ($gatewayId == GATEWAY_BITPAY) {
return PAYMENT_TYPE_BITCOIN;
} else {
$fields = Payment_Utility::load('config', 'drivers/'.strtolower($this->provider));
return PAYMENT_TYPE_CREDIT_CARD;
}
}
if ($fields == null) {
$fields = array();
}
return $fields;
public static function getPrettyPaymentType($gatewayId) {
return trans('texts.' . strtolower(Gateway::getPaymentType($gatewayId)));
}
}

View File

@ -9,7 +9,7 @@ class Invitation extends EntityModel
public function invoice()
{
return $this->belongsTo('App\Models\Invoice');
return $this->belongsTo('App\Models\Invoice')->withTrashed();
}
public function contact()
@ -29,6 +29,13 @@ class Invitation extends EntityModel
public function getLink()
{
return SITE_URL.'/view/'.$this->invitation_key;
$this->load('account');
$url = SITE_URL;
if ($this->account->subdomain) {
$url = str_replace('://www.', "://{$this->account->subdomain}.", $url);
}
return "{$url}/view/{$this->invitation_key}";
}
}

View File

@ -1,5 +1,6 @@
<?php namespace App\Models;
use DateTime;
use Illuminate\Database\Eloquent\SoftDeletes;
class Invoice extends EntityModel
@ -7,6 +8,10 @@ class Invoice extends EntityModel
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $casts = [
'is_recurring' => 'boolean',
];
public function account()
{
return $this->belongsTo('App\Models\Account');
@ -47,6 +52,17 @@ class Invoice extends EntityModel
return $this->invoice_number;
}
public function getFileName()
{
$entityType = $this->getEntityType();
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);
@ -72,6 +88,11 @@ class Invoice extends EntityModel
return $this->invoice_status_id >= INVOICE_STATUS_PAID;
}
public function getRequestedAmount()
{
return $this->partial > 0 ? $this->partial : $this->balance;
}
public function hidePrivateFields()
{
$this->setVisible([
@ -99,6 +120,7 @@ class Invoice extends EntityModel
'custom_value2',
'custom_taxes1',
'custom_taxes2',
'partial',
]);
$this->client->setVisible([

View File

@ -1,8 +1,23 @@
<?php namespace App\Models;
<?php namespace app\Models;
use Eloquent;
use Auth;
class InvoiceDesign extends Eloquent
{
public $timestamps = false;
public function scopeAvailableDesigns($query)
{
$designs = $query->where('id', '<=', \Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
foreach ($designs as $design) {
$fileName = public_path(strtolower("js/templates/{$design->name}.js"));
if (Auth::user()->account->utf8_invoices && file_exists($fileName)) {
$design->javascript = file_get_contents($fileName);
}
}
return $designs;
}
}

View File

@ -1,5 +1,6 @@
<?php namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class License extends Eloquent

View File

@ -2,6 +2,7 @@
use Auth;
use Utils;
use Eloquent;
class Project extends Eloquent
{

View File

@ -2,7 +2,7 @@
use Auth;
use Utils;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class ProjectCode extends Eloquent

View File

@ -1,5 +1,6 @@
<?php namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class Timesheet extends Eloquent

View File

@ -2,7 +2,7 @@
use Auth;
use Utils;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class TimesheetEvent extends Eloquent

View File

@ -2,7 +2,7 @@
use Auth;
use Utils;
use Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
class TimesheetEventSource extends Eloquent

View File

@ -19,7 +19,7 @@ class ContactMailer extends Mailer
$subject = trans("texts.{$entityType}_subject", ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]);
$accountName = $invoice->account->getDisplayName();
$emailTemplate = $invoice->account->getEmailTemplate($entityType);
$invoiceAmount = Utils::formatMoney($invoice->amount, $invoice->client->currency_id);
$invoiceAmount = Utils::formatMoney($invoice->getRequestedAmount(), $invoice->client->currency_id);
foreach ($invoice->invitations as $invitation) {
if (!$invitation->user || !$invitation->user->email) {
@ -44,7 +44,7 @@ class ContactMailer extends Mailer
$data['body'] = str_replace(array_keys($variables), array_values($variables), $emailTemplate);
$data['link'] = $invitation->getLink();
$data['entityType'] = $entityType;
$data['id'] = $invoice->getAttributes()['id'];
$data['invoice_id'] = $invoice->id;
$fromEmail = $invitation->user->email;
$this->sendTo($invitation->contact->email, $fromEmail, $accountName, $subject, $view, $data);

View File

@ -21,16 +21,12 @@ class Mailer
$fromEmail = NINJA_FROM_EMAIL;
}
if(isset($data['id'])) {
$invoice = Invoice::find($data['id']);
$invoice->load('account');
$accountAttributes = $invoice->account()->getParent()->getRelations()['account']->getAttributes();
$pdfPath = storage_path().'/pdfcache/cache-'.$invoice->id.'.pdf';
if($accountAttributes['pdf_email_attachment'] === 1 && file_exists($pdfPath)) {
if(isset($data['invoice_id'])) {
$invoice = Invoice::with('account')->where('id', '=', $data['invoice_id'])->get()->first();
if($invoice->account->pdf_email_attachment && file_exists($invoice->getPDFPath())) {
$message->attach(
$pdfPath,
array('as' => $accountAttributes['name'].'_'.$accountAttributes['invoice_number_prefix'].$invoice->getName().'.pdf', 'mime' => 'application/pdf')
$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;
@ -44,7 +44,7 @@ class AccountRepository
}
$user->confirmed = !Utils::isNinja();
$user->registered = !Utils::isNinja();
$user->registered = !Utils::isNinja() && $user->email;
if (!$user->confirmed) {
$user->confirmation_code = str_random(RANDOM_KEY_LENGTH);
@ -108,19 +108,19 @@ class AccountRepository
if (Auth::user()->isPro()) {
return false;
}
$ninjaAccount = $this->getNinjaAccount();
$lastInvoice = Invoice::withTrashed()->whereAccountId($ninjaAccount->id)->orderBy('public_id', 'DESC')->first();
$publicId = $lastInvoice ? ($lastInvoice->public_id + 1) : 1;
$ninjaClient = $this->getNinjaClient($ninjaAccount);
$invitation = $this->createNinjaInvoice($publicId, $ninjaAccount, $ninjaClient);
$client = $this->getNinjaClient(Auth::user()->account);
$invitation = $this->createNinjaInvoice($client);
return $invitation;
}
private function createNinjaInvoice($publicId, $account, $client)
public function createNinjaInvoice($client)
{
$account = $this->getNinjaAccount();
$lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first();
$publicId = $lastInvoice ? ($lastInvoice->public_id + 1) : 1;
$invoice = new Invoice();
$invoice->account_id = $account->id;
$invoice->user_id = $account->users()->first()->id;
@ -174,7 +174,6 @@ class AccountRepository
$user->confirmed = true;
$user->email = 'contact@invoiceninja.com';
$user->password = $random;
$user->password_confirmation = $random;
$user->username = $random;
$user->first_name = 'Invoice';
$user->last_name = 'Ninja';
@ -193,27 +192,29 @@ class AccountRepository
return $account;
}
private function getNinjaClient($ninjaAccount)
public function getNinjaClient($account)
{
$client = Client::whereAccountId($ninjaAccount->id)->wherePublicId(Auth::user()->account_id)->first();
$account->load('users');
$ninjaAccount = $this->getNinjaAccount();
$client = Client::whereAccountId($ninjaAccount->id)->wherePublicId($account->id)->first();
if (!$client) {
$client = new Client();
$client->public_id = Auth::user()->account_id;
$client->public_id = $account->id;
$client->user_id = $ninjaAccount->users()->first()->id;
$client->currency_id = 1;
foreach (['name', 'address1', 'address2', 'city', 'state', 'postal_code', 'country_id', 'work_phone'] as $field) {
$client->$field = Auth::user()->account->$field;
$client->$field = $account->$field;
}
$ninjaAccount->clients()->save($client);
$contact = new Contact();
$contact->user_id = $ninjaAccount->users()->first()->id;
$contact->account_id = $ninjaAccount->id;
$contact->public_id = Auth::user()->account_id;
$contact->public_id = $account->id;
$contact->is_primary = true;
foreach (['first_name', 'last_name', 'email', 'phone'] as $field) {
$contact->$field = Auth::user()->$field;
$contact->$field = $account->users()->first()->$field;
}
$client->contacts()->save($contact);
}
@ -223,13 +224,13 @@ class AccountRepository
public function registerUser($user)
{
$url = NINJA_APP_URL.'/signup/register';
$url = (Utils::isNinjaDev() ? '' : NINJA_APP_URL) . '/signup/register';
$data = '';
$fields = [
'first_name' => urlencode($user->first_name),
'last_name' => urlencode($user->last_name),
'email' => urlencode($user->email),
];
'first_name' => urlencode($user->first_name),
'last_name' => urlencode($user->last_name),
'email' => urlencode($user->email),
];
foreach ($fields as $key => $value) {
$data .= $key.'='.$value.'&';

View File

@ -34,7 +34,10 @@ class ClientRepository
public function getErrors($data)
{
$contact = isset($data['contacts']) ? (array) $data['contacts'][0] : (isset($data['contact']) ? $data['contact'] : []);
$validator = \Validator::make($contact, ['email' => 'required|email']);
$validator = \Validator::make($contact, [
'email' => 'email|required_without:first_name',
'first_name' => 'required_without:email',
]);
if ($validator->fails()) {
return $validator->messages();
}

View File

@ -19,7 +19,7 @@ class InvoiceRepository
->where('contacts.deleted_at', '=', null)
->where('invoices.is_recurring', '=', false)
->where('contacts.is_primary', '=', true)
->select('clients.public_id as client_public_id', 'invoice_number', 'invoice_status_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'quote_id', 'quote_invoice_id', 'invoices.deleted_at', 'invoices.is_deleted');
->select('clients.public_id as client_public_id', 'invoice_number', 'invoice_status_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'quote_id', 'quote_invoice_id', 'invoices.deleted_at', 'invoices.is_deleted', 'invoices.partial');
if (!\Session::get('show_trash:'.$entityType)) {
$query->where('invoices.deleted_at', '=', null);
@ -86,7 +86,7 @@ class InvoiceRepository
->where('invoices.is_deleted', '=', false)
->where('clients.deleted_at', '=', null)
->where('invoices.is_recurring', '=', false)
->select('invitation_key', 'invoice_number', 'invoice_date', 'invoices.balance as balance', 'due_date', 'clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'start_date', 'end_date', 'clients.currency_id');
->select('invitation_key', 'invoice_number', 'invoice_date', 'invoices.balance as balance', 'due_date', 'clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'start_date', 'end_date', 'clients.currency_id', 'invoices.partial');
$table = \Datatable::query($query)
->addColumn('invoice_number', function ($model) use ($entityType) { return link_to('/view/'.$model->invitation_key, $model->invoice_number); })
@ -94,7 +94,11 @@ class InvoiceRepository
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); });
if ($entityType == ENTITY_INVOICE) {
$table->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); });
$table->addColumn('balance', function ($model) {
return $model->partial > 0 ?
trans('texts.partial_remaining', ['partial' => Utils::formatMoney($model->partial, $model->currency_id), 'balance' => Utils::formatMoney($model->balance, $model->currency_id)]) :
Utils::formatMoney($model->balance, $model->currency_id);
});
}
return $table->addColumn('due_date', function ($model) { return Utils::fromSqlDate($model->due_date); })
@ -122,11 +126,15 @@ class InvoiceRepository
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); });
if ($entityType == ENTITY_INVOICE) {
$table->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); });
$table->addColumn('balance', function ($model) {
return $model->partial > 0 ?
trans('texts.partial_remaining', ['partial' => Utils::formatMoney($model->partial, $model->currency_id), 'balance' => Utils::formatMoney($model->balance, $model->currency_id)]) :
Utils::formatMoney($model->balance, $model->currency_id);
});
}
return $table->addColumn('due_date', function ($model) { return Utils::fromSqlDate($model->due_date); })
->addColumn('invoice_status_name', function ($model) { return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted')) : $model->invoice_status_name; })
->addColumn('invoice_status_name', function ($model) { return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted')) : self::getStatusLabel($model->invoice_status_id, $model->invoice_status_name); })
->addColumn('dropdown', function ($model) use ($entityType) {
if ($model->is_deleted) {
@ -179,10 +187,33 @@ class InvoiceRepository
->make();
}
private function getStatusLabel($statusId, $statusName) {
$label = trans("texts.{$statusName}");
$class = 'default';
switch ($statusId) {
case INVOICE_STATUS_SENT:
$class = 'info';
break;
case INVOICE_STATUS_VIEWED:
$class = 'warning';
break;
case INVOICE_STATUS_PARTIAL:
$class = 'primary';
break;
case INVOICE_STATUS_PAID:
$class = 'success';
break;
}
return "<h4><div class=\"label label-{$class}\">$statusName</div></h4>";
}
public function getErrors($input)
{
$contact = (array) $input->client->contacts[0];
$rules = ['email' => 'required|email'];
$rules = [
'email' => 'email|required_without:first_name',
'first_name' => 'required_without:email',
];
$validator = \Validator::make($contact, $rules);
if ($validator->fails()) {
@ -238,9 +269,13 @@ class InvoiceRepository
$invoice->discount = round(Utils::parseFloat($data['discount']), 2);
$invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
$invoice->invoice_number = trim($data['invoice_number']);
$invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;
$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']);
if (!$publicId) {
$invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;
}
if ($invoice->is_recurring) {
$invoice->frequency_id = $data['frequency_id'] ? $data['frequency_id'] : 0;
$invoice->start_date = Utils::toSqlDate($data['start_date']);
@ -253,8 +288,8 @@ class InvoiceRepository
$invoice->end_date = null;
}
$invoice->terms = trim($data['terms']) ? trim($data['terms']) : ($account->invoice_terms ? $account->invoice_terms : '');
$invoice->invoice_footer = trim($data['invoice_footer']) ? trim($data['invoice_footer']) : $account->invoice_footer;
$invoice->terms = trim($data['terms']) ? trim($data['terms']) : (!$publicId && $account->invoice_terms ? $account->invoice_terms : '');
$invoice->invoice_footer = trim($data['invoice_footer']) ? trim($data['invoice_footer']) : (!$publicId && $account->invoice_footer ? $account->invoice_footer : '');
$invoice->public_notes = trim($data['public_notes']);
$invoice->po_number = trim($data['po_number']);
$invoice->invoice_design_id = $data['invoice_design_id'];

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Facturation en ligne libre',
'description' => 'Invoice Ninja est une solution libre pour la tenue de comptes clients et leur facturation. Avec Invoice Ninja, vous pouvez facilement créer et envoyer de belles factures de n\'importe quel dispositif connecté au web. Vos clients peuvent imprimer leurs factures, les télécharger au format PDF, et même vous payer directement en ligne.',
'invoice_now' => 'Facturer maintenant',
'no_signup_needed' => 'Sans inscription',
'link_blog' => 'Carnet',
'link_about_us' => 'À propos',
'link_contact_us' => 'Contactez-nous',
'link_features' => 'Fonctionalités',
'link_plans' => 'Plans',
'link_compare' => 'Comparer',
'link_testimonials' => 'Témoignages',
'link_faq' => 'FAQ',
'my_account' => 'Mon compte',
'login' => 'Inscription',
'connect_with_us' => 'Connectez avec nous',
'safe_and_secure' => 'Sécuritaire',
'toggle_navigation' => 'Changer de navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Gratuit. Toujours.',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Logiciel libre',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Aperçu PDF en ligne',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Paiements en ligne',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'Qu\'est-ce qu\'Invoice Ninja?',
'team_ninja' => 'L\'équipe Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, demandes spéciales, ou simples salutations?',
'sub_header' => 'Complétez ce formulaire et nous répondrons dans les meilleurs délais. On espère vous lire!',
'other_ways' => 'D\'autres manières de nous contacter',
'name' => 'Nom',
'name_help' => 'Votre nom.',
'email' => 'Courriel',
'email_help' => 'Votre adresse de courriel.',
'message' => 'Message',
'message_help' => 'Votre message.',
'send_message' => 'Envoyer',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

27
bower.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "hillelcoren/invoice-ninja",
"version": "0.9.0",
"dependencies": {
"jquery": "~1.11",
"bootstrap": "~3.*",
"jquery-ui": "~1.*",
"datatables": "1.10.4",
"datatables-bootstrap3": "*",
"knockout.js": "~3.*",
"knockout-mapping": "*",
"knockout-sortable": "*",
"font-awesome": "~4.*",
"underscore": "~1.*",
"jspdf": "*",
"bootstrap-datepicker": "~1.*",
"typeahead.js": "~0.9.3",
"accounting": "~0.*",
"spectrum": "~1.3.4",
"d3": "~3.4.11",
"handsontable": "*",
"pdfmake": "*"
},
"resolutions": {
"jquery": "~1.11"
}
}

View File

@ -33,7 +33,8 @@
"coatesap/omnipay-realex": "~2.0",
"fruitcakestudio/omnipay-sisow": "~2.0",
"alfaproject/omnipay-skrill": "dev-master",
"illuminate/html": "5.*"
"illuminate/html": "5.*",
"omnipay/bitpay": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "~4.0",

268
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "f464570c808999ffcb0fa78193b13229",
"hash": "4093891914bbd46ffab78737da36898a",
"packages": [
{
"name": "alfaproject/omnipay-neteller",
@ -120,12 +120,12 @@
"source": {
"type": "git",
"url": "https://github.com/formers/former.git",
"reference": "ed7d00c2b11578a4db31531e1fee97f6ccd85030"
"reference": "4a03cdd08f1bdd975bd2521bed74ab38bf590388"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/formers/former/zipball/ed7d00c2b11578a4db31531e1fee97f6ccd85030",
"reference": "ed7d00c2b11578a4db31531e1fee97f6ccd85030",
"url": "https://api.github.com/repos/formers/former/zipball/4a03cdd08f1bdd975bd2521bed74ab38bf590388",
"reference": "4a03cdd08f1bdd975bd2521bed74ab38bf590388",
"shasum": ""
},
"require": {
@ -171,7 +171,7 @@
"foundation",
"laravel"
],
"time": "2015-03-06 17:50:05"
"time": "2015-04-20 13:53:18"
},
{
"name": "anahkiasen/html-object",
@ -335,12 +335,12 @@
"source": {
"type": "git",
"url": "https://github.com/Chumper/Datatable.git",
"reference": "58f212270a4bd37ebf1371cb5302749cbbcb941d"
"reference": "7fa47cb5469f07c620fb69dee94b8e1a96943ee2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Chumper/Datatable/zipball/58f212270a4bd37ebf1371cb5302749cbbcb941d",
"reference": "58f212270a4bd37ebf1371cb5302749cbbcb941d",
"url": "https://api.github.com/repos/Chumper/Datatable/zipball/7fa47cb5469f07c620fb69dee94b8e1a96943ee2",
"reference": "7fa47cb5469f07c620fb69dee94b8e1a96943ee2",
"shasum": ""
},
"require": {
@ -380,24 +380,24 @@
"jquery",
"laravel"
],
"time": "2015-04-04 15:19:43"
"time": "2015-04-20 09:21:21"
},
{
"name": "classpreloader/classpreloader",
"version": "1.2.0",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/ClassPreloader/ClassPreloader.git",
"reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f"
"reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/f0bfbf71fb3335c9473f695d4d966ba2fb879a9f",
"reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f",
"url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/0544616ba33fb2a6b792b3a7822650810c6d65d9",
"reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9",
"shasum": ""
},
"require": {
"nikic/php-parser": "~1.0",
"nikic/php-parser": "^1.2.2",
"php": ">=5.3.3",
"symfony/console": "~2.1",
"symfony/filesystem": "~2.1",
@ -412,7 +412,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "1.3-dev"
}
},
"autoload": {
@ -440,7 +440,7 @@
"class",
"preload"
],
"time": "2015-01-26 22:06:19"
"time": "2015-04-15 21:59:30"
},
{
"name": "coatesap/omnipay-datacash",
@ -702,16 +702,16 @@
},
{
"name": "doctrine/annotations",
"version": "v1.2.3",
"version": "v1.2.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "eeda578cbe24a170331a1cfdf78be723412df7a4"
"reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/eeda578cbe24a170331a1cfdf78be723412df7a4",
"reference": "eeda578cbe24a170331a1cfdf78be723412df7a4",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e",
"reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e",
"shasum": ""
},
"require": {
@ -766,20 +766,20 @@
"docblock",
"parser"
],
"time": "2014-12-20 20:49:38"
"time": "2014-12-23 22:40:37"
},
{
"name": "doctrine/cache",
"version": "v1.4.0",
"version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "2346085d2b027b233ae1d5de59b07440b9f288c8"
"reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/2346085d2b027b233ae1d5de59b07440b9f288c8",
"reference": "2346085d2b027b233ae1d5de59b07440b9f288c8",
"url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03",
"reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03",
"shasum": ""
},
"require": {
@ -790,13 +790,13 @@
},
"require-dev": {
"phpunit/phpunit": ">=3.7",
"predis/predis": "~0.8",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
"dev-master": "1.5.x-dev"
}
},
"autoload": {
@ -836,25 +836,28 @@
"cache",
"caching"
],
"time": "2015-01-15 20:38:55"
"time": "2015-04-15 00:11:59"
},
{
"name": "doctrine/collections",
"version": "v1.2",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "b99c5c46c87126201899afe88ec490a25eedd6a2"
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/b99c5c46c87126201899afe88ec490a25eedd6a2",
"reference": "b99c5c46c87126201899afe88ec490a25eedd6a2",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
@ -871,17 +874,6 @@
"MIT"
],
"authors": [
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com",
"homepage": "http://www.jwage.com/",
"role": "Creator"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com",
"homepage": "http://www.instaclick.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@ -890,11 +882,17 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh",
"role": "Developer of wrapped JMSSerializerBundle"
"email": "schmittjoh@gmail.com"
}
],
"description": "Collections Abstraction library",
@ -904,7 +902,7 @@
"collections",
"iterator"
],
"time": "2014-02-03 23:07:43"
"time": "2015-04-14 22:21:58"
},
{
"name": "doctrine/common",
@ -1374,12 +1372,12 @@
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "8f3761154b4c1f5128365dfc32cbf757f27d97b6"
"reference": "6626d7624ac0895137a38c123943afedd0827efc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/8f3761154b4c1f5128365dfc32cbf757f27d97b6",
"reference": "8f3761154b4c1f5128365dfc32cbf757f27d97b6",
"url": "https://api.github.com/repos/Intervention/image/zipball/6626d7624ac0895137a38c123943afedd0827efc",
"reference": "6626d7624ac0895137a38c123943afedd0827efc",
"shasum": ""
},
"require": {
@ -1422,7 +1420,7 @@
"thumbnail",
"watermark"
],
"time": "2015-03-18 17:41:04"
"time": "2015-04-24 14:50:48"
},
{
"name": "ircmaxell/password-compat",
@ -1652,16 +1650,16 @@
},
{
"name": "laravel/framework",
"version": "v5.0.27",
"version": "v5.0.28",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "4d6330118a295086ce9ff8eed2200d5b67f17688"
"reference": "06a09429322cf53e5bd4587db1060f02a291562e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/4d6330118a295086ce9ff8eed2200d5b67f17688",
"reference": "4d6330118a295086ce9ff8eed2200d5b67f17688",
"url": "https://api.github.com/repos/laravel/framework/zipball/06a09429322cf53e5bd4587db1060f02a291562e",
"reference": "06a09429322cf53e5bd4587db1060f02a291562e",
"shasum": ""
},
"require": {
@ -1731,7 +1729,7 @@
"predis/predis": "~1.0"
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver (~2.4).",
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~2.4).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.0).",
"iron-io/iron_mq": "Required to use the iron queue driver (~1.5).",
@ -1774,7 +1772,7 @@
"framework",
"laravel"
],
"time": "2015-04-04 01:34:57"
"time": "2015-04-21 01:44:32"
},
{
"name": "league/flysystem",
@ -1966,16 +1964,16 @@
},
{
"name": "mfauveau/omnipay-pacnet",
"version": "2.0.0",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/mfauveau/omnipay-pacnet.git",
"reference": "84201b2d216c8327f1cba379e123abb5e09b0f74"
"reference": "58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mfauveau/omnipay-pacnet/zipball/84201b2d216c8327f1cba379e123abb5e09b0f74",
"reference": "84201b2d216c8327f1cba379e123abb5e09b0f74",
"url": "https://api.github.com/repos/mfauveau/omnipay-pacnet/zipball/58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd",
"reference": "58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd",
"shasum": ""
},
"require": {
@ -2017,7 +2015,7 @@
"purchase",
"raven"
],
"time": "2014-08-19 18:50:39"
"time": "2015-04-17 01:14:08"
},
{
"name": "monolog/monolog",
@ -2346,6 +2344,64 @@
],
"time": "2015-01-19 19:06:04"
},
{
"name": "omnipay/bitpay",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-bitpay.git",
"reference": "e659f0e993c586cb36acafaf50835570b4a16eb2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-bitpay/zipball/e659f0e993c586cb36acafaf50835570b4a16eb2",
"reference": "e659f0e993c586cb36acafaf50835570b4a16eb2",
"shasum": ""
},
"require": {
"omnipay/common": "~2.0"
},
"require-dev": {
"omnipay/tests": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Omnipay\\BitPay\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Adrian Macneil",
"email": "adrian@adrianmacneil.com"
},
{
"name": "Omnipay Contributors",
"homepage": "https://github.com/thephpleague/omnipay-bitpay/contributors"
}
],
"description": "BitPay driver for the Omnipay payment processing library",
"homepage": "https://github.com/thephpleague/omnipay-bitpay",
"keywords": [
"bitcoin",
"bitpay",
"gateway",
"merchant",
"omnipay",
"pay",
"payment"
],
"time": "2015-03-23 14:18:26"
},
{
"name": "omnipay/buckaroo",
"version": "v2.0.1",
@ -2981,16 +3037,16 @@
},
{
"name": "omnipay/mollie",
"version": "3.0.3",
"version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-mollie.git",
"reference": "ea3830b0aaa845430387e5afc1f638be18a152ec"
"reference": "a89cb0d15447023b24c03f86873c1c1489cd021b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-mollie/zipball/ea3830b0aaa845430387e5afc1f638be18a152ec",
"reference": "ea3830b0aaa845430387e5afc1f638be18a152ec",
"url": "https://api.github.com/repos/thephpleague/omnipay-mollie/zipball/a89cb0d15447023b24c03f86873c1c1489cd021b",
"reference": "a89cb0d15447023b24c03f86873c1c1489cd021b",
"shasum": ""
},
"require": {
@ -3034,7 +3090,7 @@
"pay",
"payment"
],
"time": "2014-10-15 14:25:03"
"time": "2015-03-03 18:55:42"
},
{
"name": "omnipay/multisafepay",
@ -3436,16 +3492,16 @@
},
{
"name": "omnipay/paymentexpress",
"version": "v2.1.1",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-paymentexpress.git",
"reference": "a6309569a4a4372fe1c9cb464ff2ef57101df46d"
"reference": "bd417f02bacb2128c168956739cd3a902d3ee48c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-paymentexpress/zipball/a6309569a4a4372fe1c9cb464ff2ef57101df46d",
"reference": "a6309569a4a4372fe1c9cb464ff2ef57101df46d",
"url": "https://api.github.com/repos/thephpleague/omnipay-paymentexpress/zipball/bd417f02bacb2128c168956739cd3a902d3ee48c",
"reference": "bd417f02bacb2128c168956739cd3a902d3ee48c",
"shasum": ""
},
"require": {
@ -3495,7 +3551,7 @@
"pxpay",
"pxpost"
],
"time": "2014-09-17 00:37:09"
"time": "2015-04-03 00:20:28"
},
{
"name": "omnipay/paypal",
@ -3730,16 +3786,16 @@
},
{
"name": "omnipay/stripe",
"version": "v2.2.0",
"version": "v2.2.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-stripe.git",
"reference": "b3ed1028bb72837905012311fa74259d9ed8ba3c"
"reference": "906377e50045dc2ba9c612aa1f6924157e1f750e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/b3ed1028bb72837905012311fa74259d9ed8ba3c",
"reference": "b3ed1028bb72837905012311fa74259d9ed8ba3c",
"url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/906377e50045dc2ba9c612aa1f6924157e1f750e",
"reference": "906377e50045dc2ba9c612aa1f6924157e1f750e",
"shasum": ""
},
"require": {
@ -3783,7 +3839,7 @@
"payment",
"stripe"
],
"time": "2015-03-16 19:24:07"
"time": "2015-04-14 18:55:56"
},
{
"name": "omnipay/targetpay",
@ -5177,23 +5233,23 @@
},
{
"name": "phpspec/phpspec",
"version": "2.1.1",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/phpspec.git",
"reference": "66a1df93099282b1514e9e001fcf6e9393f7783d"
"reference": "9727d75919a00455433e867565bc022f0b985a39"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/66a1df93099282b1514e9e001fcf6e9393f7783d",
"reference": "66a1df93099282b1514e9e001fcf6e9393f7783d",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/9727d75919a00455433e867565bc022f0b985a39",
"reference": "9727d75919a00455433e867565bc022f0b985a39",
"shasum": ""
},
"require": {
"doctrine/instantiator": "~1.0,>=1.0.1",
"doctrine/instantiator": "^1.0.1",
"php": ">=5.3.3",
"phpspec/php-diff": "~1.0.0",
"phpspec/prophecy": "~1.1",
"phpspec/prophecy": "~1.4",
"sebastian/exporter": "~1.0",
"symfony/console": "~2.3",
"symfony/event-dispatcher": "~2.1",
@ -5202,9 +5258,11 @@
"symfony/yaml": "~2.1"
},
"require-dev": {
"behat/behat": "~3.0,>=3.0.11",
"behat/behat": "^3.0.11",
"bossa/phpspec2-expect": "~1.0",
"symfony/filesystem": "~2.1"
"phpunit/phpunit": "~4.4",
"symfony/filesystem": "~2.1",
"symfony/process": "~2.1"
},
"suggest": {
"phpspec/nyan-formatters": "~1.0 Adds Nyan formatters"
@ -5215,7 +5273,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
"dev-master": "2.2.x-dev"
}
},
"autoload": {
@ -5249,7 +5307,7 @@
"testing",
"tests"
],
"time": "2015-01-09 13:21:45"
"time": "2015-04-18 16:22:51"
},
{
"name": "phpspec/prophecy",
@ -5313,16 +5371,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.15",
"version": "2.0.16",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
"reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c",
"reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c",
"shasum": ""
},
"require": {
@ -5371,7 +5429,7 @@
"testing",
"xunit"
],
"time": "2015-01-24 10:06:35"
"time": "2015-04-11 04:35:00"
},
{
"name": "phpunit/php-file-iterator",
@ -5510,16 +5568,16 @@
},
{
"name": "phpunit/php-token-stream",
"version": "1.4.0",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
"reference": "eab81d02569310739373308137284e0158424330"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330",
"reference": "eab81d02569310739373308137284e0158424330",
"shasum": ""
},
"require": {
@ -5555,20 +5613,20 @@
"keywords": [
"tokenizer"
],
"time": "2015-01-17 09:51:32"
"time": "2015-04-08 04:46:07"
},
{
"name": "phpunit/phpunit",
"version": "4.6.1",
"version": "4.6.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "08b2aacdd8433abbba468f995d6d64b76a7a62ec"
"reference": "163232991e652e6efed2f8470326fffa61e848e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/08b2aacdd8433abbba468f995d6d64b76a7a62ec",
"reference": "08b2aacdd8433abbba468f995d6d64b76a7a62ec",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/163232991e652e6efed2f8470326fffa61e848e2",
"reference": "163232991e652e6efed2f8470326fffa61e848e2",
"shasum": ""
},
"require": {
@ -5607,9 +5665,6 @@
"autoload": {
"classmap": [
"src/"
],
"files": [
"src/Framework/Assert/Functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@ -5630,7 +5685,7 @@
"testing",
"xunit"
],
"time": "2015-04-03 13:46:59"
"time": "2015-04-11 05:23:21"
},
{
"name": "phpunit/phpunit-mock-objects",
@ -6118,7 +6173,8 @@
"webpatser/laravel-countries": 20,
"lokielse/omnipay-alipay": 20,
"alfaproject/omnipay-neteller": 20,
"alfaproject/omnipay-skrill": 20
"alfaproject/omnipay-skrill": 20,
"omnipay/bitpay": 20
},
"prefer-stable": false,
"prefer-lowest": false,

View File

@ -95,7 +95,7 @@ return [
|
*/
'log' => 'daily',
'log' => 'single',
/*
|--------------------------------------------------------------------------

View File

@ -51,7 +51,8 @@ return [
'driver' => 'memcached',
'servers' => [
[
'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100
'host' => env('CACHE_HOST', '127.0.0.1'), 'port' => env('CACHE_PORT1', 11211), 'weight' => 100,
'host' => env('CACHE_HOST', '127.0.0.1'), 'port' => env('CACHE_PORT2', 11211), 'weight' => 100
],
],
],

View File

@ -29,7 +29,7 @@ return [
|
*/
'lifetime' => 120,
'lifetime' => 360,
'expire_on_close' => false,
@ -44,7 +44,7 @@ return [
|
*/
'encrypt' => false,
'encrypt' => env('SESSION_ENCRYPT', false),
/*
|--------------------------------------------------------------------------
@ -109,7 +109,7 @@ return [
|
*/
'cookie' => 'laravel_session',
'cookie' => 'ninja_session',
/*
|--------------------------------------------------------------------------
@ -135,7 +135,7 @@ return [
|
*/
'domain' => null,
'domain' => env('SESSION_DOMAIN', null),
/*
|--------------------------------------------------------------------------
@ -148,6 +148,6 @@ return [
|
*/
'secure' => false,
'secure' => env('SESSION_SECURE', false),
];

View File

@ -17,7 +17,7 @@ class AddCompanyVatNumber extends Migration {
$table->string('vat_number')->nullable();
});
Schema::table('clients', function($table)
Schema::table('clients', function($table)
{
$table->string('vat_number')->nullable();
});
@ -34,7 +34,8 @@ class AddCompanyVatNumber extends Migration {
{
$table->dropColumn('vat_number');
});
Schema::table('clients', function($table)
Schema::table('clients', function($table)
{
$table->dropColumn('vat_number');
});

View File

@ -12,7 +12,10 @@ class AddSvLanguage extends Migration {
*/
public function up()
{
DB::table('languages')->insert(['name' => 'Swedish', 'locale' => 'sv']);
DB::table('languages')->insert(['name' => 'Swedish', 'locale' => 'sv']);
DB::table('languages')->insert(['name' => 'Spanish - Spain', 'locale' => 'es_ES']);
DB::table('languages')->insert(['name' => 'French - Canada', 'locale' => 'fr_CA']);
DB::table('languages')->insert(['name' => 'Lithuanian', 'locale' => 'lt']);
}
/**
@ -22,8 +25,21 @@ class AddSvLanguage extends Migration {
*/
public function down()
{
$language = \App\Models\Language::whereLocale('sv')->first();
$language->delete();
if ($language = \App\Models\Language::whereLocale('sv')->first()) {
$language->delete();
}
if ($language = \App\Models\Language::whereLocale('es_ES')->first()) {
$language->delete();
}
if ($language = \App\Models\Language::whereLocale('fr_CA')->first()) {
$language->delete();
}
if ($language = \App\Models\Language::whereLocale('lt')->first()) {
$language->delete();
}
}
}

View File

@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddPartialAmountToInvoices extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->decimal('partial', 13, 2)->nullable();
});
Schema::table('accounts', function($table)
{
$table->boolean('utf8_invoices')->default(false);
$table->boolean('auto_wrap')->default(false);
$table->string('subdomain')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropColumn('partial');
});
Schema::table('accounts', function($table)
{
$table->dropColumn('utf8_invoices');
$table->dropColumn('auto_wrap');
$table->dropColumn('subdomain');
});
}
}

View File

@ -103,14 +103,14 @@ class ConstantsSeeder extends Seeder
Size::create(array('name' => '101 - 500'));
Size::create(array('name' => '500+'));
PaymentTerm::create(array('num_days' => 7, 'name' => 'Net 7'));
PaymentTerm::create(array('num_days' => 7, 'name' => 'Net 7'));
PaymentTerm::create(array('num_days' => 10, 'name' => 'Net 10'));
PaymentTerm::create(array('num_days' => 14, 'name' => 'Net 14'));
PaymentTerm::create(array('num_days' => 15, 'name' => 'Net 15'));
PaymentTerm::create(array('num_days' => 30, 'name' => 'Net 30'));
PaymentTerm::create(array('num_days' => 60, 'name' => 'Net 60'));
PaymentTerm::create(array('num_days' => 90, 'name' => 'Net 90'));
Currency::create(array('name' => 'US Dollar', 'code' => 'USD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
Currency::create(array('name' => 'Pound Sterling', 'code' => 'GBP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
Currency::create(array('name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));

View File

@ -1,6 +1,7 @@
<?php
use App\Models\Gateway;
use App\Models\PaymentTerm;
class PaymentLibrariesSeeder extends Seeder
{
@ -22,7 +23,8 @@ class PaymentLibrariesSeeder extends Seeder
['name' => 'PaymentSense', 'provider' => 'PaymentSense', 'payment_library_id' => 1],
['name' => 'Realex', 'provider' => 'Realex_Remote', 'payment_library_id' => 1],
['name' => 'Sisow', 'provider' => 'Sisow', 'payment_library_id' => 1],
['name' => 'Skrill', 'provider' => 'Skrill', 'payment_library_id' => 1]
['name' => 'Skrill', 'provider' => 'Skrill', 'payment_library_id' => 1],
['name' => 'BitPay', 'provider' => 'BitPay', 'payment_library_id' => 1],
];
foreach ($gateways as $gateway)
@ -33,5 +35,16 @@ class PaymentLibrariesSeeder extends Seeder
}
}
$paymentTerms = [
['num_days' => -1, 'name' => 'Net 0']
];
foreach ($paymentTerms as $paymentTerm)
{
if (!DB::table('payment_terms')->where('name', '=', $paymentTerm['name'])->get())
{
PaymentTerm::create($paymentTerm);
}
}
}
}

View File

@ -3,11 +3,13 @@
"devDependencies": {
"gulp": "^3.8.8",
"laravel-elixir": "*",
"grunt": "~0.4.0",
"grunt": "~0.4.4",
"grunt-contrib-jshint": "~0.6.3",
"grunt-contrib-nodeunit": "~0.2.0",
"grunt-contrib-uglify": "~0.2.2",
"grunt-contrib-concat": "~0.4.0"
"grunt-contrib-concat": "~0.4.0"
},
"dependencies": {
"grunt-dump-dir": "^0.1.2"
}
}

661
public/css/built.css vendored
View File

@ -721,8 +721,6 @@ div.DTFC_LeftFootWrapper table {
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
}
@ -754,7 +752,7 @@ div.DTFC_LeftFootWrapper table {
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
border-bottom: 6px solid #fff;
border-top: 0;
position: absolute;
}
@ -784,7 +782,7 @@ div.DTFC_LeftFootWrapper table {
.datepicker-dropdown.datepicker-orient-bottom:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #ffffff;
border-top: 6px solid #fff;
}
.datepicker > div {
display: none;
@ -807,13 +805,11 @@ div.DTFC_LeftFootWrapper table {
-ms-user-select: none;
user-select: none;
}
.datepicker td,
.datepicker th {
.datepicker table tr td,
.datepicker table tr th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
width: 30px;
height: 30px;
border-radius: 4px;
border: none;
}
@ -840,24 +836,18 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
color: #000000;
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:focus,
.datepicker table tr td.today:hover:focus,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
@ -866,15 +856,13 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
color: #000000;
background-color: #ffcd70;
border-color: #f59e00;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
@ -883,8 +871,75 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
.datepicker table tr td.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.today,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today.disabled,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today:hover.disabled:hover,
.datepicker table tr td.today.disabled.disabled:hover,
.datepicker table tr td.today.disabled:hover.disabled:hover,
.datepicker table tr td.today[disabled]:hover,
.datepicker table tr td.today:hover[disabled]:hover,
.datepicker table tr td.today.disabled[disabled]:hover,
.datepicker table tr td.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today:hover:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today:hover.disabled:focus,
.datepicker table tr td.today.disabled.disabled:focus,
.datepicker table tr td.today.disabled:hover.disabled:focus,
.datepicker table tr td.today[disabled]:focus,
.datepicker table tr td.today:hover[disabled]:focus,
.datepicker table tr td.today.disabled[disabled]:focus,
.datepicker table tr td.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.today:focus,
fieldset[disabled] .datepicker table tr td.today:hover:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today:hover.disabled:active,
.datepicker table tr td.today.disabled.disabled:active,
.datepicker table tr td.today.disabled:hover.disabled:active,
.datepicker table tr td.today[disabled]:active,
.datepicker table tr td.today:hover[disabled]:active,
.datepicker table tr td.today.disabled[disabled]:active,
.datepicker table tr td.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.today:active,
fieldset[disabled] .datepicker table tr td.today:hover:active,
fieldset[disabled] .datepicker table tr td.today.disabled:active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today:hover.disabled.active,
.datepicker table tr td.today.disabled.disabled.active,
.datepicker table tr td.today.disabled:hover.disabled.active,
.datepicker table tr td.today[disabled].active,
.datepicker table tr td.today:hover[disabled].active,
.datepicker table tr td.today.disabled[disabled].active,
.datepicker table tr td.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.today.active,
fieldset[disabled] .datepicker table tr td.today:hover.active,
fieldset[disabled] .datepicker table tr td.today.disabled.active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover.active {
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover:hover {
color: #000;
@ -897,34 +952,25 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
color: #000000;
background-color: #f7ca77;
border-color: #f1a417;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:focus,
.datepicker table tr td.range.today:hover:focus,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
@ -933,15 +979,13 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled] {
background-color: #f3e97a;
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
color: #000000;
background-color: #f4bb51;
border-color: #bf800c;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
@ -950,32 +994,93 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active {
background-color: #efe24b \9;
.datepicker table tr td.range.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.range.today,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today:hover.disabled:hover,
.datepicker table tr td.range.today.disabled.disabled:hover,
.datepicker table tr td.range.today.disabled:hover.disabled:hover,
.datepicker table tr td.range.today[disabled]:hover,
.datepicker table tr td.range.today:hover[disabled]:hover,
.datepicker table tr td.range.today.disabled[disabled]:hover,
.datepicker table tr td.range.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today:hover.disabled:focus,
.datepicker table tr td.range.today.disabled.disabled:focus,
.datepicker table tr td.range.today.disabled:hover.disabled:focus,
.datepicker table tr td.range.today[disabled]:focus,
.datepicker table tr td.range.today:hover[disabled]:focus,
.datepicker table tr td.range.today.disabled[disabled]:focus,
.datepicker table tr td.range.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.range.today:focus,
fieldset[disabled] .datepicker table tr td.range.today:hover:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today:hover.disabled:active,
.datepicker table tr td.range.today.disabled.disabled:active,
.datepicker table tr td.range.today.disabled:hover.disabled:active,
.datepicker table tr td.range.today[disabled]:active,
.datepicker table tr td.range.today:hover[disabled]:active,
.datepicker table tr td.range.today.disabled[disabled]:active,
.datepicker table tr td.range.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.range.today:active,
fieldset[disabled] .datepicker table tr td.range.today:hover:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today:hover.disabled.active,
.datepicker table tr td.range.today.disabled.disabled.active,
.datepicker table tr td.range.today.disabled:hover.disabled.active,
.datepicker table tr td.range.today[disabled].active,
.datepicker table tr td.range.today:hover[disabled].active,
.datepicker table tr td.range.today.disabled[disabled].active,
.datepicker table tr td.range.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.range.today.active,
fieldset[disabled] .datepicker table tr td.range.today:hover.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {
background-color: #f7ca77;
border-color: #f1a417;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
background-image: linear-gradient(top, #b3b3b3, #808080);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: #808080 #808080 #595959;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
color: #ffffff;
background-color: #999999;
border-color: #555555;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:focus,
.datepicker table tr td.selected:hover:focus,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
@ -984,15 +1089,13 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled] {
background-color: #808080;
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
color: #ffffff;
background-color: #858585;
border-color: #373737;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
@ -1001,32 +1104,93 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active {
background-color: #666666 \9;
.datepicker table tr td.selected.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
background-image: none;
}
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.selected,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected:hover.disabled:hover,
.datepicker table tr td.selected.disabled.disabled:hover,
.datepicker table tr td.selected.disabled:hover.disabled:hover,
.datepicker table tr td.selected[disabled]:hover,
.datepicker table tr td.selected:hover[disabled]:hover,
.datepicker table tr td.selected.disabled[disabled]:hover,
.datepicker table tr td.selected.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected:hover:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected:hover.disabled:focus,
.datepicker table tr td.selected.disabled.disabled:focus,
.datepicker table tr td.selected.disabled:hover.disabled:focus,
.datepicker table tr td.selected[disabled]:focus,
.datepicker table tr td.selected:hover[disabled]:focus,
.datepicker table tr td.selected.disabled[disabled]:focus,
.datepicker table tr td.selected.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.selected:focus,
fieldset[disabled] .datepicker table tr td.selected:hover:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected:hover.disabled:active,
.datepicker table tr td.selected.disabled.disabled:active,
.datepicker table tr td.selected.disabled:hover.disabled:active,
.datepicker table tr td.selected[disabled]:active,
.datepicker table tr td.selected:hover[disabled]:active,
.datepicker table tr td.selected.disabled[disabled]:active,
.datepicker table tr td.selected.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.selected:active,
fieldset[disabled] .datepicker table tr td.selected:hover:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected:hover.disabled.active,
.datepicker table tr td.selected.disabled.disabled.active,
.datepicker table tr td.selected.disabled:hover.disabled.active,
.datepicker table tr td.selected[disabled].active,
.datepicker table tr td.selected:hover[disabled].active,
.datepicker table tr td.selected.disabled[disabled].active,
.datepicker table tr td.selected.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.selected.active,
fieldset[disabled] .datepicker table tr td.selected:hover.active,
fieldset[disabled] .datepicker table tr td.selected.disabled.active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {
background-color: #999999;
border-color: #555555;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:focus,
.datepicker table tr td.active:hover:focus,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
@ -1035,15 +1199,13 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
@ -1052,8 +1214,75 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
.datepicker table tr td.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
background-image: none;
}
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.active,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active.disabled,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active:hover.disabled:hover,
.datepicker table tr td.active.disabled.disabled:hover,
.datepicker table tr td.active.disabled:hover.disabled:hover,
.datepicker table tr td.active[disabled]:hover,
.datepicker table tr td.active:hover[disabled]:hover,
.datepicker table tr td.active.disabled[disabled]:hover,
.datepicker table tr td.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active:hover:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active:hover.disabled:focus,
.datepicker table tr td.active.disabled.disabled:focus,
.datepicker table tr td.active.disabled:hover.disabled:focus,
.datepicker table tr td.active[disabled]:focus,
.datepicker table tr td.active:hover[disabled]:focus,
.datepicker table tr td.active.disabled[disabled]:focus,
.datepicker table tr td.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.active:focus,
fieldset[disabled] .datepicker table tr td.active:hover:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active:hover.disabled:active,
.datepicker table tr td.active.disabled.disabled:active,
.datepicker table tr td.active.disabled:hover.disabled:active,
.datepicker table tr td.active[disabled]:active,
.datepicker table tr td.active:hover[disabled]:active,
.datepicker table tr td.active.disabled[disabled]:active,
.datepicker table tr td.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.active:active,
fieldset[disabled] .datepicker table tr td.active:hover:active,
fieldset[disabled] .datepicker table tr td.active.disabled:active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active:hover.disabled.active,
.datepicker table tr td.active.disabled.disabled.active,
.datepicker table tr td.active.disabled:hover.disabled.active,
.datepicker table tr td.active[disabled].active,
.datepicker table tr td.active:hover[disabled].active,
.datepicker table tr td.active.disabled[disabled].active,
.datepicker table tr td.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.active.active,
fieldset[disabled] .datepicker table tr td.active:hover.active,
fieldset[disabled] .datepicker table tr td.active.disabled.active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span {
display: block;
@ -1063,8 +1292,6 @@ div.DTFC_LeftFootWrapper table {
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
@ -1080,25 +1307,19 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:focus,
.datepicker table tr td span.active:hover:focus,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
@ -1107,15 +1328,13 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
@ -1124,8 +1343,75 @@ div.DTFC_LeftFootWrapper table {
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
.datepicker table tr td span.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
background-image: none;
}
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td span.active,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active:hover.disabled:hover,
.datepicker table tr td span.active.disabled.disabled:hover,
.datepicker table tr td span.active.disabled:hover.disabled:hover,
.datepicker table tr td span.active[disabled]:hover,
.datepicker table tr td span.active:hover[disabled]:hover,
.datepicker table tr td span.active.disabled[disabled]:hover,
.datepicker table tr td span.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active:hover:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active:hover.disabled:focus,
.datepicker table tr td span.active.disabled.disabled:focus,
.datepicker table tr td span.active.disabled:hover.disabled:focus,
.datepicker table tr td span.active[disabled]:focus,
.datepicker table tr td span.active:hover[disabled]:focus,
.datepicker table tr td span.active.disabled[disabled]:focus,
.datepicker table tr td span.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td span.active:focus,
fieldset[disabled] .datepicker table tr td span.active:hover:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active:hover.disabled:active,
.datepicker table tr td span.active.disabled.disabled:active,
.datepicker table tr td span.active.disabled:hover.disabled:active,
.datepicker table tr td span.active[disabled]:active,
.datepicker table tr td span.active:hover[disabled]:active,
.datepicker table tr td span.active.disabled[disabled]:active,
.datepicker table tr td span.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td span.active:active,
fieldset[disabled] .datepicker table tr td span.active:hover:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active:hover.disabled.active,
.datepicker table tr td span.active.disabled.disabled.active,
.datepicker table tr td span.active.disabled:hover.disabled.active,
.datepicker table tr td span.active[disabled].active,
.datepicker table tr td span.active:hover[disabled].active,
.datepicker table tr td span.active.disabled[disabled].active,
.datepicker table tr td span.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td span.active.active,
fieldset[disabled] .datepicker table tr td span.active:hover.active,
fieldset[disabled] .datepicker table tr td span.active.disabled.active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
@ -1152,38 +1438,30 @@ div.DTFC_LeftFootWrapper table {
cursor: default;
background-color: transparent;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i {
.input-group.date .input-group-addon i {
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.input-daterange .add-on {
display: inline-block;
.input-daterange .input-group-addon {
width: auto;
min-width: 16px;
height: 20px;
padding: 4px 5px;
font-weight: normal;
line-height: 20px;
line-height: 1.42857143;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
text-shadow: 0 1px 0 #fff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
border: solid #cccccc;
border-width: 1px 0;
margin-left: -5px;
margin-right: -5px;
}
@ -1199,8 +1477,6 @@ div.DTFC_LeftFootWrapper table {
background-color: #ffffff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
@ -1212,13 +1488,13 @@ div.DTFC_LeftFootWrapper table {
*border-bottom-width: 2px;
color: #333333;
font-size: 13px;
line-height: 20px;
line-height: 1.42857143;
}
.datepicker.dropdown-menu th,
.datepicker.datepicker-inline th,
.datepicker.dropdown-menu td,
.datepicker.datepicker-inline td {
padding: 4px 5px;
padding: 0px 5px;
}
/***
@ -2108,10 +2384,11 @@ body:after {
body { background: #f8f8f8 !important;
font-family: 'Roboto', sans-serif;
font-size: 15px;
}
.bold { font-weight: 700; }
a {color:#0b4d78;}
a:hover { text-decoration: none; color: #0a3857;}
/*a:hover { text-decoration: none; color: #0a3857;}*/
.breadcrumb {
padding: 8px 0!important;
}
@ -2144,10 +2421,10 @@ display: block;
width: 100%;
height: 40px;
padding: 9px 12px;
font-size: 14px;
font-size: 16px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
color: #000 !important;
background: #f9f9f9 !important;
background-image: none;
border: 1px solid #dfe0e1;
border-radius: 2px;
@ -2900,6 +3177,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; }
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
margin-left: 0;
padding-left: 0px !important;
margin-right: 5px;
height: inherit;
width: inherit;
@ -2908,3 +3186,72 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; }
position: relative;
margin-top: 3px;
}
div.checkbox > label {
padding-left: 0px !important;
}
.container input[type=text],
.container input[type=email],
.container textarea,
.container select {
font-size: 16px;
font-weight: 400;
width: 100%;
color: #000 !important;
background: #f9f9f9 !important;
/*border: 1px solid #ebe7e7;*/
border-radius: 3px;
}
.container input[placeholder],
.container textarea[placeholder],
.container select[placeholder] {
color: #444444;
}
.container input:disabled,
.container textarea:disabled,
.container select:disabled {
background-color: #EEE !important;
}
.panel-title {
font-size: 18px;
color: white;
}
.panel-heading {
/*background-color: #e37329 !important;*/
background-color: #0b4d78 !important;
}
/*
.panel-default {
border-color: #e37329 !important;
}
*/
.alert-hide {
position: absolute;
margin-left: 25%;
z-index: 9999;
}
div.dataTables_length {
padding-left: 20px;
padding-top: 10px;
}
div.dataTables_length select {
background-color: white !important;
}
div.dataTables_length label {
font-weight: 500;
}
a .glyphicon,
button .glyphicon {
padding-left: 8px;
}

File diff suppressed because one or more lines are too long

79
public/css/style.css vendored
View File

@ -1,9 +1,10 @@
body { background: #f8f8f8 !important;
font-family: 'Roboto', sans-serif;
font-size: 15px;
}
.bold { font-weight: 700; }
a {color:#0b4d78;}
a:hover { text-decoration: none; color: #0a3857;}
/*a:hover { text-decoration: none; color: #0a3857;}*/
.breadcrumb {
padding: 8px 0!important;
}
@ -36,10 +37,10 @@ display: block;
width: 100%;
height: 40px;
padding: 9px 12px;
font-size: 14px;
font-size: 16px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
color: #000 !important;
background: #f9f9f9 !important;
background-image: none;
border: 1px solid #dfe0e1;
border-radius: 2px;
@ -792,6 +793,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; }
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
margin-left: 0;
padding-left: 0px !important;
margin-right: 5px;
height: inherit;
width: inherit;
@ -800,3 +802,72 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; }
position: relative;
margin-top: 3px;
}
div.checkbox > label {
padding-left: 0px !important;
}
.container input[type=text],
.container input[type=email],
.container textarea,
.container select {
font-size: 16px;
font-weight: 400;
width: 100%;
color: #000 !important;
background: #f9f9f9 !important;
/*border: 1px solid #ebe7e7;*/
border-radius: 3px;
}
.container input[placeholder],
.container textarea[placeholder],
.container select[placeholder] {
color: #444444;
}
.container input:disabled,
.container textarea:disabled,
.container select:disabled {
background-color: #EEE !important;
}
.panel-title {
font-size: 18px;
color: white;
}
.panel-heading {
/*background-color: #e37329 !important;*/
background-color: #0b4d78 !important;
}
/*
.panel-default {
border-color: #e37329 !important;
}
*/
.alert-hide {
position: absolute;
margin-left: 25%;
z-index: 9999;
}
div.dataTables_length {
padding-left: 20px;
padding-top: 10px;
}
div.dataTables_length select {
background-color: white !important;
}
div.dataTables_length label {
font-weight: 500;
}
a .glyphicon,
button .glyphicon {
padding-left: 8px;
}

View File

@ -1,5 +1,5 @@
/*!
* jQuery JavaScript Library v1.11.2
* jQuery JavaScript Library v1.11.3
* http://jquery.com/
*
* Includes Sizzle.js
@ -9,7 +9,7 @@
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-12-17T15:27Z
* Date: 2015-04-28T16:19Z
*/
(function( global, factory ) {
@ -64,7 +64,7 @@ var support = {};
var
version = "1.11.2",
version = "1.11.3",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
@ -569,7 +569,12 @@ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".spli
});
function isArraylike( obj ) {
var length = obj.length,
// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = "length" in obj && obj.length,
type = jQuery.type( obj );
if ( type === "function" || jQuery.isWindow( obj ) ) {
@ -31531,16 +31536,25 @@ var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var invoiceOld;
function generatePDF(invoice, javascript, force) {
function generatePDF(invoice, javascript, force, cb) {
invoice = calculateAmounts(invoice);
var a = copyInvoice(invoice);
var b = copyInvoice(invoiceOld);
if (!force && _.isEqual(a, b)) {
return;
}
pdfmakeMarker = "//pdfmake";
invoiceOld = invoice;
report_id = invoice.invoice_design_id;
doc = GetPdf(invoice, javascript);
if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) {
doc = GetPdfMake(invoice, javascript, cb);
//doc.getDataUrl(cb);
} else {
doc = GetPdf(invoice, javascript);
doc.getDataUrl = function(cb) {
cb( this.output("datauristring"));
};
}
return doc;
}
@ -31601,6 +31615,12 @@ function GetPdf(invoice, javascript){
//set default style for report
doc.setFont('Helvetica','');
// For partial payments show "Amount Due" rather than "Balance Due"
if (!invoiceLabels.balance_due_orig) {
invoiceLabels.balance_due_orig = invoiceLabels.balance_due;
}
invoiceLabels.balance_due = NINJA.parseFloat(invoice.partial) ? invoiceLabels.amount_due : invoiceLabels.balance_due_orig;
eval(javascript);
// add footer
@ -31610,8 +31630,9 @@ function GetPdf(invoice, javascript){
SetPdfColor(invoice.invoice_design_id == 2 || invoice.invoice_design_id == 3 ? 'White' : 'Black',doc);
var top = doc.internal.pageSize.height - layout.marginLeft;
if (!invoice.is_pro) top -= 25;
var numLines = invoice.invoice_footer.split("\n").length - 1;
doc.text(layout.marginLeft, top - (numLines * 8), invoice.invoice_footer);
var footer = doc.splitTextToSize(invoice.invoice_footer, 500);
var numLines = footer.length - 1;
doc.text(layout.marginLeft, top - (numLines * 8), footer);
}
return doc;
@ -31898,7 +31919,7 @@ function isValidEmailAddress(emailAddress) {
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});
@ -32011,34 +32032,6 @@ if (window.ko) {
};
}
function wordWrapText(value, width)
{
var doc = new jsPDF('p', 'pt');
doc.setFont('Helvetica','');
doc.setFontSize(10);
var lines = value.split("\n");
for (var i = 0; i < lines.length; i++) {
var numLines = doc.splitTextToSize(lines[i], width).length;
if (numLines <= 1) continue;
var j = 0; space = lines[i].length;
while (j++ < lines[i].length) {
if (lines[i].charAt(j) === ' ') space = j;
}
if (space == lines[i].length) space = width/6;
lines[i + 1] = lines[i].substring(space + 1) + ' ' + (lines[i + 1] || '');
lines[i] = lines[i].substring(0, space);
}
var newValue = (lines.join("\n")).trim();
if (value == newValue) {
return newValue;
} else {
return wordWrapText(newValue, width);
}
}
function getClientDisplayName(client)
{
var contact = client.contacts ? client.contacts[0] : false;
@ -32233,13 +32226,20 @@ function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
}
function getInvoiceDetails(invoice) {
return [
var fields = [
{'invoice_number': invoice.invoice_number},
{'po_number': invoice.po_number},
{'invoice_date': invoice.invoice_date},
{'due_date': invoice.due_date},
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)},
];
if (NINJA.parseFloat(invoice.partial)) {
fields.push({'total': formatMoney(invoice.total_amount, invoice.client.currency_id)});
}
fields.push({'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)})
return fields;
}
function getInvoiceDetailsHeight(invoice, layout) {
@ -32294,6 +32294,10 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)});
}
if (NINJA.parseFloat(invoice.partial) && invoice.total_amount != invoice.subtotal_amount) {
data.push({'total': formatMoney(invoice.total_amount, invoice.client.currency_id)});
}
var options = {
hasheader: true,
rightAlignX: 550,
@ -32320,7 +32324,7 @@ function concatStrings() {
concatStr += ' ';
}
}
return data.length ? concatStr : false;
return data.length ? concatStr : "";
}
function displayGrid(doc, invoice, data, x, y, layout, options) {
@ -32408,17 +32412,19 @@ function displayNotesAndTerms(doc, layout, invoice, y)
var origY = y;
if (invoice.public_notes) {
doc.text(layout.marginLeft, y, invoice.public_notes);
y += 16 + (doc.splitTextToSize(invoice.public_notes, 300).length * doc.internal.getFontSize());
var notes = doc.splitTextToSize(invoice.public_notes, 260);
doc.text(layout.marginLeft, y, notes);
y += 16 + (notes.length * doc.internal.getFontSize());
}
if (invoice.terms) {
doc.setFontType("bold");
var terms = doc.splitTextToSize(invoice.terms, 260);
doc.setFontType("bold");
doc.text(layout.marginLeft, y, invoiceLabels.terms);
y += 16;
doc.setFontType("normal");
doc.text(layout.marginLeft, y, invoice.terms);
y += 16 + (doc.splitTextToSize(invoice.terms, 300).length * doc.internal.getFontSize());
doc.text(layout.marginLeft, y, terms);
y += 16 + (terms.length * doc.internal.getFontSize());
}
return y - origY;
@ -32490,11 +32496,17 @@ function calculateAmounts(invoice) {
total += roundToTwo(invoice.custom_value2);
}
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.discount_amount = discount;
invoice.tax_amount = tax;
invoice.has_taxes = hasTaxes;
if (NINJA.parseFloat(invoice.partial)) {
invoice.balance_amount = roundToTwo(invoice.partial);
} else {
invoice.balance_amount = invoice.total_amount;
}
return invoice;
}
@ -32809,6 +32821,18 @@ function displayInvoiceItems(doc, invoice, layout) {
}
// http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables
window.alert = (function() {
var nativeAlert = window.alert;
return function(message) {
window.alert = nativeAlert;
message && message.indexOf("DataTables warning") === 0 ?
console.error(message) :
nativeAlert(message);
}
})();
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript
function objectEquals(x, y) {
// if both are function
@ -33043,4 +33067,221 @@ function roundToTwo(num, toString) {
function truncate(str, length) {
return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;
}
function GetPdfMake(invoice, javascript, callback) {
var account = invoice.account;
eval(javascript);
/*
var fonts = {
Roboto: {
normal: 'Roboto-Regular.ttf',
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf',
bolditalics: 'Roboto-Italic.ttf'
},
};
*/
doc = pdfMake.createPdf(dd);
doc.save = function(fileName) {
this.download(fileName);
};
return doc;
}
function notesAndTerms(invoice)
{
var text = [];
if (invoice.public_notes) {
text.push({text:invoice.public_notes, style:'notes'});
}
if (invoice.terms) {
text.push({text:invoiceLabels.terms, style:'termsLabel'});
text.push({text:invoice.terms, style:'terms'});
}
return text;
}
function invoiceLines(invoice) {
var grid =
[[{text: invoiceLabels.item, style: 'tableHeader'},
{text: invoiceLabels.description, style: 'tableHeader'},
{text: invoiceLabels.unit_cost, style: 'tableHeader'},
{text: invoiceLabels.quantity, style: 'tableHeader'},
{text: invoice.has_taxes?invoiceLabels.tax:'', style: 'tableHeader'},
{text: invoiceLabels.line_total, style: 'tableHeader'}]];
var total = 0;
var shownItem = false;
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var hideQuantity = invoice.account.hide_quantity == '1';
for (var i = 0; i < invoice.invoice_items.length; i++) {
var row = [];
var item = invoice.invoice_items[i];
var cost = formatMoney(item.cost, currencyId, true);
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
var notes = item.notes;
var productKey = item.product_key;
var tax = "";
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') && !notes && !productKey) {
continue;
}
shownItem = true;
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = i%2===0?'odd':'even';
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
grid.push(row);
}
return grid;
}
function subtotals(invoice)
{
if (!invoice) {
return;
}
var data = [
[invoiceLabels.subtotal, formatMoney(invoice.subtotal_amount, invoice.client.currency_id)],
];
if(invoice.discount_amount != 0) {
data.push([invoiceLabels.discount, formatMoney(invoice.discount_amount, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
}
if(invoice.tax && invoice.tax.name || invoice.tax_name) {
data.push([invoiceLabels.tax, formatMoney(invoice.tax_amount, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
}
var paid = invoice.amount - invoice.balance;
if (invoice.account.hide_paid_to_date != '1' || paid) {
data.push([invoiceLabels.paid_to_date, formatMoney(paid, invoice.client.currency_id)]);
}
data.push([{text:invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style:'balanceDueLabel'},
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:'balanceDueValue'}]);
return data;
}
function accountDetails(account) {
var data = [];
if(account.name) data.push({text:account.name, style:'accountName'});
if(account.id_number) data.push({text:account.id_number, style:'accountDetails'});
if(account.vat_number) data.push({text:account.vat_number, style:'accountDetails'});
if(account.work_email) data.push({text:account.work_email, style:'accountDetails'});
if(account.work_phone) data.push({text:account.work_phone, style:'accountDetails'});
return data;
}
function accountAddress(account) {
var address = '';
if (account.city || account.state || account.postal_code) {
address = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
}
var data = [];
if(account.address1) data.push({text:account.address1, style:'accountDetails'});
if(account.address2) data.push({text:account.address2, style:'accountDetails'});
if(address) data.push({text:address, style:'accountDetails'});
if(account.country) data.push({text:account.country.name, style: 'accountDetails'});
return data;
}
function invoiceDetails(invoice) {
var data = [
[
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
{style: 'bold', text: invoice.invoice_number},
],
[
invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date,
invoice.invoice_date,
],
[
invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due,
formatMoney(invoice.balance_amount, invoice.client.currency_id),
],
];
return data;
}
function clientDetails(invoice) {
var client = invoice.client;
if (!client) {
return;
}
var fields = [
getClientDisplayName(client),
client.id_number,
client.vat_number,
concatStrings(client.address1, client.address2),
concatStrings(client.city, client.state, client.postal_code),
client.country ? client.country.name : false,
invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
];
var data = [];
for (var i=0; i<fields.length; i++) {
var field = fields[i];
if (!field) {
continue;
}
data.push(field);
}
return data;
}
function primaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.primaryColor:defaultColor;
}
function secondaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.secondaryColor:defaultColor;
}

File diff suppressed because one or more lines are too long

217
public/js/pdf.pdfmake.js Normal file
View File

@ -0,0 +1,217 @@
function GetPdfMake(invoice, javascript, callback) {
var account = invoice.account;
eval(javascript);
/*
var fonts = {
Roboto: {
normal: 'Roboto-Regular.ttf',
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf',
bolditalics: 'Roboto-Italic.ttf'
},
};
*/
doc = pdfMake.createPdf(dd);
doc.save = function(fileName) {
this.download(fileName);
};
return doc;
}
function notesAndTerms(invoice)
{
var text = [];
if (invoice.public_notes) {
text.push({text:invoice.public_notes, style:'notes'});
}
if (invoice.terms) {
text.push({text:invoiceLabels.terms, style:'termsLabel'});
text.push({text:invoice.terms, style:'terms'});
}
return text;
}
function invoiceLines(invoice) {
var grid =
[[{text: invoiceLabels.item, style: 'tableHeader'},
{text: invoiceLabels.description, style: 'tableHeader'},
{text: invoiceLabels.unit_cost, style: 'tableHeader'},
{text: invoiceLabels.quantity, style: 'tableHeader'},
{text: invoice.has_taxes?invoiceLabels.tax:'', style: 'tableHeader'},
{text: invoiceLabels.line_total, style: 'tableHeader'}]];
var total = 0;
var shownItem = false;
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var hideQuantity = invoice.account.hide_quantity == '1';
for (var i = 0; i < invoice.invoice_items.length; i++) {
var row = [];
var item = invoice.invoice_items[i];
var cost = formatMoney(item.cost, currencyId, true);
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
var notes = item.notes;
var productKey = item.product_key;
var tax = "";
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') && !notes && !productKey) {
continue;
}
shownItem = true;
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = i%2===0?'odd':'even';
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
grid.push(row);
}
return grid;
}
function subtotals(invoice)
{
if (!invoice) {
return;
}
var data = [
[invoiceLabels.subtotal, formatMoney(invoice.subtotal_amount, invoice.client.currency_id)],
];
if(invoice.discount_amount != 0) {
data.push([invoiceLabels.discount, formatMoney(invoice.discount_amount, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
}
if(invoice.tax && invoice.tax.name || invoice.tax_name) {
data.push([invoiceLabels.tax, formatMoney(invoice.tax_amount, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
}
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
}
var paid = invoice.amount - invoice.balance;
if (invoice.account.hide_paid_to_date != '1' || paid) {
data.push([invoiceLabels.paid_to_date, formatMoney(paid, invoice.client.currency_id)]);
}
data.push([{text:invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style:'balanceDueLabel'},
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:'balanceDueValue'}]);
return data;
}
function accountDetails(account) {
var data = [];
if(account.name) data.push({text:account.name, style:'accountName'});
if(account.id_number) data.push({text:account.id_number, style:'accountDetails'});
if(account.vat_number) data.push({text:account.vat_number, style:'accountDetails'});
if(account.work_email) data.push({text:account.work_email, style:'accountDetails'});
if(account.work_phone) data.push({text:account.work_phone, style:'accountDetails'});
return data;
}
function accountAddress(account) {
var address = '';
if (account.city || account.state || account.postal_code) {
address = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
}
var data = [];
if(account.address1) data.push({text:account.address1, style:'accountDetails'});
if(account.address2) data.push({text:account.address2, style:'accountDetails'});
if(address) data.push({text:address, style:'accountDetails'});
if(account.country) data.push({text:account.country.name, style: 'accountDetails'});
return data;
}
function invoiceDetails(invoice) {
var data = [
[
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
{style: 'bold', text: invoice.invoice_number},
],
[
invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date,
invoice.invoice_date,
],
[
invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due,
formatMoney(invoice.balance_amount, invoice.client.currency_id),
],
];
return data;
}
function clientDetails(invoice) {
var client = invoice.client;
if (!client) {
return;
}
var fields = [
getClientDisplayName(client),
client.id_number,
client.vat_number,
concatStrings(client.address1, client.address2),
concatStrings(client.city, client.state, client.postal_code),
client.country ? client.country.name : false,
invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
];
var data = [];
for (var i=0; i<fields.length; i++) {
var field = fields[i];
if (!field) {
continue;
}
data.push(field);
}
return data;
}
function primaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.primaryColor:defaultColor;
}
function secondaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.secondaryColor:defaultColor;
}

View File

@ -8,16 +8,25 @@ var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var invoiceOld;
function generatePDF(invoice, javascript, force) {
function generatePDF(invoice, javascript, force, cb) {
invoice = calculateAmounts(invoice);
var a = copyInvoice(invoice);
var b = copyInvoice(invoiceOld);
if (!force && _.isEqual(a, b)) {
return;
}
pdfmakeMarker = "//pdfmake";
invoiceOld = invoice;
report_id = invoice.invoice_design_id;
doc = GetPdf(invoice, javascript);
if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) {
doc = GetPdfMake(invoice, javascript, cb);
//doc.getDataUrl(cb);
} else {
doc = GetPdf(invoice, javascript);
doc.getDataUrl = function(cb) {
cb( this.output("datauristring"));
};
}
return doc;
}
@ -78,6 +87,12 @@ function GetPdf(invoice, javascript){
//set default style for report
doc.setFont('Helvetica','');
// For partial payments show "Amount Due" rather than "Balance Due"
if (!invoiceLabels.balance_due_orig) {
invoiceLabels.balance_due_orig = invoiceLabels.balance_due;
}
invoiceLabels.balance_due = NINJA.parseFloat(invoice.partial) ? invoiceLabels.amount_due : invoiceLabels.balance_due_orig;
eval(javascript);
// add footer
@ -87,8 +102,9 @@ function GetPdf(invoice, javascript){
SetPdfColor(invoice.invoice_design_id == 2 || invoice.invoice_design_id == 3 ? 'White' : 'Black',doc);
var top = doc.internal.pageSize.height - layout.marginLeft;
if (!invoice.is_pro) top -= 25;
var numLines = invoice.invoice_footer.split("\n").length - 1;
doc.text(layout.marginLeft, top - (numLines * 8), invoice.invoice_footer);
var footer = doc.splitTextToSize(invoice.invoice_footer, 500);
var numLines = footer.length - 1;
doc.text(layout.marginLeft, top - (numLines * 8), footer);
}
return doc;
@ -375,7 +391,7 @@ function isValidEmailAddress(emailAddress) {
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});
@ -488,34 +504,6 @@ if (window.ko) {
};
}
function wordWrapText(value, width)
{
var doc = new jsPDF('p', 'pt');
doc.setFont('Helvetica','');
doc.setFontSize(10);
var lines = value.split("\n");
for (var i = 0; i < lines.length; i++) {
var numLines = doc.splitTextToSize(lines[i], width).length;
if (numLines <= 1) continue;
var j = 0; space = lines[i].length;
while (j++ < lines[i].length) {
if (lines[i].charAt(j) === ' ') space = j;
}
if (space == lines[i].length) space = width/6;
lines[i + 1] = lines[i].substring(space + 1) + ' ' + (lines[i + 1] || '');
lines[i] = lines[i].substring(0, space);
}
var newValue = (lines.join("\n")).trim();
if (value == newValue) {
return newValue;
} else {
return wordWrapText(newValue, width);
}
}
function getClientDisplayName(client)
{
var contact = client.contacts ? client.contacts[0] : false;
@ -710,13 +698,20 @@ function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
}
function getInvoiceDetails(invoice) {
return [
var fields = [
{'invoice_number': invoice.invoice_number},
{'po_number': invoice.po_number},
{'invoice_date': invoice.invoice_date},
{'due_date': invoice.due_date},
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)},
];
if (NINJA.parseFloat(invoice.partial)) {
fields.push({'total': formatMoney(invoice.total_amount, invoice.client.currency_id)});
}
fields.push({'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)})
return fields;
}
function getInvoiceDetailsHeight(invoice, layout) {
@ -771,6 +766,10 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)});
}
if (NINJA.parseFloat(invoice.partial) && invoice.total_amount != invoice.subtotal_amount) {
data.push({'total': formatMoney(invoice.total_amount, invoice.client.currency_id)});
}
var options = {
hasheader: true,
rightAlignX: 550,
@ -797,7 +796,7 @@ function concatStrings() {
concatStr += ' ';
}
}
return data.length ? concatStr : false;
return data.length ? concatStr : "";
}
function displayGrid(doc, invoice, data, x, y, layout, options) {
@ -885,17 +884,19 @@ function displayNotesAndTerms(doc, layout, invoice, y)
var origY = y;
if (invoice.public_notes) {
doc.text(layout.marginLeft, y, invoice.public_notes);
y += 16 + (doc.splitTextToSize(invoice.public_notes, 300).length * doc.internal.getFontSize());
var notes = doc.splitTextToSize(invoice.public_notes, 260);
doc.text(layout.marginLeft, y, notes);
y += 16 + (notes.length * doc.internal.getFontSize());
}
if (invoice.terms) {
doc.setFontType("bold");
var terms = doc.splitTextToSize(invoice.terms, 260);
doc.setFontType("bold");
doc.text(layout.marginLeft, y, invoiceLabels.terms);
y += 16;
doc.setFontType("normal");
doc.text(layout.marginLeft, y, invoice.terms);
y += 16 + (doc.splitTextToSize(invoice.terms, 300).length * doc.internal.getFontSize());
doc.text(layout.marginLeft, y, terms);
y += 16 + (terms.length * doc.internal.getFontSize());
}
return y - origY;
@ -967,11 +968,17 @@ function calculateAmounts(invoice) {
total += roundToTwo(invoice.custom_value2);
}
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.discount_amount = discount;
invoice.tax_amount = tax;
invoice.has_taxes = hasTaxes;
if (NINJA.parseFloat(invoice.partial)) {
invoice.balance_amount = roundToTwo(invoice.partial);
} else {
invoice.balance_amount = invoice.total_amount;
}
return invoice;
}
@ -1286,6 +1293,18 @@ function displayInvoiceItems(doc, invoice, layout) {
}
// http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables
window.alert = (function() {
var nativeAlert = window.alert;
return function(message) {
window.alert = nativeAlert;
message && message.indexOf("DataTables warning") === 0 ?
console.error(message) :
nativeAlert(message);
}
})();
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript
function objectEquals(x, y) {
// if both are function

View File

@ -0,0 +1,192 @@
//pdfmake
var dd = {
content: [
{
columns: [
[
invoice.image?
{
image: invoice.image,
fit: [150, 80]
}:""
],
{
stack: accountDetails(account)
},
{
stack: accountAddress(account)
}
]
},
{
text:(invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase(),
margin: [8, 70, 8, 16],
style: 'primaryColor',
fontSize: 11
},
{
style: 'tableExample',
table: {
headerRows: 1,
widths: ['auto', 'auto', '*'],
body: [[
{
table: {
body: invoiceDetails(invoice),
},
layout: 'noBorders',
},
clientDetails(invoice),
''
]]
},
layout: {
hLineWidth: function (i, node) {
return (i === 0 || i === node.table.body.length) ? .5 : 0;
},
vLineWidth: function (i, node) {
return 0;//(i === 0 || i === node.table.widths.length) ? 2 : 1;
},
hLineColor: function (i, node) {
return '#D8D8D8';//(i === 0 || i === node.table.body.length) ? 'black' : 'gray';
},
/*vLineColor: function (i, node) {
return (i === 0 || i === node.table.widths.length) ? 'black' : 'gray';
},*/
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 4; },
paddingBottom: function(i, node) { return 4; }
}
},
'\n',
{
table: {
headerRows: 1,
widths: ['15%', '*', 'auto', 'auto', 'auto', 'auto'],
body:invoiceLines(invoice),
},
layout: {
hLineWidth: function (i, node) {
return i === 0 ? 0 : .5;
},
vLineWidth: function (i, node) {
return 0;
},
hLineColor: function (i, node) {
return '#D8D8D8';
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 8; },
paddingBottom: function(i, node) { return 8; }
},
},
'\n',
{
columns: [
notesAndTerms(invoice),
{
style: 'subtotals',
table: {
widths: ['*', '*'],
body: subtotals(invoice),
},
layout: {
hLineWidth: function (i, node) {
return 0;
},
vLineWidth: function (i, node) {
return 0;
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 4; },
paddingBottom: function(i, node) { return 4; }
},
}
]
},
],
footer: function(){
f = [{ text:invoice.invoice_footer?invoice.invoice_footer:"", margin: [40, 0]}]
if (!invoice.is_pro && logoImages.imageLogo1) {
f.push({
image: logoImages.imageLogo1,
width: 150,
margin: [40,0]
});
}
return f;
},
defaultStyle: {
//font: 'Roboto',
fontSize: 9,
margin: [8, 4, 8, 4]
},
styles: {
primaryColor:{
color: primaryColor('#299CC2')
},
accountName: {
margin: [4, 2, 4, 2],
color:primaryColor('#299CC2')
},
accountDetails: {
margin: [4, 2, 4, 2],
color: '#AAA9A9'
},
bold: {
bold: true
},
even: {
},
odd: {
fillColor:'#F4F4F4'
},
productKey: {
color:primaryColor('#299CC2')
},
cost: {
alignment: 'right'
},
quantity: {
alignment: 'right'
},
tax: {
alignment: 'right'
},
lineTotal: {
alignment: 'right'
},
right: {
alignment: 'right'
},
subtotals: {
alignment: 'right'
},
tableHeader: {
bold: true
},
balanceDueLabel: {
fontSize: 11
},
balanceDueValue: {
fontSize: 11,
color:primaryColor('#299CC2')
},
notes: {
},
terms: {
},
termsLabel: {
bold: true,
fontSize: 10,
margin: [0, 10, 0, 4]
}
},
pageMargins: [40, 40, 40, 40]
};

1
public/js/vfs_fonts.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,21 +1,14 @@
# Invoice Ninja
## Simple, Intuitive Invoicing
### [https://www.invoiceninja.com](https://www.invoiceninja.com)
##### Please [click here](https://bitnami.com/stack/invoice-ninja) to vote for us to be added to Bitnami's one-click install library
If you'd like to use our code to sell your own invoicing app we have an affiliate program. Get in touch for more details.
### Introduction
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
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 this [zip file](https://www.invoiceninja.com/knowledgebase/self-host/) (easier to setup) or checkout the code from GitHub following the instructions below (easier to stay up to date).
For a WAMP/MAMP/LAMP setup you can one-click install using Softaculous's [AMPPS](http://www.ampps.com/). To deploy the app with [Docker](http://www.docker.com/) you can use [this project](https://github.com/rollbrettler/Dockerfiles/tree/master/invoice-ninja).
To connect follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files.
@ -23,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
@ -36,65 +31,16 @@ Developed by [@hillelcoren](https://twitter.com/hillelcoren) | Designed by [kant
* [Troels Liebe Bentsen](https://github.com/tlbdk)
* [Jeramy Simpson](https://github.com/JeramyMywork) - [MyWork](https://www.mywork.com.au)
* [Sigitas Limontas](https://lt.linkedin.com/in/sigitaslimontas)
### Documentation
* [Self Host](https://www.invoiceninja.com/knowledgebase/self-host/)
* [Ubuntu and Apache](http://blog.technerdservices.com/index.php/2015/04/techpop-how-to-install-invoice-ninja-on-ubuntu-14-04/)
* [Debian and Nginx](https://www.rosehosting.com/blog/install-invoice-ninja-on-a-debian-7-vps/)
* [API Documentation](https://www.invoiceninja.com/knowledgebase/api-documentation/)
* [Developer Guide](https://www.invoiceninja.com/knowledgebase/developer-guide/)
### Steps to setup from GitHub
If you plan on submitting changes it's best to [fork the repo](https://help.github.com/articles/fork-a-repo), otherwise you can just checkout the code.
git clone https://github.com/hillelcoren/invoice-ninja.git ninja
cd ninja
Install Laravel packages using Composer
Note: you may be prompted for your Github user/pass due to their API limits.
composer install
Install JavaScript and HTML packages using Bower and NPM. This is optional, it's only needed if you want to modify the JavaScript.
bower install
npm install
Create database user and a database for ninja
CREATE SCHEMA `ninja` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'ninja'@'localhost' IDENTIFIED BY 'ninja';
GRANT ALL PRIVILEGES ON `ninja`.* TO 'ninja'@'localhost';
FLUSH PRIVILEGES;
Add public/ to your web server root then load / to configure the application.
### Developer Notes
* The application requires PHP >= 5.4.0
* If you make any changes to the JavaScript files you need to run grunt to create the built files. See Gruntfile.js for more details.
* The lookup tables are cached in memory (ie, Currencies, Timezones, Languages, etc). If you add a record to the database you need to clear the cache by uncommenting Cache::flush() in app/routes.php.
* If you run into any composer errors try running composer dump-autoload.
### Ubuntu Notes
# Install php-mcrypt
apt-get install php5-mcrypt
sudo php5enmod mcrypt
# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# Install Bower
sudo apt-get install npm nodejs-legacy
sudo npm install -g bower
sudo ln -s /usr/local/lib/node_modules/bower/bin/bower /usr/local/bin/bower
# Install Grunt (For development only)
npm install -g grunt-cli
### Frameworks/Libraries
* [laravel/laravel](https://github.com/laravel/laravel) - A PHP Framework For Web Artisans
* [twbs/bootstrap](https://github.com/twbs/bootstrap) - Sleek, intuitive, and powerful front-end framework for faster and easier web development.
@ -106,6 +52,7 @@ Add public/ to your web server root then load / to configure the application.
* [knockout/knockout](https://github.com/knockout/knockout) - Knockout makes it easier to create rich, responsive UIs with JavaScript
* [rniemeyer/knockout-sortable](https://github.com/rniemeyer/knockout-sortable) - A Knockout.js binding to connect observableArrays with jQuery UI sortable functionality
* [MrRio/jsPDF](https://github.com/MrRio/jsPDF) - Generate PDF files in JavaScript. HTML5 FTW.
* [bpampuch/pdfmake](https://github.com/bpampuch/pdfmake) - Client/server side PDF printing in pure JavaScript
* [FortAwesome/Font-Awesome](https://github.com/FortAwesome/Font-Awesome) - The iconic font designed for Bootstrap that works with twitter bootstrap
* [Anahkiasen/former](https://github.com/Anahkiasen/former) - A powerful form builder, for Laravel and other frameworks (stand-alone too)
* [barryvdh/laravel-debugbar](https://github.com/barryvdh/laravel-debugbar) - Laravel debugbar

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Gratis Open-Source Online Fakturering',
'description' => 'Invoice Ninja er en gratis, open-source løsning til fakturering af kunder. Med Invoice Ninja, kan du nemt opbygge og sende smukke fakturaer fra enhver enhed, der har adgang til internettet. Dine kunder kan printe dine fakturaer, downloade dem som PDF-filer, og endda betale dig online via systemet.',
'invoice_now' => 'Fakturér nu',
'no_signup_needed' => 'Ingen tilmelding påkrævet',
'link_blog' => 'Blog',
'link_about_us' => 'Om Os',
'link_contact_us' => 'Kontakt Os',
'link_features' => 'Funktioner',
'link_plans' => 'Løsninger',
'link_compare' => 'Sammenlign',
'link_testimonials' => 'Anbefalinger',
'link_faq' => 'OSS',
'my_account' => 'Min konto',
'login' => 'Login',
'connect_with_us' => 'Forbind med os',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Vis/Skjul navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Free, Always',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'What is Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, special requests, or just want to say hi?',
'sub_header' => 'Fill in the form below and we\'ll get back to you as soon as possible. Hope to hear from you!',
'other_ways' => 'Other ways to reach us',
'name' => 'Name',
'name_help' => 'Please enter your name.',
'email' => 'Email Address',
'email_help' => 'Please enter a valid e-mail address.',
'message' => 'Message',
'message_help' => 'Please enter a message.',
'send_message' => 'Send Message',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -257,13 +257,13 @@ return array(
'confirmation_subject' => 'Invoice Ninja kontobekræftelse',
'confirmation_header' => 'Kontobekræftelse',
'confirmation_message' => 'Venligst åbne linket nedenfor for å bekræfte din konto.',
'invoice_subject' => 'Ny faktura fra :account',
'invoice_subject' => 'Ny faktura :invoice fra :account',
'invoice_message' => 'For at se din faktura på :amount, klik på linket nedenfor.',
'payment_subject' => 'Betaling modtaget',
'payment_message' => 'Tak for din betaling pålydende :amount.',
'email_salutation' => 'Kære :name,',
'email_signature' => 'Med venlig hilsen,',
'email_from' => 'The InvoiceNinja Team',
'email_from' => 'The Invoice Ninja Team',
'user_email_footer' => 'For at justere varslingsindstillingene venligst besøg '.SITE_URL.'/company/notifications',
'invoice_link_message' => 'Hvis du vil se din klientfaktura klik på linket under:',
'notification_invoice_paid_subject' => 'Faktura :invoice betalt af :client',
@ -586,5 +586,45 @@ return array(
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

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

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Kostenlose & Open-Source Online-Rechnungsausstellung',
'description' => 'Invoice Ninja ist eine kostenlose, Open-Source Lösung für die Rechnungsstellung und Abrechnung deiner Kunden. 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.',
'invoice_now' => 'Jetzt Rechnungen schreiben',
'no_signup_needed' => 'Keine Anmeldung benötigt',
'link_blog' => 'Blog',
'link_about_us' => 'Über uns',
'link_contact_us' => 'Kontaktiere uns',
'link_features' => 'Funktionen',
'link_plans' => 'Mitgliedschaften',
'link_compare' => 'Vergleich',
'link_testimonials' => 'Referenzen',
'link_faq' => 'FAQ',
'my_account' => 'Mein Konto',
'login' => 'Einloggen',
'connect_with_us' => 'Trete mit uns in Kontakt',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Navigation umschalten',
'home' => [
'header' => 'DER <span style="color:#2299c0">EINFACHE</span> &amp; <span style="color:#edd71e">KOSTENLOSE</span> WEG RECHNUNGEN AUSZUSTELLEN',
'sub_header' => 'Es ist so einfach. Hör auf Zeit mit komplizierten und teuren Methoden der Rechnungsstellung zu verschwenden.<br>Keine Aufregung, einfach loslegen und bezahlt werden.',
'footer' => '<span>Einfache, intuitive Rechnungsausstellung,</span>Überall.',
'free_always' => 'Kostenlos, immer',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF Vorschau',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Bezahlungen',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">Über</span> Invoice Ninja',
'what_is' => 'Was ist Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Fragen, spezielle Anfragen, oder einfach nur Hallo sagen?',
'sub_header' => 'Fülle das Formular aus und wir werden uns sobald wie möglich bei dir melden! Wir freuen uns von dir zuhören!',
'other_ways' => 'Andere Wege uns zu erreichen',
'name' => 'Name',
'name_help' => 'Bitte gib deinen Namen ein.',
'email' => 'E-Mail-Adresse',
'email_help' => 'Bitte gib eine gültige E-Mail-Adresse ein.',
'message' => 'Nachricht',
'message_help' => 'Bitte gib eine Nachricht ein.',
'send_message' => 'Nachricht abschicken',
],
'features' => [
'header' => '<span class="thin">Die</span> Funktionen',
'footer' => 'Dir gefällt, was du siehst?',
'footer_action' => 'Beginne noch heute!',
'open_source' => 'Open-Source-Plattform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'KOSTENLOS. Für immer.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Teste Invoice Ninja. Du hast buchstäblich nichts zu verlieren. Wir sind uns sicher, deine Erfahrung wird so positiv sein, dass du nie wieder einen anderen Service brauchen wirst.',
'secure' => 'Sicher & Privat',
'secure_text1' => 'Invoice Ninja wurde von Grund auf entworfen, um Ihre Daten sicher zu halten. Nur du hast Zugriff auf deine Anmeldungs-und Buchaltungsdaten und wir werden deine Transaktionen niemals an dritte weitergeben.',
'secure_text2' => 'Unsere Webseite benutzt 256-bit verschlüsselung, das ist sicherer, als die meisten Online-Banking-Seiten! Invoice Ninja benutzt das kryptographische Protokoll TLS 1.0, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Wir fühlen uns hier sicher und haben masiv darin investiert, dass es dir genauso geht.',
'live_pdf' => 'Live .PDF Vorschau',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Einfach erstellen, speichern, senden und du bist fertig!',
'online_payments' => 'Online Bezahlungen',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'plans' => [
'header' => '<span class="thin">Die</span> Mitgliedschaften',
'free' => 'Kostenlos',
'unlimited' => 'Uneingeschränkt',
'pro_plan' => 'Pro-Mitgliedschaft',
'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' => 'Kostenlos<span> /Immer!</span>',
'year_price' => '$50<span> /Jahre</span>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Gratis-Mitgledschaften-Vergleich',
'paid_plan_comparison' => 'Kostenpflichtige-Mitgledschaften-Vergleich',
'app' => 'Service',
'cost' => 'Kosten',
'clients' => 'Kunden',
'invoices' => 'Rechnungen',
'payment_gateways' => 'Zahlungsanbieter',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Mehrere Vorlagen',
'recurring_payments' => 'Wiederkehrende Zahlungen',
'open_source' => 'Open-Source',
'per_month' => 'pro Monat',
'per_year' => 'pro Jahr',
'free' => 'Kostenlos',
'unlimited' => 'Unbegrenzt',
],
'testimonials' => [
'testimonials' => 'Referenzen',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">Das</span> FAQ',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Ist Invoice Ninja wirklich kostenlos? Für wie lange?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'Also, wie sicher ist diese App?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Haben wir etwas vergessen?',
'miss_something_text' => 'Schreib uns eine E-Mail an <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> mit jeder Frage und jedem Kommentar, den du uns gerne mitteilen möchtest. Wir lieben es von den Menschen zu hören, die unsere Angebot nutzen! Wir werden unser bestes geben, um deine E-Mail innerhalb eines Werktages zu beantworten.',
],
];

View File

@ -305,7 +305,7 @@ return array(
'success_message' => 'Du hast dich erfolgreich registriert. Bitte besuche den Link in deiner Bestätigungsmail um deine E-Mail Adresse zu verifizieren.',
'erase_data' => 'Diese Aktion wird deine Daten dauerhaft löschen.',
'password' => 'Passwort',
'invoice_subject' => 'Neue Rechnung von :account',
'invoice_subject' => 'Neue Rechnung :invoice von :account',
'close' => 'Schließen',
'pro_plan_product' => 'Pro Plan',
@ -577,4 +577,46 @@ return array(
'notification_quote_approved' => 'Der folgende Kunde :client nahm das Angebot :invoice über :amount an.',
'resend_confirmation' => 'Bestätigungsmail erneut senden',
'confirmation_resent' => 'Bestätigungsemail wurde erneut gesendet',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Free Open-Source Online Invoicing',
'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.',
'invoice_now' => 'Invoice Now',
'no_signup_needed' => 'No signup needed',
'link_blog' => 'Blog',
'link_about_us' => 'About Us',
'link_contact_us' => 'Contact Us',
'link_features' => 'Features',
'link_plans' => 'Plans',
'link_compare' => 'Compare',
'link_testimonials' => 'Testimonials',
'link_faq' => 'FAQ',
'my_account' => 'My Account',
'login' => 'Login',
'connect_with_us' => 'Connect with Us',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Toggle navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Free, Always',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'What is Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, special requests, or just want to say hi?',
'sub_header' => 'Fill in the form below and we\'ll get back to you as soon as possible. Hope to hear from you!',
'other_ways' => 'Other ways to reach us',
'name' => 'Name',
'name_help' => 'Please enter your name.',
'email' => 'Email Address',
'email_help' => 'Please enter a valid e-mail address.',
'message' => 'Message',
'message_help' => 'Please enter a message.',
'send_message' => 'Send Message',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -173,7 +173,7 @@ return array(
'are_you_sure' => 'Are you sure?',
// payment pages
'payment_type_id' => 'Payment type',
'payment_type_id' => 'Payment Type',
'amount' => 'Amount',
// account/company pages
@ -187,7 +187,7 @@ return array(
'remove_logo' => 'Remove logo',
'logo_help' => 'Supported: JPEG, GIF and PNG. Recommended size: 200px width by 120px height',
'payment_gateway' => 'Payment Gateway',
'gateway_id' => 'Provider',
'gateway_id' => 'Gateway',
'email_notifications' => 'Email Notifications',
'email_sent' => 'Email me when an invoice is <b>sent</b>',
'email_viewed' => 'Email me when an invoice is <b>viewed</b>',
@ -207,7 +207,7 @@ return array(
'client_will_create' => 'client will be created',
'clients_will_create' => 'clients will be created',
'email_settings' => 'Email Settings',
'pdf_email_attachment' => 'Attach PDF to Emails',
'pdf_email_attachment' => 'Attach to Emails',
// application messages
'created_client' => 'Successfully created client',
@ -255,13 +255,13 @@ return array(
'confirmation_subject' => 'Invoice Ninja Account Confirmation',
'confirmation_header' => 'Account Confirmation',
'confirmation_message' => 'Please access the link below to confirm your account.',
'invoice_subject' => 'New invoice from :account',
'invoice_subject' => 'New invoice :invoice from :account',
'invoice_message' => 'To view your invoice for :amount, click the link below.',
'payment_subject' => 'Payment Received',
'payment_message' => 'Thank you for your payment of :amount.',
'email_salutation' => 'Dear :name,',
'email_signature' => 'Regards,',
'email_from' => 'The InvoiceNinja Team',
'email_from' => 'The Invoice Ninja Team',
'user_email_footer' => 'To adjust your email notification settings please visit '.SITE_URL.'/company/notifications',
'invoice_link_message' => 'To view your client invoice click the link below:',
'notification_invoice_paid_subject' => 'Invoice :invoice was paid by :client',
@ -585,5 +585,46 @@ return array(
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
'processed_updates' => 'Successfully completed update',
);

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Free Open-Source Online Invoicing',
'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.',
'invoice_now' => 'Invoice Now',
'no_signup_needed' => 'No signup needed',
'link_blog' => 'Blog',
'link_about_us' => 'About Us',
'link_contact_us' => 'Contact Us',
'link_features' => 'Features',
'link_plans' => 'Plans',
'link_compare' => 'Compare',
'link_testimonials' => 'Testimonials',
'link_faq' => 'FAQ',
'my_account' => 'My Account',
'login' => 'Login',
'connect_with_us' => 'Connect with Us',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Toggle navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Free, Always',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'What is Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, special requests, or just want to say hi?',
'sub_header' => 'Fill in the form below and we\'ll get back to you as soon as possible. Hope to hear from you!',
'other_ways' => 'Other ways to reach us',
'name' => 'Name',
'name_help' => 'Please enter your name.',
'email' => 'Email Address',
'email_help' => 'Please enter a valid e-mail address.',
'message' => 'Message',
'message_help' => 'Please enter a message.',
'send_message' => 'Send Message',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -249,7 +249,7 @@ return array(
'confirmation_subject' => 'Corfimación de tu cuenta en Invoice Ninja',
'confirmation_header' => 'Confirmación de Cuenta',
'confirmation_message' => 'Por favor, haz clic en el enlace abajo para confirmar tu cuenta.',
'invoice_subject' => 'Nueva factura de :account',
'invoice_subject' => 'Nueva factura :invoice de :account',
'invoice_message' => 'Para visualizar tu factura por el valor de :amount, haz click en el enlace abajo.',
'payment_subject' => 'Pago recibido',
'payment_message' => 'Gracias por tu pago por valor de :amount.',
@ -556,7 +556,47 @@ return array(
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'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

@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Anterior',
'next' => 'Siguiente &raquo;',
);

View File

@ -0,0 +1,24 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Las contraseñas deben contener al menos 6 caracteres y coincidir.",
"user" => "No podemos encontrar a un usuario con ese correo electrónico.",
"token" => "Este token de recuperación de contraseña es inválido.",
"sent" => "¡Recordatorio de contraseña enviado!",
);

View File

@ -0,0 +1,630 @@
<?php
return array(
// client
'organization' => 'Empresa',
'name' => 'Nombre de Empresa',
'website' => 'Sitio Web',
'work_phone' => 'Teléfono',
'address' => 'Dirección',
'address1' => 'Calle',
'address2' => 'Bloq/Pta',
'city' => 'Ciudad',
'state' => 'Provincia',
'postal_code' => 'Código Postal',
'country_id' => 'País',
'contacts' => 'Contactos',
'first_name' => 'Nombres',
'last_name' => 'Apellidos',
'phone' => 'Teléfono',
'email' => 'Email',
'additional_info' => 'Información adicional',
'payment_terms' => 'Plazos de pago', //
'currency_id' => 'Divisa',
'size_id' => 'Tamaño',
'industry_id' => 'Industria',
'private_notes' => 'Notas Privadas',
// invoice
'invoice' => 'Factura',
'client' => 'Cliente',
'invoice_date' => 'Fecha de factura',
'due_date' => 'Fecha de pago',
'invoice_number' => 'Número de Factura',
'invoice_number_short' => 'Factura Nº',
'po_number' => 'Apartado de correo',
'po_number_short' => 'Apdo.',
'frequency_id' => 'Frecuencia',
'discount' => 'Descuento',
'taxes' => 'Impuestos',
'tax' => 'IVA',
'item' => 'Concepto',
'description' => 'Descripción',
'unit_cost' => 'Coste unitario',
'quantity' => 'Cantidad',
'line_total' => 'Total',
'subtotal' => 'Subtotal',
'paid_to_date' => 'Pagado',
'balance_due' => 'Pendiente',
'invoice_design_id' => 'Diseño',
'terms' => 'Términos',
'your_invoice' => 'Tu factura',
'remove_contact' => 'Eliminar contacto',
'add_contact' => 'Añadir contacto',
'create_new_client' => 'Crear nuevo cliente',
'edit_client_details' => 'Editar detalles del cliente',
'enable' => 'Activar',
'learn_more' => 'Saber más',
'manage_rates' => 'Gestionar tarifas',
'note_to_client' => 'Nota para el cliente',
'invoice_terms' => 'Términos de facturación',
'save_as_default_terms' => 'Guardar como términos por defecto',
'download_pdf' => 'Descargar PDF',
'pay_now' => 'Pagar Ahora',
'save_invoice' => 'Guardar factura',
'clone_invoice' => 'Clonar factura',
'archive_invoice' => 'Archivar factura',
'delete_invoice' => 'Eliminar factura',
'email_invoice' => 'Enviar factura por email',
'enter_payment' => 'Agregar pago',
'tax_rates' => 'Tasas de impuesto',
'rate' => 'Tasas',
'settings' => 'Configuración',
'enable_invoice_tax' => 'Activar impuesto <b>para la factura</b>',
'enable_line_item_tax' => 'Activar impuesto <b>por concepto</b>',
// navigation
'dashboard' => 'Inicio',
'clients' => 'Clientes',
'invoices' => 'Facturas',
'payments' => 'Pagos',
'credits' => 'Créditos',
'history' => 'Historial',
'search' => 'Búsqueda',
'sign_up' => 'Registrarse',
'guest' => 'Invitado',
'company_details' => 'Detalles de la Empresa',
'online_payments' => 'Pagos en Linea',
'notifications' => 'Notificaciones',
'import_export' => 'Importar/Exportar',
'done' => 'Hecho',
'save' => 'Guardar',
'create' => 'Crear',
'upload' => 'Subir',
'import' => 'Importar',
'download' => 'Descargar',
'cancel' => 'Cancelar',
'close' => 'Cerrar',
'provide_email' => 'Por favor facilita una dirección de correo válida.',
'powered_by' => 'Creado por',
'no_items' => 'No hay datos',
// recurring invoices
'recurring_invoices' => 'Facturas recurrentes',
'recurring_help' => '<p>Enviar facturas automáticamente a clientes semanalmente, bi-mensualmente, mensualmente, trimestral o anualmente. </p>
<p>Uso :MONTH, :QUARTER or :YEAR para fechas dinámicas. Matemáticas básicas también funcionan bien. Por ejemplo: :MONTH-1.</p>
<p>Ejemplos de variables dinámicas de factura:</p>
<ul>
<li>"Afiliación de gimnasio para el mes de:MONTH" => Afiliación de gimnasio para el mes de julio"</li>
<li>":YEAR+1 suscripción anual" => "2015 suscripción anual"</li>
<li>"Retainer payment for :QUARTER+1" => "Pago anticipo de pagos para T2"</li>
</ul>',
// dashboard
'in_total_revenue' => 'Ingreso Total',
'billed_client' => 'Cliente Facturado',
'billed_clients' => 'Clientes Facturados',
'active_client' => 'Cliente Activo',
'active_clients' => 'Clientes Activos',
'invoices_past_due' => 'Facturas Vencidas',
'upcoming_invoices' => 'Próximas Facturas',
'average_invoice' => 'Promedio de Facturación',
// list pages
'archive' => 'Archivar',
'delete' => 'Eliminar',
'archive_client' => 'Archivar Cliente',
'delete_client' => 'Eliminar Cliente',
'archive_payment' => 'Archivar Pago',
'delete_payment' => 'Eliminar Pago',
'archive_credit' => 'Archivar Crédito',
'delete_credit' => 'Eliminar Crédito',
'show_archived_deleted' => 'Mostrar archivados o eliminados en ',
'filter' => 'Filtrar',
'new_client' => 'Nuevo Cliente',
'new_invoice' => 'Nueva Factura',
'new_payment' => 'Nuevo Pago',
'new_credit' => 'Nuevo Crédito',
'contact' => 'Contacto',
'date_created' => 'Fecha de Creación',
'last_login' => 'Último Acceso',
'balance' => 'Balance',
'action' => 'Acción',
'status' => 'Estado',
'invoice_total' => 'Total Facturado',
'frequency' => 'Frequencia',
'start_date' => 'Fecha de Inicio',
'end_date' => 'Fecha de Finalización',
'transaction_reference' => 'Referencia de Transacción',
'method' => 'Método',
'payment_amount' => 'Valor del Pago',
'payment_date' => 'Fecha de Pago',
'credit_amount' => 'Cantidad de Crédito',
'credit_balance' => 'Balance de Crédito',
'credit_date' => 'Fecha de Crédito',
'empty_table' => 'Tabla vacía',
'select' => 'Seleccionar',
'edit_client' => 'Editar Cliente',
'edit_invoice' => 'Editar Factura',
// client view page
'create_invoice' => 'Crear Factura',
'Create Invoice' => 'Crear Factura',
'enter_credit' => 'Agregar Crédito',
'last_logged_in' => 'Último inicio de sesión',
'details' => 'Detalles',
'standing' => 'Situación', //
'credit' => 'Crédito',
'activity' => 'Actividad',
'date' => 'Fecha',
'message' => 'Mensaje',
'adjustment' => 'Ajustes',
'are_you_sure' => '¿Está Seguro?',
// payment pages
'payment_type_id' => 'Tipo de pago',
'amount' => 'Cantidad',
// Nuevo texto extraido - New text extracted
'Recommended Gateway' => 'Pasarelas Recomendadas',//
'Accepted Credit Cards' => 'Tarjetas de Credito Permitidas',//
'Payment Gateway' => 'Pasarelas de Pago',//
'Select Gateway' => 'Seleccione Pasarela',//
'Enable' => 'Activo',//
'Api Login Id' => 'Introduzca Api Id',//
'Transaction Key' => 'Clave de Transacción',//
'Create an account' => 'Crear cuenta nueva',//
'Other Options' => 'Otras Opciones',//
// account/company pages
'work_email' => 'Correo electrónico de la empresa',
'language_id' => 'Idioma',
'timezone_id' => 'Zona horaria',
'date_format_id' => 'Formato de fecha',
'datetime_format_id' => 'Format de fecha/hora',
'users' => 'Usuarios',
'localization' => 'Localización',
'remove_logo' => 'Eliminar logo',
'logo_help' => 'Formatos aceptados: JPEG, GIF y PNG. Altura recomendada: 120px',
'payment_gateway' => 'Pasarela de pago',
'gateway_id' => 'Proveedor',
'email_notifications' => 'Notificaciones de email',
'email_sent' => 'Avísame por email cuando una factura <b>se envía</b>',
'email_viewed' => 'Avísame por email cuando una factura <b>se visualiza</b>',
'email_paid' => 'Avísame por email cuando una factura <b>se paga</b>',
'site_updates' => 'Actualizaciones del sitio',
'custom_messages' => 'Mensajes a medida',
'default_invoice_terms' => 'Configurar términos de factura por defecto',
'default_email_footer' => 'Configurar firma de email por defecto',
'import_clients' => 'Importar datos del cliente',
'csv_file' => 'Seleccionar archivo CSV',
'export_clients' => 'Exportar datos del cliente',
'select_file' => 'Seleccionar archivo',
'first_row_headers' => 'Usar la primera fila como encabezados',
'column' => 'Columna',
'sample' => 'Ejemplo',
'import_to' => 'Importar a',
'client_will_create' => 'cliente se creará',
'clients_will_create' => 'clientes se crearan',
// application messages
'created_client' => 'cliente creado con éxito',
'created_clients' => ':count clientes creados con éxito',
'updated_settings' => 'Configuración actualizada con éxito',
'removed_logo' => 'Logo eliminado con éxito',
'sent_message' => 'Mensaje enviado con éxito',
'invoice_error' => 'Seleccionar cliente y corregir errores.',
'limit_clients' => 'Lo sentimos, se ha pasado del límite de :count clientes',
'payment_error' => 'Ha habido un error en el proceso de tu pago. Inténtalo de nuevo más tarde.',
'registration_required' => 'Inscríbete para enviar una factura',
'confirmation_required' => 'Por favor confirma tu dirección de correo electrónico',
'updated_client' => 'Cliente actualizado con éxito',
'created_client' => 'Cliente creado con éxito',
'archived_client' => 'Cliente archivado con éxito',
'archived_clients' => ':count clientes archivados con éxito',
'deleted_client' => 'Cliente eliminado con éxito',
'deleted_clients' => ':count clientes eliminados con éxito',
'updated_invoice' => 'Factura actualizada con éxito',
'created_invoice' => 'Factura creada con éxito',
'cloned_invoice' => 'Factura clonada con éxito',
'emailed_invoice' => 'Factura enviada con éxito',
'and_created_client' => 'y cliente creado ',
'archived_invoice' => 'Factura archivada con éxito',
'archived_invoices' => ':count facturas archivados con éxito',
'deleted_invoice' => 'Factura eliminada con éxito',
'deleted_invoices' => ':count facturas eliminadas con éxito',
'created_payment' => 'Pago creado con éxito',
'archived_payment' => 'Pago archivado con éxito',
'archived_payments' => ':count pagos archivados con éxito',
'deleted_payment' => 'Pago eliminado con éxito',
'deleted_payments' => ':count pagos eliminados con éxito',
'applied_payment' => 'Pago aplicado con éxito',
'created_credit' => 'Crédito creado con éxito',
'archived_credit' => 'Crédito archivado con éxito',
'archived_credits' => ':count creditos archivados con éxito',
'deleted_credit' => 'Créditos eliminados con éxito',
'deleted_credits' => ':count creditos eliminados con éxito',
// Emails
'confirmation_subject' => 'Corfimación de tu cuenta en Invoice Ninja',
'confirmation_header' => 'Confirmación de Cuenta',
'confirmation_message' => 'Por favor, haz clic en el enlace abajo para confirmar tu cuenta.',
'invoice_subject' => 'Nueva factura :invoice de :account',
'invoice_message' => 'Para visualizar tu factura por el valor de :amount, haz click en el enlace de abajo.',
'payment_subject' => 'Pago recibido',
'payment_message' => 'Gracias por su pago de :amount.',
'email_salutation' => 'Estimado :name,',
'email_signature' => 'Un cordial saludo,',
'email_from' => 'El equipo de Invoice Ninja ',
'user_email_footer' => 'Para ajustar la configuración de las notificaciones de tu email, visita '.SITE_URL.'/company/notifications',
'invoice_link_message' => 'Para visualizar la factura de cliente, haz clic en el enlace de abajo:',
'notification_invoice_paid_subject' => 'La factura :invoice ha sido pagada por el cliente :client',
'notification_invoice_sent_subject' => 'La factura :invoice ha sido enviada a el cliente :client',
'notification_invoice_viewed_subject' => 'La factura :invoice ha sido visualizado por el cliente:client',
'notification_invoice_paid' => 'Un pago por importe de :amount ha sido realizado por el cliente :client correspondiente a la factura :invoice.',
'notification_invoice_sent' => 'La factura :invoice por importe de :amount fue enviada al cliente :cliente.',
'notification_invoice_viewed' => 'La factura :invoice por importe de :amount fue visualizada por el cliente :client.',
'reset_password' => 'Puedes reconfigurar la contraseña de tu cuenta haciendo clic en el siguiente enlace:',
'reset_password_footer' => 'Si no has solicitado un cambio de contraseña, por favor contactate con nosostros: ' . CONTACT_EMAIL,
// Payment page
'secure_payment' => 'Pago seguro',
'card_number' => 'Número de tarjeta',
'expiration_month' => 'Mes de caducidad',
'expiration_year' => 'Año de caducidad',
'cvv' => 'CVV',
// Security alerts
'confide' => array(
'too_many_attempts' => 'Demasiados intentos fallidos. Inténtalo de nuevo en un par de minutos.',
'wrong_credentials' => 'Contraseña o email incorrecto.',
'confirmation' => '¡Tu cuenta se ha confirmado!',
'wrong_confirmation' => 'Código de confirmación incorrecto.',
'password_forgot' => 'La información sobre el cambio de tu contraseña se ha enviado a tu dirección de correo electrónico.',
'password_reset' => 'Tu contraseña se ha cambiado con éxito.',
'wrong_password_reset' => 'Contraseña no válida. Inténtalo de nuevo',
),
// Pro Plan
'pro_plan' => [
'remove_logo' => ':link haz click para eliminar el logo de Invoice Ninja',
'remove_logo_link' => 'Haz click aquí',
],
'logout' => 'Cerrar sesión',
'sign_up_to_save' => 'Registrate para guardar tu trabajo',
'agree_to_terms' =>'Estoy de acuerdo con los términos de Invoice Ninja :terms',
'terms_of_service' => 'Términos de servicio',
'email_taken' => 'Esta dirección de correo electrónico ya se ha registrado',
'working' => 'Procesando',
'success' => 'Éxito',
'success_message' => 'Te has registrado con éxito. Por favor, haz clic en el enlace del correo de confirmación para verificar tu dirección de correo electrónico.',
'erase_data' => 'Esta acción eliminará todos tus datos de forma permanente.',
'password' => 'Contraseña',
'pro_plan_product' => 'Plan Pro',
'pro_plan_description' => 'Un año de inscripción al Plan Pro de Invoice Ninja.',
'pro_plan_success' => '¡Gracias por unirte a Invoice Ninja! Al realizar el pago de tu factura, se iniciara tu PLAN PRO.',
'unsaved_changes' => 'Tienes cambios no guardados',
'custom_fields' => 'Campos a medida',
'company_fields' => 'Campos de la empresa',
'client_fields' => 'Campos del cliente',
'field_label' => 'Etiqueta del campo',
'field_value' => 'Valor del campo',
'edit' => 'Editar',
'view_as_recipient' => 'Ver como destinitario',
// product management
'product_library' => 'Inventario de productos',
'product' => 'Producto',
'products' => 'Productos',
'fill_products' => 'Auto-rellenar productos',
'fill_products_help' => 'Seleccionar un producto automáticamente <b>configurará la descripción y coste</b>',
'update_products' => 'Auto-actualizar productos',
'update_products_help' => 'Actualizar una factura automáticamente <b>actualizará los productos</b>',
'create_product' => 'Crear Producto',
'edit_product' => 'Editar Producto',
'archive_product' => 'Archivar Producto',
'updated_product' => 'Producto actualizado con éxito',
'created_product' => 'Producto creado con éxito',
'archived_product' => 'Producto archivado con éxito',
'pro_plan_custom_fields' => ':link haz click para para activar campos a medida',
'advanced_settings' => 'Configuración Avanzada',
'pro_plan_advanced_settings' => ':link haz click para para activar la configuración avanzada',
'invoice_design' => 'Diseño de factura',
'specify_colors' => 'Especificar colores',
'specify_colors_label' => 'Seleccionar los colores para usar en las facturas',
'chart_builder' => 'Constructor de graficos',
'ninja_email_footer' => 'Usa :site para facturar a tus clientes y recibir pagos de forma gratuita!',
'go_pro' => 'Hazte Pro',
// Quotes
'quote' => 'Presupuesto',
'quotes' => 'Presupuestos',
'quote_number' => 'Numero de Presupuesto',
'quote_number_short' => 'Presupuesto Nº ',
'quote_date' => 'Fecha Presupuesto',
'quote_total' => 'Total Presupuestado',
'your_quote' => 'Su Presupuesto',
'total' => 'Total',
'clone' => 'Clonar',
'new_quote' => 'Nuevo Presupuesto',
'create_quote' => 'Crear Presupuesto',
'edit_quote' => 'Editar Presupuesto',
'archive_quote' => 'Archivar Presupuesto',
'delete_quote' => 'Eliminar Presupuesto',
'save_quote' => 'Guardar Presupuesto',
'email_quote' => 'Enviar Presupuesto',
'clone_quote' => 'Clonar Presupuesto',
'convert_to_invoice' => 'Convertir a Factura',
'view_invoice' => 'Ver Factura',
'view_quote' => 'Ver Presupuesto',
'view_client' => 'Ver Cliente',
'updated_quote' => 'Presupuesto actualizado con éxito',
'created_quote' => 'Presupuesto creado con éxito',
'cloned_quote' => 'Presupuesto clonado con éxito',
'emailed_quote' => 'Presupuesto enviado con éxito',
'archived_quote' => 'Presupuesto archivado con éxito',
'archived_quotes' => ':count Presupuestos archivados con exito',
'deleted_quote' => 'Presupuesto eliminado con éxito',
'deleted_quotes' => ':count Presupuestos eliminados con exito',
'converted_to_invoice' => 'Presupuesto convertido a factura con éxito',
'quote_subject' => 'Nuevo Presupuesto de :account',
'quote_message' => 'Para ver el presupuesto por un importe de :amount, haga click en el enlace de abajo.',
'quote_link_message' => 'Para ver su presupuesto haga click en el enlace de abajo:',
'notification_quote_sent_subject' => 'El presupuesto :invoice enviado al cliente :client',
'notification_quote_viewed_subject' => 'El presupuesto :invoice fue visto por el cliente :client',
'notification_quote_sent' => 'El presupuesto :invoice por un valor de :amount, ha sido enviado al cliente :client.',
'notification_quote_viewed' => 'El presupuesto :invoice por un valor de :amount ha sido visto por el cliente :client.',
'session_expired' => 'Su sesión ha caducado.',
'invoice_fields' => 'Campos de Factura',
'invoice_options' => 'Opciones de Factura',
'hide_quantity' => 'Ocultar Cantidad',
'hide_quantity_help' => 'Si las cantidades de tus partidas siempre son 1, entonces puedes organizar tus facturas mejor al no mostrar este campo.',
'hide_paid_to_date' => 'Ocultar valor pagado a la fecha',
'hide_paid_to_date_help' => 'Solo mostrar la opción “Pagado a la fecha” en sus facturas cuando se ha recibido un pago.',
'charge_taxes' => 'Cargar Impuestos',
'user_management' => 'Gestión de Usuario',
'add_user' => 'Añadir Usuario',
'send_invite' => 'Enviar Invitación', //Context for its use
'sent_invite' => 'Invitación enviada con éxito',
'updated_user' => 'Usario actualizado con éxito',
'invitation_message' => ':invitor te ha invitado a unirte a su cuenta en G-Factura.',
'register_to_add_user' => 'Regístrate para añadir usarios',
'user_state' => 'Estado',
'edit_user' => 'Editar Usario',
'delete_user' => 'Eliminar Usario',
'active' => 'Activo',
'pending' => 'Pendiente',
'deleted_user' => 'Usario eliminado con éxito',
'limit_users' => 'Lo sentimos, esta acción excederá el límite de ' . MAX_NUM_USERS . ' usarios',
'confirm_email_invoice' => '¿Estás seguro que quieres enviar esta factura?',
'confirm_email_quote' => '¿Estás seguro que quieres enviar este presupuesto?',
'confirm_recurring_email_invoice' => 'Se ha marcado esta factura como recurrente, estás seguro que quieres enviar esta factura?',
'cancel_account' => 'Cancelar Cuenta',
'cancel_account_message' => 'AVISO: Esta acción eliminará todos tus datos de forma permanente.',
'go_back' => 'Atrás',
'data_visualizations' => 'Visualización de Datos',
'sample_data' => 'Datos de Ejemplo',
'hide' => 'Ocultar',
'new_version_available' => 'Una nueva versión de :releases_link disponible. Estás utilizando la versión :user_version, la última versión es :latest_version',
'invoice_settings' => 'Configuración de Facturas',
'invoice_number_prefix' => 'Prefijo de Facturación',
'invoice_number_counter' => 'Numeración de Facturación',
'quote_number_prefix' => 'Prejijo de Presupuesto',
'quote_number_counter' => 'Numeración de Presupuestos',
'share_invoice_counter' => 'Compartir la numeración para presupuesto y facturación',
'invoice_issued_to' => 'Factura emitida a',
'invalid_counter' => 'Para evitar posibles conflictos, por favor crea un prefijo de facturación y de presupuesto.',
'mark_sent' => 'Marcar como enviado',
'gateway_help_1' => ':link para registrarse en Authorize.net.',
'gateway_help_2' => ':link para registrarse en Authorize.net.',
'gateway_help_17' => ':link para obtener su firma API de PayPal.',
'gateway_help_23' => 'Nota: utilizar su clave de API secreta, no es su clave de API publica.',
'gateway_help_27' => ':link para registrarse en TwoCheckout.',
'more_designs' => 'Más diseños',
'more_designs_title' => 'Diseños adicionales para factura',
'more_designs_cloud_header' => 'Pase a Pro para añadir más diseños de facturas',
'more_designs_cloud_text' => '',
'more_designs_self_host_header' => 'Obtenga 6 diseños más para facturas por sólo '.INVOICE_DESIGNS_PRICE, // comprobar
'more_designs_self_host_text' => '',
'buy' => 'Comprar',
'bought_designs' => 'Añadidos con exito los diseños de factura',
'sent' => 'Enviado',
'timesheets' => 'Parte de Horas',
'payment_title' => 'Introduzca su dirección de facturación y la infomración de su tarjeta de crédito',
'payment_cvv' => '*los tres últimos dígitos de la parte posterior de su tarjeta',
'payment_footer1' => '*La dirección de facturación debe coincidir con la de la tarjeta de crédito.',
'payment_footer2' => '*Por favor, haga clic en "Pagar ahora" sólo una vez - esta operación puede tardar hasta 1 minuto en procesarse.',
'vat_number' => 'NIF/CIF',
'id_number' => 'Número de Identificación',
'white_label_link' => 'Marca Blanca" ',
'white_label_text' => 'Obtener una licencia de marca blanca por'.WHITE_LABEL_PRICE.' para quitar la marca Invoice Ninja de la parte superior de las páginas del cliente.', // comprobar
'white_label_link' => 'Marca Blanca" ',
'bought_white_label' => 'Se ha conseguido con exito la licencia de Marca Blanca',
'white_labeled' => 'Marca Blanca',
'restore' => 'Restaurar',
'restore_invoice' => 'Restaurar Factura',
'restore_quote' => 'Restaurar Presupuesto',
'restore_client' => 'Restaurar Cliente',
'restore_credit' => 'Restaurar Pendiente',
'restore_payment' => 'Restaurar Pago',
'restored_invoice' => 'Factura restaurada con éxito',
'restored_quote' => 'Presupuesto restaurada con éxito',
'restored_client' => 'Cliente restaurada con éxito',
'restored_payment' => 'Pago restaurada con éxito',
'restored_credit' => 'Pendiente restaurada con éxito',
'reason_for_canceling' => 'Ayudenos a mejorar nuestro sitio diciendonos porque se va, Gracias',
'discount_percent' => 'Porcentaje',
'discount_amount' => 'Cantidad',
// Ver. 1.7.0
'invoice_history' => 'Historial de Facturas',
'quote_history' => 'Historial de Presupuestos',
'current_version' => 'Versión Actual',
'select_versiony' => 'Seleccione la Versión',
'view_history' => 'Ver Historial',
'edit_payment' => 'Editar Pago',
'updated_payment' => 'Pago actualizado correctamente',
'deleted' => 'Eliminado',
'restore_user' => 'Restaurar Usuario',
'restored_user' => 'Usuario restaurado correctamente',
'show_deleted_users' => 'Mostrar usuarios eliminados',
'email_templates' => 'Plantillas de Email',
'invoice_email' => 'Email de Facturas',
'payment_email' => 'Email de Pagos',
'quote_email' => 'Email de Presupuestos',
'reset_all' => 'Restablecer Todos',
'approve' => 'Aprobar',
'token_billing_type_id' => 'Token Billing', //¿?
'token_billing_help' => 'Permite almacenar tarjetas de crédito para posteriormente realizarles el cobro.',
'token_billing_1' => 'Deshabilitar',
'token_billing_2' => 'La casilla Opt-In se muestra pero no está seleccionada',
'token_billing_3' => 'La casilla Opt-Out se muestra y se selecciona',
'token_billing_4' => 'Siempre',
'token_billing_checkbox' => 'Almacenar datos de la tarjeta de crédito',
'view_in_stripe' => 'Ver en Stripe',
'use_card_on_file' => 'Use card on file', //??
'edit_payment_details' => 'Editar detalles de pago',
'token_billing' => 'Guardar datos de la tarjeta',
'token_billing_secure' => 'Los datos serán almacenados de forma segura por :stripe_link',
'support' => 'Soporte',
'contact_information' => 'Información de Contacto',
'256_encryption' => 'Encriptación de 256-Bit',
'amount_due' => 'Importe a pagar',
'billing_address' => 'Dirección de Envio',
'billing_method' => 'Método de facturación',
'order_overview' => 'Lista de pedidos',
'match_address' => '*La dirección debe coincidir con la dirección asociada a la tarjeta de crédito.',
'click_once' => '*Por favor, haga clic en "Pagar ahora" sólo una vez - la operación puede tardar hasta 1 minuto en ser procesada.',
'default_invoice_footer' => 'Establecer pie de página por defecto en factura',
'invoice_footer' => 'Pie de página de la factura',
'save_as_default_footer' => 'Guardar como pie de página por defecto',
'token_management' => 'Administrar Tokent', //?
'tokens' => 'Tokens',
'add_token' => 'Agregar Token',
'show_deleted_tokens' => 'Mostrar tokens eliminados',
'deleted_token' => 'Token eliminado correctamente',
'created_token' => 'Token creado correctamente',
'updated_token' => 'Token actualizado correctamente',
'edit_token' => 'Editar Token',
'delete_token' => 'Eliminar Token',
'token' => 'Token',
'add_gateway' => 'Agregar Pasarela',
'delete_gateway' => 'Eliminar Pasarela',
'edit_gateway' => 'Editar Pasarela',
'updated_gateway' => 'Pasarela actualizada correctamente',
'created_gateway' => 'Pasarela creada correctamente',
'deleted_gateway' => 'Pasarela eliminada correctamente',
'pay_with_paypal' => 'PayPal',
'pay_with_card' => 'Tarjeta de Crédito',
'change_password' => 'Cambiar Contraseña',
'current_password' => 'Contraseña Actual',
'new_password' => 'Nueva Contraseña',
'confirm_password' => 'Confirmar Contraseña',
'password_error_incorrect' => 'La contraseña actual es incorrecta.',
'password_error_invalid' => 'La nueva contraseña no es válida.',
'updated_password' => 'Contraseña actualizada correctamente',
'api_tokens' => 'API Tokens',
'users_and_tokens' => 'Usuarios & Tokens',
'account_login' => 'Iniciar Sesión',
'recover_password' => 'Recuperar su contraseña',
'forgot_password' => '¿Olvidaste tu contraseña?',
'email_address' => 'Dirección de Email',
'lets_go' => 'Acceder',
'password_recovery' => 'Recuperar Contraseña',
'send_email' => 'Enviar email',
'set_password' => 'Establecer Contraseña',
'converted' => 'Modificada',
//------Texto extraido -----------------------------------------------------------------------------------------
'<i>Manual entry</i>' => '<i>Entrada Manual</i>',
// Error
'Whoops, looks like something went wrong.' => 'Vaya, parece que algo salió mal',
'Sorry, the page you are looking for could not be found.' => 'Lo sentimos, la página que está buscando no se pudo encontrar.',
'email_approved' => 'Email me when a quote is <b>approved</b>',
'notification_quote_approved_subject' => 'Quote :invoice was approved by :client',
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

View File

@ -0,0 +1,108 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => ":attribute debe ser aceptado.",
"active_url" => ":attribute no es una URL válida.",
"after" => ":attribute debe ser una fecha posterior a :date.",
"alpha" => ":attribute solo debe contener letras.",
"alpha_dash" => ":attribute solo debe contener letras, números y guiones.",
"alpha_num" => ":attribute solo debe contener letras y números.",
"array" => ":attribute debe ser un conjunto.",
"before" => ":attribute debe ser una fecha anterior a :date.",
"between" => array(
"numeric" => ":attribute tiene que estar entre :min - :max.",
"file" => ":attribute debe pesar entre :min - :max kilobytes.",
"string" => ":attribute tiene que tener entre :min - :max caracteres.",
"array" => ":attribute tiene que tener entre :min - :max ítems.",
),
"confirmed" => "La confirmación de :attribute no coincide.",
"date" => ":attribute no es una fecha válida.",
"date_format" => ":attribute no corresponde al formato :format.",
"different" => ":attribute y :other deben ser diferentes.",
"digits" => ":attribute debe tener :digits dígitos.",
"digits_between" => ":attribute debe tener entre :min y :max dígitos.",
"email" => ":attribute no es un correo válido",
"exists" => ":attribute es inválido.",
"image" => ":attribute debe ser una imagen.",
"in" => ":attribute es inválido.",
"integer" => ":attribute debe ser un número entero.",
"ip" => ":attribute debe ser una dirección IP válida.",
"max" => array(
"numeric" => ":attribute no debe ser mayor a :max.",
"file" => ":attribute no debe ser mayor que :max kilobytes.",
"string" => ":attribute no debe ser mayor que :max caracteres.",
"array" => ":attribute no debe tener más de :max elementos.",
),
"mimes" => ":attribute debe ser un archivo con formato: :values.",
"min" => array(
"numeric" => "El tamaño de :attribute debe ser de al menos :min.",
"file" => "El tamaño de :attribute debe ser de al menos :min kilobytes.",
"string" => ":attribute debe contener al menos :min caracteres.",
"array" => ":attribute debe tener al menos :min elementos.",
),
"not_in" => ":attribute es inválido.",
"numeric" => ":attribute debe ser numérico.",
"regex" => "El formato de :attribute es inválido.",
"required" => "El campo :attribute es obligatorio.",
"required_if" => "El campo :attribute es obligatorio cuando :other es :value.",
"required_with" => "El campo :attribute es obligatorio cuando :values está presente.",
"required_with_all" => "The :attribute field is required when :values is present.",
"required_without" => "El campo :attribute es obligatorio cuando :values no está presente.",
"required_without_all" => "The :attribute field is required when none of :values are present.",
"same" => ":attribute y :other deben coincidir.",
"size" => array(
"numeric" => "El tamaño de :attribute debe ser :size.",
"file" => "El tamaño de :attribute debe ser :size kilobytes.",
"string" => ":attribute debe contener :size caracteres.",
"array" => ":attribute debe contener :size elementos.",
),
"unique" => ":attribute ya ha sido registrado.",
"url" => "El formato :attribute es inválido.",
"positive" => ":attribute debe ser mayor que cero.",
"has_credit" => "el cliente no tiene crédito suficiente.",
"notmasked" => "The values are masked",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
);

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Free Open-Source Online Invoicing',
'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.',
'invoice_now' => 'Invoice Now',
'no_signup_needed' => 'No signup needed',
'link_blog' => 'Blog',
'link_about_us' => 'About Us',
'link_contact_us' => 'Contact Us',
'link_features' => 'Features',
'link_plans' => 'Plans',
'link_compare' => 'Compare',
'link_testimonials' => 'Testimonials',
'link_faq' => 'FAQ',
'my_account' => 'My Account',
'login' => 'Login',
'connect_with_us' => 'Connect with Us',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Toggle navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Free, Always',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'What is Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, special requests, or just want to say hi?',
'sub_header' => 'Fill in the form below and we\'ll get back to you as soon as possible. Hope to hear from you!',
'other_ways' => 'Other ways to reach us',
'name' => 'Name',
'name_help' => 'Please enter your name.',
'email' => 'Email Address',
'email_help' => 'Please enter a valid e-mail address.',
'message' => 'Message',
'message_help' => 'Please enter a message.',
'send_message' => 'Send Message',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -255,7 +255,7 @@ return array(
'confirmation_subject' => 'Validation du compte invoice ninja',
'confirmation_header' => 'Validation du compte',
'confirmation_message' => 'Veuillez cliquer sur le lien ci-après pour valider votre compte.',
'invoice_subject' => 'Nouvelle facture en provenance de :account',
'invoice_subject' => 'Nouvelle facture :invoice en provenance de :account',
'invoice_message' => 'Pour voir votre facture de :amount, Cliquez sur le lien ci-après.',
'payment_subject' => 'Paiement reçu',
'payment_message' => 'Merci pour votre paiement d\'un montant de :amount',
@ -578,5 +578,45 @@ return array(
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

View File

@ -572,5 +572,50 @@ return array(
'set_password' => 'Set Password',
'converted' => 'Converted',
'email_approved' => 'Email me when a quote is <b>approved</b>',
'notification_quote_approved_subject' => 'Quote :invoice was approved by :client',
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Free Open-Source Online Invoicing',
'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.',
'invoice_now' => 'Invoice Now',
'no_signup_needed' => 'No signup needed',
'link_blog' => 'Blog',
'link_about_us' => 'About Us',
'link_contact_us' => 'Contact Us',
'link_features' => 'Features',
'link_plans' => 'Plans',
'link_compare' => 'Compare',
'link_testimonials' => 'Testimonials',
'link_faq' => 'FAQ',
'my_account' => 'My Account',
'login' => 'Login',
'connect_with_us' => 'Connect with Us',
'safe_and_secure' => 'Safe & Secure',
'toggle_navigation' => 'Toggle navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Free, Always',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Open-Source',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'What is Invoice Ninja?',
'team_ninja' => 'Team Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, special requests, or just want to say hi?',
'sub_header' => 'Fill in the form below and we\'ll get back to you as soon as possible. Hope to hear from you!',
'other_ways' => 'Other ways to reach us',
'name' => 'Name',
'name_help' => 'Please enter your name.',
'email' => 'Email Address',
'email_help' => 'Please enter a valid e-mail address.',
'message' => 'Message',
'message_help' => 'Please enter a message.',
'send_message' => 'Send Message',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'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>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -255,7 +255,7 @@ return array(
'confirmation_subject' => 'Conferma Account Invoice Ninja',
'confirmation_header' => 'Conferma Account',
'confirmation_message' => 'Per favore, accedi al link qui sotto per confermare il tuo account.',
'invoice_subject' => 'Nuova fattura da :account',
'invoice_subject' => 'Nuova fattura :invoice da :account',
'invoice_message' => 'Per visualizzare la tua fattura di :amount, clicca sul link qui sotto.',
'payment_subject' => 'Pagamento Ricevuto',
'payment_message' => 'Grazie per il tuo pagamento di :amount.',
@ -580,5 +580,44 @@ return array(
'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
'payment_type_bitcoin' => 'Bitcoin',
'knowledge_base' => 'Knowledge Base',
'partial' => 'Partial',
'partial_remaining' => ':partial of :balance',
'more_fields' => 'More Fields',
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
'provide_name_or_email' => 'Please provide a contact name or email',
'charts_and_reports' => 'Charts & Reports',
'chart' => 'Chart',
'report' => 'Report',
'group_by' => 'Group by',
'paid' => 'Paid',
'enable_report' => 'Report',
'enable_chart' => 'Chart',
'totals' => 'Totals',
'run' => 'Run',
'export' => 'Export',
'documentation' => 'Documentation',
'zapier' => 'Zapier <sup>Beta</sup>',
'recurring' => 'Recurring',
'last_invoice_sent' => 'Last invoice sent :date',
);

Some files were not shown because too many files have changed in this diff Show More