diff --git a/.env.example b/.env.example
index abc9da3a5254..643dda91d834 100644
--- a/.env.example
+++ b/.env.example
@@ -18,6 +18,4 @@ MAIL_HOST
MAIL_USERNAME
MAIL_FROM_ADDRESS
MAIL_FROM_NAME
-MAIL_PASSWORD
-
-ALLOW_NEW_ACCOUNTS
\ No newline at end of file
+MAIL_PASSWORD
\ No newline at end of file
diff --git a/app/Console/Commands/SendRecurringInvoices.php b/app/Console/Commands/SendRecurringInvoices.php
index 8f65214f7fc1..6acd87aa0c6e 100644
--- a/app/Console/Commands/SendRecurringInvoices.php
+++ b/app/Console/Commands/SendRecurringInvoices.php
@@ -7,6 +7,7 @@ use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use App\Ninja\Mailers\ContactMailer as Mailer;
+use App\Ninja\Repositories\InvoiceRepository;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Invitation;
@@ -16,12 +17,14 @@ class SendRecurringInvoices extends Command
protected $name = 'ninja:send-invoices';
protected $description = 'Send recurring invoices';
protected $mailer;
+ protected $invoiceRepo;
- public function __construct(Mailer $mailer)
+ public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo)
{
parent::__construct();
$this->mailer = $mailer;
+ $this->invoiceRepo = $invoiceRepo;
}
public function fire()
@@ -34,74 +37,14 @@ class SendRecurringInvoices extends Command
$this->info(count($invoices).' recurring invoice(s) found');
foreach ($invoices as $recurInvoice) {
- if ($recurInvoice->client->deleted_at) {
- continue;
+ $this->info('Processing Invoice '.$recurInvoice->id.' - Should send '.($recurInvoice->shouldSendToday() ? 'YES' : 'NO'));
+
+ $invoice = $this->invoiceRepo->createRecurringInvoice($recurInvoice);
+
+ if ($invoice) {
+ $recurInvoice->account->loadLocalizationSettings();
+ $this->mailer->sendInvoice($invoice);
}
-
- if (!$recurInvoice->user->confirmed) {
- continue;
- }
-
- $this->info('Processing Invoice '.$recurInvoice->id.' - Should send '.($recurInvoice->shouldSendToday() ? 'YES' : 'NO'));
-
- if (!$recurInvoice->shouldSendToday()) {
- continue;
- }
-
- $invoice = Invoice::createNew($recurInvoice);
- $invoice->client_id = $recurInvoice->client_id;
- $invoice->recurring_invoice_id = $recurInvoice->id;
- $invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber(false, 'R');
- $invoice->amount = $recurInvoice->amount;
- $invoice->balance = $recurInvoice->amount;
- $invoice->invoice_date = date_create()->format('Y-m-d');
- $invoice->discount = $recurInvoice->discount;
- $invoice->po_number = $recurInvoice->po_number;
- $invoice->public_notes = Utils::processVariables($recurInvoice->public_notes);
- $invoice->terms = Utils::processVariables($recurInvoice->terms);
- $invoice->invoice_footer = Utils::processVariables($recurInvoice->invoice_footer);
- $invoice->tax_name = $recurInvoice->tax_name;
- $invoice->tax_rate = $recurInvoice->tax_rate;
- $invoice->invoice_design_id = $recurInvoice->invoice_design_id;
- $invoice->custom_value1 = $recurInvoice->custom_value1;
- $invoice->custom_value2 = $recurInvoice->custom_value2;
- $invoice->custom_taxes1 = $recurInvoice->custom_taxes1;
- $invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
- $invoice->is_amount_discount = $recurInvoice->is_amount_discount;
-
- if ($invoice->client->payment_terms != 0) {
- $days = $invoice->client->payment_terms;
- if ($days == -1) {
- $days = 0;
- }
- $invoice->due_date = date_create()->modify($days.' day')->format('Y-m-d');
- }
-
- $invoice->save();
-
- foreach ($recurInvoice->invoice_items as $recurItem) {
- $item = InvoiceItem::createNew($recurItem);
- $item->product_id = $recurItem->product_id;
- $item->qty = $recurItem->qty;
- $item->cost = $recurItem->cost;
- $item->notes = Utils::processVariables($recurItem->notes);
- $item->product_key = Utils::processVariables($recurItem->product_key);
- $item->tax_name = $recurItem->tax_name;
- $item->tax_rate = $recurItem->tax_rate;
- $invoice->invoice_items()->save($item);
- }
-
- foreach ($recurInvoice->invitations as $recurInvitation) {
- $invitation = Invitation::createNew($recurInvitation);
- $invitation->contact_id = $recurInvitation->contact_id;
- $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
- $invoice->invitations()->save($invitation);
- }
-
- $this->mailer->sendInvoice($invoice);
-
- $recurInvoice->last_sent_date = Carbon::now()->toDateTimeString();
- $recurInvoice->save();
}
$this->info('Done');
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 204e270c7e3a..42737940bbe8 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -75,18 +75,18 @@ class AccountController extends BaseController
public function getStarted()
{
- if (Auth::check()) {
- return Redirect::to('invoices/create');
- }
-
- if (!Utils::isNinja() && !Utils::allowNewAccounts() && Account::count() > 0) {
- return Redirect::to('/login');
- }
-
$user = false;
$guestKey = Input::get('guest_key'); // local storage key to login until registered
$prevUserId = Session::pull(PREV_USER_ID); // last user id used to link to new account
+ if (Auth::check()) {
+ return Redirect::to('invoices/create');
+ }
+
+ if (!Utils::isNinja() && (Account::count() > 0 && !$prevUserId)) {
+ return Redirect::to('/login');
+ }
+
if ($guestKey && !$prevUserId) {
$user = User::where('password', '=', $guestKey)->first();
@@ -149,6 +149,7 @@ class AccountController extends BaseController
public function showSection($section = ACCOUNT_DETAILS, $subSection = false)
{
if ($section == ACCOUNT_DETAILS) {
+ $primaryUser = Auth::user()->account->users()->orderBy('id')->first();
$data = [
'account' => Account::with('users')->findOrFail(Auth::user()->account_id),
'countries' => Cache::get('countries'),
@@ -159,8 +160,9 @@ class AccountController extends BaseController
'datetimeFormats' => Cache::get('datetimeFormats'),
'currencies' => Cache::get('currencies'),
'languages' => Cache::get('languages'),
- 'showUser' => Auth::user()->id === Auth::user()->account->users()->first()->id,
+ 'showUser' => Auth::user()->id === $primaryUser->id,
'title' => trans('texts.company_details'),
+ 'primaryUser' => $primaryUser,
];
return View::make('accounts.details', $data);
@@ -211,7 +213,7 @@ class AccountController extends BaseController
$client->work_email = '';
$invoice->invoice_number = $account->getNextInvoiceNumber();
- $invoice->invoice_date = date_create()->format('Y-m-d');
+ $invoice->invoice_date = Utils::fromSqlDate(date('Y-m-d'));
$invoice->account = json_decode($account->toJson());
$invoice->amount = $invoice->balance = 100;
@@ -637,9 +639,10 @@ class AccountController extends BaseController
{
$rules = array(
'name' => 'required',
+ 'logo' => 'sometimes|max:1024|mimes:jpeg,gif,png',
);
- $user = Auth::user()->account->users()->first();
+ $user = Auth::user()->account->users()->orderBy('id')->first();
if (Auth::user()->id === $user->id) {
$rules['email'] = 'email|required|unique:users,email,'.$user->id.',id';
diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php
index dac4b85ccbbb..bc6c699e728b 100644
--- a/app/Http/Controllers/AppController.php
+++ b/app/Http/Controllers/AppController.php
@@ -88,7 +88,7 @@ class AppController extends BaseController
"MAIL_HOST={$mail['host']}\n".
"MAIL_USERNAME={$mail['username']}\n".
"MAIL_FROM_NAME={$mail['from']['name']}\n".
- "MAIL_PASSWORD={$mail['password']}\n";
+ "MAIL_PASSWORD={$mail['password']}";
// Write Config Settings
$fp = fopen(base_path()."/.env", 'w');
diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php
index e17135fe7146..a5897ac6879d 100644
--- a/app/Http/Controllers/Auth/AuthController.php
+++ b/app/Http/Controllers/Auth/AuthController.php
@@ -62,7 +62,7 @@ class AuthController extends Controller {
$userId = Auth::check() ? Auth::user()->id : null;
$user = User::where('email', '=', $request->input('email'))->first();
- if ($user->failed_logins >= 3) {
+ if ($user && $user->failed_logins >= 3) {
Session::flash('error', 'These credentials do not match our records.');
return redirect()->to('login');
}
diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php
index e286b885cbf6..6ac4de2a4039 100644
--- a/app/Http/Controllers/DashboardController.php
+++ b/app/Http/Controllers/DashboardController.php
@@ -5,6 +5,7 @@ use DB;
use View;
use App\Models\Activity;
use App\Models\Invoice;
+use App\Models\Payment;
class DashboardController extends BaseController
{
@@ -50,41 +51,81 @@ class DashboardController extends BaseController
->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))
->get();
-
+ $select = DB::raw('SUM(clients.balance) as value, clients.currency_id as currency_id');
+ $balances = DB::table('accounts')
+ ->select($select)
+ ->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')
+ ->where('accounts.id', '=', Auth::user()->account_id)
+ ->where('clients.is_deleted', '=', false)
+ ->groupBy('accounts.id')
+ ->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))
+ ->get();
$activities = Activity::where('activities.account_id', '=', Auth::user()->account_id)
->where('activity_type_id', '>', 0)
- ->orderBy('created_at', 'desc')->take(14)->get();
+ ->orderBy('created_at', 'desc')
+ ->take(50)
+ ->get();
- $pastDue = Invoice::scope()->whereHas('client', function($query) {
- $query->where('deleted_at', '=', null);
- })
- ->where('due_date', '<', date('Y-m-d'))
- ->where('balance', '>', 0)
- ->where('is_recurring', '=', false)
- ->where('is_quote', '=', false)
- ->where('is_deleted', '=', false)
- ->orderBy('due_date', 'asc')->take(6)->get();
+ $pastDue = DB::table('invoices')
+ ->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
+ ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
+ ->where('invoices.account_id', '=', Auth::user()->account_id)
+ ->where('clients.deleted_at', '=', null)
+ ->where('contacts.deleted_at', '=', null)
+ ->where('invoices.is_recurring', '=', false)
+ ->where('invoices.is_quote', '=', false)
+ ->where('invoices.balance', '>', 0)
+ ->where('invoices.is_deleted', '=', false)
+ ->where('contacts.is_primary', '=', true)
+ ->where('invoices.due_date', '<', date('Y-m-d'))
+ ->select(['invoices.due_date', 'invoices.balance', 'invoices.public_id', 'invoices.invoice_number', 'clients.name as client_name', 'contacts.email', 'contacts.first_name', 'contacts.last_name', 'clients.currency_id', 'clients.public_id as client_public_id'])
+ ->orderBy('invoices.due_date', 'asc')
+ ->take(50)
+ ->get();
+
+ $upcoming = DB::table('invoices')
+ ->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
+ ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
+ ->where('invoices.account_id', '=', Auth::user()->account_id)
+ ->where('clients.deleted_at', '=', null)
+ ->where('contacts.deleted_at', '=', null)
+ ->where('invoices.is_recurring', '=', false)
+ ->where('invoices.is_quote', '=', false)
+ ->where('invoices.balance', '>', 0)
+ ->where('invoices.is_deleted', '=', false)
+ ->where('contacts.is_primary', '=', true)
+ ->where('invoices.due_date', '>=', date('Y-m-d'))
+ ->orderBy('invoices.due_date', 'asc')
+ ->take(50)
+ ->select(['invoices.due_date', 'invoices.balance', 'invoices.public_id', 'invoices.invoice_number', 'clients.name as client_name', 'contacts.email', 'contacts.first_name', 'contacts.last_name', 'clients.currency_id', 'clients.public_id as client_public_id'])
+ ->get();
+
+ $payments = DB::table('payments')
+ ->leftJoin('clients', 'clients.id', '=', 'payments.client_id')
+ ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
+ ->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
+ ->where('payments.account_id', '=', Auth::user()->account_id)
+ ->where('clients.deleted_at', '=', null)
+ ->where('contacts.deleted_at', '=', null)
+ ->where('contacts.is_primary', '=', true)
+ ->select(['payments.payment_date', 'payments.amount', 'invoices.public_id', 'invoices.invoice_number', 'clients.name as client_name', 'contacts.email', 'contacts.first_name', 'contacts.last_name', 'clients.currency_id', 'clients.public_id as client_public_id'])
+ ->orderBy('payments.id', 'desc')
+ ->take(50)
+ ->get();
- $upcoming = Invoice::scope()->whereHas('client', function($query) {
- $query->where('deleted_at', '=', null);
- })
- ->where('due_date', '>=', date('Y-m-d'))
- ->where('balance', '>', 0)
- ->where('is_recurring', '=', false)
- ->where('is_quote', '=', false)
- ->where('is_deleted', '=', false)
- ->orderBy('due_date', 'asc')->take(6)->get();
$data = [
+ 'account' => Auth::user()->account,
'paidToDate' => $paidToDate,
+ 'balances' => $balances,
'averageInvoice' => $averageInvoice,
- //'billedClients' => $metrics ? $metrics->billed_clients : 0,
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
'activeClients' => $metrics ? $metrics->active_clients : 0,
'activities' => $activities,
'pastDue' => $pastDue,
'upcoming' => $upcoming,
+ 'payments' => $payments,
'title' => trans('texts.dashboard'),
];
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index a58245e0e25b..0f8226f077b1 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -43,7 +43,7 @@ class HomeController extends BaseController
public function invoiceNow()
{
- if (Auth::check() && Input::get('new_account')) {
+ if (Auth::check() && Input::get('new_company')) {
Session::put(PREV_USER_ID, Auth::user()->id);
Auth::user()->clearSession();
Auth::logout();
@@ -72,9 +72,9 @@ class HomeController extends BaseController
$user->news_feed_id = $newsFeedId;
$user->save();
}
-
- Session::forget('news_feed_message');
}
+
+ Session::forget('news_feed_message');
return 'success';
}
diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php
index 43911db7d8c3..4c13259aecb2 100644
--- a/app/Http/Controllers/InvoiceApiController.php
+++ b/app/Http/Controllers/InvoiceApiController.php
@@ -26,7 +26,11 @@ class InvoiceApiController extends Controller
public function index()
{
- $invoices = Invoice::scope()->with('client', 'invitations.account')->where('invoices.is_quote', '=', false)->orderBy('created_at', 'desc')->get();
+ $invoices = Invoice::scope()
+ ->with('client', 'invitations.account')
+ ->where('invoices.is_quote', '=', false)
+ ->orderBy('created_at', 'desc')
+ ->get();
// Add the first invitation link to the data
foreach ($invoices as $key => $invoice) {
@@ -50,12 +54,14 @@ class InvoiceApiController extends Controller
$error = null;
// check if the invoice number is set and unique
- if (!isset($data['invoice_number'])) {
+ if (!isset($data['invoice_number']) && !isset($data['id'])) {
$data['invoice_number'] = Auth::user()->account->getNextInvoiceNumber();
- } else {
+ } else if (isset($data['invoice_number'])) {
$invoice = Invoice::scope()->where('invoice_number', '=', $data['invoice_number'])->first();
if ($invoice) {
$error = trans('validation.unique', ['attribute' => 'texts.invoice_number']);
+ } else {
+ $data['id'] = $invoice->public_id;
}
}
@@ -100,11 +106,13 @@ class InvoiceApiController extends Controller
$data['client_id'] = $client->id;
$invoice = $this->invoiceRepo->save(false, $data, false);
- $invitation = Invitation::createNew();
- $invitation->invoice_id = $invoice->id;
- $invitation->contact_id = $client->contacts[0]->id;
- $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
- $invitation->save();
+ if (!isset($data['id'])) {
+ $invitation = Invitation::createNew();
+ $invitation->invoice_id = $invoice->id;
+ $invitation->contact_id = $client->contacts[0]->id;
+ $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
+ $invitation->save();
+ }
if (isset($data['email_invoice']) && $data['email_invoice']) {
$this->mailer->sendInvoice($invoice);
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index 1939ce9c65da..6426333f1d5b 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -60,8 +60,7 @@ class InvoiceController extends BaseController
'columns' => Utils::trans(['checkbox', 'invoice_number', 'client', 'invoice_date', 'invoice_total', 'balance_due', 'due_date', 'status', 'action']),
];
- $recurringInvoices = Invoice::scope()
- ->where('is_recurring', '=', true);
+ $recurringInvoices = Invoice::scope()->where('is_recurring', '=', true);
if (Session::get('show_trash:invoice')) {
$recurringInvoices->withTrashed();
@@ -86,11 +85,12 @@ class InvoiceController extends BaseController
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
- $color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
+ $account = $invitation->account;
+ $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [
'color' => $color,
- 'hideLogo' => Session::get('white_label'),
+ 'hideLogo' => $account->isWhiteLabel(),
'title' => trans('texts.invoices'),
'entityType' => ENTITY_INVOICE,
'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']),
@@ -205,7 +205,6 @@ class InvoiceController extends BaseController
Session::set($invitationKey, true);
Session::set('invitation_key', $invitationKey);
- Session::set('white_label', $account->isWhiteLabel());
$account->loadLocalizationSettings();
@@ -215,6 +214,8 @@ class InvoiceController extends BaseController
if ($invoice->invoice_design_id == CUSTOM_DESIGN) {
$invoice->invoice_design->javascript = $account->custom_design;
+ } elseif ($account->utf8_invoices) {
+ $invoice->invoice_design->javascript = $invoice->invoice_design->pdfmake;
}
$contact = $invitation->contact;
@@ -254,7 +255,7 @@ class InvoiceController extends BaseController
'invoiceLabels' => $account->getInvoiceLabels(),
'contact' => $contact,
'paymentTypes' => $paymentTypes,
- 'paymentURL' => $paymentURL
+ 'paymentURL' => $paymentURL,
);
return View::make('invoices.view', $data);
@@ -281,7 +282,7 @@ class InvoiceController extends BaseController
$method = 'POST';
$url = "{$entityType}s";
} else {
- Utils::trackViewed($invoice->invoice_number.' - '.$invoice->client->getDisplayName(), $invoice->getEntityType());
+ Utils::trackViewed($invoice->getDisplayName().' - '.$invoice->client->getDisplayName(), $invoice->getEntityType());
$method = 'PUT';
$url = "{$entityType}s/{$publicId}";
}
@@ -336,6 +337,7 @@ class InvoiceController extends BaseController
'url' => $url,
'title' => trans("texts.edit_{$entityType}"),
'client' => $invoice->client,
+ 'isRecurring' => $invoice->is_recurring,
'actions' => $actions);
$data = array_merge($data, self::getViewModel());
@@ -359,10 +361,10 @@ class InvoiceController extends BaseController
return View::make('invoices.edit', $data);
}
- public function create($clientPublicId = 0)
+ public function create($clientPublicId = 0, $isRecurring = false)
{
$client = null;
- $invoiceNumber = Auth::user()->account->getNextInvoiceNumber();
+ $invoiceNumber = $isRecurring ? microtime(true) : Auth::user()->account->getNextInvoiceNumber();
if ($clientPublicId) {
$client = Client::scope($clientPublicId)->firstOrFail();
@@ -376,12 +378,18 @@ class InvoiceController extends BaseController
'method' => 'POST',
'url' => 'invoices',
'title' => trans('texts.new_invoice'),
+ 'isRecurring' => $isRecurring,
'client' => $client);
$data = array_merge($data, self::getViewModel());
return View::make('invoices.edit', $data);
}
+ public function createRecurring($clientPublicId = 0)
+ {
+ return self::create($clientPublicId, true);
+ }
+
private static function getViewModel()
{
$recurringHelp = '';
@@ -511,7 +519,16 @@ class InvoiceController extends BaseController
return $this->convertQuote($publicId);
} elseif ($action == 'email') {
if (Auth::user()->confirmed && !Auth::user()->isDemo()) {
- $response = $this->mailer->sendInvoice($invoice);
+ if ($invoice->is_recurring) {
+ if ($invoice->shouldSendToday()) {
+ $invoice = $this->invoiceRepo->createRecurringInvoice($invoice);
+ $response = $this->mailer->sendInvoice($invoice);
+ } else {
+ $response = trans('texts.recurring_too_soon');
+ }
+ } else {
+ $response = $this->mailer->sendInvoice($invoice);
+ }
if ($response === true) {
$message = trans("texts.emailed_{$entityType}");
Session::flash('message', $message);
diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php
index 6248a8e6917b..712f19dce6c5 100644
--- a/app/Http/Controllers/PaymentController.php
+++ b/app/Http/Controllers/PaymentController.php
@@ -61,11 +61,12 @@ class PaymentController extends BaseController
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
- $color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
+ $account = $invitation->account;
+ $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [
'color' => $color,
- 'hideLogo' => Session::get('white_label'),
+ 'hideLogo' => $account->isWhiteLabel(),
'entityType' => ENTITY_PAYMENT,
'title' => trans('texts.payments'),
'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
@@ -336,6 +337,7 @@ class PaymentController extends BaseController
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Cache::get('countries'),
'currencyId' => $client->getCurrencyId(),
+ 'currencyCode' => $client->currency ? $client->currency->code : ($account->currency ? $account->currency->code : 'USD'),
'account' => $client->account,
'hideLogo' => $account->isWhiteLabel(),
'showAddress' => $accountGateway->show_address,
@@ -387,6 +389,7 @@ class PaymentController extends BaseController
'currencyId' => 1,
'paymentTitle' => $affiliate->payment_title,
'paymentSubtitle' => $affiliate->payment_subtitle,
+ 'showAddress' => true,
];
return View::make('payments.payment', $data);
@@ -541,18 +544,19 @@ class PaymentController extends BaseController
->withErrors($validator)
->withInput();
}
+
+
+ if ($accountGateway->update_address) {
+ $client->address1 = trim(Input::get('address1'));
+ $client->address2 = trim(Input::get('address2'));
+ $client->city = trim(Input::get('city'));
+ $client->state = trim(Input::get('state'));
+ $client->postal_code = trim(Input::get('postal_code'));
+ $client->country_id = Input::get('country_id');
+ $client->save();
+ }
}
-
- if ($onSite && $accountGateway->update_address) {
- $client->address1 = trim(Input::get('address1'));
- $client->address2 = trim(Input::get('address2'));
- $client->city = trim(Input::get('city'));
- $client->state = trim(Input::get('state'));
- $client->postal_code = trim(Input::get('postal_code'));
- $client->country_id = Input::get('country_id');
- $client->save();
- }
-
+
try {
$gateway = self::createGateway($accountGateway);
$details = self::getPaymentDetails($invitation, ($useToken || !$onSite) ? false : Input::all());
diff --git a/app/Http/Controllers/QuoteApiController.php b/app/Http/Controllers/QuoteApiController.php
index 70257644c544..83e5e8781179 100644
--- a/app/Http/Controllers/QuoteApiController.php
+++ b/app/Http/Controllers/QuoteApiController.php
@@ -16,7 +16,11 @@ class QuoteApiController extends Controller
public function index()
{
- $invoices = Invoice::scope()->with('client', 'user')->where('invoices.is_quote', '=', true)->orderBy('created_at', 'desc')->get();
+ $invoices = Invoice::scope()
+ ->with('client', 'user')
+ ->where('invoices.is_quote', '=', true)
+ ->orderBy('created_at', 'desc')
+ ->get();
$invoices = Utils::remapPublicIds($invoices);
$response = json_encode($invoices, JSON_PRETTY_PRINT);
diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php
index b8dfd095e44b..589841a314bf 100644
--- a/app/Http/Controllers/QuoteController.php
+++ b/app/Http/Controllers/QuoteController.php
@@ -75,11 +75,12 @@ class QuoteController extends BaseController
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
- $color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
+ $account = $invitation->account;
+ $color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [
'color' => $color,
- 'hideLogo' => Session::get('white_label'),
+ 'hideLogo' => $account->isWhiteLabel(),
'title' => trans('texts.quotes'),
'entityType' => ENTITY_QUOTE,
'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']),
@@ -157,7 +158,8 @@ class QuoteController extends BaseController
'paymentTerms' => Cache::get('paymentTerms'),
'industries' => Cache::get('industries'),
'invoiceDesigns' => InvoiceDesign::getDesigns(),
- 'invoiceLabels' => Auth::user()->account->getInvoiceLabels()
+ 'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
+ 'isRecurring' => false,
];
}
diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php
index da37c9eb9bec..dfd7a96470b3 100644
--- a/app/Http/Controllers/ReportController.php
+++ b/app/Http/Controllers/ReportController.php
@@ -20,7 +20,9 @@ class ReportController extends BaseController
$fileName = storage_path() . '/dataviz_sample.txt';
if (Auth::user()->account->isPro()) {
- $account = Account::where('id', '=', Auth::user()->account->id)->with(['clients.invoices.invoice_items', 'clients.contacts'])->first();
+ $account = Account::where('id', '=', Auth::user()->account->id)
+ ->with(['clients.invoices.invoice_items', 'clients.contacts'])
+ ->first();
$account = $account->hideFieldsForViz();
$clients = $account->clients->toJson();
} elseif (file_exists($fileName)) {
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index dedd752190fb..85b4cede7d9a 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -95,7 +95,7 @@ class UserController extends BaseController
$user->force_pdfjs = true;
$user->save();
- Session::flash('message', trans('texts.security.updated_settings'));
+ Session::flash('message', trans('texts.updated_settings'));
return Redirect::to('/dashboard');
}
@@ -132,9 +132,12 @@ class UserController extends BaseController
*/
public function create()
{
- if (!Auth::user()->confirmed) {
+ if (!Auth::user()->registered) {
Session::flash('error', trans('texts.register_to_add_user'));
-
+ return Redirect::to('company/advanced_settings/user_management');
+ }
+ if (!Auth::user()->confirmed) {
+ Session::flash('error', trans('texts.confirmation_required'));
return Redirect::to('company/advanced_settings/user_management');
}
@@ -374,6 +377,11 @@ class UserController extends BaseController
Session::put(SESSION_USER_ACCOUNTS, $users);
Session::flash('message', trans('texts.unlinked_account'));
- return Redirect::to($referer);
+ return Redirect::to('/dashboard');
+ }
+
+ public function manageCompanies()
+ {
+ return View::make('users.account_management');
}
}
diff --git a/app/Http/Middleware/StartupCheck.php b/app/Http/Middleware/StartupCheck.php
index a6c2741977c8..a0b7fd2b1d09 100644
--- a/app/Http/Middleware/StartupCheck.php
+++ b/app/Http/Middleware/StartupCheck.php
@@ -158,7 +158,7 @@ class StartupCheck
}
}
- if (preg_match('/(?i)msie [2-8]/', $_SERVER['HTTP_USER_AGENT'])) {
+ if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(?i)msie [2-8]/', $_SERVER['HTTP_USER_AGENT'])) {
Session::flash('error', trans('texts.old_browser'));
}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 156e66ea6573..f7c829070f3a 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -95,6 +95,7 @@ Route::group(['middleware' => 'auth'], function() {
Route::post('users/change_password', 'UserController@changePassword');
Route::get('/switch_account/{user_id}', 'UserController@switchAccount');
Route::get('/unlink_account/{user_account_id}/{user_id}', 'UserController@unlinkAccount');
+ Route::get('/manage_companies', 'UserController@manageCompanies');
Route::get('api/tokens', array('as'=>'api.tokens', 'uses'=>'TokenController@getDatatable'));
Route::resource('tokens', 'TokenController');
@@ -130,7 +131,6 @@ Route::group(['middleware' => 'auth'], function() {
Route::get('tasks/create/{client_id?}', 'TaskController@create');
Route::post('tasks/bulk', 'TaskController@bulk');
- Route::get('recurring_invoices', 'InvoiceController@recurringIndex');
Route::get('api/recurring_invoices/{client_id?}', array('as'=>'api.recurring_invoices', 'uses'=>'InvoiceController@getRecurringDatatable'));
Route::get('invoices/invoice_history/{invoice_id}', 'InvoiceController@invoiceHistory');
@@ -139,6 +139,7 @@ Route::group(['middleware' => 'auth'], function() {
Route::resource('invoices', 'InvoiceController');
Route::get('api/invoices/{client_id?}', array('as'=>'api.invoices', 'uses'=>'InvoiceController@getDatatable'));
Route::get('invoices/create/{client_id?}', 'InvoiceController@create');
+ Route::get('recurring_invoices/create/{client_id?}', 'InvoiceController@createRecurring');
Route::get('invoices/{public_id}/clone', 'InvoiceController@cloneInvoice');
Route::post('invoices/bulk', 'InvoiceController@bulk');
@@ -325,6 +326,7 @@ define('SESSION_LAST_REQUEST_TIME', 'SESSION_LAST_REQUEST_TIME');
define('DEFAULT_TIMEZONE', 'US/Eastern');
define('DEFAULT_CURRENCY', 1); // US Dollar
+define('DEFAULT_LANGUAGE', 1); // English
define('DEFAULT_DATE_FORMAT', 'M j, Y');
define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
@@ -363,7 +365,7 @@ define('NINJA_GATEWAY_ID', GATEWAY_STRIPE);
define('NINJA_GATEWAY_CONFIG', '');
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
-define('NINJA_VERSION', '2.2.2');
+define('NINJA_VERSION', '2.3.0');
define('NINJA_DATE', '2000-01-01');
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
@@ -472,4 +474,4 @@ if (Auth::check() && Auth::user()->id === 1)
{
Auth::loginUsingId(1);
}
-*/
+*/
\ No newline at end of file
diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php
index 184dd453e498..1263b4ed6763 100644
--- a/app/Libraries/Utils.php
+++ b/app/Libraries/Utils.php
@@ -3,6 +3,7 @@
use Auth;
use Cache;
use DB;
+use App;
use Schema;
use Session;
use Request;
@@ -61,7 +62,7 @@ class Utils
public static function allowNewAccounts()
{
- return Utils::isNinja() || (isset($_ENV['ALLOW_NEW_ACCOUNTS']) && $_ENV['ALLOW_NEW_ACCOUNTS'] == 'true');
+ return Utils::isNinja() || Auth::check();
}
public static function isPro()
@@ -69,6 +70,11 @@ class Utils
return Auth::check() && Auth::user()->isPro();
}
+ public static function isEnglish()
+ {
+ return App::getLocale() == 'en';
+ }
+
public static function getUserType()
{
if (Utils::isNinja()) {
@@ -335,10 +341,11 @@ class Utils
return;
}
- $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
+ //$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
- $dateTime = DateTime::createFromFormat($format, $date, new DateTimeZone($timezone));
+ //$dateTime = DateTime::createFromFormat($format, $date, new DateTimeZone($timezone));
+ $dateTime = DateTime::createFromFormat($format, $date);
return $formatResult ? $dateTime->format('Y-m-d') : $dateTime;
}
@@ -349,11 +356,11 @@ class Utils
return '';
}
- $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
+ //$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
$dateTime = DateTime::createFromFormat('Y-m-d', $date);
- $dateTime->setTimeZone(new DateTimeZone($timezone));
+ //$dateTime->setTimeZone(new DateTimeZone($timezone));
return $formatResult ? $dateTime->format($format) : $dateTime;
}
@@ -400,10 +407,12 @@ class Utils
}
$object = new stdClass();
+ $object->accountId = Auth::user()->account_id;
$object->url = $url;
$object->name = ucwords($type).': '.$name;
$data = [];
+ $counts = [];
for ($i = 0; $i
{!! Button::success(trans(Input::get('new_account') && Utils::allowNewAccounts() ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}
+{!! Button::success(trans(Input::get('new_company') ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}
- @if (Input::get('new_account') && Utils::allowNewAccounts()) + @if (Input::get('new_company') && Utils::allowNewAccounts())- {{ trans('texts.or') }} -
{!! Button::primary(trans('texts.new_account'))->asLinkTo(URL::to('/invoice_now?new_account=true'))->large()->submit()->block() !!}
+{!! Button::primary(trans('texts.new_company'))->asLinkTo(URL::to('/invoice_now?new_company=true&sign_up=true'))->large()->submit()->block() !!}
@endif diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 661edbe5e014..f4e52f16e67f 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -6,7 +6,10 @@{{ trans('texts.invoice_number_short') }} | +{{ trans('texts.client') }} | +{{ trans('texts.payment_date') }} | +{{ trans('texts.amount') }} | + + + @foreach ($payments as $payment) +
---|---|---|---|
{!! \App\Models\Invoice::calcLink($payment) !!} | +{!! link_to('/clients/'.$payment->client_public_id, trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email)) !!} | +{{ Utils::fromSqlDate($payment->payment_date) }} | +{{ Utils::formatMoney($payment->amount, $payment->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} | +
{{ trans('texts.invoice_number_short') }} | @@ -95,23 +132,23 @@ @foreach ($pastDue as $invoice)||||||
---|---|---|---|---|---|---|
{!! $invoice->getLink() !!} | -{{ $invoice->client->getDisplayName() }} | +{!! \App\Models\Invoice::calcLink($invoice) !!} | +{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!} | {{ Utils::fromSqlDate($invoice->due_date) }} | -{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }} | +{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} |
{{ trans('texts.invoice_number_short') }} | @@ -122,10 +159,10 @@ @foreach ($upcoming as $invoice)||||||
---|---|---|---|---|---|---|
{!! $invoice->getLink() !!} | -{{ $invoice->client->getDisplayName() }} | +{!! \App\Models\Invoice::calcLink($invoice) !!} | +{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!} | {{ Utils::fromSqlDate($invoice->due_date) }} | -{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }} | +{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} |