Working on OFX support

This commit is contained in:
Hillel Coren 2016-01-26 22:22:33 +02:00
parent c96c91ec88
commit efc9ab4f9e
60 changed files with 2774 additions and 659 deletions

View File

@ -19,12 +19,14 @@ class TestOFX extends Command
{
$this->info(date('Y-m-d').' Running TestOFX...');
/*
$bankId = env('TEST_BANK_ID');
$username = env('TEST_BANK_USERNAME');
$password = env('TEST_BANK_PASSWORD');
$data = $this->bankAccountService->loadBankAccounts($bankId, $username, $password, false);
print "<pre>".print_r($data, 1)."</pre>";
echo json_encode($data);
*/
}
}

View File

@ -247,6 +247,7 @@ class AppController extends BaseController
Artisan::call('migrate', array('--force' => true));
Artisan::call('db:seed', array('--force' => true, '--class' => 'PaymentLibrariesSeeder'));
Artisan::call('db:seed', array('--force' => true, '--class' => 'FontsSeeder'));
Artisan::call('db:seed', array('--force' => true, '--class' => 'BanksSeeder'));
Event::fire(new UserSettingsChanged());
Session::flash('message', trans('texts.processed_updates'));
} catch (Exception $e) {

View File

@ -1,6 +1,5 @@
<?php namespace App\Http\Controllers;
use Crypt;
use Cache;
use Auth;
use Datatable;
@ -11,23 +10,27 @@ use Session;
use View;
use Validator;
use stdClass;
use Crypt;
use URL;
use Utils;
use App\Models\Gateway;
use App\Models\Account;
use App\Models\BankAccount;
use App\Ninja\Repositories\AccountRepository;
use App\Ninja\Repositories\BankAccountRepository;
use App\Services\BankAccountService;
use App\Http\Requests\CreateBankAccountRequest;
class BankAccountController extends BaseController
{
protected $bankAccountService;
protected $bankAccountRepo;
public function __construct(BankAccountService $bankAccountService)
public function __construct(BankAccountService $bankAccountService, BankAccountRepository $bankAccountRepo)
{
parent::__construct();
$this->bankAccountService = $bankAccountService;
$this->bankAccountRepo = $bankAccountRepo;
}
public function index()
@ -43,11 +46,8 @@ class BankAccountController extends BaseController
public function edit($publicId)
{
$bankAccount = BankAccount::scope($publicId)->firstOrFail();
$bankAccount->username = str_repeat('*', 16);
$data = [
'url' => 'bank_accounts/' . $publicId,
'method' => 'PUT',
'title' => trans('texts.edit_bank_account'),
'banks' => Cache::get('banks'),
'bankAccount' => $bankAccount,
@ -61,11 +61,6 @@ class BankAccountController extends BaseController
return $this->save($publicId);
}
public function store()
{
return $this->save();
}
/**
* Displays the form for account creation
*
@ -73,9 +68,6 @@ class BankAccountController extends BaseController
public function create()
{
$data = [
'url' => 'bank_accounts',
'method' => 'POST',
'title' => trans('texts.add_bank_account'),
'banks' => Cache::get('banks'),
'bankAccount' => null,
];
@ -94,59 +86,40 @@ class BankAccountController extends BaseController
return Redirect::to('settings/' . ACCOUNT_BANKS);
}
/**
* Stores new account
*
*/
public function save($bankAccountPublicId = false)
public function validateAccount()
{
$account = Auth::user()->account;
$publicId = Input::get('public_id');
$username = trim(Input::get('bank_username'));
$password = trim(Input::get('bank_password'));
if ($publicId) {
$bankAccount = BankAccount::scope($publicId)->firstOrFail();
if ($username != $bankAccount->username) {
// TODO update username
}
$username = Crypt::decrypt($username);
$bankId = $bankAccount->bank_id;
} else {
$bankId = Input::get('bank_id');
$username = Input::get('bank_username');
$rules = [
'bank_id' => $bankAccountPublicId ? '' : 'required',
'bank_username' => 'required',
];
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('bank_accounts/create')
->withErrors($validator)
->withInput();
} else {
if ($bankAccountPublicId) {
$bankAccount = BankAccount::scope($bankAccountPublicId)->firstOrFail();
} else {
$bankAccount = BankAccount::createNew();
$bankAccount->bank_id = $bankId;
}
if ($username != str_repeat('*', strlen($username))) {
$bankAccount->username = Crypt::encrypt(trim($username));
return json_encode($this->bankAccountService->loadBankAccounts($bankId, $username, $password, $publicId));
}
if ($bankAccountPublicId) {
$bankAccount->save();
$message = trans('texts.updated_bank_account');
} else {
$account->bank_accounts()->save($bankAccount);
$message = trans('texts.created_bank_account');
}
Session::flash('message', $message);
return Redirect::to("bank_accounts/{$bankAccount->public_id}/edit");
}
}
public function test()
public function store(CreateBankAccountRequest $request)
{
$bankAccount = $this->bankAccountRepo->save(Input::all());
$bankId = Input::get('bank_id');
$username = Input::get('bank_username');
$password = Input::get('bank_password');
$username = trim(Input::get('bank_username'));
$password = trim(Input::get('bank_password'));
return json_encode($this->bankAccountService->loadBankAccounts($bankId, $username, $password, false));
return json_encode($this->bankAccountService->loadBankAccounts($bankId, $username, $password, true));
}
public function importExpenses($bankId)
{
return $this->bankAccountService->importExpenses($bankId, Input::all());
}
}

View File

@ -55,7 +55,8 @@ class VendorController extends BaseController
'columns' => Utils::trans([
'checkbox',
'vendor',
'contact',
'city',
'phone',
'email',
'date_created',
''

View File

@ -0,0 +1,32 @@
<?php namespace app\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class CreateBankAccountRequest extends Request
{
// Expenses
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'bank_id' => 'required',
'bank_username' => 'required',
'bank_password' => 'required',
];
}
}

View File

@ -1,5 +1,6 @@
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
@ -140,7 +141,8 @@ Route::group(['middleware' => 'auth'], function() {
Route::resource('bank_accounts', 'BankAccountController');
Route::get('api/bank_accounts', array('as'=>'api.bank_accounts', 'uses'=>'BankAccountController@getDatatable'));
Route::post('bank_accounts/bulk', 'BankAccountController@bulk');
Route::post('bank_accounts/test', 'BankAccountController@test');
Route::post('bank_accounts/validate', 'BankAccountController@validateAccount');
Route::post('bank_accounts/import_expenses/{bank_id}', 'BankAccountController@importExpenses');
Route::resource('clients', 'ClientController');
Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable'));
@ -283,7 +285,6 @@ if (!defined('CONTACT_EMAIL')) {
define('ENTITY_QUOTE', 'quote');
define('ENTITY_TASK', 'task');
define('ENTITY_ACCOUNT_GATEWAY', 'account_gateway');
define('ENTITY_BANK_ACCOUNT', 'bank_account');
define('ENTITY_USER', 'user');
define('ENTITY_TOKEN', 'token');
define('ENTITY_TAX_RATE', 'tax_rate');
@ -294,6 +295,8 @@ if (!defined('CONTACT_EMAIL')) {
define('ENTITY_EXPENSE', 'expense');
define('ENTITY_PAYMENT_TERM', 'payment_term');
define('ENTITY_EXPENSE_ACTIVITY', 'expense_activity');
define('ENTITY_BANK_ACCOUNT', 'bank_account');
define('ENTITY_BANK_SUBACCOUNT', 'bank_subaccount');
define('PERSON_CONTACT', 'contact');
define('PERSON_USER', 'user');
@ -309,6 +312,7 @@ if (!defined('CONTACT_EMAIL')) {
define('ACCOUNT_IMPORT_EXPORT', 'import_export');
define('ACCOUNT_PAYMENTS', 'online_payments');
define('ACCOUNT_BANKS', 'bank_accounts');
define('ACCOUNT_IMPORT_EXPENSES', 'import_expenses');
define('ACCOUNT_MAP', 'import_map');
define('ACCOUNT_EXPORT', 'export');
define('ACCOUNT_TAX_RATES', 'tax_rates');
@ -512,6 +516,7 @@ if (!defined('CONTACT_EMAIL')) {
define('PHP_DATE_FORMATS', 'http://php.net/manual/en/function.date.php');
define('REFERRAL_PROGRAM_URL', 'https://www.invoiceninja.com/referral-program/');
define('EMAIL_MARKUP_URL', 'https://developers.google.com/gmail/markup');
define('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all');
define('COUNT_FREE_DESIGNS', 4);
define('COUNT_FREE_DESIGNS_SELF_HOST', 5); // include the custom design

View File

@ -24,8 +24,9 @@ class OFX
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/x-ofx'));
curl_setopt($c, CURLOPT_POSTFIELDS, $this->request);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
$this->response = curl_exec($c);
//print_r($this->response);
//\Log::info(print_r($this->response, true));
curl_close($c);
$tmp = explode('<OFX>', $this->response);
$this->responseHeader = $tmp[0];

View File

@ -26,7 +26,7 @@ class Account extends Eloquent
ACCOUNT_USER_DETAILS,
ACCOUNT_LOCALIZATION,
ACCOUNT_PAYMENTS,
//ACCOUNT_BANKS,
ACCOUNT_BANKS,
ACCOUNT_TAX_RATES,
ACCOUNT_PRODUCTS,
ACCOUNT_NOTIFICATIONS,

View File

@ -19,5 +19,9 @@ class BankAccount extends EntityModel
return $this->belongsTo('App\Models\Bank');
}
public function bank_subaccounts()
{
return $this->hasMany('App\Models\BankSubaccount');
}
}

View File

@ -0,0 +1,23 @@
<?php namespace App\Models;
use Crypt;
use App\Models\Bank;
use Illuminate\Database\Eloquent\SoftDeletes;
class BankSubaccount extends EntityModel
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function getEntityType()
{
return ENTITY_BANK_SUBACCOUNT;
}
public function bank_account()
{
return $this->belongsTo('App\Models\BankAccount');
}
}

View File

@ -24,6 +24,8 @@ class Expense extends EntityModel
'exchange_rate',
'private_notes',
'public_notes',
'bank_id',
'transaction_id',
];
public function account()
{

View File

@ -29,6 +29,7 @@ class Vendor extends EntityModel
'private_notes',
'currency_id',
'website',
'transaction_name',
];
public static $fieldName = 'name';

View File

@ -1,9 +1,11 @@
<?php namespace App\Ninja\Repositories;
use DB;
use Crypt;
use Utils;
use Session;
use App\Models\BankAccount;
use App\Models\BankSubaccount;
use App\Ninja\Repositories\BaseRepository;
class BankAccountRepository extends BaseRepository
@ -19,6 +21,34 @@ class BankAccountRepository extends BaseRepository
->join('banks', 'banks.id', '=', 'bank_accounts.bank_id')
->where('bank_accounts.deleted_at', '=', null)
->where('bank_accounts.account_id', '=', $accountId)
->select('bank_accounts.public_id', 'banks.name as bank_name', 'bank_accounts.deleted_at', 'banks.bank_library_id');
->select(
'bank_accounts.public_id',
'banks.name as bank_name',
'bank_accounts.deleted_at',
'banks.bank_library_id'
);
}
public function save($input)
{
$bankAccount = BankAccount::createNew();
$bankAccount->bank_id = $input['bank_id'];
$bankAccount->username = Crypt::encrypt(trim($input['bank_username']));
$account = \Auth::user()->account;
$account->bank_accounts()->save($bankAccount);
foreach ($input['bank_accounts'] as $data) {
if ( ! isset($data['include']) || ! filter_var($data['include'], FILTER_VALIDATE_BOOLEAN)) {
continue;
}
$subaccount = BankSubaccount::createNew();
$subaccount->account_name = trim($data['account_name']);
$subaccount->account_number = trim($data['hashed_account_number']);
$bankAccount->bank_subaccounts()->save($subaccount);
}
return $bankAccount;
}
}

View File

@ -26,11 +26,12 @@ class ExpenseRepository extends BaseRepository
public function findVendor($vendorPublicId)
{
$vendorId = Vendor::getPrivateId($vendorPublicId);
$accountid = \Auth::user()->account_id;
$query = DB::table('expenses')
->join('accounts', 'accounts.id', '=', 'expenses.account_id')
->where('expenses.account_id', '=', $accountid)
->where('expenses.vendor_id', '=', $vendorPublicId)
->where('expenses.vendor_id', '=', $vendorId)
->select(
'expenses.id',
'expenses.expense_date',
@ -119,7 +120,10 @@ class ExpenseRepository extends BaseRepository
$expense->fill($input);
$expense->expense_date = Utils::toSqlDate($input['expense_date']);
if (isset($input['private_notes'])) {
$expense->private_notes = trim($input['private_notes']);
}
$expense->public_notes = trim($input['public_notes']);
$expense->should_be_invoiced = isset($input['should_be_invoiced']) || $expense->client_id ? true : false;

View File

@ -39,6 +39,7 @@ class VendorRepository extends BaseRepository
'vendor_contacts.last_name',
'vendors.created_at',
'vendors.work_phone',
'vendors.city',
'vendor_contacts.email',
'vendors.deleted_at',
'vendors.is_deleted'
@ -73,10 +74,6 @@ class VendorRepository extends BaseRepository
$vendor->fill($data);
$vendor->save();
if ( ! isset($data['vendorcontact']) && ! isset($data['vendorcontacts'])) {
return $vendor;
}
$first = true;
$vendorcontacts = isset($data['vendorcontact']) ? [$data['vendorcontact']] : $data['vendorcontacts'];

View File

@ -3,21 +3,30 @@
use stdClass;
use Utils;
use URL;
use Hash;
use App\Models\Gateway;
use App\Models\BankSubaccount;
use App\Models\Vendor;
use App\Models\Expense;
use App\Services\BaseService;
use App\Ninja\Repositories\BankAccountRepository;
use App\Ninja\Repositories\ExpenseRepository;
use App\Ninja\Repositories\VendorRepository;
use App\Libraries\Finance;
use App\Libraries\Login;
class BankAccountService extends BaseService
{
protected $bankAccountRepo;
protected $expenseRepo;
protected $vendorRepo;
protected $datatableService;
public function __construct(BankAccountRepository $bankAccountRepo, DatatableService $datatableService)
public function __construct(BankAccountRepository $bankAccountRepo, ExpenseRepository $expenseRepo, VendorRepository $vendorRepo, DatatableService $datatableService)
{
$this->bankAccountRepo = $bankAccountRepo;
$this->vendorRepo = $vendorRepo;
$this->expenseRepo = $expenseRepo;
$this->datatableService = $datatableService;
}
@ -26,22 +35,31 @@ class BankAccountService extends BaseService
return $this->bankAccountRepo;
}
/*
public function save()
{
return null;
}
*/
public function loadBankAccounts($bankId, $username, $password, $includeTransactions = true)
{
if ( ! $bankId || ! $username || ! $password) {
return false;
}
$expenses = Expense::scope()
->whereBankId($bankId)
->where('transaction_id', '!=', '')
->withTrashed()
->get(['transaction_id'])
->toArray();
$expenses = array_flip(array_map(function($val) {
return $val['transaction_id'];
}, $expenses));
$bankAccounts = BankSubaccount::scope()
->whereHas('bank_account', function($query) use ($bankId) {
$query->where('bank_id', '=', $bankId);
})
->get();
$bank = Utils::getFromCache($bankId, 'banks');
$data = [];
// load OFX trnansactions
try {
$finance = new Finance();
$finance->banks[$bankId] = $bank->getOFXBank($finance);
@ -52,11 +70,9 @@ class BankAccountService extends BaseService
$login->setup();
foreach ($login->accounts as $account) {
$account->setup($includeTransactions);
$obj = new stdClass;
$obj->account_number = Utils::maskAccountNumber($account->id);
$obj->type = $account->type;
$obj->balance = Utils::formatMoney($account->ledgerBalance, CURRENCY_DOLLAR);
$data[] = $obj;
if ($account = $this->parseBankAccount($account, $bankAccounts, $expenses, $includeTransactions)) {
$data[] = $account;
}
}
}
}
@ -67,6 +83,124 @@ class BankAccountService extends BaseService
}
}
private function parseBankAccount($account, $bankAccounts, $expenses, $includeTransactions)
{
$obj = new stdClass;
$obj->account_name = '';
// look up bank account name
foreach ($bankAccounts as $bankAccount) {
if (Hash::check($account->id, $bankAccount->account_number)) {
$obj->account_name = $bankAccount->account_name;
}
}
// if we can't find a match skip the account
if (count($bankAccounts) && ! $obj->account_name) {
return false;
}
$obj->masked_account_number = Utils::maskAccountNumber($account->id);
$obj->hashed_account_number = bcrypt($account->id);
$obj->type = $account->type;
$obj->balance = Utils::formatMoney($account->ledgerBalance, CURRENCY_DOLLAR);
if ($includeTransactions) {
$ofxParser = new \OfxParser\Parser;
$ofx = $ofxParser->loadFromString($account->response);
$obj->start_date = $ofx->BankAccount->Statement->startDate;
$obj->end_date = $ofx->BankAccount->Statement->endDate;
$obj->transactions = [];
foreach ($ofx->BankAccount->Statement->transactions as $transaction) {
// ensure transactions aren't imported as expenses twice
if (isset($expenses[$transaction->uniqueId])) {
continue;
}
if ($transaction->amount >= 0) {
continue;
}
$transaction->vendor = $this->prepareValue(substr($transaction->name, 0, 20));
$transaction->info = $this->prepareValue(substr($transaction->name, 20));
$transaction->memo = $this->prepareValue($transaction->memo);
$transaction->date = \Auth::user()->account->formatDate($transaction->date);
$transaction->amount *= -1;
$obj->transactions[] = $transaction;
}
}
return $obj;
}
private function prepareValue($value) {
return ucwords(strtolower(trim($value)));
}
public function importExpenses($bankId, $input) {
$countVendors = 0;
$countExpenses = 0;
// create a vendor map
$vendorMap = [];
$vendors = Vendor::scope()
->withTrashed()
->get(['id', 'name', 'transaction_name']);
foreach ($vendors as $vendor) {
$vendorMap[strtolower($vendor->name)] = $vendor;
$vendorMap[strtolower($vendor->transaction_name)] = $vendor;
}
foreach ($input as $transaction) {
$vendorName = $transaction['vendor'];
$key = strtolower($vendorName);
$info = $transaction['info'];
// find vendor otherwise create it
if (isset($vendorMap[$key])) {
$vendor = $vendorMap[$key];
} else {
$field = $this->determineInfoField($info);
$vendor = $this->vendorRepo->save([
$field => $info,
'name' => $vendorName,
'transaction_name' => $transaction['vendor_orig'],
'vendorcontact' => []
]);
$vendorMap[$key] = $vendor;
$vendorMap[$transaction['vendor_orig']] = $vendor;
$countVendors++;
}
// create the expense record
$this->expenseRepo->save([
'vendor_id' => $vendor->id,
'amount' => $transaction['amount'],
'public_notes' => $transaction['memo'],
'expense_date' => $transaction['date'],
'transaction_id' => $transaction['id'],
'bank_id' => $bankId,
'should_be_invoiced' => true,
]);
$countExpenses++;
}
return trans('texts.imported_expenses', [
'count_vendors' => $countVendors,
'count_expenses' => $countExpenses
]);
}
private function determineInfoField($value) {
if (preg_match("/^[0-9\-\(\)\.]+$/", $value)) {
return 'work_phone';
} elseif (strpos($value, '.') !== false) {
return 'private_notes';
} else {
return 'city';
}
}
public function getDatatable($accountId)
{
$query = $this->bankAccountRepo->find($accountId);

View File

@ -50,9 +50,15 @@ class VendorService extends BaseService
}
],
[
'first_name',
'city',
function ($model) {
return link_to("vendors/{$model->public_id}", $model->first_name.' '.$model->last_name);
return $model->city;
}
],
[
'work_phone',
function ($model) {
return $model->work_phone;
}
],
[

View File

@ -7,16 +7,13 @@
{
"name": "Hillel Coren",
"email": "hillelcoren@gmail.com"
},
{
"name": "Jeramy Simpson",
"email": "jeramy.n.simpson@gmail.com"
}
],
"require": {
"omnipay/mollie": "dev-master#22956c1a62a9662afa5f5d119723b413770ac525",
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
"omnipay/gocardless": "dev-master",
"omnipay/stripe": "2.3.0",
"laravel/framework": "5.0.*",
"patricktalmadge/bootstrapper": "5.5.x",
"anahkiasen/former": "4.0.*@dev",
@ -25,7 +22,7 @@
"omnipay/omnipay": "~2.3.0",
"intervention/image": "dev-master",
"webpatser/laravel-countries": "dev-master",
"barryvdh/laravel-ide-helper": "^2.1",
"barryvdh/laravel-ide-helper": "dev-master",
"doctrine/dbal": "2.5.x",
"jsanc623/phpbenchtime": "2.x",
"lokielse/omnipay-alipay": "dev-master",
@ -66,7 +63,8 @@
"jlapp/swaggervel": "master-dev",
"maatwebsite/excel": "~2.0",
"ezyang/htmlpurifier": "~v4.7",
"cerdic/css-tidy": "~v1.5"
"cerdic/css-tidy": "~v1.5",
"asgrim/ofxparser": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "~4.0",

386
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "9ed916108c17ac2634ffc4b9676098d1",
"content-hash": "e5177cc53f079158f3180a7e4ef0ded6",
"hash": "6e219bb4f5ffaf8423177bd6fccc89f8",
"content-hash": "4778ab164bfb93c4af1bb51c4320ea4c",
"packages": [
{
"name": "agmscode/omnipay-agms",
@ -123,12 +123,12 @@
"source": {
"type": "git",
"url": "https://github.com/alfaproject/omnipay-skrill.git",
"reference": "2fa2ba8083fd5289366660f8de1b46b5f49ac052"
"reference": "41a7a03c5b90d496720e288bebc157d898837ccd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/alfaproject/omnipay-skrill/zipball/41a7a03c5b90d496720e288bebc157d898837ccd",
"reference": "2fa2ba8083fd5289366660f8de1b46b5f49ac052",
"reference": "41a7a03c5b90d496720e288bebc157d898837ccd",
"shasum": ""
},
"require": {
@ -169,7 +169,7 @@
"payment",
"skrill"
],
"time": "2014-02-25 13:40:07"
"time": "2016-01-13 16:33:07"
},
{
"name": "anahkiasen/former",
@ -323,6 +323,58 @@
],
"time": "2015-03-19 21:32:19"
},
{
"name": "asgrim/ofxparser",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/asgrim/ofxparser.git",
"reference": "7652efea77a1c5dda007f9764d8061f870248ea1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asgrim/ofxparser/zipball/7652efea77a1c5dda007f9764d8061f870248ea1",
"reference": "7652efea77a1c5dda007f9764d8061f870248ea1",
"shasum": ""
},
"require": {
"php": ">=5.4"
},
"type": "library",
"autoload": {
"psr-0": {
"OfxParser": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guillaume Bailleul",
"email": "contact@guillaume-bailleul.fr",
"homepage": "http://www.guillaume-bailleul.fr"
},
{
"name": "James Titcumb",
"email": "hello@jamestitcumb.com",
"homepage": "http://www.jamestitcumb.com/"
},
{
"name": "Oliver Lowe",
"email": "mrtriangle@gmail.com"
}
],
"description": "Simple OFX file parser",
"keywords": [
"finance",
"ofx",
"open financial exchange",
"parser"
],
"time": "2015-12-11 11:08:57"
},
{
"name": "barryvdh/laravel-debugbar",
"version": "v2.0.6",
@ -379,25 +431,25 @@
},
{
"name": "barryvdh/laravel-ide-helper",
"version": "v2.0.6",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "037386153630a7515a1542f29410d8c267651689"
"reference": "aa8f772a46c35ecdcb7119f38772ac2ec952a941"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/037386153630a7515a1542f29410d8c267651689",
"reference": "037386153630a7515a1542f29410d8c267651689",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/aa8f772a46c35ecdcb7119f38772ac2ec952a941",
"reference": "aa8f772a46c35ecdcb7119f38772ac2ec952a941",
"shasum": ""
},
"require": {
"illuminate/console": "5.0.x|5.1.x",
"illuminate/filesystem": "5.0.x|5.1.x",
"illuminate/support": "5.0.x|5.1.x",
"illuminate/console": "5.0.x|5.1.x|5.2.x",
"illuminate/filesystem": "5.0.x|5.1.x|5.2.x",
"illuminate/support": "5.0.x|5.1.x|5.2.x",
"php": ">=5.4.0",
"phpdocumentor/reflection-docblock": "2.0.4",
"symfony/class-loader": "~2.3"
"symfony/class-loader": "~2.3|~3.0"
},
"require-dev": {
"doctrine/dbal": "~2.3"
@ -408,7 +460,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "2.1-dev"
}
},
"autoload": {
@ -438,7 +490,7 @@
"phpstorm",
"sublime"
],
"time": "2015-06-25 08:58:59"
"time": "2016-01-22 13:33:15"
},
{
"name": "cardgate/omnipay-cardgate",
@ -1272,33 +1324,33 @@
},
{
"name": "doctrine/cache",
"version": "v1.5.4",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136"
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/47cdc76ceb95cc591d9c79a36dc3794975b5d136",
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136",
"url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": ">=3.7",
"phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5.x-dev"
"dev-master": "1.6.x-dev"
}
},
"autoload": {
@ -1338,7 +1390,7 @@
"cache",
"caching"
],
"time": "2015-12-19 05:03:47"
"time": "2015-12-31 16:37:02"
},
{
"name": "doctrine/collections",
@ -1481,16 +1533,16 @@
},
{
"name": "doctrine/dbal",
"version": "v2.5.3",
"version": "v2.5.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "2fbcea96eae34a53183377cdbb0b9bec33974648"
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/2fbcea96eae34a53183377cdbb0b9bec33974648",
"reference": "2fbcea96eae34a53183377cdbb0b9bec33974648",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
"shasum": ""
},
"require": {
@ -1548,7 +1600,7 @@
"persistence",
"queryobject"
],
"time": "2015-12-25 16:28:24"
"time": "2016-01-05 22:11:12"
},
{
"name": "doctrine/inflector",
@ -2091,16 +2143,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.2.1",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb",
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb",
"shasum": ""
},
"require": {
@ -2145,7 +2197,7 @@
"stream",
"uri"
],
"time": "2015-11-03 01:34:55"
"time": "2016-01-23 01:23:02"
},
{
"name": "illuminate/html",
@ -2254,12 +2306,12 @@
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70"
"reference": "86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931",
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70",
"reference": "86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931",
"shasum": ""
},
"require": {
@ -2308,7 +2360,7 @@
"thumbnail",
"watermark"
],
"time": "2015-12-04 17:09:36"
"time": "2016-01-10 11:20:02"
},
{
"name": "ircmaxell/password-compat",
@ -3232,12 +3284,12 @@
"source": {
"type": "git",
"url": "https://github.com/lokielse/omnipay-alipay.git",
"reference": "cbfbee089e0a84a58c73e9d3794894b81a6a82d6"
"reference": "f39ce21a5cbfe5c7cd4108d264b398dbd42be05b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/cbfbee089e0a84a58c73e9d3794894b81a6a82d6",
"reference": "cbfbee089e0a84a58c73e9d3794894b81a6a82d6",
"url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/f39ce21a5cbfe5c7cd4108d264b398dbd42be05b",
"reference": "f39ce21a5cbfe5c7cd4108d264b398dbd42be05b",
"shasum": ""
},
"require": {
@ -3273,7 +3325,7 @@
"payment",
"purchase"
],
"time": "2015-10-07 09:33:48"
"time": "2016-01-19 15:08:12"
},
{
"name": "maatwebsite/excel",
@ -3463,12 +3515,12 @@
"source": {
"type": "git",
"url": "https://github.com/meebio/omnipay-secure-trading.git",
"reference": "42f97ee5ad1d28605550d816fc1893919e19e502"
"reference": "992224a3c8dd834ee18f6f253a77ecb4c87c1c1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/meebio/omnipay-secure-trading/zipball/992224a3c8dd834ee18f6f253a77ecb4c87c1c1a",
"reference": "42f97ee5ad1d28605550d816fc1893919e19e502",
"reference": "992224a3c8dd834ee18f6f253a77ecb4c87c1c1a",
"shasum": ""
},
"require": {
@ -3513,7 +3565,7 @@
"secure trading",
"securetrading"
],
"time": "2015-12-01 10:03:20"
"time": "2016-01-05 09:26:36"
},
{
"name": "mfauveau/omnipay-pacnet",
@ -4363,16 +4415,16 @@
},
{
"name": "omnipay/firstdata",
"version": "v2.2.0",
"version": "v2.3.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-firstdata.git",
"reference": "0853bba0ee313f5557eb1c696d3ce5538dbd4aca"
"reference": "e33826821db88d90886cad6c81a29452d3cf91a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/0853bba0ee313f5557eb1c696d3ce5538dbd4aca",
"reference": "0853bba0ee313f5557eb1c696d3ce5538dbd4aca",
"url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/e33826821db88d90886cad6c81a29452d3cf91a2",
"reference": "e33826821db88d90886cad6c81a29452d3cf91a2",
"shasum": ""
},
"require": {
@ -4417,7 +4469,7 @@
"pay",
"payment"
],
"time": "2015-07-28 17:50:44"
"time": "2016-01-14 06:24:28"
},
{
"name": "omnipay/gocardless",
@ -5112,16 +5164,16 @@
},
{
"name": "omnipay/paypal",
"version": "2.5.0",
"version": "v2.5.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-paypal.git",
"reference": "67efe5a927dec13fc7520e29bc44f15fd3a728e9"
"reference": "b546d24241725061d44e60516f0fbce202336963"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/67efe5a927dec13fc7520e29bc44f15fd3a728e9",
"reference": "67efe5a927dec13fc7520e29bc44f15fd3a728e9",
"url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/b546d24241725061d44e60516f0fbce202336963",
"reference": "b546d24241725061d44e60516f0fbce202336963",
"shasum": ""
},
"require": {
@ -5166,20 +5218,20 @@
"paypal",
"purchase"
],
"time": "2015-11-11 21:48:00"
"time": "2016-01-13 07:03:27"
},
{
"name": "omnipay/pin",
"version": "v2.1.0",
"version": "v2.2.1",
"source": {
"type": "git",
"url": "https://github.com/omnipay/pin.git",
"reference": "04e778e9689882d4c40419263014068b69b93168"
"url": "https://github.com/thephpleague/omnipay-pin.git",
"reference": "c2252e41f3674267b2bbe79eaeec73b6b1e4ee58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/omnipay/pin/zipball/04e778e9689882d4c40419263014068b69b93168",
"reference": "04e778e9689882d4c40419263014068b69b93168",
"url": "https://api.github.com/repos/thephpleague/omnipay-pin/zipball/c2252e41f3674267b2bbe79eaeec73b6b1e4ee58",
"reference": "c2252e41f3674267b2bbe79eaeec73b6b1e4ee58",
"shasum": ""
},
"require": {
@ -5210,11 +5262,11 @@
},
{
"name": "Omnipay Contributors",
"homepage": "https://github.com/omnipay/pin/contributors"
"homepage": "https://github.com/thephpleague/omnipay-pin/contributors"
}
],
"description": "Pin Payments driver for the Omnipay payment processing library",
"homepage": "https://github.com/omnipay/pin",
"homepage": "https://github.com/thephpleague/omnipay-pin",
"keywords": [
"gateway",
"merchant",
@ -5223,20 +5275,20 @@
"payment",
"pin"
],
"time": "2014-04-14 11:26:15"
"time": "2016-01-13 07:00:17"
},
{
"name": "omnipay/sagepay",
"version": "v2.2.0",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-sagepay.git",
"reference": "899507095428fa54276ba5ca89f11fd7f8fd78ab"
"reference": "4208d23b33b2f8a59176e44ad22d304c461ecb62"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/899507095428fa54276ba5ca89f11fd7f8fd78ab",
"reference": "899507095428fa54276ba5ca89f11fd7f8fd78ab",
"url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/4208d23b33b2f8a59176e44ad22d304c461ecb62",
"reference": "4208d23b33b2f8a59176e44ad22d304c461ecb62",
"shasum": ""
},
"require": {
@ -5282,7 +5334,7 @@
"sage pay",
"sagepay"
],
"time": "2015-04-02 17:46:20"
"time": "2016-01-12 12:43:31"
},
{
"name": "omnipay/securepay",
@ -5512,6 +5564,54 @@
],
"time": "2014-09-17 00:37:18"
},
{
"name": "paragonie/random_compat",
"version": "1.1.5",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2016-01-06 13:31:20"
},
{
"name": "patricktalmadge/bootstrapper",
"version": "5.5.3",
@ -6058,28 +6158,28 @@
},
{
"name": "symfony/class-loader",
"version": "v2.8.1",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c"
"reference": "6294f616bb9888ba2e13c8bfdcc4d306c1c95da7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/6294f616bb9888ba2e13c8bfdcc4d306c1c95da7",
"reference": "6294f616bb9888ba2e13c8bfdcc4d306c1c95da7",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
"php": ">=5.5.9"
},
"require-dev": {
"symfony/finder": "~2.0,>=2.0.5|~3.0.0"
"symfony/finder": "~2.8|~3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
"dev-master": "3.0-dev"
}
},
"autoload": {
@ -6106,11 +6206,11 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
"time": "2015-12-05 17:37:59"
"time": "2015-12-05 17:45:07"
},
{
"name": "symfony/console",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
@ -6168,16 +6268,16 @@
},
{
"name": "symfony/css-selector",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "eaa3320e32f09a01dc432c6efbe8051aee59cfef"
"reference": "ac06d8173bd80790536c0a4a634a7d705b91f54f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/eaa3320e32f09a01dc432c6efbe8051aee59cfef",
"reference": "eaa3320e32f09a01dc432c6efbe8051aee59cfef",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/ac06d8173bd80790536c0a4a634a7d705b91f54f",
"reference": "ac06d8173bd80790536c0a4a634a7d705b91f54f",
"shasum": ""
},
"require": {
@ -6217,11 +6317,11 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2015-12-05 17:37:59"
"time": "2016-01-03 15:33:41"
},
{
"name": "symfony/debug",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
@ -6282,16 +6382,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc"
"reference": "ee278f7c851533e58ca307f66305ccb9188aceda"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc",
"reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda",
"reference": "ee278f7c851533e58ca307f66305ccb9188aceda",
"shasum": ""
},
"require": {
@ -6338,20 +6438,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2015-10-30 20:15:42"
"time": "2016-01-13 10:28:07"
},
{
"name": "symfony/filesystem",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc"
"reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/a7ad724530a764d70c168d321ac226ba3d2f10fc",
"reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/637b64d0ee10f44ae98dbad651b1ecdf35a11e8c",
"reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c",
"shasum": ""
},
"require": {
@ -6387,11 +6487,11 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2015-12-22 10:25:57"
"time": "2016-01-13 10:28:07"
},
{
"name": "symfony/finder",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
@ -6441,7 +6541,7 @@
},
{
"name": "symfony/http-foundation",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
@ -6495,17 +6595,17 @@
},
{
"name": "symfony/http-kernel",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6"
"reference": "cdd991d304fed833514dc44d6aafcf19397c26cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/cdd991d304fed833514dc44d6aafcf19397c26cb",
"reference": "cdd991d304fed833514dc44d6aafcf19397c26cb",
"shasum": ""
},
"require": {
@ -6569,7 +6669,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2015-11-23 11:37:53"
"time": "2016-01-14 10:11:16"
},
{
"name": "symfony/polyfill-php56",
@ -6681,7 +6781,7 @@
},
{
"name": "symfony/process",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
@ -6731,7 +6831,7 @@
},
{
"name": "symfony/routing",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
@ -6800,20 +6900,21 @@
},
{
"name": "symfony/security-core",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Security/Core",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-core.git",
"reference": "05f58bb3814e8a853332dc448e3b7addaa87679c"
"reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/security-core/zipball/05f58bb3814e8a853332dc448e3b7addaa87679c",
"reference": "05f58bb3814e8a853332dc448e3b7addaa87679c",
"url": "https://api.github.com/repos/symfony/security-core/zipball/813cf2aaacccbbe1a4705aef8d4ac0d79d993a76",
"reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76",
"shasum": ""
},
"require": {
"paragonie/random_compat": "~1.0",
"php": ">=5.3.3"
},
"require-dev": {
@ -6860,11 +6961,11 @@
],
"description": "Symfony Security Component - Core Library",
"homepage": "https://symfony.com",
"time": "2015-07-22 10:08:40"
"time": "2016-01-14 09:04:34"
},
{
"name": "symfony/translation",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/Translation",
"source": {
"type": "git",
@ -6923,7 +7024,7 @@
},
{
"name": "symfony/var-dumper",
"version": "v2.6.12",
"version": "v2.6.13",
"target-dir": "Symfony/Component/VarDumper",
"source": {
"type": "git",
@ -7030,16 +7131,16 @@
},
{
"name": "true/punycode",
"version": "v2.0.1",
"version": "v2.0.2",
"source": {
"type": "git",
"url": "https://github.com/true/php-punycode.git",
"reference": "b672918d992b84f8016bbe353a42516928393c63"
"reference": "74fa01d4de396c40e239794123b3874cb594a30c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/true/php-punycode/zipball/b672918d992b84f8016bbe353a42516928393c63",
"reference": "b672918d992b84f8016bbe353a42516928393c63",
"url": "https://api.github.com/repos/true/php-punycode/zipball/74fa01d4de396c40e239794123b3874cb594a30c",
"reference": "74fa01d4de396c40e239794123b3874cb594a30c",
"shasum": ""
},
"require": {
@ -7072,7 +7173,7 @@
"idna",
"punycode"
],
"time": "2015-09-01 14:53:31"
"time": "2016-01-07 17:12:58"
},
{
"name": "twbs/bootstrap",
@ -7347,16 +7448,16 @@
},
{
"name": "zircote/swagger-php",
"version": "2.0.4",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/zircote/swagger-php.git",
"reference": "be5d96e56c23cbe52c5bc5e267851323d95c57cd"
"reference": "c19af4edcc13c00e82fabeee926335b1fe1d92e9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/be5d96e56c23cbe52c5bc5e267851323d95c57cd",
"reference": "be5d96e56c23cbe52c5bc5e267851323d95c57cd",
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/c19af4edcc13c00e82fabeee926335b1fe1d92e9",
"reference": "c19af4edcc13c00e82fabeee926335b1fe1d92e9",
"shasum": ""
},
"require": {
@ -7403,7 +7504,7 @@
"rest",
"service discovery"
],
"time": "2015-11-13 13:50:11"
"time": "2016-01-15 09:39:28"
}
],
"packages-dev": [
@ -7593,16 +7694,16 @@
},
{
"name": "facebook/webdriver",
"version": "1.1.0",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/facebook/php-webdriver.git",
"reference": "518a9e0635e69777f07e41619cdf5d82fae284b6"
"reference": "1c98108ba3eb435b681655764de11502a0653705"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/518a9e0635e69777f07e41619cdf5d82fae284b6",
"reference": "518a9e0635e69777f07e41619cdf5d82fae284b6",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/1c98108ba3eb435b681655764de11502a0653705",
"reference": "1c98108ba3eb435b681655764de11502a0653705",
"shasum": ""
},
"require": {
@ -7632,7 +7733,7 @@
"selenium",
"webdriver"
],
"time": "2015-12-08 17:04:30"
"time": "2015-12-31 15:58:49"
},
{
"name": "fzaninotto/faker",
@ -7722,16 +7823,16 @@
},
{
"name": "phpspec/phpspec",
"version": "2.4.0",
"version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/phpspec/phpspec.git",
"reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358"
"reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
"reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/5528ce1e93a1efa090c9404aba3395c329b4e6ed",
"reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed",
"shasum": ""
},
"require": {
@ -7796,7 +7897,7 @@
"testing",
"tests"
],
"time": "2015-11-29 02:03:49"
"time": "2016-01-01 10:17:54"
},
{
"name": "phpspec/prophecy",
@ -8599,16 +8700,16 @@
},
{
"name": "symfony/browser-kit",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
"reference": "dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca"
"reference": "a93dffaf763182acad12a4c42c7efc372899891e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca",
"reference": "dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/a93dffaf763182acad12a4c42c7efc372899891e",
"reference": "a93dffaf763182acad12a4c42c7efc372899891e",
"shasum": ""
},
"require": {
@ -8652,20 +8753,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"time": "2015-12-26 13:37:56"
"time": "2016-01-12 17:46:01"
},
{
"name": "symfony/dom-crawler",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "a2712aff8b250d9601ad6bd23a2ff82a12730e8e"
"reference": "650d37aacb1fa0dcc24cced483169852b3a0594e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a2712aff8b250d9601ad6bd23a2ff82a12730e8e",
"reference": "a2712aff8b250d9601ad6bd23a2ff82a12730e8e",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/650d37aacb1fa0dcc24cced483169852b3a0594e",
"reference": "650d37aacb1fa0dcc24cced483169852b3a0594e",
"shasum": ""
},
"require": {
@ -8708,7 +8809,7 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2015-12-23 17:16:29"
"time": "2016-01-03 15:33:41"
},
{
"name": "symfony/polyfill-mbstring",
@ -8771,16 +8872,16 @@
},
{
"name": "symfony/yaml",
"version": "v2.8.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966"
"reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
"url": "https://api.github.com/repos/symfony/yaml/zipball/34c8a4b51e751e7ea869b8262f883d008a2b81b8",
"reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8",
"shasum": ""
},
"require": {
@ -8816,7 +8917,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2015-12-26 13:37:56"
"time": "2016-01-13 10:28:07"
}
],
"aliases": [],
@ -8829,6 +8930,7 @@
"chumper/datatable": 20,
"intervention/image": 20,
"webpatser/laravel-countries": 20,
"barryvdh/laravel-ide-helper": 20,
"lokielse/omnipay-alipay": 20,
"alfaproject/omnipay-neteller": 20,
"alfaproject/omnipay-skrill": 20,

View File

@ -0,0 +1,69 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddBankSubaccounts extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('bank_subaccounts', function($table)
{
$table->increments('id');
$table->unsignedInteger('account_id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('bank_account_id');
$table->string('account_name');
$table->string('account_number');
$table->timestamps();
$table->softDeletes();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('bank_account_id')->references('id')->on('bank_accounts')->onDelete('cascade');
$table->unsignedInteger('public_id')->index();
$table->unique(['account_id', 'public_id']);
});
Schema::table('expenses', function($table)
{
$table->string('transaction_id');
$table->unsignedInteger('bank_id');
});
Schema::table('vendors', function($table)
{
$table->string('transaction_name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('bank_subaccounts');
Schema::table('expenses', function($table)
{
$table->dropColumn('transaction_id');
$table->dropColumn('bank_id');
});
Schema::table('vendors', function($table)
{
$table->dropColumn('transaction_name');
});
}
}

File diff suppressed because one or more lines are too long

View File

@ -3386,3 +3386,8 @@ ul.user-accounts a:hover div.remove {
div.panel-body div.panel-body {
padding-bottom: 0px;
}
.vcenter {
display: inline-block;
vertical-align: middle;
}

View File

@ -989,5 +989,126 @@
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -25,7 +25,7 @@ return array(
"numeric" => ":attribute skal være imellem :min - :max.",
"file" => ":attribute skal være imellem :min - :max kilobytes.",
"string" => ":attribute skal være imellem :min - :max tegn.",
"array" => ":attribute skal indeholde mellem :min - :max elementer."
"array" => ":attribute skal indeholde mellem :min - :max elementer.",
),
"boolean" => ":attribute skal være sandt eller falsk",
"confirmed" => ":attribute er ikke det samme som bekræftelsesfeltet.",
@ -44,14 +44,14 @@ return array(
"numeric" => ":attribute skal være højest :max.",
"file" => ":attribute skal være højest :max kilobytes.",
"string" => ":attribute skal være højest :max tegn.",
"array" => ":attribute må ikke indeholde mere end :max elementer."
"array" => ":attribute må ikke indeholde mere end :max elementer.",
),
"mimes" => ":attribute skal være en fil af typen: :values.",
"min" => array(
"numeric" => ":attribute skal være mindst :min.",
"file" => ":attribute skal være mindst :min kilobytes.",
"string" => ":attribute skal være mindst :min tegn.",
"array" => ":attribute skal indeholde mindst :min elementer."
"array" => ":attribute skal indeholde mindst :min elementer.",
),
"not_in" => "Den valgte :attribute er ugyldig.",
"numeric" => ":attribute skal være et tal.",
@ -67,7 +67,7 @@ return array(
"numeric" => ":attribute skal være :size.",
"file" => ":attribute skal være :size kilobytes.",
"string" => ":attribute skal være :size tegn lang.",
"array" => ":attribute skal indeholde :size elementer."
"array" => ":attribute skal indeholde :size elementer.",
),
"timezone" => "The :attribute must be a valid zone.",
"unique" => ":attribute er allerede taget.",

View File

@ -273,7 +273,6 @@ return array(
'reset_password' => 'Du kannst dein Passwort zurücksetzen, indem du auf den folgenden Link klickst:',
'reset_password_footer' => 'Wenn du das Zurücksetzen des Passworts nicht beantragt hast, benachrichtige bitte unseren Support: '.CONTACT_EMAIL,
// Payment page
'secure_payment' => 'Sichere Zahlung',
'card_number' => 'Kartennummer',
@ -991,4 +990,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -25,7 +25,7 @@ return array(
"numeric" => ":attribute muss zwischen :min & :max liegen.",
"file" => ":attribute muss zwischen :min & :max Kilobytes groß sein.",
"string" => ":attribute muss zwischen :min & :max Zeichen lang sein.",
"array" => ":attribute muss zwischen :min & :max Elemente haben."
"array" => ":attribute muss zwischen :min & :max Elemente haben.",
),
"confirmed" => ":attribute stimmt nicht mit der Bestätigung überein.",
"date" => ":attribute muss ein gültiges Datum sein.",
@ -43,14 +43,14 @@ return array(
"numeric" => ":attribute darf maximal :max sein.",
"file" => ":attribute darf maximal :max Kilobytes groß sein.",
"string" => ":attribute darf maximal :max Zeichen haben.",
"array" => ":attribute darf nicht mehr als :max Elemente haben."
"array" => ":attribute darf nicht mehr als :max Elemente haben.",
),
"mimes" => ":attribute muss den Dateityp :values haben.",
"min" => array(
"numeric" => ":attribute muss mindestens :min sein.",
"file" => ":attribute muss mindestens :min Kilobytes groß sein.",
"string" => ":attribute muss mindestens :min Zeichen lang sein.",
"array" => ":attribute muss mindestens :min Elemente haben."
"array" => ":attribute muss mindestens :min Elemente haben.",
),
"not_in" => "Der gewählte Wert für :attribute ist ungültig.",
"numeric" => ":attribute muss eine Zahl sein.",
@ -66,7 +66,7 @@ return array(
"numeric" => ":attribute muss gleich :size sein.",
"file" => ":attribute muss :size Kilobyte groß sein.",
"string" => ":attribute muss :size Zeichen lang sein.",
"array" => ":attribute muss genau :size Elemente haben."
"array" => ":attribute muss genau :size Elemente haben.",
),
"unique" => ":attribute ist schon vergeben.",
"url" => "Das Format von :attribute ist ungültig.",

View File

@ -263,7 +263,6 @@ return array(
'deleted_vendor' => 'Successfully deleted vendor',
'deleted_vendors' => 'Successfully deleted :count vendors',
// Emails
'confirmation_subject' => 'Invoice Ninja Account Confirmation',
'confirmation_header' => 'Account Confirmation',
@ -286,7 +285,6 @@ return array(
'reset_password' => 'You can reset your account password by clicking the following button:',
'reset_password_footer' => 'If you did not request this password reset please email our support: '.CONTACT_EMAIL,
// Payment page
'secure_payment' => 'Secure Payment',
'card_number' => 'Card Number',
@ -1107,6 +1105,8 @@ return array(
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
@ -1114,17 +1114,20 @@ return array(
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'test' => 'Test',
'test_bank_account' => 'Test Bank Account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -966,5 +966,126 @@ return array(
'schedule' => 'Schedule',
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -988,4 +988,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -427,7 +427,6 @@ return array(
'hide' => 'Cacher',
'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version',
'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture',
'invoice_number_counter' => 'Compteur du numéro de facture',
@ -982,4 +981,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -25,7 +25,7 @@ return array(
"numeric" => "La valeur de :attribute doit être comprise entre :min et :max.",
"file" => "Le fichier :attribute doit avoir une taille entre :min et :max kilobytes.",
"string" => "Le texte :attribute doit avoir entre :min et :max caractères.",
"array" => "Le champ :attribute doit avoir entre :min et :max éléments."
"array" => "Le champ :attribute doit avoir entre :min et :max éléments.",
),
"confirmed" => "Le champ de confirmation :attribute ne correspond pas.",
"date" => "Le champ :attribute n'est pas une date valide.",
@ -50,7 +50,7 @@ return array(
"numeric" => "La valeur de :attribute doit être supérieure à :min.",
"file" => "Le fichier :attribute doit être plus que gros que :min kilobytes.",
"string" => "Le texte :attribute doit contenir au moins :min caractères.",
"array" => "Le champ :attribute doit avoir au moins :min éléments."
"array" => "Le champ :attribute doit avoir au moins :min éléments.",
),
"not_in" => "Le champ :attribute sélectionné n'est pas valide.",
"numeric" => "Le champ :attribute doit contenir un nombre.",
@ -66,7 +66,7 @@ return array(
"numeric" => "La valeur de :attribute doit être :size.",
"file" => "La taille du fichier de :attribute doit être de :size kilobytes.",
"string" => "Le texte de :attribute doit contenir :size caractères.",
"array" => "Le champ :attribute doit contenir :size éléments."
"array" => "Le champ :attribute doit contenir :size éléments.",
),
"unique" => "La valeur du champ :attribute est déjà utilisée.",
"url" => "Le format de l'URL de :attribute n'est pas valide.",
@ -136,7 +136,7 @@ return array(
"date" => "Date",
"time" => "Heure",
"available" => "Disponible",
"size" => "Taille"
"size" => "Taille",
),
);

View File

@ -427,7 +427,6 @@ return array(
'hide' => 'Cacher',
'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version',
'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture',
'invoice_number_counter' => 'Compteur du numéro de facture',
@ -667,7 +666,6 @@ return array(
'partial_value' => 'Must be greater than zero and less than the total',
'more_actions' => 'More Actions',
'pro_plan_title' => 'NINJA PRO',
'pro_plan_call_to_action' => 'Upgrade Now!',
'pro_plan_feature1' => 'Create Unlimited Clients',
@ -982,4 +980,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -25,7 +25,7 @@ return array(
"numeric" => "La valeur de :attribute doit être comprise entre :min et :max.",
"file" => "Le fichier :attribute doit avoir une taille entre :min et :max kilobytes.",
"string" => "Le texte :attribute doit avoir entre :min et :max caractères.",
"array" => "Le champ :attribute doit avoir entre :min et :max éléments."
"array" => "Le champ :attribute doit avoir entre :min et :max éléments.",
),
"confirmed" => "Le champ de confirmation :attribute ne correspond pas.",
"date" => "Le champ :attribute n'est pas une date valide.",
@ -50,7 +50,7 @@ return array(
"numeric" => "La valeur de :attribute doit être supérieure à :min.",
"file" => "Le fichier :attribute doit être plus que gros que :min kilobytes.",
"string" => "Le texte :attribute doit contenir au moins :min caractères.",
"array" => "Le champ :attribute doit avoir au moins :min éléments."
"array" => "Le champ :attribute doit avoir au moins :min éléments.",
),
"not_in" => "Le champ :attribute sélectionné n'est pas valide.",
"numeric" => "Le champ :attribute doit contenir un nombre.",
@ -66,7 +66,7 @@ return array(
"numeric" => "La valeur de :attribute doit être :size.",
"file" => "La taille du fichier de :attribute doit être de :size kilobytes.",
"string" => "Le texte de :attribute doit contenir :size caractères.",
"array" => "Le champ :attribute doit contenir :size éléments."
"array" => "Le champ :attribute doit contenir :size éléments.",
),
"unique" => "La valeur du champ :attribute est déjà utilisée.",
"url" => "Le format de l'URL de :attribute n'est pas valide.",
@ -136,7 +136,7 @@ return array(
"date" => "Date",
"time" => "Heure",
"available" => "Disponible",
"size" => "Taille"
"size" => "Taille",
),
);

View File

@ -984,4 +984,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -24,7 +24,7 @@ return array(
"numeric" => ":attribute deve trovarsi tra :min - :max.",
"file" => ":attribute deve trovarsi tra :min - :max kilobytes.",
"string" => ":attribute deve trovarsi tra :min - :max caratteri.",
"array" => ":attribute deve avere tra :min - :max elementi."
"array" => ":attribute deve avere tra :min - :max elementi.",
),
"confirmed" => "Il campo di conferma per :attribute non coincide.",
"date" => ":attribute non è una data valida.",
@ -42,14 +42,14 @@ return array(
"numeric" => ":attribute deve essere minore di :max.",
"file" => ":attribute non deve essere più grande di :max kilobytes.",
"string" => ":attribute non può contenere più di :max caratteri.",
"array" => ":attribute non può avere più di :max elementi."
"array" => ":attribute non può avere più di :max elementi.",
),
"mimes" => ":attribute deve essere del tipo: :values.",
"min" => array(
"numeric" => ":attribute deve valere almeno :min.",
"file" => ":attribute deve essere più grande di :min kilobytes.",
"string" => ":attribute deve contenere almeno :min caratteri.",
"array" => ":attribute deve avere almeno :min elementi."
"array" => ":attribute deve avere almeno :min elementi.",
),
"not_in" => "Il valore selezionato per :attribute non è valido.",
"numeric" => ":attribute deve essere un numero.",
@ -65,7 +65,7 @@ return array(
"numeric" => ":attribute deve valere :size.",
"file" => ":attribute deve essere grande :size kilobytes.",
"string" => ":attribute deve contenere :size caratteri.",
"array" => ":attribute deve contenere :size elementi."
"array" => ":attribute deve contenere :size elementi.",
),
"unique" => ":attribute è stato già utilizzato.",
"url" => ":attribute deve essere un URL.",

View File

@ -991,5 +991,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
);
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -989,4 +989,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -440,7 +440,6 @@ return array(
'invalid_counter' => 'Stel een factuurnummervoorvoegsel of offertenummervoorvoegsel in om een mogelijk conflict te voorkomen.',
'mark_sent' => 'Markeer als verzonden',
'gateway_help_1' => ':link om in te schrijven voor Authorize.net.',
'gateway_help_2' => ':link om in te schrijven voor Authorize.net.',
'gateway_help_17' => ':link om uw PayPal API signature te krijgen.',
@ -455,7 +454,6 @@ return array(
'buy' => 'Koop',
'bought_designs' => 'Aanvullende factuurontwerpen succesvol toegevoegd',
'sent' => 'verzonden',
'timesheets' => 'Timesheets',
@ -472,7 +470,6 @@ return array(
'bought_white_label' => 'White label licentie succesvol geactiveerd',
'white_labeled' => 'White labeled',
'restore' => 'Herstel',
'restore_invoice' => 'Herstel factuur',
'restore_quote' => 'Herstel offerte',
@ -987,4 +984,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -25,7 +25,7 @@ return array(
"numeric" => ":attribute moet tussen :min en :max zijn.",
"file" => ":attribute moet tussen :min en :max kilobytes zijn.",
"string" => ":attribute moet tussen :min en :max karakters zijn.",
"array" => ":attribute moet tussen :min en :max items bevatten."
"array" => ":attribute moet tussen :min en :max items bevatten.",
),
"confirmed" => ":attribute bevestiging komt niet overeen.",
"count" => ":attribute moet precies :count geselecteerde elementen bevatten.",
@ -48,14 +48,14 @@ return array(
"numeric" => ":attribute moet minder dan :max zijn.",
"file" => ":attribute moet minder dan :max kilobytes zijn.",
"string" => ":attribute moet minder dan :max karakters zijn.",
"array" => ":attribute mag maximaal :max items bevatten."
"array" => ":attribute mag maximaal :max items bevatten.",
),
"mimes" => ":attribute moet een bestand zijn van het bestandstype :values.",
"min" => array(
"numeric" => ":attribute moet minimaal :min zijn.",
"file" => ":attribute moet minimaal :min kilobytes zijn.",
"string" => ":attribute moet minimaal :min karakters zijn.",
"array" => ":attribute moet minimaal :min items bevatten."
"array" => ":attribute moet minimaal :min items bevatten.",
),
"not_in" => "Het geselecteerde :attribute is ongeldig.",
"numeric" => ":attribute moet een nummer zijn.",
@ -71,7 +71,7 @@ return array(
"numeric" => ":attribute moet :size zijn.",
"file" => ":attribute moet :size kilobyte zijn.",
"string" => ":attribute moet :size karakters lang zijn.",
"array" => ":attribute moet :size items bevatten."
"array" => ":attribute moet :size items bevatten.",
),
"unique" => ":attribute is al in gebruik.",
"url" => ":attribute is geen geldige URL.",

View File

@ -981,4 +981,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -986,5 +986,126 @@ return array(
'email_designs' => 'Email Designs',
'assigned_when_sent' => 'Assigned when sent',
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
'white_label_purchase_link' => 'Purchase a white label license',
// Expense / vendor
'expense' => 'Expense',
'expenses' => 'Expenses',
'new_expense' => 'Enter Expense',
'enter_expense' => 'Enter Expense',
'vendors' => 'Vendors',
'new_vendor' => 'Create Vendor',
'payment_terms_net' => 'Net',
'vendor' => 'Vendor',
'edit_vendor' => 'Edit Vendor',
'archive_vendor' => 'Archive Vendor',
'delete_vendor' => 'Delete Vendor',
'view_vendor' => 'View Vendor',
'deleted_expense' => 'Successfully deleted expense',
'archived_expense' => 'Successfully archived expense',
'deleted_expenses' => 'Successfully deleted expenses',
'archived_expenses' => 'Successfully archived expenses',
// Expenses
'expense_amount' => 'Expense Amount',
'expense_balance' => 'Expense Balance',
'expense_date' => 'Expense Date',
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
'public_notes' => 'Public Notes',
'invoice_amount' => 'Invoice Amount',
'exchange_rate' => 'Exchange Rate',
'yes' => 'Yes',
'no' => 'No',
'should_be_invoiced' => 'Should be invoiced',
'view_expense' => 'View expense # :expense',
'edit_expense' => 'Edit Expense',
'archive_expense' => 'Archive Expense',
'delete_expense' => 'Delete Expense',
'view_expense_num' => 'Expense # :expense',
'updated_expense' => 'Successfully updated expense',
'created_expense' => 'Successfully created expense',
'enter_expense' => 'Enter Expense',
'view' => 'View',
'restore_expense' => 'Restore Expense',
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense has already been invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
'num_days' => 'Number of days',
'create_payment_term' => 'Create Payment Term',
'edit_payment_terms' => 'Edit Payment Term',
'edit_payment_term' => 'Edit Payment Term',
'archive_payment_term' => 'Archive Payment Term',
// recurring due dates
'recurring_due_dates' => 'Recurring Invoice Due Dates',
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
<p>Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.</p>
<p>Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.</p>
<p>For example:</p>
<ul>
<li>Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.</li>
<li>Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month.
</li>
<li>Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of <strong>next</strong> month.
</li>
<li>Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today.
</li>
</ul>',
'due' => 'Due',
'next_due_on' => 'Due Next: :date',
'use_client_terms' => 'Use client terms',
'day_of_month' => ':ordinal day of month',
'last_day_of_month' => 'Last day of month',
'day_of_week_after' => ':ordinal :day after',
'sunday' => 'Sunday',
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
'live_preview' => 'Live Preview',
'invalid_mail_config' => 'Unable to send email, please check that the mail settings are correct.',
'invoice_message_button' => 'To view your invoice for :amount, click the button below.',
'quote_message_button' => 'To view your quote for :amount, click the button below.',
'payment_message_button' => 'Thank you for your payment of :amount.',
'payment_type_direct_debit' => 'Direct Debit',
'bank_accounts' => 'Bank Accounts',
'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses',
'bank_id' => 'bank',
'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account',
'archive_bank_account' => 'Archive Bank Account',
'archived_bank_account' => 'Successfully archived bank account',
'created_bank_account' => 'Successfully created bank account',
'validate_bank_account' => 'Validate Bank Account',
'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and <a href="'.OFX_HOME_URL.'" target="_blank">400+ US banks.</a>',
'bank_password_help' => 'Note: your password is transmitted securely and never stored on our servers.',
'bank_password_warning' => 'Warning: your password may be transmitted in plain text, consider enabling HTTPS.',
'username' => 'Username',
'account_number' => 'Account Number',
'account_name' => 'Account Name',
'bank_account_error' => 'Failed to retreive account details, please check your credentials.',
'status_approved' => 'Approved',
'quote_settings' => 'Quote Settings',
'auto_convert_quote' => 'Auto convert quote',
'auto_convert_quote_help' => 'Automatically convert a quote to an invoice when approved by a client.',
'validate' => 'Validate',
'info' => 'Info',
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
);

View File

@ -3,15 +3,15 @@
@section('head')
@parent
@include('money_script')
<style type="text/css">
table.accounts-table > thead > tr > th.header {
background-color: #e37329 !important;
color:#fff !important;
padding-top:8px;
}
</style>
@stop
@section('content')
@ -19,157 +19,359 @@
@include('accounts.nav', ['selected' => ACCOUNT_BANKS])
{!! Former::open($url)
->method($method)
->rule()
->addClass('main-form warn-on-exit') !!}
{!! Former::open()->addClass('main-form warn-on-exit') !!}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{!! trans($title) !!}</h3>
<h3 class="panel-title" data-bind="text: title"></h3>
</div>
<div class="panel-body form-padding-right">
<div class="panel-body">
<div data-bind="visible: page() == 'login'">
<div class="form-padding-right">
@if ($bankAccount)
{!! Former::populateField('bank_id', $bankAccount->bank_id) !!}
@endif
{!! Former::populateField('public_id', $bankAccount->public_id) !!}
{!! Former::hidden('public_id') !!}
@else
{!! Former::select('bank_id')
->data_bind('dropdown: bank_id')
->data_bind('combobox: bank_id')
->addOption('', '')
->fromQuery($banks, 'name', 'id') !!}
->fromQuery($banks, 'name', 'id')
->blockHelp('texts.bank_accounts_help') !!}
@endif
{!! Former::password('bank_username')
->data_bind("value: bank_username, valueUpdate: 'afterkeydown'")
->label(trans('texts.username'))
->label(trans('texts.username')) !!}
{!! Former::password('bank_password')
->label(trans('texts.password'))
->data_bind("value: bank_password, valueUpdate: 'afterkeydown'")
->blockHelp(trans(Request::secure() ? 'texts.bank_password_help' : 'texts.bank_password_warning')) !!}
</div>
</div>
<div class="modal fade" id="testModal" tabindex="-1" role="dialog" aria-labelledby="testModalLabel" aria-hidden="true">
<div class="modal-dialog" style="min-width:150px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="testModalLabel">{!! trans('texts.test_bank_account') !!}</h4>
<div class="col-lg-12 col-sm-12" data-bind="visible: page() == 'setup'" style="display:none">
<table class="table accounts-table" style="width:100%">
<thead>
<tr>
<th class="header">{{ trans('texts.account_name') }}</th>
<th class="header">{{ trans('texts.account_number') }}</th>
<th class="header">{{ trans('texts.balance') }}</th>
<th class="header">{{ trans('texts.include') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: bank_accounts">
<tr>
<td>
<input type="text" class="form-control" data-bind="value: account_name, valueUpdate: 'afterkeydown', attr: {name: 'bank_accounts[' + $index() + '][account_name]'}"/>
<input type="text" style="display:none" data-bind="value: hashed_account_number, attr: {name: 'bank_accounts[' + $index() + '][hashed_account_number]'}"/>
</td>
<td data-bind="text: masked_account_number"></td>
<td data-bind="text: balance"></td>
<td style="text-align:center">
<input type="checkbox" value="1"
data-bind="checked: includeAccount, attr: {name: 'bank_accounts[' + $index() + '][include]'}"/>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-body row">
<div class="form-group" style="padding-bottom:30px">
<label for="username" class="control-label col-lg-4 col-sm-4">{{ trans('texts.password') }}</label>
<div class="col-lg-6 col-sm-6">
<input class="form-control" id="bank_password" name="bank_password" type="password" data-bind="value: bank_password, valueUpdate: 'afterkeydown'"><br/>
<div class="col-lg-12 col-sm-12" data-bind="visible: page() == 'import'" style="display:none">
<div class="row panel">
<div class="col-md-8" style="height:60px;padding-top:10px;">
<span data-bind="text: statusLabel"></span>
</div>
<div class="col-md-4">
<input type="text" class="form-control" data-bind="value: $root.filter, valueUpdate: 'afterkeydown'"
placeholder="{{ trans('texts.filter') }}"/>
</div>
</div>
<div class="col-lg-12 col-sm-12" data-bind="visible: state() == 'loading'">
<div data-bind="foreach: bank_accounts">
<h4 data-bind="text: account_name"></h4><br/>
<table class="table accounts-table" style="width:100%;">
<thead>
<tr>
<th class="header">
<input type="checkbox" data-bind="checked: checkall, click: updateChecked"/>
</th>
<th class="header">{{ trans('texts.vendor') }}</th>
<th class="header">{{ trans('texts.info') }}</th>
<th class="header">{{ trans('texts.public_notes') }}</th>
<th class="header" nowrap>{{ trans('texts.date') }}</th>
<th class="header" nowrap>{{ trans('texts.amount') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: filteredTransactions">
<tr>
<td style="text-align:center">
<input type="checkbox" value="1"
data-bind="checked: includeTransaction, attr: {name: 'bank_accounts[' + $index() + '][include]'}"/>
</td>
<td>
<input type="text" class="form-control"
data-bind="value: vendor.pretty, valueUpdate: 'afterkeydown'"/>
</td>
<td>
<input type="text" class="form-control"
data-bind="value: info, valueUpdate: 'afterkeydown'"/>
</td>
<td>
<input type="text" class="form-control"
data-bind="value: memo, valueUpdate: 'afterkeydown'"/>
</td>
<td data-bind="text: date" nowrap></td>
<td data-bind="text: amount.pretty" nowrap></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</div>
</div>
<div class="col-lg-12 col-sm-12" data-bind="visible: page() == 'done'" style="display:none">
<div class="alert alert-info" role="alert">
<span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
<span data-bind="text: importResults()"></span>
</div>
</div>
<div class="col-lg-12 col-sm-12" data-bind="visible: isLoading" style="display:none">
<p>&nbsp;</p>
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
</div>
</div>
</div>
<div class="col-lg-12 col-sm-12" data-bind="visible: state() == 'error'">
<div class="col-lg-12 col-sm-12" data-bind="visible: errorStr" style="display:none">
<div class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
{{ trans('texts.bank_account_error') }}
</div>
</div>
<div class="col-lg-12 col-sm-12" data-bind="visible: bank_accounts().length">
<table class="table table-striped accounts-table">
<thead>
<tr>
<th class="header">{{ trans('texts.account_number') }}</th>
<th class="header">{{ trans('texts.type') }}</th>
<th class="header">{{ trans('texts.balance') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: bank_accounts">
<tr>
<td data-bind="text: account_number"></td>
<td data-bind="text: type"></td>
<td data-bind="text: balance"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer" style="margin-top: 0px; padding-top:30px;">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.close') }}</button>
<button type="button" class="btn btn-success" onclick="doTest()" data-bind="css: { disabled: disableDoTest }">{{ trans('texts.test') }}</button>
</div>
</div>
</div>
</div>
<p/>&nbsp;<p/>
{!! Former::actions(
count(Cache::get('banks')) > 0 ? Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/bank_accounts'))->appendIcon(Icon::create('remove-circle')) : false,
(!$bankAccount ?
Button::primary(trans('texts.test'))
count(Cache::get('banks')) > 0 ?
Button::normal(trans('texts.cancel'))
->withAttributes([
'data-bind' => 'css: {disabled: disableMainButton}',
'onclick' => 'showTest()'
'data-bind' => 'visible: !importResults()',
])
->large()
->appendIcon(Icon::create('download-alt'))
: false),
Button::success(trans('texts.save'))
->submit()->large()
->asLinkTo(URL::to('/settings/bank_accounts'))
->appendIcon(Icon::create('remove-circle')) : false,
Button::success(trans('texts.validate'))
->withAttributes([
'data-bind' => 'css: {disabled: disableMainButton}',
'data-bind' => 'css: {disabled: disableValidate}, visible: page() == "login"',
'onclick' => 'validate()'
])
->large()
->appendIcon(Icon::create('lock')),
Button::success(trans('texts.save'))
->withAttributes([
'data-bind' => 'css: {disabled: disableSave}, visible: page() == "setup"',
'style' => 'display:none',
'onclick' => 'save()'
])
->large()
->appendIcon(Icon::create('floppy-disk')) ,
Button::success(trans('texts.import'))
->withAttributes([
'data-bind' => 'css: {disabled: disableSaveExpenses}, visible: page() == "import"',
'style' => 'display:none',
'onclick' => 'saveExpenses()'
])
->large()
->appendIcon(Icon::create('floppy-disk'))) !!}
{!! Former::close() !!}
<script type="text/javascript">
function showTest() {
$('#testModal').modal('show');
}
function doTest() {
model.state('loading');
$.post('{{ URL::to('/bank_accounts/test') }}', $('.main-form').serialize())
function validate() {
model.errorStr(false);
model.isLoading(true);
$.post('{{ URL::to('/bank_accounts/validate') }}', $('.main-form').serialize())
.done(function(data) {
model.state('');
data = JSON.parse(data);
if (!data || !data.length) {
model.state('error');
model.isLoading(false);
model.errorStr('error');
} else {
for (var i=0; i<data.length; i++) {
model.bank_accounts.push(data[i]);
}
loadTransactions(data);
@if ($bankAccount)
model.setPage('import')
@else
model.setPage('setup')
@endif
}
}).fail(function() {
model.state('error');
model.isLoading(false);
model.errorStr('error');
});
}
function save() {
model.errorStr(false);
model.isLoading(true);
$.post('{{ URL::to('/bank_accounts') }}', $('.main-form').serialize())
.done(function(data) {
data = JSON.parse(data);
if (!data || !data.length) {
model.isLoading(false);
model.errorStr('error');
} else {
loadTransactions(data);
model.setPage('import')
}
}).fail(function() {
model.isLoading(false);
model.errorStr('error');
});
}
function loadTransactions(data) {
model.bank_accounts.removeAll();
for (var i=0; i<data.length; i++) {
var row = data[i];
var account = new BankAccountModel(row);
if (row.transactions) {
var transactions = account.transactions();
for (var j=0; j<row.transactions.length; j++) {
var transaction = row.transactions[j];
transactions.push(new TransactionModel(transaction));
}
account.transactions.valueHasMutated();
}
model.bank_accounts.push(account);
}
}
function saveExpenses() {
model.errorStr(false);
model.isLoading(true);
$.ajax({
url: '{{ URL::to('/bank_accounts/import_expenses') }}' + '/' + model.bank_id(),
type: 'POST',
data: ko.toJSON(model.includedTransactions()),
datatype: 'json',
processData: false,
contentType: 'application/json; charset=utf-8',
success: function (result) {
model.importResults(result);
model.setPage('done');
}
});
}
$(function() {
@if ($bankAccount)
$('#bank_id').prop('disabled', true);
@else
$('#bank_id').combobox().on('change', function(e) {
model.bank_id($('#bank_id').val());
});
@endif
$('#testModal').on('shown.bs.modal', function() {
$('#bank_password').focus();
});
$('#bank_id').focus();
});
var TransactionModel = function(data) {
var self = this;
self.vendor = ko.observable(data.vendor);
self.info = ko.observable(data.info);
self.memo = ko.observable(data.memo);
self.amount = ko.observable(data.amount);
self.date = ko.observable(data.date);
self.vendor_orig = data.vendor;
self.id = data.uniqueId;
self.includeTransaction = ko.observable();
self.vendor.pretty = ko.computed({
read: function () {
return self.vendor();
},
write: function (value) {
this.vendor(value);
for (var i=0; i<model.bank_accounts().length; i++) {
var account = model.bank_accounts()[i];
var transactions = account.transactions();
for (var j=0; j<transactions.length; j++) {
var transaction = transactions[j];
if (transaction.vendor_orig == this.vendor_orig) {
transaction.vendor(value);
}
}
}
},
owner: self
})
self.amount.pretty = ko.computed({
read: function () {
return self.amount() ? formatMoney(self.amount()) : '';
},
write: function (value) {
this.amount(value);
},
owner: self
});
self.isMatch = function(filter) {
var filter = filter.toLowerCase();
var values = [
self.vendor(),
self.info(),
self.memo()
];
for (var i=0; i<values.length; i++) {
if (values[i] && values[i].toLowerCase().indexOf(filter) >= 0) {
return true;
}
}
return false;
}
}
var BankAccountModel = function(data) {
var self = this;
self.includeAccount = ko.observable(true);
self.checkall = ko.observable();
self.hashed_account_number = ko.observable(data.hashed_account_number);
self.masked_account_number = ko.observable(data.masked_account_number);
self.account_name = ko.observable(data.account_name);
self.balance = ko.observable(data.balance);
self.transactions = ko.observableArray();
self.filteredTransactions = ko.computed(function() {
if (!model.filter()) {
return self.transactions();
} else {
return ko.utils.arrayFilter(self.transactions(), function(transaction) {
return transaction.isMatch(model.filter());
});
}
}, self).extend({ rateLimit: { timeout: 350, method: 'notifyWhenChangesStop' } });
self.isValid = ko.computed(function() {
return self.account_name() ? true : false;
}, self);
self.updateChecked = function() {
var data = self.filteredTransactions();
for (var i=0; i<data.length; i++) {
data[i].includeTransaction(self.checkall());
}
self.transactions.valueHasMutated();
return true;
}
}
var ViewModel = function() {
var self = this;
@ -178,14 +380,101 @@
self.bank_password = ko.observable();
self.bank_accounts = ko.observableArray();
self.state = ko.observable(false);
self.page = ko.observable();
self.title = ko.observable();
self.errorStr = ko.observable(false);
self.isLoading = ko.observable(false);
self.importResults = ko.observable();
self.filter = ko.observable();
self.disableMainButton = ko.computed(function() {
return !self.bank_id() || !self.bank_username();
self.setPage = function(page) {
self.isLoading(false);
self.page(page);
if (page == 'login') {
@if ($bankAccount)
self.title("{{ $bankAccount->bank->name }}");
@else
self.title("{{ trans('texts.add_bank_account') }}");
@endif
} else if (page == 'setup') {
self.title("{{ trans('texts.setup_account') }}");
} else if (page == 'import') {
self.title("{{ trans('texts.import_expenses') }}");
}
}
self.setPage('login')
self.includedTransactions = ko.computed(function() {
var data = [];
for (var i=0; i<self.bank_accounts().length; i++) {
var account = self.bank_accounts()[i];
var transactions = ko.utils.arrayFilter(account.transactions(), function(transaction) {
return transaction.includeTransaction();
});
data = data.concat(transactions);
}
return data;
});
self.countExpenses = ko.computed(function() {
var count = 0;
for (var i=0; i<self.bank_accounts().length; i++) {
var account = self.bank_accounts()[i];
var transactions = ko.utils.arrayFilter(account.transactions(), function(transaction) {
return transaction.includeTransaction();
});
count += transactions.length;
}
return count;
});
self.statusLabel = ko.computed(function() {
var count = 0;
var total = 0;
for (var i=0; i<self.bank_accounts().length; i++) {
var account = self.bank_accounts()[i];
var transactions = ko.utils.arrayFilter(account.transactions(), function(transaction) {
return transaction.includeTransaction();
});
count += transactions.length;
for (var j=0; j<transactions.length; j++) {
total += transactions[j].amount();
}
}
var str = count + (count == 1 ? " {{ trans('texts.expense') }}" : " {{ trans('texts.expenses') }}") + " | ";
return str + formatMoney(total);
});
self.disableValidate = ko.computed(function() {
if (self.isLoading()) {
return true;
}
return !self.bank_id() || !self.bank_username() || !self.bank_password();
}, self);
self.disableDoTest = ko.computed(function() {
return !self.bank_id() || !self.bank_username() || !self.bank_password();
self.disableSave = ko.computed(function() {
if (self.disableValidate()) {
return true;
}
var hasAccount = false;
for (var i=0; i<self.bank_accounts().length; i++) {
var account = self.bank_accounts()[i];
if (account.includeAccount()) {
if (account.isValid()) {
hasAccount = true;
} else {
return true;
}
}
}
return !hasAccount;
}, self);
self.disableSaveExpenses = ko.computed(function() {
if (self.isLoading()) {
return true;
}
return self.countExpenses() == 0;
}, self);
};

View File

@ -33,12 +33,10 @@ class InvoiceDesignCest
$I->click('#primary_color + .sp-replacer');
$I->executeJS('$("#primary_color").val("#7364b6")');
//$I->executeJS('$("#primary_color + .sp-replacer .sp-preview-inner").attr("style", "background-color: rgb(0,98,254);")');
$I->executeJS('$(".sp-container:nth-child(1) .sp-choose").click()');
$I->click('#secondary_color + .sp-replacer');
$I->executeJS('$("#secondary_color").val("#aa6709")');
//$I->executeJS('$("#secondary_color + .sp-replacer .sp-preview-inner").attr("style", "background-color: rgb(254,0,50);")');
$I->executeJS('$(".sp-container:nth-child(2) .sp-choose").click()');
/*

View File

@ -129,21 +129,6 @@ class SettingsCest
}
*/
public function updateInvoiceDesign(FunctionalTester $I)
{
$I->wantTo('update invoice design');
$I->amOnPage('/settings/invoice_design');
$color = $this->faker->hexcolor;
$I->fillField(['name' => 'labels_item'], $this->faker->text(14));
$I->fillField(['name' => 'primary_color'], $color);
$I->click('Save');
$I->seeResponseCodeIs(200);
$I->seeRecord('accounts', array('primary_color' => $color));
}
public function updateInvoiceSettings(FunctionalTester $I)
{
$I->wantTo('update invoice settings');