Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
David Bomba 2016-11-03 19:40:25 +11:00
commit 293811d5ca
30 changed files with 262 additions and 205 deletions

View File

@ -10,6 +10,8 @@
## [Hosted](https://www.invoiceninja.com) | [Self-hosted](https://www.invoiceninja.org) ## [Hosted](https://www.invoiceninja.com) | [Self-hosted](https://www.invoiceninja.org)
**We're starting work on custom modules, join the discussion [here](https://github.com/invoiceninja/invoiceninja/issues/1131).**
All Pro and Enterprise features from our hosted app are included in both the [self-host zip](https://www.invoiceninja.com/self-host/) and the GitHub repository. All Pro and Enterprise features from our hosted app are included in both the [self-host zip](https://www.invoiceninja.com/self-host/) and the GitHub repository.
Our [iPhone app](https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1072566815&mt=8) is now available, our Android app is up next... Our [iPhone app](https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1072566815&mt=8) is now available, our Android app is up next...

View File

@ -429,6 +429,7 @@ class AccountController extends BaseController
'currencies' => Cache::get('currencies'), 'currencies' => Cache::get('currencies'),
'title' => trans('texts.localization'), 'title' => trans('texts.localization'),
'weekdays' => Utils::getTranslatedWeekdayNames(), 'weekdays' => Utils::getTranslatedWeekdayNames(),
'months' => Utils::getMonthOptions(),
]; ];
return View::make('accounts.localization', $data); return View::make('accounts.localization', $data);
@ -674,11 +675,9 @@ class AccountController extends BaseController
* @param $section * @param $section
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*/ */
public function doSection($section = ACCOUNT_COMPANY_DETAILS) public function doSection($section)
{ {
if ($section === ACCOUNT_COMPANY_DETAILS) { if ($section === ACCOUNT_LOCALIZATION) {
return AccountController::saveDetails();
} elseif ($section === ACCOUNT_LOCALIZATION) {
return AccountController::saveLocalization(); return AccountController::saveLocalization();
} elseif ($section == ACCOUNT_PAYMENTS) { } elseif ($section == ACCOUNT_PAYMENTS) {
return self::saveOnlinePayments(); return self::saveOnlinePayments();
@ -1225,6 +1224,7 @@ class AccountController extends BaseController
$account->military_time = Input::get('military_time') ? true : false; $account->military_time = Input::get('military_time') ? true : false;
$account->show_currency_code = Input::get('show_currency_code') ? true : false; $account->show_currency_code = Input::get('show_currency_code') ? true : false;
$account->start_of_week = Input::get('start_of_week') ? Input::get('start_of_week') : 0; $account->start_of_week = Input::get('start_of_week') ? Input::get('start_of_week') : 0;
$account->financial_year_start = Input::get('financial_year_start') ? Input::get('financial_year_start') : null;
$account->save(); $account->save();
event(new UserSettingsChanged()); event(new UserSettingsChanged());

View File

@ -211,6 +211,8 @@ class ClientPortalController extends BaseController
$client = $contact->client; $client = $contact->client;
$account = $client->account; $account = $client->account;
$account->loadLocalizationSettings($client);
$color = $account->primary_color ? $account->primary_color : '#0b4d78'; $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$customer = false; $customer = false;
@ -277,6 +279,7 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
@ -304,6 +307,7 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
@ -350,12 +354,14 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
} }
$color = $account->primary_color ? $account->primary_color : '#0b4d78'; $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [ $data = [
'color' => $color, 'color' => $color,
'account' => $account, 'account' => $account,
@ -420,12 +426,14 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
} }
$color = $account->primary_color ? $account->primary_color : '#0b4d78'; $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [ $data = [
'color' => $color, 'color' => $color,
'account' => $account, 'account' => $account,
@ -455,12 +463,14 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
} }
$color = $account->primary_color ? $account->primary_color : '#0b4d78'; $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [ $data = [
'color' => $color, 'color' => $color,
'account' => $account, 'account' => $account,
@ -489,12 +499,14 @@ class ClientPortalController extends BaseController
} }
$account = $contact->account; $account = $contact->account;
$account->loadLocalizationSettings($contact->client);
if (!$account->enable_client_portal) { if (!$account->enable_client_portal) {
return $this->returnError(); return $this->returnError();
} }
$color = $account->primary_color ? $account->primary_color : '#0b4d78'; $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [ $data = [
'color' => $color, 'color' => $color,
'account' => $account, 'account' => $account,

View File

@ -23,8 +23,8 @@ class DashboardApiController extends BaseAPIController
$dashboardRepo = $this->dashboardRepo; $dashboardRepo = $this->dashboardRepo;
$metrics = $dashboardRepo->totals($accountId, $userId, $viewAll); $metrics = $dashboardRepo->totals($accountId, $userId, $viewAll);
$paidToDate = $dashboardRepo->paidToDate($accountId, $userId, $viewAll); $paidToDate = $dashboardRepo->paidToDate($account, $userId, $viewAll);
$averageInvoice = $dashboardRepo->averages($accountId, $userId, $viewAll); $averageInvoice = $dashboardRepo->averages($account, $userId, $viewAll);
$balances = $dashboardRepo->balances($accountId, $userId, $viewAll); $balances = $dashboardRepo->balances($accountId, $userId, $viewAll);
$activities = $dashboardRepo->activities($accountId, $userId, $viewAll); $activities = $dashboardRepo->activities($accountId, $userId, $viewAll);
$pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll); $pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll);

View File

@ -33,8 +33,8 @@ class DashboardController extends BaseController
$dashboardRepo = $this->dashboardRepo; $dashboardRepo = $this->dashboardRepo;
$metrics = $dashboardRepo->totals($accountId, $userId, $viewAll); $metrics = $dashboardRepo->totals($accountId, $userId, $viewAll);
$paidToDate = $dashboardRepo->paidToDate($accountId, $userId, $viewAll); $paidToDate = $dashboardRepo->paidToDate($account, $userId, $viewAll);
$averageInvoice = $dashboardRepo->averages($accountId, $userId, $viewAll); $averageInvoice = $dashboardRepo->averages($account, $userId, $viewAll);
$balances = $dashboardRepo->balances($accountId, $userId, $viewAll); $balances = $dashboardRepo->balances($accountId, $userId, $viewAll);
$activities = $dashboardRepo->activities($accountId, $userId, $viewAll); $activities = $dashboardRepo->activities($accountId, $userId, $viewAll);
$pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll); $pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll);

View File

@ -70,11 +70,13 @@ class OnlinePaymentController extends BaseController
]); ]);
} }
if ( ! floatval($invitation->invoice->balance)) { if ( ! $invitation->invoice->canBePaid()) {
return redirect()->to('view/' . $invitation->invitation_key); return redirect()->to('view/' . $invitation->invitation_key);
} }
$invitation = $invitation->load('invoice.client.account.account_gateways.gateway'); $invitation = $invitation->load('invoice.client.account.account_gateways.gateway');
$account = $invitation->account;
$account->loadLocalizationSettings($invitation->invoice->client);
if ( ! $gatewayTypeAlias) { if ( ! $gatewayTypeAlias) {
$gatewayTypeId = Session::get($invitation->id . 'gateway_type'); $gatewayTypeId = Session::get($invitation->id . 'gateway_type');
@ -84,7 +86,7 @@ class OnlinePaymentController extends BaseController
$gatewayTypeId = $gatewayTypeAlias; $gatewayTypeId = $gatewayTypeAlias;
} }
$paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId); $paymentDriver = $account->paymentDriver($invitation, $gatewayTypeId);
try { try {
return $paymentDriver->startPurchase(Input::all(), $sourceId); return $paymentDriver->startPurchase(Input::all(), $sourceId);
@ -103,6 +105,10 @@ class OnlinePaymentController extends BaseController
$gatewayTypeId = Session::get($invitation->id . 'gateway_type'); $gatewayTypeId = Session::get($invitation->id . 'gateway_type');
$paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId); $paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId);
if ( ! $invitation->invoice->canBePaid()) {
return redirect()->to('view/' . $invitation->invitation_key);
}
try { try {
$paymentDriver->completeOnsitePurchase($request->all()); $paymentDriver->completeOnsitePurchase($request->all());

View File

@ -18,7 +18,6 @@ class Kernel extends HttpKernel {
'App\Http\Middleware\VerifyCsrfToken', 'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\DuplicateSubmissionCheck', 'App\Http\Middleware\DuplicateSubmissionCheck',
'App\Http\Middleware\QueryLogging', 'App\Http\Middleware\QueryLogging',
'App\Http\Middleware\SessionDataCheckMiddleware',
'App\Http\Middleware\StartupCheck', 'App\Http\Middleware\StartupCheck',
]; ];

View File

@ -1,31 +0,0 @@
<?php namespace App\Http\Middleware;
use Closure;
use Auth;
use Session;
// https://arjunphp.com/laravel5-inactivity-idle-session-logout/
class SessionDataCheckMiddleware {
/**
* Check session data, if role is not valid logout the request
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$bag = Session::getMetadataBag();
$max = env('IDLE_TIMEOUT_MINUTES', 6 * 60) * 60; // minute to second conversion
$elapsed = time() - $bag->getLastUsed();
if ( ! $bag || $elapsed > $max) {
$request->session()->flush();
Auth::logout();
$request->session()->flash('warning', trans('texts.inactive_logout'));
}
return $next($request);
}
}

View File

@ -13,7 +13,7 @@ use Event;
use Schema; use Schema;
use App\Models\Language; use App\Models\Language;
use App\Models\InvoiceDesign; use App\Models\InvoiceDesign;
use App\Events\UserSettingsChanged; use App\Events\UserLoggedIn;
use App\Libraries\CurlUtils; use App\Libraries\CurlUtils;
/** /**
@ -118,7 +118,7 @@ class StartupCheck
// Make sure the account/user localization settings are in the session // Make sure the account/user localization settings are in the session
if (Auth::check() && !Session::has(SESSION_TIMEZONE)) { if (Auth::check() && !Session::has(SESSION_TIMEZONE)) {
Event::fire(new UserSettingsChanged()); Event::fire(new UserLoggedIn());
} }
// Check if the user is claiming a license (ie, additional invoices, white label, etc.) // Check if the user is claiming a license (ie, additional invoices, white label, etc.)

View File

@ -152,7 +152,7 @@ class parseCSV {
* @param input CSV file or string * @param input CSV file or string
* @return nothing * @return nothing
*/ */
function parseCSV ($input = null, $offset = null, $limit = null, $conditions = null) { function __construct ($input = null, $offset = null, $limit = null, $conditions = null) {
if ( $offset !== null ) $this->offset = $offset; if ( $offset !== null ) $this->offset = $offset;
if ( $limit !== null ) $this->limit = $limit; if ( $limit !== null ) $this->limit = $limit;
if ( count($conditions) > 0 ) $this->conditions = $conditions; if ( count($conditions) > 0 ) $this->conditions = $conditions;

View File

@ -22,6 +22,9 @@ class Utils
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
]; ];
public static $months = [
'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december',
];
public static function isRegistered() public static function isRegistered()
{ {
@ -92,6 +95,15 @@ class Utils
return Utils::getResllerType() ? true : false; return Utils::getResllerType() ? true : false;
} }
public static function isWhiteLabel()
{
if (Utils::isNinjaProd()) {
return false;
}
return \App\Models\Account::first()->hasFeature(FEATURE_WHITE_LABEL);
}
public static function getResllerType() public static function getResllerType()
{ {
return isset($_ENV['RESELLER_TYPE']) ? $_ENV['RESELLER_TYPE'] : false; return isset($_ENV['RESELLER_TYPE']) ? $_ENV['RESELLER_TYPE'] : false;
@ -151,6 +163,11 @@ class Utils
return Auth::check() && Auth::user()->isTrial(); return Auth::check() && Auth::user()->isTrial();
} }
public static function isPaidPro()
{
return static::isPro() && ! static::isTrial();
}
public static function isEnglish() public static function isEnglish()
{ {
return App::getLocale() == 'en'; return App::getLocale() == 'en';
@ -641,11 +658,22 @@ class Utils
} }
} }
public static function getMonthOptions()
{
$months = [];
for ($i=1; $i<=count(static::$months); $i++) {
$month = static::$months[$i-1];
$number = $i < 10 ? '0' . $i : $i;
$months["2000-{$number}-01"] = trans("texts.{$month}");
}
return $months;
}
private static function getMonth($offset) private static function getMonth($offset)
{ {
$months = ['january', 'february', 'march', 'april', 'may', 'june', $months = static::$months;
'july', 'august', 'september', 'october', 'november', 'december', ];
$month = intval(date('n')) - 1; $month = intval(date('n')) - 1;
$month += $offset; $month += $offset;

View File

@ -69,6 +69,7 @@ class Account extends Eloquent
'enable_second_tax_rate', 'enable_second_tax_rate',
'include_item_taxes_inline', 'include_item_taxes_inline',
'start_of_week', 'start_of_week',
'financial_year_start',
]; ];
/** /**

View File

@ -345,7 +345,7 @@ class Client extends EntityModel
$contact = $this->contacts[0]; $contact = $this->contacts[0];
return $contact->getDisplayName() ?: trans('texts.unnamed_client'); return $contact->getDisplayName();
} }
/** /**

View File

@ -514,6 +514,11 @@ class Invoice extends EntityModel implements BalanceAffecting
return storage_path() . '/pdfcache/cache-' . $this->id . '.pdf'; return storage_path() . '/pdfcache/cache-' . $this->id . '.pdf';
} }
public function canBePaid()
{
return floatval($this->balance) > 0 && ! $this->is_deleted;
}
/** /**
* @param $invoice * @param $invoice
* @return string * @return string

View File

@ -175,29 +175,39 @@ class DashboardRepository
return $metrics->groupBy('accounts.id')->first(); return $metrics->groupBy('accounts.id')->first();
} }
public function paidToDate($accountId, $userId, $viewAll) public function paidToDate($account, $userId, $viewAll)
{ {
$accountId = $account->id;
$select = DB::raw( $select = DB::raw(
'SUM('.DB::getQueryGrammar()->wrap('clients.paid_to_date', true).') as value,' 'SUM('.DB::getQueryGrammar()->wrap('payments.amount', true).' - '.DB::getQueryGrammar()->wrap('payments.refunded', true).') as value,'
.DB::getQueryGrammar()->wrap('clients.currency_id', true).' as currency_id' .DB::getQueryGrammar()->wrap('clients.currency_id', true).' as currency_id'
); );
$paidToDate = DB::table('accounts') $paidToDate = DB::table('payments')
->select($select) ->select($select)
->leftJoin('clients', 'accounts.id', '=', 'clients.account_id') ->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
->where('accounts.id', '=', $accountId) ->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
->where('clients.is_deleted', '=', false); ->where('payments.account_id', '=', $accountId)
->where('clients.is_deleted', '=', false)
->where('invoices.is_deleted', '=', false)
->whereNotIn('payments.payment_status_id', [PAYMENT_STATUS_VOIDED, PAYMENT_STATUS_FAILED]);
if (!$viewAll){ if (!$viewAll){
$paidToDate = $paidToDate->where('clients.user_id', '=', $userId); $paidToDate->where('invoices.user_id', '=', $userId);
} }
return $paidToDate->groupBy('accounts.id') if ($account->financial_year_start) {
->groupBy(DB::raw('CASE WHEN '.DB::getQueryGrammar()->wrap('clients.currency_id', true).' IS NULL THEN CASE WHEN '.DB::getQueryGrammar()->wrap('accounts.currency_id', true).' IS NULL THEN 1 ELSE '.DB::getQueryGrammar()->wrap('accounts.currency_id', true).' END ELSE '.DB::getQueryGrammar()->wrap('clients.currency_id', true).' END')) $yearStart = str_replace('2000', date('Y'), $account->financial_year_start);
$paidToDate->where('payments.payment_date', '>=', $yearStart);
}
return $paidToDate->groupBy('payments.account_id')
->groupBy(DB::raw('CASE WHEN '.DB::getQueryGrammar()->wrap('clients.currency_id', true).' IS NULL THEN '.($account->currency_id ?: DEFAULT_CURRENCY).' ELSE '.DB::getQueryGrammar()->wrap('clients.currency_id', true).' END'))
->get(); ->get();
} }
public function averages($accountId, $userId, $viewAll) public function averages($account, $userId, $viewAll)
{ {
$accountId = $account->id;
$select = DB::raw( $select = DB::raw(
'AVG('.DB::getQueryGrammar()->wrap('invoices.amount', true).') as invoice_avg, ' 'AVG('.DB::getQueryGrammar()->wrap('invoices.amount', true).') as invoice_avg, '
.DB::getQueryGrammar()->wrap('clients.currency_id', true).' as currency_id' .DB::getQueryGrammar()->wrap('clients.currency_id', true).' as currency_id'
@ -213,7 +223,12 @@ class DashboardRepository
->where('invoices.is_recurring', '=', false); ->where('invoices.is_recurring', '=', false);
if (!$viewAll){ if (!$viewAll){
$averageInvoice = $averageInvoice->where('invoices.user_id', '=', $userId); $averageInvoice->where('invoices.user_id', '=', $userId);
}
if ($account->financial_year_start) {
$yearStart = str_replace('2000', date('Y'), $account->financial_year_start);
$averageInvoice->where('invoices.invoice_date', '>=', $yearStart);
} }
return $averageInvoice->groupBy('accounts.id') return $averageInvoice->groupBy('accounts.id')
@ -252,7 +267,7 @@ class DashboardRepository
} }
return $activities->orderBy('activities.created_at', 'desc') return $activities->orderBy('activities.created_at', 'desc')
->with('client.contacts', 'user', 'invoice', 'payment', 'credit', 'account', 'task', 'expense') ->with('client.contacts', 'user', 'invoice', 'payment', 'credit', 'account', 'task', 'expense', 'contact')
->take(50) ->take(50)
->get(); ->get();
} }

View File

@ -86,11 +86,16 @@ class InvoiceService extends BaseService
$sendInvoiceIds = []; $sendInvoiceIds = [];
foreach ($client->contacts as $contact) { foreach ($client->contacts as $contact) {
if ($contact->send_invoice || count($client->contacts) == 1) { if ($contact->send_invoice) {
$sendInvoiceIds[] = $contact->id; $sendInvoiceIds[] = $contact->id;
} }
} }
// if no contacts are selected auto-select the first to enusre there's an invitation
if ( ! count($sendInvoiceIds)) {
$sendInvoiceIds[] = $client->contacts[0]->id;
}
foreach ($client->contacts as $contact) { foreach ($client->contacts as $contact) {
$invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first(); $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first();

View File

@ -77,7 +77,7 @@
"gatepay/FedACHdir": "dev-master@dev", "gatepay/FedACHdir": "dev-master@dev",
"websight/l5-google-cloud-storage": "^1.0", "websight/l5-google-cloud-storage": "^1.0",
"wepay/php-sdk": "^0.2", "wepay/php-sdk": "^0.2",
"collizo4sky/omnipay-wepay": "dev-additional-calls", "collizo4sky/omnipay-wepay": "dev-address-fix",
"barryvdh/laravel-ide-helper": "~2.2", "barryvdh/laravel-ide-helper": "~2.2",
"barryvdh/laravel-debugbar": "~2.2", "barryvdh/laravel-debugbar": "~2.2",
"fzaninotto/faker": "^1.5", "fzaninotto/faker": "^1.5",

39
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", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "f61ec0361b0757ca0cade78837862d39", "hash": "cf642e3384eec7504bcdace749d2bb88",
"content-hash": "37549f849d74405b68eb7e2df64dfb43", "content-hash": "c0a5b571bc2305c4b0d9eae18bf5011b",
"packages": [ "packages": [
{ {
"name": "agmscode/omnipay-agms", "name": "agmscode/omnipay-agms",
@ -1081,16 +1081,16 @@
}, },
{ {
"name": "collizo4sky/omnipay-wepay", "name": "collizo4sky/omnipay-wepay",
"version": "dev-additional-calls", "version": "dev-address-fix",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/hillelcoren/omnipay-wepay.git", "url": "https://github.com/hillelcoren/omnipay-wepay.git",
"reference": "a341b9997d71803d0f774d86908cb49a8bc4c405" "reference": "916785146c5433e9216f295d09d1cbcec2fdf33a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/hillelcoren/omnipay-wepay/zipball/a341b9997d71803d0f774d86908cb49a8bc4c405", "url": "https://api.github.com/repos/hillelcoren/omnipay-wepay/zipball/916785146c5433e9216f295d09d1cbcec2fdf33a",
"reference": "a341b9997d71803d0f774d86908cb49a8bc4c405", "reference": "916785146c5433e9216f295d09d1cbcec2fdf33a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1120,9 +1120,9 @@
"wepay" "wepay"
], ],
"support": { "support": {
"source": "https://github.com/sometechie/omnipay-wepay/tree/additional-calls" "source": "https://github.com/hillelcoren/omnipay-wepay/tree/address-fix"
}, },
"time": "2016-05-25 19:18:42" "time": "2016-11-01 10:54:54"
}, },
{ {
"name": "container-interop/container-interop", "name": "container-interop/container-interop",
@ -2184,7 +2184,7 @@
"shasum": null "shasum": null
}, },
"type": "library", "type": "library",
"time": "2016-06-03 12:00:26" "time": "2016-10-12 12:00:38"
}, },
{ {
"name": "google/apiclient", "name": "google/apiclient",
@ -3091,6 +3091,7 @@
"purchase", "purchase",
"wechat" "wechat"
], ],
"abandoned": "lokielse/omnipay-wechatpay",
"time": "2016-05-10 08:43:41" "time": "2016-05-10 08:43:41"
}, },
{ {
@ -7211,16 +7212,16 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.8.9", "version": "v2.8.13",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "889983a79a043dfda68f38c38b6dba092dd49cd8" "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
"reference": "889983a79a043dfda68f38c38b6dba092dd49cd8", "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7267,7 +7268,7 @@
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-07-28 16:56:28" "time": "2016-10-13 01:43:15"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
@ -7320,16 +7321,16 @@
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v2.8.9", "version": "v2.8.13",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "f20bea598906c990eebe3c70a63ca5ed18cdbc11" "reference": "a6e6c34d337f3c74c39b29c5f54d33023de8897c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/f20bea598906c990eebe3c70a63ca5ed18cdbc11", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a6e6c34d337f3c74c39b29c5f54d33023de8897c",
"reference": "f20bea598906c990eebe3c70a63ca5ed18cdbc11", "reference": "a6e6c34d337f3c74c39b29c5f54d33023de8897c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7371,7 +7372,7 @@
], ],
"description": "Symfony HttpFoundation Component", "description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-07-30 07:20:35" "time": "2016-10-24 15:52:36"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -534,7 +534,7 @@ NINJA.subtotals = function(invoice, hideBalance)
} }
var paid = invoice.amount - invoice.balance; var paid = invoice.amount - invoice.balance;
if (invoice.account.hide_paid_to_date != '1' || paid) { if (!invoice.is_quote && (invoice.account.hide_paid_to_date != '1' || paid)) {
data.push([{text:invoiceLabels.paid_to_date, style: ['subtotalsLabel', 'paidToDateLabel']}, {text:formatMoneyInvoice(paid, invoice), style: ['subtotals', 'paidToDate']}]); data.push([{text:invoiceLabels.paid_to_date, style: ['subtotalsLabel', 'paidToDateLabel']}, {text:formatMoneyInvoice(paid, invoice), style: ['subtotals', 'paidToDate']}]);
} }
@ -542,7 +542,7 @@ NINJA.subtotals = function(invoice, hideBalance)
if (!hideBalance || isPartial) { if (!hideBalance || isPartial) {
data.push([ data.push([
{ text: invoiceLabels.balance_due, style: ['subtotalsLabel', isPartial ? '' : 'balanceDueLabel'] }, { text: invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style: ['subtotalsLabel', isPartial ? '' : 'balanceDueLabel'] },
{ text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['subtotals', isPartial ? '' : 'balanceDue'] } { text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['subtotals', isPartial ? '' : 'balanceDue'] }
]); ]);
} }
@ -562,7 +562,7 @@ NINJA.subtotals = function(invoice, hideBalance)
NINJA.subtotalsBalance = function(invoice) { NINJA.subtotalsBalance = function(invoice) {
var isPartial = NINJA.parseFloat(invoice.partial); var isPartial = NINJA.parseFloat(invoice.partial);
return [[ return [[
{text: isPartial ? invoiceLabels.partial_due : invoiceLabels.balance_due, style:['subtotalsLabel', 'balanceDueLabel']}, {text: isPartial ? invoiceLabels.partial_due : (invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due), style:['subtotalsLabel', 'balanceDueLabel']},
{text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['subtotals', 'balanceDue']} {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['subtotals', 'balanceDue']}
]]; ]];
} }
@ -667,7 +667,7 @@ NINJA.renderInvoiceField = function(invoice, field) {
} }
} else if (field == 'invoice.balance_due') { } else if (field == 'invoice.balance_due') {
return [ return [
{text: invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']}, {text: invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']},
{text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['invoiceDetailBalanceDue']} {text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['invoiceDetailBalanceDue']}
]; ];
} else if (field == invoice.partial_due) { } else if (field == invoice.partial_due) {

View File

@ -1369,7 +1369,7 @@ $LANG = array(
'failed_remove_payment_method' => 'Failed to remove the payment method', 'failed_remove_payment_method' => 'Failed to remove the payment method',
'gateway_exists' => 'This gateway already exists', 'gateway_exists' => 'This gateway already exists',
'manual_entry' => 'Manual entry', 'manual_entry' => 'Manual entry',
'start_of_week' => 'First day of the week', 'start_of_week' => 'First Day of the Week',
// Frequencies // Frequencies
'freq_weekly' => 'Weekly', 'freq_weekly' => 'Weekly',
@ -2174,6 +2174,7 @@ $LANG = array(
'invalid_white_label_license' => 'The white label license is not valid', 'invalid_white_label_license' => 'The white label license is not valid',
'created_by' => 'Created by :name', 'created_by' => 'Created by :name',
'modules' => 'Modules', 'modules' => 'Modules',
'financial_year_start' => 'First Month of the Year',
); );

View File

@ -185,7 +185,6 @@
<script> <script>
var products = {!! $products !!}; var products = {!! $products !!};
console.log(products);
$(function() { $(function() {
var $productSelect = $('select#product'); var $productSelect = $('select#product');

View File

@ -42,7 +42,7 @@
{!! Former::select('language_id')->addOption('','') {!! Former::select('language_id')->addOption('','')
->fromQuery($languages, 'name', 'id') ->fromQuery($languages, 'name', 'id')
->help(trans('texts.translate_app', ['link' => link_to(TRANSIFEX_URL, 'Transifex.com', ['target' => '_blank'])])) !!} ->help(trans('texts.translate_app', ['link' => link_to(TRANSIFEX_URL, 'Transifex.com', ['target' => '_blank'])])) !!}
<br/> <br/>&nbsp;<br/>
{!! Former::select('timezone_id')->addOption('','') {!! Former::select('timezone_id')->addOption('','')
->fromQuery($timezones, 'location', 'id') !!} ->fromQuery($timezones, 'location', 'id') !!}
@ -50,9 +50,16 @@
->fromQuery($dateFormats) !!} ->fromQuery($dateFormats) !!}
{!! Former::select('datetime_format_id')->addOption('','') {!! Former::select('datetime_format_id')->addOption('','')
->fromQuery($datetimeFormats) !!} ->fromQuery($datetimeFormats) !!}
{!! Former::checkbox('military_time')->text(trans('texts.enable')) !!}
<br/>&nbsp;<br/>
{!! Former::select('start_of_week')->addOption('','') {!! Former::select('start_of_week')->addOption('','')
->fromQuery($weekdays) !!} ->fromQuery($weekdays) !!}
{!! Former::checkbox('military_time')->text(trans('texts.enable')) !!} {!! Former::select('financial_year_start')
->addOption('','')
->options($months) !!}
</div> </div>
</div> </div>

View File

@ -16,7 +16,7 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading" style="color:white"> <div class="panel-heading" style="color:white">
{{ trans("texts.{$type}") }} {{ trans("texts.{$type}") }}
@if ($type === ADVANCED_SETTINGS && !Utils::isPro()) @if ($type === ADVANCED_SETTINGS && ! Utils::isPaidPro())
<sup>{{ strtoupper(trans('texts.pro')) }}</sup> <sup>{{ strtoupper(trans('texts.pro')) }}</sup>
@endif @endif
</div> </div>

View File

@ -17,6 +17,7 @@
} }
.modal-header h4 { .modal-header h4 {
margin:0; margin:0;
color:#fff;
} }
.modal-header img { .modal-header img {
float: left; float: left;
@ -89,10 +90,14 @@
{{ Former::populateField('remember', 'true') }} {{ Former::populateField('remember', 'true') }}
<div class="modal-header"> <div class="modal-header">
@if (Utils::isWhiteLabel())
<h4>{{ trans('texts.account_login') }}</h4>
@else
<a href="{{ NINJA_WEB_URL }}" target="_blank"> <a href="{{ NINJA_WEB_URL }}" target="_blank">
<img src="{{ asset('images/icon-login.png') }}" /> <img src="{{ asset('images/icon-login.png') }}" />
<h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4> <h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4>
</a> </a>
@endif
</div> </div>
<div class="inner"> <div class="inner">
<p> <p>

View File

@ -76,8 +76,15 @@
{!! Former::open('recover_password')->rules(['email' => 'required|email'])->addClass('form-signin') !!} {!! Former::open('recover_password')->rules(['email' => 'required|email'])->addClass('form-signin') !!}
<div class="modal-header"> <div class="modal-header">
@if (Utils::isWhiteLabel())
<h4>{{ trans('texts.password_recovery') }}</h4>
@else
<a href="{{ NINJA_WEB_URL }}" target="_blank">
<img src="{{ asset('images/icon-login.png') }}" /> <img src="{{ asset('images/icon-login.png') }}" />
<h4>Invoice Ninja | {{ trans('texts.password_recovery') }}</h4></div> </a>
<h4>Invoice Ninja | {{ trans('texts.password_recovery') }}</h4>
@endif
</div>
<div class="inner"> <div class="inner">
<p> <p>

View File

@ -62,14 +62,7 @@
<div class="container"> <div class="container">
<div class="form-signin"> <div class="form-signin">
<div class="modal-header"> <div class="modal-header">
@if (!isset($account) || !$account->hasFeature(FEATURE_WHITE_LABEL))
<a href="{{ NINJA_WEB_URL }}" target="_blank">
<img src="{{ asset('images/icon-login.png') }}" />
<h4>Invoice Ninja | {{ trans('texts.client_session_expired') }}</h4>
</a>
@else
<h4>{{ trans('texts.session_expired') }}</h4> <h4>{{ trans('texts.session_expired') }}</h4>
@endif
</div> </div>
<div class="inner"> <div class="inner">
<div class="alert alert-info">{{ trans('texts.client_session_expired_message') }}</div> <div class="alert alert-info">{{ trans('texts.client_session_expired_message') }}</div>

View File

@ -341,11 +341,11 @@
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="notes" style="padding-bottom:44px"> <div role="tabpanel" class="tab-pane active" id="notes" style="padding-bottom:44px">
{!! Former::textarea('public_notes')->data_bind("value: public_notes, valueUpdate: 'afterkeydown'") {!! Former::textarea('public_notes')->data_bind("value: public_notes, valueUpdate: 'afterkeydown'")
->label(null)->style('resize: none; width: 500px;')->rows(4) !!} ->label(null)->style('width: 500px;')->rows(4) !!}
</div> </div>
<div role="tabpanel" class="tab-pane" id="terms"> <div role="tabpanel" class="tab-pane" id="terms">
{!! Former::textarea('terms')->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'") {!! Former::textarea('terms')->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('resize: none; width: 500px')->rows(4) ->label(false)->style('width: 500px')->rows(4)
->help('<div class="checkbox"> ->help('<div class="checkbox">
<label> <label>
<input name="set_default_terms" type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>'.trans('texts.save_as_default_terms').' <input name="set_default_terms" type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>'.trans('texts.save_as_default_terms').'
@ -357,7 +357,7 @@
</div> </div>
<div role="tabpanel" class="tab-pane" id="footer"> <div role="tabpanel" class="tab-pane" id="footer">
{!! Former::textarea('invoice_footer')->data_bind("value:invoice_footer, placeholder: footer_placeholder, valueUpdate: 'afterkeydown'") {!! Former::textarea('invoice_footer')->data_bind("value:invoice_footer, placeholder: footer_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('resize: none; width: 500px')->rows(4) ->label(false)->style('width: 500px')->rows(4)
->help('<div class="checkbox"> ->help('<div class="checkbox">
<label> <label>
<input name="set_default_footer" type="checkbox" style="width: 24px" data-bind="checked: set_default_footer"/>'.trans('texts.save_as_default_footer').' <input name="set_default_footer" type="checkbox" style="width: 24px" data-bind="checked: set_default_footer"/>'.trans('texts.save_as_default_footer').'
@ -563,7 +563,14 @@
</div> </div>
<p>&nbsp;</p> <p>&nbsp;</p>
@if (Auth::user()->account->live_preview))
@include('invoices.pdf', ['account' => Auth::user()->account]) @include('invoices.pdf', ['account' => Auth::user()->account])
@else
<script type="text/javascript">
var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!};
function refreshPDF() {}
</script>
@endif
@if (!Auth::user()->account->isPro()) @if (!Auth::user()->account->isPro())
<div style="font-size:larger"> <div style="font-size:larger">
@ -1118,7 +1125,7 @@
refreshPDF(true); refreshPDF(true);
}); });
$('textarea').on('keyup focus', function(e) { $('textarea.word-wrap').on('keyup focus', function(e) {
$(this).height(0).height(this.scrollHeight-18); $(this).height(0).height(this.scrollHeight-18);
}); });
@ -1167,11 +1174,6 @@
window.generatedPDF = false; window.generatedPDF = false;
function getPDFString(cb, force) { function getPDFString(cb, force) {
@if (!$account->live_preview)
if (window.generatedPDF) {
return;
}
@endif
var invoice = createInvoiceModel(); var invoice = createInvoiceModel();
var design = getDesignJavascript(); var design = getDesignJavascript();
if (!design) return; if (!design) return;

View File

@ -58,7 +58,7 @@
"type": "rect", "type": "rect",
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 515, "w": 532,
"h": 26, "h": 26,
"r": 0, "r": 0,
"lineWidth": 1, "lineWidth": 1,