mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
293811d5ca
@ -10,6 +10,8 @@
|
||||
|
||||
## [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.
|
||||
|
||||
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...
|
||||
|
@ -429,6 +429,7 @@ class AccountController extends BaseController
|
||||
'currencies' => Cache::get('currencies'),
|
||||
'title' => trans('texts.localization'),
|
||||
'weekdays' => Utils::getTranslatedWeekdayNames(),
|
||||
'months' => Utils::getMonthOptions(),
|
||||
];
|
||||
|
||||
return View::make('accounts.localization', $data);
|
||||
@ -674,11 +675,9 @@ class AccountController extends BaseController
|
||||
* @param $section
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function doSection($section = ACCOUNT_COMPANY_DETAILS)
|
||||
public function doSection($section)
|
||||
{
|
||||
if ($section === ACCOUNT_COMPANY_DETAILS) {
|
||||
return AccountController::saveDetails();
|
||||
} elseif ($section === ACCOUNT_LOCALIZATION) {
|
||||
if ($section === ACCOUNT_LOCALIZATION) {
|
||||
return AccountController::saveLocalization();
|
||||
} elseif ($section == ACCOUNT_PAYMENTS) {
|
||||
return self::saveOnlinePayments();
|
||||
@ -1225,6 +1224,7 @@ class AccountController extends BaseController
|
||||
$account->military_time = Input::get('military_time') ? 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->financial_year_start = Input::get('financial_year_start') ? Input::get('financial_year_start') : null;
|
||||
$account->save();
|
||||
|
||||
event(new UserSettingsChanged());
|
||||
|
@ -211,6 +211,8 @@ class ClientPortalController extends BaseController
|
||||
|
||||
$client = $contact->client;
|
||||
$account = $client->account;
|
||||
$account->loadLocalizationSettings($client);
|
||||
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
$customer = false;
|
||||
|
||||
@ -277,6 +279,7 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
@ -304,6 +307,7 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
@ -350,12 +354,14 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
}
|
||||
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'account' => $account,
|
||||
@ -420,12 +426,14 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
}
|
||||
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'account' => $account,
|
||||
@ -455,12 +463,14 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
}
|
||||
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'account' => $account,
|
||||
@ -489,12 +499,14 @@ class ClientPortalController extends BaseController
|
||||
}
|
||||
|
||||
$account = $contact->account;
|
||||
$account->loadLocalizationSettings($contact->client);
|
||||
|
||||
if (!$account->enable_client_portal) {
|
||||
return $this->returnError();
|
||||
}
|
||||
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'account' => $account,
|
||||
|
@ -23,8 +23,8 @@ class DashboardApiController extends BaseAPIController
|
||||
|
||||
$dashboardRepo = $this->dashboardRepo;
|
||||
$metrics = $dashboardRepo->totals($accountId, $userId, $viewAll);
|
||||
$paidToDate = $dashboardRepo->paidToDate($accountId, $userId, $viewAll);
|
||||
$averageInvoice = $dashboardRepo->averages($accountId, $userId, $viewAll);
|
||||
$paidToDate = $dashboardRepo->paidToDate($account, $userId, $viewAll);
|
||||
$averageInvoice = $dashboardRepo->averages($account, $userId, $viewAll);
|
||||
$balances = $dashboardRepo->balances($accountId, $userId, $viewAll);
|
||||
$activities = $dashboardRepo->activities($accountId, $userId, $viewAll);
|
||||
$pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll);
|
||||
|
@ -33,9 +33,9 @@ class DashboardController extends BaseController
|
||||
|
||||
$dashboardRepo = $this->dashboardRepo;
|
||||
$metrics = $dashboardRepo->totals($accountId, $userId, $viewAll);
|
||||
$paidToDate = $dashboardRepo->paidToDate($accountId, $userId, $viewAll);
|
||||
$averageInvoice = $dashboardRepo->averages($accountId, $userId, $viewAll);
|
||||
$balances = $dashboardRepo->balances($accountId, $userId, $viewAll);
|
||||
$paidToDate = $dashboardRepo->paidToDate($account, $userId, $viewAll);
|
||||
$averageInvoice = $dashboardRepo->averages($account, $userId, $viewAll);
|
||||
$balances = $dashboardRepo->balances($accountId, $userId, $viewAll);
|
||||
$activities = $dashboardRepo->activities($accountId, $userId, $viewAll);
|
||||
$pastDue = $dashboardRepo->pastDue($accountId, $userId, $viewAll);
|
||||
$upcoming = $dashboardRepo->upcoming($accountId, $userId, $viewAll);
|
||||
|
@ -70,11 +70,13 @@ class OnlinePaymentController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
if ( ! floatval($invitation->invoice->balance)) {
|
||||
if ( ! $invitation->invoice->canBePaid()) {
|
||||
return redirect()->to('view/' . $invitation->invitation_key);
|
||||
}
|
||||
|
||||
$invitation = $invitation->load('invoice.client.account.account_gateways.gateway');
|
||||
$account = $invitation->account;
|
||||
$account->loadLocalizationSettings($invitation->invoice->client);
|
||||
|
||||
if ( ! $gatewayTypeAlias) {
|
||||
$gatewayTypeId = Session::get($invitation->id . 'gateway_type');
|
||||
@ -84,7 +86,7 @@ class OnlinePaymentController extends BaseController
|
||||
$gatewayTypeId = $gatewayTypeAlias;
|
||||
}
|
||||
|
||||
$paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId);
|
||||
$paymentDriver = $account->paymentDriver($invitation, $gatewayTypeId);
|
||||
|
||||
try {
|
||||
return $paymentDriver->startPurchase(Input::all(), $sourceId);
|
||||
@ -103,6 +105,10 @@ class OnlinePaymentController extends BaseController
|
||||
$gatewayTypeId = Session::get($invitation->id . 'gateway_type');
|
||||
$paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId);
|
||||
|
||||
if ( ! $invitation->invoice->canBePaid()) {
|
||||
return redirect()->to('view/' . $invitation->invitation_key);
|
||||
}
|
||||
|
||||
try {
|
||||
$paymentDriver->completeOnsitePurchase($request->all());
|
||||
|
||||
|
@ -18,7 +18,6 @@ class Kernel extends HttpKernel {
|
||||
'App\Http\Middleware\VerifyCsrfToken',
|
||||
'App\Http\Middleware\DuplicateSubmissionCheck',
|
||||
'App\Http\Middleware\QueryLogging',
|
||||
'App\Http\Middleware\SessionDataCheckMiddleware',
|
||||
'App\Http\Middleware\StartupCheck',
|
||||
];
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ use Event;
|
||||
use Schema;
|
||||
use App\Models\Language;
|
||||
use App\Models\InvoiceDesign;
|
||||
use App\Events\UserSettingsChanged;
|
||||
use App\Events\UserLoggedIn;
|
||||
use App\Libraries\CurlUtils;
|
||||
|
||||
/**
|
||||
@ -118,7 +118,7 @@ class StartupCheck
|
||||
|
||||
// Make sure the account/user localization settings are in the session
|
||||
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.)
|
||||
|
@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
class parseCSV {
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Class: parseCSV v0.3.2
|
||||
http://code.google.com/p/parsecsv-for-php/
|
||||
|
||||
|
||||
|
||||
|
||||
Fully conforms to the specifications lined out on wikipedia:
|
||||
- http://en.wikipedia.org/wiki/Comma-separated_values
|
||||
|
||||
|
||||
Based on the concept of Ming Hong Ng's CsvFileParser class:
|
||||
- http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@ -35,9 +35,9 @@ class parseCSV {
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Code Examples
|
||||
----------------
|
||||
# general usage
|
||||
@ -74,7 +74,7 @@ class parseCSV {
|
||||
$csv = new parseCSV();
|
||||
$csv->output (true, 'movies.csv', $array);
|
||||
----------------
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
@ -83,87 +83,87 @@ class parseCSV {
|
||||
* Configuration
|
||||
* - set these options with $object->var_name = 'value';
|
||||
*/
|
||||
|
||||
|
||||
# use first line/entry as field names
|
||||
var $heading = true;
|
||||
|
||||
|
||||
# override field names
|
||||
var $fields = [];
|
||||
|
||||
|
||||
# sort entries by this field
|
||||
var $sort_by = null;
|
||||
var $sort_reverse = false;
|
||||
|
||||
|
||||
# delimiter (comma) and enclosure (double quote)
|
||||
var $delimiter = ',';
|
||||
var $enclosure = '"';
|
||||
|
||||
|
||||
# basic SQL-like conditions for row matching
|
||||
var $conditions = null;
|
||||
|
||||
|
||||
# number of rows to ignore from beginning of data
|
||||
var $offset = null;
|
||||
|
||||
|
||||
# limits the number of returned rows to specified amount
|
||||
var $limit = null;
|
||||
|
||||
|
||||
# number of rows to analyze when attempting to auto-detect delimiter
|
||||
var $auto_depth = 15;
|
||||
|
||||
|
||||
# characters to ignore when attempting to auto-detect delimiter
|
||||
var $auto_non_chars = "a-zA-Z0-9\n\r";
|
||||
|
||||
|
||||
# preferred delimiter characters, only used when all filtering method
|
||||
# returns multiple possible delimiters (happens very rarely)
|
||||
var $auto_preferred = ",;\t.:|";
|
||||
|
||||
|
||||
# character encoding options
|
||||
var $convert_encoding = false;
|
||||
var $input_encoding = 'ISO-8859-1';
|
||||
var $output_encoding = 'ISO-8859-1';
|
||||
|
||||
|
||||
# used by unparse(), save(), and output() functions
|
||||
var $linefeed = "\r\n";
|
||||
|
||||
|
||||
# only used by output() function
|
||||
var $output_delimiter = ',';
|
||||
var $output_filename = 'data.csv';
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal variables
|
||||
*/
|
||||
|
||||
|
||||
# current file
|
||||
var $file;
|
||||
|
||||
|
||||
# loaded file contents
|
||||
var $file_data;
|
||||
|
||||
|
||||
# array of field values in data parsed
|
||||
var $titles = [];
|
||||
|
||||
|
||||
# two dimentional array of CSV data
|
||||
var $data = [];
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param input CSV file or string
|
||||
* @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 ( $limit !== null ) $this->limit = $limit;
|
||||
if ( count($conditions) > 0 ) $this->conditions = $conditions;
|
||||
if ( !empty($input) ) $this->parse($input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ==============================================
|
||||
// ----- [ Main Functions ] ---------------------
|
||||
// ==============================================
|
||||
|
||||
|
||||
/**
|
||||
* Parse CSV file or string
|
||||
* @param input CSV file or string
|
||||
@ -184,7 +184,7 @@ class parseCSV {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save changes, or new file and/or data
|
||||
* @param file file to save to
|
||||
@ -199,7 +199,7 @@ class parseCSV {
|
||||
$is_php = ( preg_match('/\.php$/i', $file) ) ? true : false ;
|
||||
return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate CSV based string for output
|
||||
* @param output if true, prints headers and strings to browser
|
||||
@ -220,7 +220,7 @@ class parseCSV {
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert character encoding
|
||||
* @param input input character encoding, uses default if left blank
|
||||
@ -232,7 +232,7 @@ class parseCSV {
|
||||
if ( $input !== null ) $this->input_encoding = $input;
|
||||
if ( $output !== null ) $this->output_encoding = $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auto-Detect Delimiter: Find delimiter by analyzing a specific number of
|
||||
* rows to determine most probable delimiter character
|
||||
@ -244,13 +244,13 @@ class parseCSV {
|
||||
* @return delimiter character
|
||||
*/
|
||||
function auto ($file = null, $parse = true, $search_depth = null, $preferred = null, $enclosure = null) {
|
||||
|
||||
|
||||
if ( $file === null ) $file = $this->file;
|
||||
if ( empty($search_depth) ) $search_depth = $this->auto_depth;
|
||||
if ( $enclosure === null ) $enclosure = $this->enclosure;
|
||||
|
||||
|
||||
if ( $preferred === null ) $preferred = $this->auto_preferred;
|
||||
|
||||
|
||||
if ( empty($this->file_data) ) {
|
||||
if ( $this->_check_data($file) ) {
|
||||
$data = &$this->file_data;
|
||||
@ -258,24 +258,24 @@ class parseCSV {
|
||||
} else {
|
||||
$data = &$this->file_data;
|
||||
}
|
||||
|
||||
|
||||
$chars = [];
|
||||
$strlen = strlen($data);
|
||||
$enclosed = false;
|
||||
$n = 1;
|
||||
$to_end = true;
|
||||
|
||||
|
||||
// walk specific depth finding posssible delimiter characters
|
||||
for ( $i=0; $i < $strlen; $i++ ) {
|
||||
$ch = $data{$i};
|
||||
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
|
||||
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
|
||||
|
||||
|
||||
// open and closing quotes
|
||||
if ( $ch == $enclosure && (!$enclosed || $nch != $enclosure) ) {
|
||||
$enclosed = ( $enclosed ) ? false : true ;
|
||||
|
||||
// inline quotes
|
||||
|
||||
// inline quotes
|
||||
} elseif ( $ch == $enclosure && $enclosed ) {
|
||||
$i++;
|
||||
|
||||
@ -287,7 +287,7 @@ class parseCSV {
|
||||
} else {
|
||||
$n++;
|
||||
}
|
||||
|
||||
|
||||
// count character
|
||||
} elseif (!$enclosed) {
|
||||
if ( !preg_match('/['.preg_quote($this->auto_non_chars, '/').']/i', $ch) ) {
|
||||
@ -299,7 +299,7 @@ class parseCSV {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// filtering
|
||||
$depth = ( $to_end ) ? $n-1 : $n ;
|
||||
$filtered = [];
|
||||
@ -308,24 +308,24 @@ class parseCSV {
|
||||
$filtered[$match] = $char;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// capture most probable delimiter
|
||||
ksort($filtered);
|
||||
$delimiter = reset($filtered);
|
||||
$this->delimiter = $delimiter;
|
||||
|
||||
|
||||
// parse data
|
||||
if ( $parse ) $this->data = $this->parse_string();
|
||||
|
||||
|
||||
return $delimiter;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ==============================================
|
||||
// ----- [ Core Functions ] ---------------------
|
||||
// ==============================================
|
||||
|
||||
|
||||
/**
|
||||
* Read file to string and call parse_string()
|
||||
* @param file local CSV file
|
||||
@ -336,7 +336,7 @@ class parseCSV {
|
||||
if ( empty($this->file_data) ) $this->load_data($file);
|
||||
return ( !empty($this->file_data) ) ? $this->parse_string() : false ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse CSV strings to arrays
|
||||
* @param data CSV string
|
||||
@ -348,7 +348,7 @@ class parseCSV {
|
||||
$data = &$this->file_data;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
|
||||
$rows = [];
|
||||
$row = [];
|
||||
$row_count = 0;
|
||||
@ -358,19 +358,19 @@ class parseCSV {
|
||||
$enclosed = false;
|
||||
$was_enclosed = false;
|
||||
$strlen = strlen($data);
|
||||
|
||||
|
||||
// walk through each character
|
||||
for ( $i=0; $i < $strlen; $i++ ) {
|
||||
$ch = $data{$i};
|
||||
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
|
||||
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
|
||||
|
||||
|
||||
// open and closing quotes
|
||||
if ( $ch == $this->enclosure && (!$enclosed || $nch != $this->enclosure) ) {
|
||||
$enclosed = ( $enclosed ) ? false : true ;
|
||||
if ( $enclosed ) $was_enclosed = true;
|
||||
|
||||
// inline quotes
|
||||
|
||||
// inline quotes
|
||||
} elseif ( $ch == $this->enclosure && $enclosed ) {
|
||||
$current .= $ch;
|
||||
$i++;
|
||||
@ -382,7 +382,7 @@ class parseCSV {
|
||||
$row[$key] = $current;
|
||||
$current = '';
|
||||
$col++;
|
||||
|
||||
|
||||
// end of row
|
||||
if ( $ch == "\n" || $ch == "\r" ) {
|
||||
if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) {
|
||||
@ -406,7 +406,7 @@ class parseCSV {
|
||||
$i = $strlen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// append character to current field
|
||||
} else {
|
||||
$current .= $ch;
|
||||
@ -421,7 +421,7 @@ class parseCSV {
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create CSV data from array
|
||||
* @param data 2D array with data
|
||||
@ -436,10 +436,10 @@ class parseCSV {
|
||||
if ( !is_array($data) || empty($data) ) $data = &$this->data;
|
||||
if ( !is_array($fields) || empty($fields) ) $fields = &$this->titles;
|
||||
if ( $delimiter === null ) $delimiter = $this->delimiter;
|
||||
|
||||
|
||||
$string = ( $is_php ) ? "<?php header('Status: 403'); die(' '); ?>".$this->linefeed : '' ;
|
||||
$entry = [];
|
||||
|
||||
|
||||
// create heading
|
||||
if ( $this->heading && !$append ) {
|
||||
foreach( $fields as $key => $value ) {
|
||||
@ -448,7 +448,7 @@ class parseCSV {
|
||||
$string .= implode($delimiter, $entry).$this->linefeed;
|
||||
$entry = [];
|
||||
}
|
||||
|
||||
|
||||
// create data
|
||||
foreach( $data as $key => $row ) {
|
||||
foreach( $row as $field => $value ) {
|
||||
@ -457,10 +457,10 @@ class parseCSV {
|
||||
$string .= implode($delimiter, $entry).$this->linefeed;
|
||||
$entry = [];
|
||||
}
|
||||
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load local file or string
|
||||
* @param input local CSV file
|
||||
@ -488,16 +488,16 @@ class parseCSV {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ==============================================
|
||||
// ----- [ Internal Functions ] -----------------
|
||||
// ==============================================
|
||||
|
||||
|
||||
/**
|
||||
* Validate a row against specified conditions
|
||||
* @param row array with values from a row
|
||||
* @param conditions specified conditions that the row must match
|
||||
* @param conditions specified conditions that the row must match
|
||||
* @return true of false
|
||||
*/
|
||||
function _validate_row_conditions ($row = [], $conditions = null) {
|
||||
@ -523,11 +523,11 @@ class parseCSV {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate a row against a single condition
|
||||
* @param row array with values from a row
|
||||
* @param condition specified condition that the row must match
|
||||
* @param condition specified condition that the row must match
|
||||
* @return true of false
|
||||
*/
|
||||
function _validate_row_condition ($row, $condition) {
|
||||
@ -583,7 +583,7 @@ class parseCSV {
|
||||
}
|
||||
return '1';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates if the row is within the offset or not if sorting is disabled
|
||||
* @param current_row the current row number being processed
|
||||
@ -593,7 +593,7 @@ class parseCSV {
|
||||
if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enclose values if needed
|
||||
* - only used by unparse()
|
||||
@ -611,7 +611,7 @@ class parseCSV {
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check file data
|
||||
* @param file local filename
|
||||
@ -624,8 +624,8 @@ class parseCSV {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if passed info might be delimiter
|
||||
* - only used by find_delimiter()
|
||||
@ -656,7 +656,7 @@ class parseCSV {
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read local file
|
||||
* @param file local filename
|
||||
@ -689,7 +689,7 @@ class parseCSV {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
@ -22,6 +22,9 @@ class Utils
|
||||
"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()
|
||||
{
|
||||
@ -92,6 +95,15 @@ class Utils
|
||||
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()
|
||||
{
|
||||
return isset($_ENV['RESELLER_TYPE']) ? $_ENV['RESELLER_TYPE'] : false;
|
||||
@ -151,6 +163,11 @@ class Utils
|
||||
return Auth::check() && Auth::user()->isTrial();
|
||||
}
|
||||
|
||||
public static function isPaidPro()
|
||||
{
|
||||
return static::isPro() && ! static::isTrial();
|
||||
}
|
||||
|
||||
public static function isEnglish()
|
||||
{
|
||||
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)
|
||||
{
|
||||
$months = ['january', 'february', 'march', 'april', 'may', 'june',
|
||||
'july', 'august', 'september', 'october', 'november', 'december', ];
|
||||
|
||||
$months = static::$months;
|
||||
$month = intval(date('n')) - 1;
|
||||
|
||||
$month += $offset;
|
||||
|
@ -69,6 +69,7 @@ class Account extends Eloquent
|
||||
'enable_second_tax_rate',
|
||||
'include_item_taxes_inline',
|
||||
'start_of_week',
|
||||
'financial_year_start',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -345,7 +345,7 @@ class Client extends EntityModel
|
||||
|
||||
$contact = $this->contacts[0];
|
||||
|
||||
return $contact->getDisplayName() ?: trans('texts.unnamed_client');
|
||||
return $contact->getDisplayName();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -514,6 +514,11 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
return storage_path() . '/pdfcache/cache-' . $this->id . '.pdf';
|
||||
}
|
||||
|
||||
public function canBePaid()
|
||||
{
|
||||
return floatval($this->balance) > 0 && ! $this->is_deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $invoice
|
||||
* @return string
|
||||
|
@ -175,29 +175,39 @@ class DashboardRepository
|
||||
return $metrics->groupBy('accounts.id')->first();
|
||||
}
|
||||
|
||||
public function paidToDate($accountId, $userId, $viewAll)
|
||||
public function paidToDate($account, $userId, $viewAll)
|
||||
{
|
||||
$accountId = $account->id;
|
||||
$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'
|
||||
);
|
||||
$paidToDate = DB::table('accounts')
|
||||
$paidToDate = DB::table('payments')
|
||||
->select($select)
|
||||
->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')
|
||||
->where('accounts.id', '=', $accountId)
|
||||
->where('clients.is_deleted', '=', false);
|
||||
->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
|
||||
->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->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){
|
||||
$paidToDate = $paidToDate->where('clients.user_id', '=', $userId);
|
||||
$paidToDate->where('invoices.user_id', '=', $userId);
|
||||
}
|
||||
|
||||
return $paidToDate->groupBy('accounts.id')
|
||||
->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'))
|
||||
if ($account->financial_year_start) {
|
||||
$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();
|
||||
}
|
||||
|
||||
public function averages($accountId, $userId, $viewAll)
|
||||
public function averages($account, $userId, $viewAll)
|
||||
{
|
||||
$accountId = $account->id;
|
||||
$select = DB::raw(
|
||||
'AVG('.DB::getQueryGrammar()->wrap('invoices.amount', true).') as invoice_avg, '
|
||||
.DB::getQueryGrammar()->wrap('clients.currency_id', true).' as currency_id'
|
||||
@ -213,7 +223,12 @@ class DashboardRepository
|
||||
->where('invoices.is_recurring', '=', false);
|
||||
|
||||
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')
|
||||
@ -252,7 +267,7 @@ class DashboardRepository
|
||||
}
|
||||
|
||||
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)
|
||||
->get();
|
||||
}
|
||||
|
@ -86,11 +86,16 @@ class InvoiceService extends BaseService
|
||||
$sendInvoiceIds = [];
|
||||
|
||||
foreach ($client->contacts as $contact) {
|
||||
if ($contact->send_invoice || count($client->contacts) == 1) {
|
||||
if ($contact->send_invoice) {
|
||||
$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) {
|
||||
$invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first();
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
||||
"gatepay/FedACHdir": "dev-master@dev",
|
||||
"websight/l5-google-cloud-storage": "^1.0",
|
||||
"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-debugbar": "~2.2",
|
||||
"fzaninotto/faker": "^1.5",
|
||||
|
39
composer.lock
generated
39
composer.lock
generated
@ -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": "f61ec0361b0757ca0cade78837862d39",
|
||||
"content-hash": "37549f849d74405b68eb7e2df64dfb43",
|
||||
"hash": "cf642e3384eec7504bcdace749d2bb88",
|
||||
"content-hash": "c0a5b571bc2305c4b0d9eae18bf5011b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "agmscode/omnipay-agms",
|
||||
@ -1081,16 +1081,16 @@
|
||||
},
|
||||
{
|
||||
"name": "collizo4sky/omnipay-wepay",
|
||||
"version": "dev-additional-calls",
|
||||
"version": "dev-address-fix",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hillelcoren/omnipay-wepay.git",
|
||||
"reference": "a341b9997d71803d0f774d86908cb49a8bc4c405"
|
||||
"reference": "916785146c5433e9216f295d09d1cbcec2fdf33a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hillelcoren/omnipay-wepay/zipball/a341b9997d71803d0f774d86908cb49a8bc4c405",
|
||||
"reference": "a341b9997d71803d0f774d86908cb49a8bc4c405",
|
||||
"url": "https://api.github.com/repos/hillelcoren/omnipay-wepay/zipball/916785146c5433e9216f295d09d1cbcec2fdf33a",
|
||||
"reference": "916785146c5433e9216f295d09d1cbcec2fdf33a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1120,9 +1120,9 @@
|
||||
"wepay"
|
||||
],
|
||||
"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",
|
||||
@ -2184,7 +2184,7 @@
|
||||
"shasum": null
|
||||
},
|
||||
"type": "library",
|
||||
"time": "2016-06-03 12:00:26"
|
||||
"time": "2016-10-12 12:00:38"
|
||||
},
|
||||
{
|
||||
"name": "google/apiclient",
|
||||
@ -3091,6 +3091,7 @@
|
||||
"purchase",
|
||||
"wechat"
|
||||
],
|
||||
"abandoned": "lokielse/omnipay-wechatpay",
|
||||
"time": "2016-05-10 08:43:41"
|
||||
},
|
||||
{
|
||||
@ -7211,16 +7212,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.8.9",
|
||||
"version": "v2.8.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "889983a79a043dfda68f38c38b6dba092dd49cd8"
|
||||
"reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8",
|
||||
"reference": "889983a79a043dfda68f38c38b6dba092dd49cd8",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
|
||||
"reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7267,7 +7268,7 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-07-28 16:56:28"
|
||||
"time": "2016-10-13 01:43:15"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
@ -7320,16 +7321,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v2.8.9",
|
||||
"version": "v2.8.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "f20bea598906c990eebe3c70a63ca5ed18cdbc11"
|
||||
"reference": "a6e6c34d337f3c74c39b29c5f54d33023de8897c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/f20bea598906c990eebe3c70a63ca5ed18cdbc11",
|
||||
"reference": "f20bea598906c990eebe3c70a63ca5ed18cdbc11",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/a6e6c34d337f3c74c39b29c5f54d33023de8897c",
|
||||
"reference": "a6e6c34d337f3c74c39b29c5f54d33023de8897c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7371,7 +7372,7 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-07-30 07:20:35"
|
||||
"time": "2016-10-24 15:52:36"
|
||||
},
|
||||
{
|
||||
"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
@ -534,7 +534,7 @@ NINJA.subtotals = function(invoice, hideBalance)
|
||||
}
|
||||
|
||||
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']}]);
|
||||
}
|
||||
|
||||
@ -542,7 +542,7 @@ NINJA.subtotals = function(invoice, hideBalance)
|
||||
|
||||
if (!hideBalance || isPartial) {
|
||||
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'] }
|
||||
]);
|
||||
}
|
||||
@ -562,7 +562,7 @@ NINJA.subtotals = function(invoice, hideBalance)
|
||||
NINJA.subtotalsBalance = function(invoice) {
|
||||
var isPartial = NINJA.parseFloat(invoice.partial);
|
||||
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']}
|
||||
]];
|
||||
}
|
||||
@ -667,7 +667,7 @@ NINJA.renderInvoiceField = function(invoice, field) {
|
||||
}
|
||||
} else if (field == 'invoice.balance_due') {
|
||||
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']}
|
||||
];
|
||||
} else if (field == invoice.partial_due) {
|
||||
|
@ -1369,7 +1369,7 @@ $LANG = array(
|
||||
'failed_remove_payment_method' => 'Failed to remove the payment method',
|
||||
'gateway_exists' => 'This gateway already exists',
|
||||
'manual_entry' => 'Manual entry',
|
||||
'start_of_week' => 'First day of the week',
|
||||
'start_of_week' => 'First Day of the Week',
|
||||
|
||||
// Frequencies
|
||||
'freq_weekly' => 'Weekly',
|
||||
@ -2174,6 +2174,7 @@ $LANG = array(
|
||||
'invalid_white_label_license' => 'The white label license is not valid',
|
||||
'created_by' => 'Created by :name',
|
||||
'modules' => 'Modules',
|
||||
'financial_year_start' => 'First Month of the Year',
|
||||
|
||||
);
|
||||
|
||||
|
@ -185,7 +185,6 @@
|
||||
<script>
|
||||
|
||||
var products = {!! $products !!};
|
||||
console.log(products);
|
||||
|
||||
$(function() {
|
||||
var $productSelect = $('select#product');
|
||||
|
@ -42,7 +42,7 @@
|
||||
{!! Former::select('language_id')->addOption('','')
|
||||
->fromQuery($languages, 'name', 'id')
|
||||
->help(trans('texts.translate_app', ['link' => link_to(TRANSIFEX_URL, 'Transifex.com', ['target' => '_blank'])])) !!}
|
||||
<br/>
|
||||
<br/> <br/>
|
||||
|
||||
{!! Former::select('timezone_id')->addOption('','')
|
||||
->fromQuery($timezones, 'location', 'id') !!}
|
||||
@ -50,9 +50,16 @@
|
||||
->fromQuery($dateFormats) !!}
|
||||
{!! Former::select('datetime_format_id')->addOption('','')
|
||||
->fromQuery($datetimeFormats) !!}
|
||||
{!! Former::checkbox('military_time')->text(trans('texts.enable')) !!}
|
||||
|
||||
<br/> <br/>
|
||||
|
||||
{!! Former::select('start_of_week')->addOption('','')
|
||||
->fromQuery($weekdays) !!}
|
||||
{!! Former::checkbox('military_time')->text(trans('texts.enable')) !!}
|
||||
{!! Former::select('financial_year_start')
|
||||
->addOption('','')
|
||||
->options($months) !!}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" style="color:white">
|
||||
{{ trans("texts.{$type}") }}
|
||||
@if ($type === ADVANCED_SETTINGS && !Utils::isPro())
|
||||
@if ($type === ADVANCED_SETTINGS && ! Utils::isPaidPro())
|
||||
<sup>{{ strtoupper(trans('texts.pro')) }}</sup>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -17,6 +17,7 @@
|
||||
}
|
||||
.modal-header h4 {
|
||||
margin:0;
|
||||
color:#fff;
|
||||
}
|
||||
.modal-header img {
|
||||
float: left;
|
||||
@ -89,10 +90,14 @@
|
||||
{{ Former::populateField('remember', 'true') }}
|
||||
|
||||
<div class="modal-header">
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4>
|
||||
</a>
|
||||
@if (Utils::isWhiteLabel())
|
||||
<h4>{{ trans('texts.account_login') }}</h4>
|
||||
@else
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="inner">
|
||||
<p>
|
||||
|
@ -76,8 +76,15 @@
|
||||
|
||||
{!! Former::open('recover_password')->rules(['email' => 'required|email'])->addClass('form-signin') !!}
|
||||
<div class="modal-header">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.password_recovery') }}</h4></div>
|
||||
@if (Utils::isWhiteLabel())
|
||||
<h4>{{ trans('texts.password_recovery') }}</h4>
|
||||
@else
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
</a>
|
||||
<h4>Invoice Ninja | {{ trans('texts.password_recovery') }}</h4>
|
||||
@endif
|
||||
</div>
|
||||
<div class="inner">
|
||||
|
||||
<p>
|
||||
|
@ -62,18 +62,11 @@
|
||||
<div class="container">
|
||||
<div class="form-signin">
|
||||
<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>
|
||||
@endif
|
||||
<h4>{{ trans('texts.session_expired') }}</h4>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<div class="alert alert-info">{{ trans('texts.client_session_expired_message') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
@ -341,11 +341,11 @@
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="notes" style="padding-bottom:44px">
|
||||
{!! 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 role="tabpanel" class="tab-pane" id="terms">
|
||||
{!! 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">
|
||||
<label>
|
||||
<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 role="tabpanel" class="tab-pane" id="footer">
|
||||
{!! 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">
|
||||
<label>
|
||||
<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>
|
||||
<p> </p>
|
||||
|
||||
@include('invoices.pdf', ['account' => Auth::user()->account])
|
||||
@if (Auth::user()->account->live_preview))
|
||||
@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())
|
||||
<div style="font-size:larger">
|
||||
@ -1118,7 +1125,7 @@
|
||||
refreshPDF(true);
|
||||
});
|
||||
|
||||
$('textarea').on('keyup focus', function(e) {
|
||||
$('textarea.word-wrap').on('keyup focus', function(e) {
|
||||
$(this).height(0).height(this.scrollHeight-18);
|
||||
});
|
||||
|
||||
@ -1167,11 +1174,6 @@
|
||||
|
||||
window.generatedPDF = false;
|
||||
function getPDFString(cb, force) {
|
||||
@if (!$account->live_preview)
|
||||
if (window.generatedPDF) {
|
||||
return;
|
||||
}
|
||||
@endif
|
||||
var invoice = createInvoiceModel();
|
||||
var design = getDesignJavascript();
|
||||
if (!design) return;
|
||||
|
@ -58,7 +58,7 @@
|
||||
"type": "rect",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 515,
|
||||
"w": 532,
|
||||
"h": 26,
|
||||
"r": 0,
|
||||
"lineWidth": 1,
|
||||
@ -260,4 +260,4 @@
|
||||
}
|
||||
},
|
||||
"pageMargins": [40, 120, 40, 50]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user