mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
commit
4753b47c22
@ -18,6 +18,4 @@ MAIL_HOST
|
||||
MAIL_USERNAME
|
||||
MAIL_FROM_ADDRESS
|
||||
MAIL_FROM_NAME
|
||||
MAIL_PASSWORD
|
||||
|
||||
ALLOW_NEW_ACCOUNTS
|
||||
MAIL_PASSWORD
|
@ -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');
|
||||
|
@ -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';
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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'),
|
||||
];
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
*/
|
||||
*/
|
@ -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<count($viewed); $i++) {
|
||||
$item = $viewed[$i];
|
||||
@ -412,12 +421,22 @@ class Utils
|
||||
continue;
|
||||
}
|
||||
|
||||
// temporary fix to check for new property in session
|
||||
if (!property_exists($item, 'accountId')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array_unshift($data, $item);
|
||||
if (isset($counts[$item->accountId])) {
|
||||
$counts[$item->accountId]++;
|
||||
} else {
|
||||
$counts[$item->accountId] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
array_unshift($data, $object);
|
||||
|
||||
if (count($data) > RECENTLY_VIEWED_LIMIT) {
|
||||
|
||||
if (isset($counts[Auth::user()->account_id]) && $counts[Auth::user()->account_id] > RECENTLY_VIEWED_LIMIT) {
|
||||
array_pop($data);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use Eloquent;
|
||||
use Utils;
|
||||
use Session;
|
||||
use DateTime;
|
||||
|
||||
use App;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Account extends Eloquent
|
||||
@ -92,6 +92,11 @@ class Account extends Eloquent
|
||||
}
|
||||
}
|
||||
|
||||
public function isEnglish()
|
||||
{
|
||||
return !$this->language_id || $this->language_id == DEFAULT_LANGUAGE;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
if ($this->name) {
|
||||
@ -147,7 +152,8 @@ class Account extends Eloquent
|
||||
public function getLogoPath()
|
||||
{
|
||||
$fileName = 'logo/' . $this->account_key;
|
||||
return file_exists($fileName.'.png') ? $fileName.'.png' : $fileName.'.jpg';
|
||||
|
||||
return file_exists($fileName.'.png') && $this->utf8_invoices ? $fileName.'.png' : $fileName.'.jpg';
|
||||
}
|
||||
|
||||
public function getLogoWidth()
|
||||
@ -176,37 +182,36 @@ class Account extends Eloquent
|
||||
{
|
||||
$counter = $isQuote && !$this->share_counter ? $this->quote_number_counter : $this->invoice_number_counter;
|
||||
$prefix .= $isQuote ? $this->quote_number_prefix : $this->invoice_number_prefix;
|
||||
|
||||
$counterOffset = 0;
|
||||
|
||||
// confirm the invoice number isn't already taken
|
||||
do {
|
||||
$number = $prefix.str_pad($counter, 4, "0", STR_PAD_LEFT);
|
||||
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
|
||||
$counter++;
|
||||
$counterOffset++;
|
||||
} while ($check);
|
||||
|
||||
// update the invoice counter to be caught up
|
||||
if ($counterOffset > 1) {
|
||||
if ($isQuote && !$this->share_counter) {
|
||||
$this->quote_number_counter += $counterOffset - 1;
|
||||
} else {
|
||||
$this->invoice_number_counter += $counterOffset - 1;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
public function incrementCounter($invoiceNumber, $isQuote = false, $isRecurring)
|
||||
public function incrementCounter($isQuote = false)
|
||||
{
|
||||
// check if the user modified the invoice number
|
||||
if (!$isRecurring && $invoiceNumber != $this->getNextInvoiceNumber($isQuote)) {
|
||||
// remove the prefix
|
||||
$prefix = $isQuote ? $this->quote_number_prefix : $this->invoice_number_prefix;
|
||||
$invoiceNumber = preg_replace('/^'.$prefix.'/', '', $invoiceNumber);
|
||||
$invoiceNumber = intval(preg_replace('/[^0-9]/', '', $invoiceNumber));
|
||||
if ($isQuote && !$this->share_counter) {
|
||||
$this->quote_number_counter = $invoiceNumber + 1;
|
||||
} else {
|
||||
$this->invoice_number_counter = $invoiceNumber + 1;
|
||||
}
|
||||
// otherwise, just increment the counter
|
||||
if ($isQuote && !$this->share_counter) {
|
||||
$this->quote_number_counter += 1;
|
||||
} else {
|
||||
if ($isQuote && !$this->share_counter) {
|
||||
$this->quote_number_counter += 1;
|
||||
} else {
|
||||
$this->invoice_number_counter += 1;
|
||||
}
|
||||
$this->invoice_number_counter += 1;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
@ -229,6 +234,8 @@ class Account extends Eloquent
|
||||
Session::put(SESSION_DATETIME_FORMAT, $this->datetime_format ? $this->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
||||
Session::put(SESSION_CURRENCY, $this->currency_id ? $this->currency_id : DEFAULT_CURRENCY);
|
||||
Session::put(SESSION_LOCALE, $this->language_id ? $this->language->locale : DEFAULT_LOCALE);
|
||||
|
||||
App::setLocale(session(SESSION_LOCALE));
|
||||
}
|
||||
|
||||
public function getInvoiceLabels()
|
||||
@ -277,7 +284,7 @@ class Account extends Eloquent
|
||||
if (isset($custom[$field]) && $custom[$field]) {
|
||||
$data[$field] = $custom[$field];
|
||||
} else {
|
||||
$data[$field] = uctrans("texts.$field");
|
||||
$data[$field] = $this->isEnglish() ? uctrans("texts.$field") : trans("texts.$field");
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,11 +322,11 @@ class Account extends Eloquent
|
||||
|
||||
public function isWhiteLabel()
|
||||
{
|
||||
if (Utils::isNinjaProd()) {
|
||||
return false;
|
||||
if (Utils::isNinja()) {
|
||||
return self::isPro() && $this->pro_plan_paid != NINJA_DATE;
|
||||
} else {
|
||||
return $this->pro_plan_paid == NINJA_DATE;
|
||||
}
|
||||
|
||||
return $this->pro_plan_paid == NINJA_DATE;
|
||||
}
|
||||
|
||||
public function getSubscription($eventId)
|
||||
@ -348,6 +355,8 @@ class Account extends Eloquent
|
||||
'invoice_status_id',
|
||||
'invoice_items',
|
||||
'created_at',
|
||||
'is_recurring',
|
||||
'is_quote',
|
||||
]);
|
||||
|
||||
foreach ($invoice->invoice_items as $invoiceItem) {
|
||||
|
@ -214,6 +214,8 @@ class Activity extends Eloquent
|
||||
|
||||
if ($invoice->isPaid() && $invoice->balance > 0) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_PARTIAL;
|
||||
} elseif ($invoice->invoice_status_id && $invoice->balance == 0) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,15 +76,13 @@ class Client extends EntityModel
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
if ($this->name) {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
$this->load('contacts');
|
||||
|
||||
|
||||
$contact = $this->contacts()->first();
|
||||
|
||||
return $contact->getDisplayName();
|
||||
@ -152,11 +150,15 @@ class Client extends EntityModel
|
||||
|
||||
public function getCurrencyId()
|
||||
{
|
||||
if ($this->currency_id) {
|
||||
return $this->currency_id;
|
||||
}
|
||||
|
||||
if (!$this->account) {
|
||||
$this->load('account');
|
||||
}
|
||||
|
||||
return $this->currency_id ?: ($this->account->currency_id ?: DEFAULT_CURRENCY);
|
||||
return $this->account->currency_id ?: DEFAULT_CURRENCY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class EntityModel extends Eloquent
|
||||
|
||||
public function getActivityKey()
|
||||
{
|
||||
return '[' . $this->getEntityType().':'.$this->public_id.':'.$this->getName() . ']';
|
||||
return '[' . $this->getEntityType().':'.$this->public_id.':'.$this->getDisplayName() . ']';
|
||||
}
|
||||
|
||||
/*
|
||||
@ -83,6 +83,11 @@ class EntityModel extends Eloquent
|
||||
return $this->public_id;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
// Remap ids to public_ids and show name
|
||||
public function toPublicArray()
|
||||
{
|
||||
|
@ -48,6 +48,11 @@ class Invoice extends EntityModel
|
||||
return $this->belongsTo('App\Models\Invoice');
|
||||
}
|
||||
|
||||
public function recurring_invoices()
|
||||
{
|
||||
return $this->hasMany('App\Models\Invoice', 'recurring_invoice_id');
|
||||
}
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
return $this->hasMany('App\Models\Invitation')->orderBy('invitations.contact_id');
|
||||
@ -55,7 +60,7 @@ class Invoice extends EntityModel
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->invoice_number;
|
||||
return $this->is_recurring ? trans('texts.recurring') : $this->invoice_number;
|
||||
}
|
||||
|
||||
public function getFileName()
|
||||
@ -69,9 +74,14 @@ class Invoice extends EntityModel
|
||||
return storage_path() . '/pdfcache/cache-' . $this->id . '.pdf';
|
||||
}
|
||||
|
||||
public static function calcLink($invoice)
|
||||
{
|
||||
return link_to('invoices/' . $invoice->public_id, $invoice->invoice_number);
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return link_to('invoices/'.$this->public_id, $this->invoice_number);
|
||||
return self::calcLink($this);
|
||||
}
|
||||
|
||||
public function getEntityType()
|
||||
@ -253,7 +263,9 @@ class Invoice extends EntityModel
|
||||
}
|
||||
|
||||
Invoice::creating(function ($invoice) {
|
||||
$invoice->account->incrementCounter($invoice->invoice_number, $invoice->is_quote, $invoice->recurring_invoice_id);
|
||||
if (!$invoice->is_recurring) {
|
||||
$invoice->account->incrementCounter($invoice->is_quote);
|
||||
}
|
||||
});
|
||||
|
||||
Invoice::created(function ($invoice) {
|
||||
|
@ -47,7 +47,7 @@ class UserMailer extends Mailer
|
||||
'clientName' => $invoice->client->getDisplayName(),
|
||||
'accountName' => $invoice->account->getDisplayName(),
|
||||
'userName' => $user->getDisplayName(),
|
||||
'invoiceAmount' => Utils::formatMoney($invoice->amount, $invoice->client->getCurrencyId()),
|
||||
'invoiceAmount' => Utils::formatMoney($invoice->getRequestedAmount(), $invoice->client->getCurrencyId()),
|
||||
'invoiceNumber' => $invoice->invoice_number,
|
||||
'invoiceLink' => SITE_URL."/{$entityType}s/{$invoice->public_id}",
|
||||
];
|
||||
|
@ -6,7 +6,7 @@ use Session;
|
||||
use Utils;
|
||||
use DB;
|
||||
use stdClass;
|
||||
|
||||
use Schema;
|
||||
use App\Models\AccountGateway;
|
||||
use App\Models\Invitation;
|
||||
use App\Models\Invoice;
|
||||
@ -250,6 +250,10 @@ class AccountRepository
|
||||
|
||||
public function findUserAccounts($userId1, $userId2 = false)
|
||||
{
|
||||
if (!Schema::hasTable('user_accounts')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = UserAccount::where('user_id1', '=', $userId1)
|
||||
->orWhere('user_id2', '=', $userId1)
|
||||
->orWhere('user_id3', '=', $userId1)
|
||||
@ -294,7 +298,7 @@ class AccountRepository
|
||||
$item->account_id = $user->account->id;
|
||||
$item->account_name = $user->account->getDisplayName();
|
||||
$item->pro_plan_paid = $user->account->pro_plan_paid;
|
||||
$item->account_key = file_exists($user->account->getLogoPath()) ? $user->account->account_key : null;
|
||||
$item->logo_path = file_exists($user->account->getLogoPath()) ? $user->account->getLogoPath() : null;
|
||||
$data[] = $item;
|
||||
}
|
||||
|
||||
@ -312,6 +316,9 @@ class AccountRepository
|
||||
}
|
||||
|
||||
public function syncUserAccounts($users, $proPlanPaid = false) {
|
||||
if (!$users) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$proPlanPaid) {
|
||||
foreach ($users as $user) {
|
||||
|
@ -1,11 +1,12 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use Carbon;
|
||||
use Utils;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceItem;
|
||||
use App\Models\Invitation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Task;
|
||||
use Utils;
|
||||
|
||||
class InvoiceRepository
|
||||
{
|
||||
@ -266,15 +267,18 @@ class InvoiceRepository
|
||||
$account->save();
|
||||
}
|
||||
|
||||
$invoice->client_id = $data['client_id'];
|
||||
if (isset($data['invoice_number'])) {
|
||||
$invoice->invoice_number = trim($data['invoice_number']);
|
||||
}
|
||||
|
||||
$invoice->discount = round(Utils::parseFloat($data['discount']), 2);
|
||||
$invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
|
||||
$invoice->invoice_number = trim($data['invoice_number']);
|
||||
$invoice->partial = round(Utils::parseFloat($data['partial']), 2);
|
||||
$invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']);
|
||||
$invoice->has_tasks = isset($data['has_tasks']) ? $data['has_tasks'] : false;
|
||||
|
||||
if (!$publicId) {
|
||||
$invoice->client_id = $data['client_id'];
|
||||
$invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;
|
||||
}
|
||||
|
||||
@ -387,7 +391,7 @@ class InvoiceRepository
|
||||
$task->invoice_id = $invoice->id;
|
||||
$task->client_id = $invoice->client_id;
|
||||
$task->save();
|
||||
} else if ($item['product_key']) {
|
||||
} else if ($item['product_key'] && !$invoice->has_tasks) {
|
||||
$product = Product::findProductByKey(trim($item['product_key']));
|
||||
|
||||
if (!$product) {
|
||||
@ -543,9 +547,82 @@ class InvoiceRepository
|
||||
->whereClientId($clientId)
|
||||
->whereIsQuote(false)
|
||||
->whereIsRecurring(false)
|
||||
->whereDeletedAt(null)
|
||||
->whereHasTasks(true)
|
||||
->where('balance', '>', 0)
|
||||
->where('invoice_status_id', '<', 5)
|
||||
->select(['public_id', 'invoice_number'])
|
||||
->get();
|
||||
}
|
||||
|
||||
public function createRecurringInvoice($recurInvoice)
|
||||
{
|
||||
$recurInvoice->load('account.timezone', 'invoice_items', 'client', 'user');
|
||||
|
||||
if ($recurInvoice->client->deleted_at) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$recurInvoice->user->confirmed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$recurInvoice->shouldSendToday()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$recurInvoice->last_sent_date = Carbon::now()->toDateTimeString();
|
||||
$recurInvoice->save();
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class TaskRepository
|
||||
}
|
||||
|
||||
public function save($publicId, $data)
|
||||
{
|
||||
{
|
||||
if ($publicId) {
|
||||
$task = Task::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
@ -60,8 +60,14 @@ class TaskRepository
|
||||
$task->description = trim($data['description']);
|
||||
}
|
||||
|
||||
//$timeLog = $task->time_log ? json_decode($task->time_log, true) : [];
|
||||
$timeLog = isset($data['time_log']) ? json_decode($data['time_log']) : [];
|
||||
if (isset($data['time_log'])) {
|
||||
$timeLog = json_decode($data['time_log']);
|
||||
} elseif ($task->time_log) {
|
||||
$timeLog = json_decode($task->time_log);
|
||||
} else {
|
||||
$timeLog = [];
|
||||
}
|
||||
|
||||
if ($data['action'] == 'start') {
|
||||
$task->is_running = true;
|
||||
$timeLog[] = [strtotime('now'), false];
|
||||
|
@ -40,10 +40,13 @@ class AppServiceProvider extends ServiceProvider {
|
||||
<ul class="dropdown-menu" id="menu1">
|
||||
<li><a href="'.URL::to($types.'/create').'">'.trans("texts.new_$type").'</a></li>';
|
||||
|
||||
if ($type == ENTITY_INVOICE && Auth::user()->isPro()) {
|
||||
$str .= '<li class="divider"></li>
|
||||
if ($type == ENTITY_INVOICE) {
|
||||
$str .= '<li><a href="'.URL::to('recurring_invoices/create').'">'.trans("texts.new_recurring_invoice").'</a></li>';
|
||||
if (Auth::user()->isPro()) {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('quotes').'">'.trans("texts.quotes").'</a></li>
|
||||
<li><a href="'.URL::to('quotes/create').'">'.trans("texts.new_quote").'</a></li>';
|
||||
}
|
||||
} else if ($type == ENTITY_CLIENT) {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('credits').'">'.trans("texts.credits").'</a></li>
|
||||
|
@ -19,7 +19,7 @@ class AddPartialAmountToInvoices extends Migration {
|
||||
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
$table->boolean('utf8_invoices')->default(false);
|
||||
$table->boolean('utf8_invoices')->default(true);
|
||||
$table->boolean('auto_wrap')->default(false);
|
||||
$table->string('subdomain')->nullable();
|
||||
});
|
||||
|
@ -64,7 +64,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
['name' => 'US Dollar', 'code' => 'USD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Pound Sterling', 'code' => 'GBP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Rand', 'code' => 'ZAR', 'symbol' => 'R', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'South African Rand', 'code' => 'ZAR', 'symbol' => 'R', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Danish Krone', 'code' => 'DKK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Israeli Shekel', 'code' => 'ILS', 'symbol' => 'NIS ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Swedish Krona', 'code' => 'SEK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
@ -82,10 +82,16 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
['name' => 'Malaysian Ringgit', 'code' => 'MYR', 'symbol' => 'RM', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Brazilian Real', 'code' => 'BRL', 'symbol' => 'R$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Thai baht', 'code' => 'THB', 'symbol' => 'THB ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Nigerian Naira', 'code' => 'NGN', 'symbol' => 'NGN ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
['name' => 'Argentine Peso', 'code' => 'ARS', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||
];
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
if (!DB::table('currencies')->whereName($currency['name'])->get()) {
|
||||
$record = Currency::whereCode($currency['code'])->first();
|
||||
if ($record) {
|
||||
$record->name = $currency['name'];
|
||||
$record->save();
|
||||
} else {
|
||||
Currency::create($currency);
|
||||
}
|
||||
}
|
||||
@ -147,17 +153,21 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
'Photo',
|
||||
];
|
||||
|
||||
foreach ($designs as $design) {
|
||||
for ($i=0; $i<count($designs); $i++) {
|
||||
$design = $designs[$i];
|
||||
$fileName = storage_path() . '/templates/' . strtolower($design) . '.js';
|
||||
$pdfmake = file_get_contents($fileName);
|
||||
if ($pdfmake) {
|
||||
$record = InvoiceDesign::whereName($design)->first();
|
||||
if (!$record) {
|
||||
$record = new InvoiceDesign;
|
||||
$record->name = $design;
|
||||
if (file_exists($fileName)) {
|
||||
$pdfmake = file_get_contents($fileName);
|
||||
if ($pdfmake) {
|
||||
$record = InvoiceDesign::whereName($design)->first();
|
||||
if (!$record) {
|
||||
$record = new InvoiceDesign;
|
||||
$record->id = $i + 1;
|
||||
$record->name = $design;
|
||||
}
|
||||
$record->pdfmake = $pdfmake;
|
||||
$record->save();
|
||||
}
|
||||
$record->pdfmake = $pdfmake;
|
||||
$record->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
public/css/built.css
vendored
5
public/css/built.css
vendored
@ -2839,15 +2839,12 @@ background-clip: padding-box;
|
||||
|
||||
.dashboard .panel-body {padding: 0;}
|
||||
|
||||
.dashboard .table-striped>tbody>tr>td, .table-striped>tbody>tr>th { background-color: #fbfbfb;}
|
||||
.dashboard .table-striped>tbody>tr:nth-child(odd)>tr, .table-striped>tbody>tr:nth-child(odd)>th {
|
||||
background-color: #fff;
|
||||
}
|
||||
.dashboard th {
|
||||
border-left: none;
|
||||
background-color: #fbfbfb;
|
||||
border-bottom: 1px solid #dfe0e1;
|
||||
}
|
||||
|
||||
.dashboard table.table thead > tr > th {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
5
public/css/style.css
vendored
5
public/css/style.css
vendored
@ -489,15 +489,12 @@ background-clip: padding-box;
|
||||
|
||||
.dashboard .panel-body {padding: 0;}
|
||||
|
||||
.dashboard .table-striped>tbody>tr>td, .table-striped>tbody>tr>th { background-color: #fbfbfb;}
|
||||
.dashboard .table-striped>tbody>tr:nth-child(odd)>tr, .table-striped>tbody>tr:nth-child(odd)>th {
|
||||
background-color: #fff;
|
||||
}
|
||||
.dashboard th {
|
||||
border-left: none;
|
||||
background-color: #fbfbfb;
|
||||
border-bottom: 1px solid #dfe0e1;
|
||||
}
|
||||
|
||||
.dashboard table.table thead > tr > th {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -122,7 +122,10 @@ NINJA.decodeJavascript = function(invoice, javascript)
|
||||
field = match.substring(2, match.indexOf('Label'));
|
||||
field = toSnakeCase(field);
|
||||
var value = getDescendantProp(invoice, field);
|
||||
if (match.indexOf('?') < 0) {
|
||||
if (match.indexOf('?') < 0 || value) {
|
||||
if (invoice.partial && field == 'balance_due') {
|
||||
field = 'amount_due';
|
||||
}
|
||||
var label = invoiceLabels[field];
|
||||
if (match.indexOf('UC') >= 0) {
|
||||
if (!label) console.log('match: ' + field);
|
||||
@ -139,7 +142,7 @@ NINJA.decodeJavascript = function(invoice, javascript)
|
||||
}
|
||||
|
||||
// search/replace values
|
||||
var regExp = new RegExp('"\\$\\\w*?Value"', 'g');
|
||||
var regExp = new RegExp('"\\$[\\\w\\\.]*?Value"', 'g');
|
||||
var matches = javascript.match(regExp);
|
||||
|
||||
if (matches) {
|
||||
@ -148,6 +151,7 @@ NINJA.decodeJavascript = function(invoice, javascript)
|
||||
field = match.substring(2, match.indexOf('Value'));
|
||||
field = toSnakeCase(field);
|
||||
var value = getDescendantProp(invoice, field) || ' ';
|
||||
|
||||
if (field.toLowerCase().indexOf('date') >= 0 && value != ' ') {
|
||||
value = moment(value, 'YYYY-MM-DD').format('MMM D YYYY');
|
||||
}
|
||||
@ -186,14 +190,14 @@ NINJA.invoiceColumns = function(invoice)
|
||||
|
||||
NINJA.invoiceLines = function(invoice) {
|
||||
var grid = [
|
||||
[
|
||||
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
|
||||
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
|
||||
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
|
||||
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
|
||||
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
|
||||
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
|
||||
]
|
||||
[
|
||||
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
|
||||
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
|
||||
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
|
||||
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
|
||||
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
|
||||
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
|
||||
]
|
||||
];
|
||||
|
||||
var total = 0;
|
||||
@ -202,7 +206,7 @@ NINJA.invoiceLines = function(invoice) {
|
||||
var hideQuantity = invoice.account.hide_quantity == '1';
|
||||
|
||||
for (var i = 0; i < invoice.invoice_items.length; i++) {
|
||||
|
||||
|
||||
var row = [];
|
||||
var item = invoice.invoice_items[i];
|
||||
var cost = formatMoney(item.cost, currencyId, true);
|
||||
@ -258,7 +262,7 @@ NINJA.invoiceLines = function(invoice) {
|
||||
return NINJA.prepareDataTable(grid, 'invoiceItems');
|
||||
}
|
||||
|
||||
NINJA.subtotals = function(invoice, removeBalance)
|
||||
NINJA.subtotals = function(invoice, hideBalance)
|
||||
{
|
||||
if (!invoice) {
|
||||
return;
|
||||
@ -280,7 +284,8 @@ NINJA.subtotals = function(invoice, removeBalance)
|
||||
}
|
||||
|
||||
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
|
||||
data.push([{text: invoiceLabels.tax}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);
|
||||
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
@ -290,16 +295,17 @@ NINJA.subtotals = function(invoice, removeBalance)
|
||||
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
if (invoice.account.hide_paid_to_date != '1' || paid) {
|
||||
data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoney(paid, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (!removeBalance) {
|
||||
if (!hideBalance) {
|
||||
var isPartial = NINJA.parseFloat(invoice.partial);
|
||||
data.push([
|
||||
{text:invoice.is_quote ? invoiceLabels.balance_due : invoiceLabels.balance_due, style:['balanceDueLabel']},
|
||||
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']}
|
||||
]);
|
||||
{text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style:['balanceDueLabel']},
|
||||
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']}
|
||||
]);
|
||||
}
|
||||
|
||||
return NINJA.prepareDataPairs(data, 'subtotals');
|
||||
@ -308,11 +314,11 @@ NINJA.subtotals = function(invoice, removeBalance)
|
||||
NINJA.accountDetails = function(invoice) {
|
||||
var account = invoice.account;
|
||||
var data = [
|
||||
{text:account.name, style: ['accountName']},
|
||||
{text:account.id_number},
|
||||
{text:account.vat_number},
|
||||
{text:account.work_email},
|
||||
{text:account.work_phone}
|
||||
{text:account.name, style: ['accountName']},
|
||||
{text:account.id_number},
|
||||
{text:account.vat_number},
|
||||
{text:account.work_email},
|
||||
{text:account.work_phone}
|
||||
];
|
||||
return NINJA.prepareDataList(data, 'accountDetails');
|
||||
}
|
||||
@ -324,11 +330,11 @@ NINJA.accountAddress = function(invoice) {
|
||||
cityStatePostal = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
|
||||
}
|
||||
|
||||
var data = [
|
||||
{text: account.address1},
|
||||
{text: account.address2},
|
||||
{text: cityStatePostal},
|
||||
{text: account.country ? account.country.name : ''}
|
||||
var data = [
|
||||
{text: account.address1},
|
||||
{text: account.address2},
|
||||
{text: cityStatePostal},
|
||||
{text: account.country ? account.country.name : ''}
|
||||
];
|
||||
|
||||
return NINJA.prepareDataList(data, 'accountAddress');
|
||||
@ -337,42 +343,43 @@ NINJA.accountAddress = function(invoice) {
|
||||
NINJA.invoiceDetails = function(invoice) {
|
||||
|
||||
var data = [
|
||||
[
|
||||
{text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']},
|
||||
{text: invoice.invoice_number, style: ['invoiceNumber']}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.po_number},
|
||||
{text: invoice.po_number}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.invoice_date},
|
||||
{text: invoice.invoice_date}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.due_date},
|
||||
{text: invoice.due_date}
|
||||
]
|
||||
[
|
||||
{text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']},
|
||||
{text: invoice.invoice_number, style: ['invoiceNumber']}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.po_number},
|
||||
{text: invoice.po_number}
|
||||
],
|
||||
[
|
||||
{text: (invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date)},
|
||||
{text: invoice.invoice_date}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.due_date},
|
||||
{text: invoice.due_date}
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
var isPartial = NINJA.parseFloat(invoice.partial);
|
||||
|
||||
if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) {
|
||||
data.push([
|
||||
{text: invoiceLabels.total},
|
||||
{text: formatMoney(invoice.amount, invoice.client.currency_id)}
|
||||
]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.partial)) {
|
||||
]);
|
||||
} else if (isPartial) {
|
||||
data.push([
|
||||
{text: invoiceLabels.balance},
|
||||
{text: invoiceLabels.total},
|
||||
{text: formatMoney(invoice.total_amount, invoice.client.currency_id)}
|
||||
]);
|
||||
]);
|
||||
}
|
||||
|
||||
data.push([
|
||||
{text: invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']},
|
||||
{text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']},
|
||||
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']}
|
||||
])
|
||||
])
|
||||
|
||||
return NINJA.prepareDataPairs(data, 'invoiceDetails');
|
||||
}
|
||||
@ -388,11 +395,11 @@ NINJA.clientDetails = function(invoice) {
|
||||
var clientEmail = client.contacts[0].email == clientName ? '' : client.contacts[0].email;
|
||||
|
||||
data = [
|
||||
{text:clientName || ' ', style: ['clientName']},
|
||||
{text:client.address1},
|
||||
{text:concatStrings(client.city, client.state, client.postal_code)},
|
||||
{text:client.country ? client.country.name : ''},
|
||||
{text:clientEmail}
|
||||
{text:clientName || ' ', style: ['clientName']},
|
||||
{text:client.address1},
|
||||
{text:concatStrings(client.city, client.state, client.postal_code)},
|
||||
{text:client.country ? client.country.name : ''},
|
||||
{text:clientEmail}
|
||||
];
|
||||
|
||||
return NINJA.prepareDataList(data, 'clientDetails');
|
||||
|
@ -13,7 +13,7 @@ function generatePDF(invoice, javascript, force, cb) {
|
||||
if (!invoice || !javascript) {
|
||||
return;
|
||||
}
|
||||
console.log('== generatePDF - force: %s', force);
|
||||
//console.log('== generatePDF - force: %s', force);
|
||||
if (force || !invoiceOld) {
|
||||
refreshTimer = null;
|
||||
} else {
|
||||
@ -877,9 +877,6 @@ function displayGrid(doc, invoice, data, x, y, layout, options) {
|
||||
key = invoice.account[key];
|
||||
} else if (key === 'tax' && invoice.tax_name) {
|
||||
key = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
||||
if (invoice.tax_name.toLowerCase().indexOf(invoiceLabels['tax'].toLowerCase()) == -1) {
|
||||
key = invoiceLabels['tax'] + ': ' + key;
|
||||
}
|
||||
} else if (key === 'discount' && NINJA.parseFloat(invoice.discount) && !parseInt(invoice.is_amount_discount)) {
|
||||
key = invoiceLabels[key] + ' ' + parseFloat(invoice.discount) + '%';
|
||||
} else {
|
||||
|
@ -698,16 +698,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -738,6 +737,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -688,48 +688,57 @@ return array(
|
||||
|
||||
'email_receipt' => 'Zahlungsbestätigung an Kunden per E-Mail senden',
|
||||
'created_payment_emailed_client' => 'Zahlung erfolgreich erstellt und Kunde per E-Mail benachrichtigt',
|
||||
'add_account' => 'Konto hinzufügen',
|
||||
'add_company' => 'Konto hinzufügen',
|
||||
'untitled' => 'Unbenannt',
|
||||
'new_account' => 'Neues Konto',
|
||||
'new_company' => 'Neues Konto',
|
||||
'associated_accounts' => 'Konten erfolgreich verlinkt',
|
||||
'unlinked_account' => 'Konten erfolgreich getrennt',
|
||||
'login' => 'Login',
|
||||
'or' => 'oder',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
'unlink_account' => 'Unlink Account',
|
||||
'unlink' => 'Unlink',
|
||||
'show_address' => 'Show Address',
|
||||
'show_address_help' => 'Require client to provide their billing address',
|
||||
'update_address' => 'Update Address',
|
||||
'update_address_help' => 'Update client\'s address with provided details',
|
||||
'times' => 'Times',
|
||||
'set_now' => 'Set now',
|
||||
'dark_mode' => 'Dark Mode',
|
||||
'dark_mode_help' => 'Show white text on black background',
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
'email_error' => 'Es gab ein Problem beim Senden dieses E-Mails.',
|
||||
'confirm_recurring_timing' => 'Beachten Sie: E-Mails werden zu Beginn der Stunde gesendet.',
|
||||
'old_browser' => 'Bitte verwenden Sie einen <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">neueren Browser</a>',
|
||||
'payment_terms_help' => 'Setzt das Standardfälligkeitssdatum',
|
||||
'unlink_account' => 'Konten Trennen',
|
||||
'unlink' => 'Trennen',
|
||||
'show_address' => 'Adresse Anzeigen',
|
||||
'show_address_help' => 'Verlange von Kunden ihre Rechnungsadresse anzugeben',
|
||||
'update_address' => 'Adresse Aktualisieren',
|
||||
'update_address_help' => 'Kundenadresse mit den gemachten Angaben aktualisieren',
|
||||
'times' => 'Zeiten',
|
||||
'set_now' => 'Jetzt setzen',
|
||||
'dark_mode' => 'Dunkler Modus',
|
||||
'dark_mode_help' => 'Weisser Text auf schwarzem Hintergrund anzeigen',
|
||||
'add_to_invoice' => 'Zur Rechnung :invoice hinzufügen',
|
||||
'create_new_invoice' => 'Neue Rechnung erstellen',
|
||||
'task_errors' => 'Bitte korrigieren Sie alle überlappenden Zeiten',
|
||||
'utf8_invoices' => 'Neue PDF Engine <sup>Beta</sup>',
|
||||
'from' => 'Von',
|
||||
'to' => 'An',
|
||||
'font_size' => 'Schriftgrösse',
|
||||
'primary_color' => 'Primäre Farbe',
|
||||
'secondary_color' => 'Sekundäre Farbe',
|
||||
'customize_design' => 'Design Anpassen',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
'content' => 'Inhalt',
|
||||
'styles' => 'Stile',
|
||||
'defaults' => 'Standards',
|
||||
'margins' => 'Aussenabstände',
|
||||
'header' => 'Kopfzeile',
|
||||
'footer' => 'Fusszeile',
|
||||
'custom' => 'Benutzerdefiniert',
|
||||
'invoice_to' => 'Rechnunge an',
|
||||
'invoice_no' => 'Rechnung Nr.',
|
||||
'recent_payments' => 'Kürzliche Zahlungen',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
);
|
@ -119,8 +119,8 @@ return array(
|
||||
'active_client' => 'active client',
|
||||
'active_clients' => 'active clients',
|
||||
'invoices_past_due' => 'Invoices Past Due',
|
||||
'upcoming_invoices' => 'Upcoming invoices',
|
||||
'average_invoice' => 'Average invoice',
|
||||
'upcoming_invoices' => 'Upcoming Invoices',
|
||||
'average_invoice' => 'Average Invoice',
|
||||
|
||||
// list pages
|
||||
'archive' => 'Archive',
|
||||
@ -696,16 +696,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -738,6 +737,17 @@ return array(
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
@ -668,16 +668,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -708,6 +707,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
);
|
@ -697,16 +697,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -737,6 +736,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -689,16 +689,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Paiement crée avec succès et envoyé au client',
|
||||
'add_account' => 'Ajouter compte',
|
||||
'add_company' => 'Ajouter compte',
|
||||
'untitled' => 'Sans titre',
|
||||
'new_account' => 'Nouveau compte',
|
||||
'new_company' => 'Nouveau compte',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Connexion',
|
||||
'or' => 'ou',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -729,6 +728,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -690,16 +690,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -730,6 +729,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
);
|
||||
|
@ -692,16 +692,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -732,6 +731,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -699,16 +699,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -739,6 +738,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -697,16 +697,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -737,6 +736,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -692,16 +692,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -732,6 +731,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -692,16 +692,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -732,6 +731,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
);
|
||||
|
@ -695,16 +695,15 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'add_company' => 'Add Company',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'new_company' => 'New Company',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
'email_error' => 'There was a problem sending the email',
|
||||
'created_by_recurring' => 'Created by recurring invoice :invoice',
|
||||
'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.',
|
||||
'old_browser' => 'Please use a <a href="'.OUTDATE_BROWSER_URL.'" target="_blank">newer browser</a>',
|
||||
'payment_terms_help' => 'Sets the default invoice due date',
|
||||
@ -735,6 +734,18 @@ return array(
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
'invoice_to' => 'Invoice to',
|
||||
'invoice_no' => 'Invoice No.',
|
||||
'recent_payments' => 'Recent Payments',
|
||||
'outstanding' => 'Outstanding',
|
||||
'manage_companies' => 'Manage Companies',
|
||||
'total_revenue' => 'Total Revenue',
|
||||
|
||||
'current_user' => 'Current User',
|
||||
'new_recurring_invoice' => 'New Recurring Invoice',
|
||||
'recurring_invoice' => 'Recurring Invoice',
|
||||
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
|
||||
'created_by_invoice' => 'Created by :invoice',
|
||||
|
||||
|
||||
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
{{ Former::populate($account) }}
|
||||
@if ($showUser)
|
||||
{{ Former::populateField('first_name', $account->users()->first()->first_name) }}
|
||||
{{ Former::populateField('last_name', $account->users()->first()->last_name) }}
|
||||
{{ Former::populateField('email', $account->users()->first()->email) }}
|
||||
{{ Former::populateField('phone', $account->users()->first()->phone) }}
|
||||
{{ Former::populateField('first_name', $primaryUser->first_name) }}
|
||||
{{ Former::populateField('last_name', $primaryUser->last_name) }}
|
||||
{{ Former::populateField('email', $primaryUser->email) }}
|
||||
{{ Former::populateField('phone', $primaryUser->phone) }}
|
||||
@if (Utils::isNinja())
|
||||
{{ Former::populateField('dark_mode', intval($account->users()->first()->dark_mode)) }}
|
||||
{{ Former::populateField('dark_mode', intval($primaryUser->dark_mode)) }}
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
@if (file_exists($account->getLogoPath()))
|
||||
<center>
|
||||
{!! HTML::image($account->getLogoPath().'?no_cache='.time(), "Logo") !!}
|
||||
{!! HTML::image($account->getLogoPath().'?no_cache='.time(), 'Logo', ['width' => 200]) !!}
|
||||
<a href="#" onclick="deleteLogo()">{{ trans('texts.remove_logo') }}</a>
|
||||
</center><br/>
|
||||
@endif
|
||||
|
@ -108,7 +108,7 @@
|
||||
}
|
||||
|
||||
keys = ['footer', 'account', 'client', 'amount', 'link', 'contact'];
|
||||
vals = [{!! json_encode($emailFooter) !!}, '{!! Auth::user()->account->getDisplayName() !!}', 'Client Name', formatMoney(100), '{!! NINJA_WEB_URL !!}', 'Contact Name'];
|
||||
vals = [{!! json_encode($emailFooter) !!}, '{!! Auth::user()->account->getDisplayName() !!}', 'Client Name', formatMoney(100), '{!! SITE_URL . '/view/...' !!}', 'Contact Name'];
|
||||
|
||||
// Add any available payment method links
|
||||
@foreach (\App\Models\Gateway::getPaymentTypeLinks() as $type)
|
||||
|
@ -79,11 +79,11 @@
|
||||
{!! Former::hidden('remember')->raw() !!}
|
||||
</p>
|
||||
|
||||
<p>{!! Button::success(trans(Input::get('new_account') && Utils::allowNewAccounts() ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}</p>
|
||||
<p>{!! Button::success(trans(Input::get('new_company') ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}</p>
|
||||
|
||||
@if (Input::get('new_account') && Utils::allowNewAccounts())
|
||||
@if (Input::get('new_company') && Utils::allowNewAccounts())
|
||||
<center><p>- {{ trans('texts.or') }} -</p></center>
|
||||
<p>{!! Button::primary(trans('texts.new_account'))->asLinkTo(URL::to('/invoice_now?new_account=true'))->large()->submit()->block() !!}</p>
|
||||
<p>{!! Button::primary(trans('texts.new_company'))->asLinkTo(URL::to('/invoice_now?new_company=true&sign_up=true'))->large()->submit()->block() !!}</p>
|
||||
@endif
|
||||
|
||||
|
||||
|
@ -6,7 +6,10 @@
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<img src="{{ asset('images/totalincome.png') }}" class="in-image"/>
|
||||
<img src="{{ asset('images/totalinvoices.png') }}" class="in-image"/>
|
||||
<div class="in-thin">
|
||||
{{ trans('texts.total_revenue') }}
|
||||
</div>
|
||||
<div class="in-bold">
|
||||
@if (count($paidToDate))
|
||||
@foreach ($paidToDate as $item)
|
||||
@ -16,9 +19,6 @@
|
||||
{{ Utils::formatMoney(0) }}
|
||||
@endif
|
||||
</div>
|
||||
<div class="in-thin">
|
||||
{{ trans('texts.in_total_revenue') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -44,12 +44,18 @@
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<img src="{{ asset('images/totalinvoices.png') }}" class="in-image"/>
|
||||
<div class="in-bold">
|
||||
{{ $invoicesSent }}
|
||||
</div>
|
||||
<img src="{{ asset('images/totalincome.png') }}" class="in-image"/>
|
||||
<div class="in-thin">
|
||||
{{ Utils::pluralize('invoice', $invoicesSent) }} {{ trans('texts.sent') }}
|
||||
{{ trans('texts.outstanding') }}
|
||||
</div>
|
||||
<div class="in-bold">
|
||||
@if (count($balances))
|
||||
@foreach ($balances as $item)
|
||||
{{ Utils::formatMoney($item->value, $item->currency_id) }}<br/>
|
||||
@endforeach
|
||||
@else
|
||||
{{ Utils::formatMoney(0) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,13 +67,16 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default dashboard" style="min-height:660px">
|
||||
<div class="panel panel-default dashboard" style="height:320px">
|
||||
<div class="panel-heading" style="background-color:#0b4d78 !important">
|
||||
<h3 class="panel-title in-bold-white">
|
||||
<i class="glyphicon glyphicon-exclamation-sign"></i> {{ trans('texts.notifications') }}
|
||||
<div class="pull-right" style="font-size:14px;padding-top:4px">
|
||||
{{ $invoicesSent }} {{ Utils::pluralize('invoice', $invoicesSent) }} {{ trans('texts.sent') }}
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
<ul class="panel-body list-group">
|
||||
<ul class="panel-body list-group" style="height:276px;overflow-y:auto;">
|
||||
@foreach ($activities as $activity)
|
||||
<li class="list-group-item">
|
||||
<span style="color:#888;font-style:italic">{{ Utils::timestampToDateString(strtotime($activity->created_at)) }}:</span>
|
||||
@ -76,15 +85,43 @@
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel panel-default dashboard" style="height:320px;">
|
||||
<div class="panel-heading" style="margin:0; background-color: #f5f5f5 !important;">
|
||||
<h3 class="panel-title" style="color: black !important">
|
||||
<i class="glyphicon glyphicon-ok-sign"></i> {{ trans('texts.recent_payments') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body" style="height:274px;overflow-y:auto;">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th>{{ trans('texts.invoice_number_short') }}</th>
|
||||
<th>{{ trans('texts.client') }}</th>
|
||||
<th>{{ trans('texts.payment_date') }}</th>
|
||||
<th>{{ trans('texts.amount') }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($payments as $payment)
|
||||
<tr>
|
||||
<td>{!! \App\Models\Invoice::calcLink($payment) !!}</td>
|
||||
<td>{!! link_to('/clients/'.$payment->client_public_id, trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email)) !!}</td>
|
||||
<td>{{ Utils::fromSqlDate($payment->payment_date) }}</td>
|
||||
<td>{{ Utils::formatMoney($payment->amount, $payment->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default dashboard" style="min-height:320px">
|
||||
<div class="panel panel-default dashboard" style="height:320px">
|
||||
<div class="panel-heading" style="background-color:#e37329 !important">
|
||||
<h3 class="panel-title in-bold-white">
|
||||
<i class="glyphicon glyphicon-time"></i> {{ trans('texts.invoices_past_due') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="panel-body" style="height:274px;overflow-y:auto;">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th>{{ trans('texts.invoice_number_short') }}</th>
|
||||
@ -95,23 +132,23 @@
|
||||
<tbody>
|
||||
@foreach ($pastDue as $invoice)
|
||||
<tr>
|
||||
<td>{!! $invoice->getLink() !!}</td>
|
||||
<td>{{ $invoice->client->getDisplayName() }}</td>
|
||||
<td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td>
|
||||
<td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td>
|
||||
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
|
||||
<td>{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }}</td>
|
||||
<td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default dashboard" style="min-height:320px;">
|
||||
<div class="panel panel-default dashboard" style="height:320px;">
|
||||
<div class="panel-heading" style="margin:0; background-color: #f5f5f5 !important;">
|
||||
<h3 class="panel-title" style="color: black !important">
|
||||
<i class="glyphicon glyphicon-time"></i> {{ trans('texts.upcoming_invoices') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="panel-body" style="height:274px;overflow-y:auto;">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th>{{ trans('texts.invoice_number_short') }}</th>
|
||||
@ -122,10 +159,10 @@
|
||||
<tbody>
|
||||
@foreach ($upcoming as $invoice)
|
||||
<tr>
|
||||
<td>{!! $invoice->getLink() !!}</td>
|
||||
<td>{{ $invoice->client->getDisplayName() }}</td>
|
||||
<td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td>
|
||||
<td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td>
|
||||
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
|
||||
<td>{{ Utils::formatMoney($invoice->balance, $invoice->client->getCurrencyId()) }}</td>
|
||||
<td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
@ -1,4 +1,8 @@
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
@if (false && !$invitationMessage)
|
||||
@include('emails.confirm_action', ['user' => $user])
|
||||
|
@ -1,4 +1,8 @@
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
@if (false)
|
||||
@include('emails.view_action', ['link' => $link, 'entityType' => $entityType])
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{App::getLocale()}}">
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
@ -1,18 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{ $client }},<p/>
|
||||
{{ $client }},<p/>
|
||||
|
||||
{{ trans('texts.payment_message', ['amount' => $amount]) }}<p/>
|
||||
{{ trans('texts.payment_message', ['amount' => $amount]) }}<p/>
|
||||
|
||||
{{ $license }}<p/>
|
||||
{{ $license }}<p/>
|
||||
|
||||
{{ trans('texts.email_signature') }}<br/>
|
||||
{{ $account }}
|
||||
|
||||
</body>
|
||||
{{ trans('texts.email_signature') }}<br/>
|
||||
{{ $account }}
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>{!! $body !!}</body>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>{!! $body !!}</body>
|
||||
</html>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="{{ App::getLocale() }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
@ -203,19 +203,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
function showUnlink(userAccountId, userId) {
|
||||
NINJA.unlink = {
|
||||
'userAccountId': userAccountId,
|
||||
'userId': userId
|
||||
};
|
||||
$('#unlinkModal').modal('show');
|
||||
return false;
|
||||
}
|
||||
|
||||
function unlinkAccount() {
|
||||
window.location = '{{ URL::to('/unlink_account') }}' + '/' + NINJA.unlink.userAccountId + '/' + NINJA.unlink.userId;
|
||||
}
|
||||
|
||||
function wordWrapText(value, width)
|
||||
{
|
||||
@if (Auth::user()->account->auto_wrap)
|
||||
@ -266,12 +253,12 @@
|
||||
}, 2000);
|
||||
|
||||
$('#search').blur(function(){
|
||||
$('#search').css('width', '150px');
|
||||
$('#search').css('width', '{{ Utils::isEnglish() ? 150 : 110 }}px');
|
||||
$('ul.navbar-right').show();
|
||||
});
|
||||
|
||||
$('#search').focus(function(){
|
||||
$('#search').css('width', '256px');
|
||||
$('#search').css('width', '{{ Utils::isEnglish() ? 256 : 216 }}px');
|
||||
$('ul.navbar-right').hide();
|
||||
if (!window.hasOwnProperty('searchData')) {
|
||||
$.get('{{ URL::route('getSearchData') }}', function(data) {
|
||||
@ -389,7 +376,7 @@
|
||||
<span class="caret"></span>
|
||||
</div>
|
||||
</button>
|
||||
<ul class="dropdown-menu user-accounts" role="menu">
|
||||
<ul class="dropdown-menu user-accounts">
|
||||
@if (session(SESSION_USER_ACCOUNTS))
|
||||
@foreach (session(SESSION_USER_ACCOUNTS) as $item)
|
||||
@if ($item->user_id == Auth::user()->id)
|
||||
@ -398,9 +385,8 @@
|
||||
'user_id' => $item->user_id,
|
||||
'account_name' => $item->account_name,
|
||||
'user_name' => $item->user_name,
|
||||
'account_key' => $item->account_key,
|
||||
'logo_path' => isset($item->logo_path) ? $item->logo_path : "",
|
||||
'selected' => true,
|
||||
'show_remove' => count(session(SESSION_USER_ACCOUNTS)) > 1,
|
||||
])
|
||||
@endif
|
||||
@endforeach
|
||||
@ -411,9 +397,8 @@
|
||||
'user_id' => $item->user_id,
|
||||
'account_name' => $item->account_name,
|
||||
'user_name' => $item->user_name,
|
||||
'account_key' => $item->account_key,
|
||||
'logo_path' => isset($item->logo_path) ? $item->logo_path : "",
|
||||
'selected' => false,
|
||||
'show_remove' => count(session(SESSION_USER_ACCOUNTS)) > 1,
|
||||
])
|
||||
@endif
|
||||
@endforeach
|
||||
@ -421,13 +406,15 @@
|
||||
@include('user_account', [
|
||||
'account_name' => Auth::user()->account->name ?: trans('texts.untitled'),
|
||||
'user_name' => Auth::user()->getDisplayName(),
|
||||
'account_key' => Auth::user()->account->account_key,
|
||||
'logo_path' => Auth::user()->account->getLogoPath(),
|
||||
'selected' => true,
|
||||
])
|
||||
@endif
|
||||
<li class="divider"></li>
|
||||
@if (!session(SESSION_USER_ACCOUNTS) || count(session(SESSION_USER_ACCOUNTS)) < 5)
|
||||
<li>{!! link_to('/login?new_account=true', trans('texts.add_account')) !!}</li>
|
||||
@if (count(session(SESSION_USER_ACCOUNTS)) > 1)
|
||||
<li>{!! link_to('/manage_companies', trans('texts.manage_companies')) !!}</li>
|
||||
@elseif (!session(SESSION_USER_ACCOUNTS) || count(session(SESSION_USER_ACCOUNTS)) < 5)
|
||||
<li>{!! link_to('/login?new_company=true', trans('texts.add_company')) !!}</li>
|
||||
@endif
|
||||
<li>{!! link_to('#', trans('texts.logout'), array('onclick'=>'logout()')) !!}</li>
|
||||
</ul>
|
||||
@ -462,7 +449,9 @@
|
||||
<li><a href="#">{{ trans('texts.no_items') }}</a></li>
|
||||
@else
|
||||
@foreach (Session::get(RECENTLY_VIEWED) as $link)
|
||||
<li><a href="{{ $link->url }}">{{ $link->name }}</a></li>
|
||||
@if (property_exists($link, 'accountId') && $link->accountId == Auth::user()->account_id)
|
||||
<li><a href="{{ $link->url }}">{{ $link->name }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
@ -471,7 +460,7 @@
|
||||
|
||||
<form class="navbar-form navbar-right" role="search">
|
||||
<div class="form-group">
|
||||
<input type="text" id="search" style="width: 150px"
|
||||
<input type="text" id="search" style="width: {{ Utils::isEnglish() ? 150 : 110 }}px"
|
||||
class="form-control" placeholder="{{ trans('texts.search') }}">
|
||||
</div>
|
||||
</form>
|
||||
@ -601,28 +590,6 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Auth::check() && session(SESSION_USER_ACCOUNTS) && count(session(SESSION_USER_ACCOUNTS)))
|
||||
<div class="modal fade" id="unlinkModal" tabindex="-1" role="dialog" aria-labelledby="unlinkModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="myModalLabel">{{ trans('texts.unlink_account') }}</h4>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h3>{{ trans('texts.are_you_sure') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer" id="signUpFooter">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary" onclick="unlinkAccount()">{{ trans('texts.unlink') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Auth::check() && !Auth::user()->isPro())
|
||||
<div class="modal fade" id="proPlanModal" tabindex="-1" role="dialog" aria-labelledby="proPlanModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog large-dialog">
|
||||
|
@ -17,8 +17,12 @@
|
||||
|
||||
@if ($invoice && $invoice->id)
|
||||
<ol class="breadcrumb">
|
||||
<li>{!! link_to(($entityType == ENTITY_QUOTE ? 'quotes' : 'invoices'), trans('texts.' . ($entityType == ENTITY_QUOTE ? 'quotes' : 'invoices'))) !!}</li>
|
||||
<li class='active'>{{ $invoice->invoice_number }}</li>
|
||||
@if ($isRecurring)
|
||||
<li>{!! link_to('invoices', trans('texts.recurring_invoice')) !!}</li>
|
||||
@else
|
||||
<li>{!! link_to(($entityType == ENTITY_QUOTE ? 'quotes' : 'invoices'), trans('texts.' . ($entityType == ENTITY_QUOTE ? 'quotes' : 'invoices'))) !!}</li>
|
||||
<li class='active'>{{ $invoice->invoice_number }}</li>
|
||||
@endif
|
||||
</ol>
|
||||
@endif
|
||||
|
||||
@ -53,7 +57,7 @@
|
||||
|
||||
<div class="form-group" style="margin-bottom: 8px">
|
||||
<div class="col-lg-8 col-sm-8 col-lg-offset-4 col-sm-offset-4">
|
||||
<a id="createClientLink" class="pointer" data-bind="click: $root.showClientForm, text: $root.clientLinkText"></a>
|
||||
<a id="createClientLink" class="pointer" data-bind="click: $root.showClientForm, html: $root.clientLinkText"></a>
|
||||
<span data-bind="visible: $root.invoice().client().public_id() > 0">|
|
||||
<a data-bind="attr: {href: '{{ url('/clients') }}/' + $root.invoice().client().public_id()}" target="_blank">{{ trans('texts.view_client') }}</a>
|
||||
</span>
|
||||
@ -79,53 +83,41 @@
|
||||
<div class="col-md-4" id="col_2">
|
||||
<div data-bind="visible: !is_recurring()">
|
||||
{!! Former::text('invoice_date')->data_bind("datePicker: invoice_date, valueUpdate: 'afterkeydown'")->label(trans("texts.{$entityType}_date"))
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'invoice_date\')"></i>') !!}
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('invoice_date') !!}
|
||||
{!! Former::text('due_date')->data_bind("datePicker: due_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'due_date\')"></i>') !!}
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('due_date') !!}
|
||||
|
||||
{!! Former::text('partial')->data_bind("value: partial, valueUpdate: 'afterkeydown'")->onchange('onPartialChange()')
|
||||
->rel('tooltip')->data_toggle('tooltip')->data_placement('bottom')->title(trans('texts.partial_value')) !!}
|
||||
</div>
|
||||
@if ($entityType == ENTITY_INVOICE)
|
||||
<div data-bind="visible: is_recurring" style="display: none">
|
||||
{!! Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id") !!}
|
||||
{!! Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id")
|
||||
->appendIcon('question-sign')->addGroupClass('frequency_id') !!}
|
||||
{!! Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') !!}
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('start_date') !!}
|
||||
{!! Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'end_date\')"></i>') !!}
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('end_date') !!}
|
||||
</div>
|
||||
@if ($invoice && $invoice->recurring_invoice_id)
|
||||
@if ($invoice && $invoice->recurring_invoice)
|
||||
<div class="pull-right" style="padding-top: 6px">
|
||||
{!! trans('texts.created_by_recurring', ['invoice' => link_to('/invoices/'.$invoice->recurring_invoice->public_id, $invoice->recurring_invoice->invoice_number)]) !!}
|
||||
{!! trans('texts.created_by_invoice', ['invoice' => link_to('/invoices/'.$invoice->recurring_invoice->public_id, trans('texts.recurring_invoice'))]) !!}
|
||||
</div>
|
||||
@else
|
||||
<div data-bind="visible: invoice_status_id() === 0">
|
||||
<div class="form-group">
|
||||
<label for="" class="control-label col-lg-4 col-sm-4">
|
||||
{{ trans('texts.recurring') }}
|
||||
</label>
|
||||
<div class="col-lg-8 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label for="recurring" class="">
|
||||
<input onclick="onRecurringEnabled()" data-bind="checked: is_recurring" id="recurring" type="checkbox" name="recurring" value="1">{{ trans('texts.enable') }}
|
||||
<a href="#" onclick="showLearnMore()"><i class="glyphicon glyphicon-question-sign"></i> {{ trans('texts.learn_more') }}</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@elseif ($invoice && $invoice->last_sent_date)
|
||||
<div class="pull-right" style="padding-top: 6px">
|
||||
{!! trans('texts.last_invoice_sent', [
|
||||
'date' => link_to('/invoices/'.$invoice->recurring_invoices->last()->public_id, Utils::dateToString($invoice->last_sent_date))
|
||||
]) !!}
|
||||
</div>
|
||||
@if ($invoice && $invoice->last_sent_date)
|
||||
<div class="pull-right">
|
||||
{{ trans('texts.last_invoice_sent', ['date' => Utils::dateToString($invoice->last_sent_date)]) }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" id="col_2">
|
||||
{!! Former::text('invoice_number')->label(trans("texts.{$entityType}_number_short"))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") !!}
|
||||
@if (!$isRecurring)
|
||||
{!! Former::text('invoice_number')->label(trans("texts.{$entityType}_number_short"))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") !!}
|
||||
@endif
|
||||
{!! Former::text('po_number')->label(trans('texts.po_number_short'))->data_bind("value: po_number, valueUpdate: 'afterkeydown'") !!}
|
||||
{!! Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")
|
||||
->addGroupClass('discount-group')->type('number')->min('0')->step('any')->append(
|
||||
@ -334,10 +326,7 @@
|
||||
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
||||
|
||||
{!! Button::success(trans("texts.save_{$entityType}"))->withAttributes(array('id' => 'saveButton', 'onclick' => 'onSaveClick()'))->appendIcon(Icon::create('floppy-disk')) !!}
|
||||
|
||||
@if (!$invoice || ($invoice && !$invoice->is_recurring))
|
||||
{!! Button::info(trans("texts.email_{$entityType}"))->withAttributes(array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->appendIcon(Icon::create('send')) !!}
|
||||
@endif
|
||||
{!! Button::info(trans("texts.email_{$entityType}"))->withAttributes(array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->appendIcon(Icon::create('send')) !!}
|
||||
|
||||
@if ($invoice && $invoice->id)
|
||||
{!! DropdownButton::normal(trans('texts.more_actions'))
|
||||
@ -604,6 +593,20 @@
|
||||
}, 1);
|
||||
});
|
||||
|
||||
$('.frequency_id .input-group-addon').click(function() {
|
||||
showLearnMore();
|
||||
});
|
||||
|
||||
var fields = ['invoice_date', 'due_date', 'start_date', 'end_date'];
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var field = fields[i];
|
||||
(function (_field) {
|
||||
$('.' + _field + ' .input-group-addon').click(function() {
|
||||
toggleDatePicker(_field);
|
||||
});
|
||||
})(field);
|
||||
}
|
||||
|
||||
@if ($client || $invoice || count($clients) == 0)
|
||||
$('#invoice_number').focus();
|
||||
@else
|
||||
@ -670,9 +673,15 @@
|
||||
var product = products[i];
|
||||
if (product.product_key == key) {
|
||||
var model = ko.dataFor(this);
|
||||
model.notes(product.notes);
|
||||
model.cost(accounting.toFixed(product.cost,2));
|
||||
model.qty(1);
|
||||
if (!model.notes()) {
|
||||
model.notes(product.notes);
|
||||
}
|
||||
if (!model.cost()) {
|
||||
model.cost(accounting.toFixed(product.cost,2));
|
||||
}
|
||||
if (!model.qty()) {
|
||||
model.qty(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -688,6 +697,10 @@
|
||||
invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }};
|
||||
invoice.contact = _.findWhere(invoice.client.contacts, {send_invoice: true});
|
||||
|
||||
if (invoice.is_recurring) {
|
||||
invoice.invoice_number = '0000';
|
||||
}
|
||||
|
||||
@if (!$invoice)
|
||||
if (!invoice.terms) {
|
||||
invoice.terms = wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) !!}', 300);
|
||||
@ -1115,10 +1128,10 @@
|
||||
var self = this;
|
||||
this.client = ko.observable(data ? false : new ClientModel());
|
||||
self.account = {!! $account !!};
|
||||
this.id = ko.observable('');
|
||||
self.id = ko.observable('');
|
||||
self.discount = ko.observable('');
|
||||
self.is_amount_discount = ko.observable(0);
|
||||
self.frequency_id = ko.observable('');
|
||||
self.frequency_id = ko.observable(4); // default to monthly
|
||||
self.terms = ko.observable('');
|
||||
self.default_terms = ko.observable({{ !$invoice && $account->invoice_terms ? 'true' : 'false' }} ? wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) !!}', 300) : '');
|
||||
self.set_default_terms = ko.observable(false);
|
||||
@ -1134,7 +1147,7 @@
|
||||
self.end_date = ko.observable('');
|
||||
self.tax_name = ko.observable();
|
||||
self.tax_rate = ko.observable();
|
||||
self.is_recurring = ko.observable(false);
|
||||
self.is_recurring = ko.observable({{ $isRecurring ? 'true' : 'false' }});
|
||||
self.invoice_status_id = ko.observable(0);
|
||||
self.invoice_items = ko.observableArray();
|
||||
self.amount = ko.observable(0);
|
||||
|
@ -74,6 +74,7 @@
|
||||
var NINJA = NINJA || {};
|
||||
NINJA.primaryColor = "{{ $account->primary_color }}";
|
||||
NINJA.secondaryColor = "{{ $account->secondary_color }}";
|
||||
NINJA.fontSize = {{ $account->font_size }};
|
||||
|
||||
var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!};
|
||||
|
||||
|
@ -24,13 +24,16 @@
|
||||
</label>
|
||||
|
||||
<div id="top_right_buttons" class="pull-right">
|
||||
<input id="tableFilter" type="text" style="width:140px;margin-right:17px;background-color: white !important" class="form-control pull-left" placeholder="{{ trans('texts.filter') }}"/>
|
||||
<input id="tableFilter" type="text" style="width:140px;margin-right:17px;background-color: white !important" class="form-control pull-left" placeholder="{{ trans('texts.filter') }}"/>
|
||||
@if (Auth::user()->isPro() && $entityType == ENTITY_INVOICE)
|
||||
{!! Button::normal(trans('texts.quotes'))->asLinkTo(URL::to('/quotes'))->appendIcon(Icon::create('list')) !!}
|
||||
@elseif ($entityType == ENTITY_CLIENT)
|
||||
{!! Button::normal(trans('texts.credits'))->asLinkTo(URL::to('/credits'))->appendIcon(Icon::create('list')) !!}
|
||||
@endif
|
||||
{!! Button::primary(trans("texts.new_$entityType"))->asLinkTo(URL::to("/{$entityType}s/create"))->appendIcon(Icon::create('plus-sign')) !!}
|
||||
|
||||
@if ($entityType != ENTITY_TASK || Auth::user()->account->timezone_id)
|
||||
{!! Button::primary(trans("texts.new_$entityType"))->asLinkTo(URL::to("/{$entityType}s/create"))->appendIcon(Icon::create('plus-sign')) !!}
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if (isset($secEntityType))
|
||||
|
@ -53,10 +53,13 @@
|
||||
'sSearch': ''
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
/*
|
||||
$.extend( true, $.fn.datepicker.defaults, {
|
||||
language:'{{App::getLocale()}}'
|
||||
});
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
|
@ -169,7 +169,7 @@ header h3 em {
|
||||
<header>
|
||||
@if ($client)
|
||||
<h2>{{ $client->getDisplayName() }}</h2>
|
||||
<h3>{{ trans('texts.invoice') . ' ' . $invoiceNumber }}<span>| {{ trans('texts.amount_due') }}: <em>{{ Utils::formatMoney($amount, $currencyId) }}</em></span></h3>
|
||||
<h3>{{ trans('texts.invoice') . ' ' . $invoiceNumber }}<span>| {{ trans('texts.amount_due') }}: <em>{{ Utils::formatMoney($amount, $currencyId) }} {{ $currencyCode }}</em></span></h3>
|
||||
@elseif ($paymentTitle)
|
||||
<h2>{{ $paymentTitle }}<br/><small>{{ $paymentSubtitle }}</small></h2>
|
||||
@endif
|
||||
|
@ -75,7 +75,7 @@
|
||||
|
||||
// remove quotes and recurring invoices
|
||||
invoices = _.filter(invoices, function(invoice) {
|
||||
return !parseInt(invoice.is_quote) && !parseInt(invoice.is_recurring);
|
||||
return !parseInt(invoice.is_quote) && !invoice.is_recurring;
|
||||
});
|
||||
|
||||
var products = _.flatten(_.pluck(invoices, 'invoice_items'));
|
||||
|
@ -4,10 +4,9 @@
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
.time-input input,
|
||||
.time-input select {
|
||||
float: left;
|
||||
input.time-input {
|
||||
width: 110px;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -79,13 +78,13 @@
|
||||
<td style="padding: 0px 12px 12px 0 !important">
|
||||
<div data-bind="css: { 'has-error': !isStartValid() }">
|
||||
<input type="text" data-bind="value: startTime.pretty, event:{ change: $root.refresh }"
|
||||
class="form-control" placeholder="{{ trans('texts.start_time') }}"/>
|
||||
class="form-control time-input" placeholder="{{ trans('texts.start_time') }}"/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding: 0px 12px 12px 0 !important">
|
||||
<div data-bind="css: { 'has-error': !isEndValid() }">
|
||||
<input type="text" data-bind="value: endTime.pretty, event:{ change: $root.refresh }"
|
||||
class="form-control" placeholder="{{ trans('texts.end_time') }}"/>
|
||||
class="form-control time-input" placeholder="{{ trans('texts.end_time') }}"/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:100px">
|
||||
@ -202,9 +201,6 @@
|
||||
}
|
||||
|
||||
function TimeModel(data) {
|
||||
console.log('== TimeModel ==');
|
||||
console.log(data);
|
||||
|
||||
var self = this;
|
||||
self.startTime = ko.observable(0);
|
||||
self.endTime = ko.observable(0);
|
||||
@ -223,7 +219,7 @@
|
||||
});
|
||||
|
||||
self.startTime.pretty = ko.computed({
|
||||
read: function() {
|
||||
read: function() {
|
||||
return self.startTime() ? moment.unix(self.startTime()).utcOffset({{ $minuteOffset }}).format('MMM D YYYY h:mm:ss a') : '';
|
||||
},
|
||||
write: function(data) {
|
||||
@ -341,13 +337,6 @@
|
||||
|
||||
$clientSelect.combobox();
|
||||
|
||||
@if ($task)
|
||||
$('#date').datepicker('update', new Date('{{ Utils::fromSqlDateTime($task->start_time) }}'));
|
||||
@else
|
||||
var date = new Date();
|
||||
$('#date').datepicker('update', date);
|
||||
@endif
|
||||
|
||||
@if (!$task && !$clientPublicId)
|
||||
$('.client-select input.form-control').focus();
|
||||
@else
|
||||
|
@ -1,16 +1,14 @@
|
||||
<li style="margin-top: 4px; margin-bottom: 4px; min-width: 220px; cursor: pointer">
|
||||
@if (isset($user_id) && $show_remove)
|
||||
<a href='{{ URL::to("/switch_account/{$user_id}") }}'>
|
||||
@if (isset($user_id) && $user_id != Auth::user()->id)
|
||||
<a href="{{ URL::to("/switch_account/{$user_id}") }}">
|
||||
@else
|
||||
<a href='#' onclick="return false;">
|
||||
<a href="{{ URL::to("/company/details") }}">
|
||||
@endif
|
||||
|
||||
@if (isset($show_remove) && $show_remove)
|
||||
<div class="pull-right glyphicon glyphicon-remove remove" onclick="return showUnlink({{ $user_account_id }}, {{ $user_id }})"></div>
|
||||
@endif
|
||||
|
||||
@if (file_exists('logo/'.$account_key.'.jpg'))
|
||||
<img class="pull-left" style="width: 40px; min-height: 40px; margin-right: 16px" src="{{ asset('logo/'.$account_key.'.jpg') }}"/>
|
||||
@if (file_exists($logo_path))
|
||||
<div class="pull-left" style="height: 40px; margin-right: 16px;">
|
||||
<img style="width: 40px; margin-top:6px" src="{{ asset($logo_path) }}"/>
|
||||
</div>
|
||||
@else
|
||||
<div class="pull-left" style="width: 40px; min-height: 40px; margin-right: 16px"> </div>
|
||||
@endif
|
||||
|
83
resources/views/users/account_management.blade.php
Normal file
83
resources/views/users/account_management.blade.php
Normal file
@ -0,0 +1,83 @@
|
||||
@extends('header')
|
||||
|
||||
@section('content')
|
||||
|
||||
|
||||
<center>
|
||||
{!! Button::success(trans('texts.add_company'))->asLinkTo('/login?new_company=true') !!}
|
||||
</center>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<table class="table table-striped">
|
||||
@foreach (Session::get(SESSION_USER_ACCOUNTS) as $account)
|
||||
<tr>
|
||||
<td>
|
||||
@if (isset($account->logo_path))
|
||||
{!! HTML::image($account->logo_path.'?no_cache='.time(), 'Logo', ['width' => 100]) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<h3>{{ $account->account_name }}<br/>
|
||||
<small>{{ $account->user_name }}
|
||||
@if ($account->user_id == Auth::user()->id)
|
||||
| {{ trans('texts.current_user')}}
|
||||
@endif
|
||||
</small></h3>
|
||||
</td>
|
||||
<td>{!! Button::primary(trans('texts.unlink'))->withAttributes(['onclick'=>"return showUnlink({$account->id}, {$account->user_id})"]) !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="unlinkModal" tabindex="-1" role="dialog" aria-labelledby="unlinkModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="myModalLabel">{{ trans('texts.unlink_account') }}</h4>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h3>{{ trans('texts.are_you_sure') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer" id="signUpFooter">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary" onclick="unlinkAccount()">{{ trans('texts.unlink') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
function showUnlink(userAccountId, userId) {
|
||||
NINJA.unlink = {
|
||||
'userAccountId': userAccountId,
|
||||
'userId': userId
|
||||
};
|
||||
$('#unlinkModal').modal('show');
|
||||
return false;
|
||||
}
|
||||
|
||||
function unlinkAccount() {
|
||||
window.location = '{{ URL::to('/unlink_account') }}' + '/' + NINJA.unlink.userAccountId + '/' + NINJA.unlink.userId;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@stop
|
@ -65,7 +65,7 @@
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"widths": ["*", "40%"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
|
@ -3,7 +3,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 140
|
||||
"fit": [120, 80]
|
||||
},
|
||||
{
|
||||
"stack": "$accountDetails",
|
||||
@ -16,7 +16,7 @@
|
||||
},
|
||||
{
|
||||
"text": "$entityTypeUC",
|
||||
"margin": [8, 50, 8, 5],
|
||||
"margin": [8, 30, 8, 5],
|
||||
"style": "entityTypeLabel"
|
||||
|
||||
},
|
||||
@ -30,7 +30,7 @@
|
||||
"table": {
|
||||
"body": "$invoiceDetails"
|
||||
},
|
||||
"margin": [0, 4, 12, 4],
|
||||
"margin": [0, 4, 12, 4],
|
||||
"layout": "noBorders"
|
||||
},
|
||||
{
|
||||
@ -70,17 +70,17 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
"columns": [
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"widths": ["*", "40%"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$none",
|
||||
"vLineWidth": "$none",
|
||||
"paddingLeft": "$amount:8",
|
||||
"paddingLeft": "$amount:34",
|
||||
"paddingRight": "$amount:8",
|
||||
"paddingTop": "$amount:4",
|
||||
"paddingBottom": "$amount:4"
|
||||
@ -97,12 +97,10 @@
|
||||
"columns": [
|
||||
{
|
||||
"text": "$invoiceFooter",
|
||||
"alignment": "left",
|
||||
"margin": [0, 0, 0, 12]
|
||||
|
||||
"alignment": "left"
|
||||
}
|
||||
],
|
||||
"margin": [40, -20, 40, 40]
|
||||
"margin": [40, -20, 40, 0]
|
||||
},
|
||||
"styles": {
|
||||
"entityTypeLabel": {
|
||||
@ -116,6 +114,9 @@
|
||||
"color": "$primaryColor:#37a3c6",
|
||||
"bold": true
|
||||
},
|
||||
"invoiceDetails": {
|
||||
"margin": [0, 0, 8, 0]
|
||||
},
|
||||
"accountDetails": {
|
||||
"margin": [0, 2, 0, 2]
|
||||
},
|
||||
@ -136,10 +137,10 @@
|
||||
"bold": true
|
||||
},
|
||||
"balanceDueLabel": {
|
||||
"fontSize": "$fontSizeLargest"
|
||||
"fontSize": "$fontSizeLarger"
|
||||
},
|
||||
"balanceDue": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"fontSize": "$fontSizeLarger",
|
||||
"color": "$primaryColor:#37a3c6"
|
||||
},
|
||||
"invoiceNumber": {
|
||||
@ -147,7 +148,7 @@
|
||||
},
|
||||
"tableHeader": {
|
||||
"bold": true,
|
||||
"fontSize": "$fontSizeLargest"
|
||||
"fontSize": "$fontSizeLarger"
|
||||
},
|
||||
"invoiceLineItemsTable": {
|
||||
"margin": [0, 16, 0, 16]
|
||||
@ -171,8 +172,7 @@
|
||||
"alignment": "right"
|
||||
},
|
||||
"termsLabel": {
|
||||
"bold": true,
|
||||
"margin": [0, 0, 0, 4]
|
||||
"bold": true
|
||||
}
|
||||
},
|
||||
"pageMargins": [40, 40, 40, 60]
|
||||
|
@ -4,7 +4,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 80,
|
||||
"fit": [120, 80],
|
||||
"margin": [0, 60, 0, 30]
|
||||
},
|
||||
{
|
||||
@ -37,13 +37,13 @@
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"widths": ["*", "40%"],
|
||||
"body": "$subtotalsWithoutBalance"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$none",
|
||||
"vLineWidth": "$none",
|
||||
"paddingLeft": "$amount:8",
|
||||
"paddingLeft": "$amount:34",
|
||||
"paddingRight": "$amount:8",
|
||||
"paddingTop": "$amount:4",
|
||||
"paddingBottom": "$amount:4"
|
||||
|
@ -11,7 +11,7 @@
|
||||
[
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 100
|
||||
"fit": [120, 80]
|
||||
}
|
||||
]
|
||||
]},
|
||||
@ -66,13 +66,13 @@
|
||||
{
|
||||
"style": "subtotals",
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"widths": ["*", "40%"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$none",
|
||||
"vLineWidth": "$none",
|
||||
"paddingLeft": "$amount:8",
|
||||
"paddingLeft": "$amount:34",
|
||||
"paddingRight": "$amount:8",
|
||||
"paddingTop": "$amount:4",
|
||||
"paddingBottom": "$amount:4"
|
||||
|
Loading…
Reference in New Issue
Block a user