diff --git a/.env.example b/.env.example index ce0cd9128663..8ae5c8ae153a 100644 --- a/.env.example +++ b/.env.example @@ -20,6 +20,6 @@ MAIL_FROM_ADDRESS MAIL_FROM_NAME MAIL_PASSWORD -PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address' +#PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address' LOG=single diff --git a/Gruntfile.js b/Gruntfile.js index 30585856a853..fdd48d76c49d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -120,13 +120,10 @@ module.exports = function(grunt) { src: [ 'public/vendor/bootstrap/dist/css/bootstrap.min.css', 'public/vendor/font-awesome/css/font-awesome.min.css', - /* - 'public/css/bootstrap.splash.css', - 'public/css/splash.css', - */ 'public/css/bootstrap-combobox.css', 'public/vendor/datatables/media/css/jquery.dataTables.css', 'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css', + 'public/css/public.style.css', ], dest: 'public/css/built.public.css', nonull: true, diff --git a/app/Console/Commands/SendReminders.php b/app/Console/Commands/SendReminders.php index 123e086feb30..a2bfdc29da8b 100644 --- a/app/Console/Commands/SendReminders.php +++ b/app/Console/Commands/SendReminders.php @@ -36,6 +36,10 @@ class SendReminders extends Command $this->info(count($accounts).' accounts found'); foreach ($accounts as $account) { + if (!$account->isPro()) { + continue; + } + $invoices = $this->invoiceRepo->findNeedingReminding($account); $this->info($account->name . ': ' . count($invoices).' invoices found'); diff --git a/app/Events/UserSettingsChanged.php b/app/Events/UserSettingsChanged.php index 02c3a0195875..ead79b390898 100644 --- a/app/Events/UserSettingsChanged.php +++ b/app/Events/UserSettingsChanged.php @@ -8,14 +8,16 @@ class UserSettingsChanged extends Event { use SerializesModels; + public $user; + /** * Create a new event instance. * * @return void */ - public function __construct() + public function __construct($user = false) { - // + $this->user = $user; } } diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 1eb38bcbdc8a..26777a54feba 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -373,8 +373,10 @@ class AccountController extends BaseController $rules = []; $user = Auth::user(); $iframeURL = preg_replace('/[^a-zA-Z0-9_\-\:\/\.]/', '', substr(strtolower(Input::get('iframe_url')), 0, MAX_IFRAME_URL_LENGTH)); - $subdomain = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', substr(strtolower(Input::get('subdomain')), 0, MAX_SUBDOMAIN_LENGTH)); - if (!$subdomain || in_array($subdomain, ['www', 'app', 'mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner'])) { + $iframeURL = rtrim($iframeURL, "/"); + + $subdomain = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', substr(strtolower(Input::get('subdomain')), 0, MAX_SUBDOMAIN_LENGTH)); + if ($iframeURL || !$subdomain || in_array($subdomain, ['www', 'app', 'mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner'])) { $subdomain = null; } if ($subdomain) { diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index 9704b3adaaad..39419f227df6 100644 --- a/app/Http/Controllers/ActivityController.php +++ b/app/Http/Controllers/ActivityController.php @@ -20,14 +20,7 @@ class ActivityController extends BaseController ->addColumn('activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); }) ->addColumn('message', function ($model) { return Utils::decodeActivity($model->message); }) ->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); }) - ->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? self::wrapAdjustment($model->adjustment, $model->currency_id) : ''; }) + ->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; }) ->make(); } - - private function wrapAdjustment($adjustment, $currencyId) - { - $class = $adjustment <= 0 ? 'success' : 'default'; - $adjustment = Utils::formatMoney($adjustment, $currencyId); - return "

$adjustment

"; - } } diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index 5ced7948658e..7d186e29c37b 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -94,7 +94,7 @@ class AppController extends BaseController "MAIL_USERNAME={$mail['username']}\n". "MAIL_FROM_NAME={$mail['from']['name']}\n". "MAIL_PASSWORD={$mail['password']}\n\n". - "PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address'"; + "#PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address'"; // Write Config Settings $fp = fopen(base_path()."/.env", 'w'); diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 27e0a1de90fa..2dd1eef286f6 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -181,6 +181,10 @@ class InvoiceApiController extends Controller // initialize the line items if (isset($data['product_key']) || isset($data['cost']) || isset($data['notes']) || isset($data['qty'])) { $data['invoice_items'] = [self::prepareItem($data)]; + + // make sure the tax isn't applied twice (for the invoice and the line item) + unset($data['invoice_items'][0]['tax_name']); + unset($data['invoice_items'][0]['tax_rate']); } else { foreach ($data['invoice_items'] as $index => $item) { $data['invoice_items'][$index] = self::prepareItem($item); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 948a21532f0e..1c20642d8795 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -76,28 +76,6 @@ class InvoiceController extends BaseController return View::make('list', $data); } - public function clientIndex() - { - $invitationKey = Session::get('invitation_key'); - if (!$invitationKey) { - app()->abort(404); - } - - $invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first(); - $account = $invitation->account; - $color = $account->primary_color ? $account->primary_color : '#0b4d78'; - - $data = [ - 'color' => $color, - 'hideLogo' => $account->isWhiteLabel(), - 'title' => trans('texts.invoices'), - 'entityType' => ENTITY_INVOICE, - 'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']), - ]; - - return View::make('public_list', $data); - } - public function getDatatable($clientPublicId = null) { $accountId = Auth::user()->account_id; @@ -106,25 +84,6 @@ class InvoiceController extends BaseController return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_INVOICE, $search); } - public function getClientDatatable() - { - $search = Input::get('sSearch'); - $invitationKey = Session::get('invitation_key'); - $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first(); - - if (!$invitation || $invitation->is_deleted) { - return []; - } - - $invoice = $invitation->invoice; - - if (!$invoice || $invoice->is_deleted) { - return []; - } - - return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, $search); - } - public function getRecurringDatatable($clientPublicId = null) { $query = $this->invoiceRepo->getRecurringInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch')); @@ -172,42 +131,22 @@ class InvoiceController extends BaseController public function view($invitationKey) { - $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first(); - - if (!$invitation) { - app()->abort(404, trans('texts.invoice_not_found')); - } - + $invitation = $this->invoiceRepo->findInvoiceByInvitation($invitationKey); $invoice = $invitation->invoice; - - if (!$invoice || $invoice->is_deleted) { - app()->abort(404, trans('texts.invoice_not_found')); - } - - $invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country'); $client = $invoice->client; - $account = $client->account; + $account = $invoice->account; - if (!$client || $client->is_deleted) { + if (!$account->checkSubdomain(Request::server('HTTP_HOST'))) { app()->abort(404, trans('texts.invoice_not_found')); } - if ($account->subdomain) { - $server = explode('.', Request::server('HTTP_HOST')); - $subdomain = $server[0]; - - if (!in_array($subdomain, ['app', 'www']) && $subdomain != $account->subdomain) { - return View::make('invoices.deleted'); - } - } - if (!Input::has('phantomjs') && !Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) { Activity::viewInvoice($invitation); Event::fire(new InvoiceViewed($invoice)); } - Session::set($invitationKey, true); - Session::set('invitation_key', $invitationKey); + Session::set($invitationKey, true); // track this invitation has been seen + Session::set('invitation_key', $invitationKey); // track current invitation $account->loadLocalizationSettings($client); @@ -226,27 +165,16 @@ class InvoiceController extends BaseController 'first_name', 'last_name', 'email', - 'phone', ]); - - // Determine payment options - $paymentTypes = []; - if ($client->getGatewayToken()) { - $paymentTypes[] = [ - 'url' => URL::to("payment/{$invitation->invitation_key}/token"), 'label' => trans('texts.use_card_on_file') - ]; - } - foreach(Gateway::$paymentTypes as $type) { - if ($account->getGatewayByType($type)) { - $typeLink = strtolower(str_replace('PAYMENT_TYPE_', '', $type)); - $paymentTypes[] = [ - 'url' => URL::to("/payment/{$invitation->invitation_key}/{$typeLink}"), 'label' => trans('texts.'.strtolower($type)) - ]; - } - } + 'phone', + ]); + $paymentTypes = $this->getPaymentTypes($client, $invitation); $paymentURL = ''; if (count($paymentTypes)) { $paymentURL = $paymentTypes[0]['url']; + if (!$account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) { + $paymentURL = URL::to($paymentURL); + } } $showApprove = $invoice->quote_invoice_id ? false : true; @@ -271,6 +199,34 @@ class InvoiceController extends BaseController return View::make('invoices.view', $data); } + private function getPaymentTypes($client, $invitation) + { + $paymentTypes = []; + $account = $client->account; + + if ($client->getGatewayToken()) { + $paymentTypes[] = [ + 'url' => URL::to("payment/{$invitation->invitation_key}/token"), 'label' => trans('texts.use_card_on_file') + ]; + } + foreach(Gateway::$paymentTypes as $type) { + if ($account->getGatewayByType($type)) { + $typeLink = strtolower(str_replace('PAYMENT_TYPE_', '', $type)); + $url = URL::to("/payment/{$invitation->invitation_key}/{$typeLink}"); + + // PayPal doesn't allow being run in an iframe so we need to open in new tab + if ($type === PAYMENT_TYPE_PAYPAL && $account->iframe_url) { + $url = 'javascript:window.open("'.$url.'", "_blank")'; + } + $paymentTypes[] = [ + 'url' => $url, 'label' => trans('texts.'.strtolower($type)) + ]; + } + } + + return $paymentTypes; + } + public function edit($publicId, $clone = false) { $invoice = Invoice::scope($publicId)->withTrashed()->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items')->firstOrFail(); @@ -468,121 +424,138 @@ class InvoiceController extends BaseController { $action = Input::get('action'); $entityType = Input::get('entityType'); + $input = json_decode(Input::get('data')); if (in_array($action, ['archive', 'delete', 'mark', 'restore'])) { return InvoiceController::bulk($entityType); } - $input = json_decode(Input::get('data')); - $invoice = $input->invoice; - - if ($errors = $this->invoiceRepo->getErrors($invoice)) { + if ($errors = $this->invoiceRepo->getErrors($input->invoice)) { Session::flash('error', trans('texts.invoice_error')); return Redirect::to("{$entityType}s/create") ->withInput()->withErrors($errors); } else { - $this->taxRateRepo->save($input->tax_rates); - - $clientData = (array) $invoice->client; - $client = $this->clientRepo->save($invoice->client->public_id, $clientData); - - $invoiceData = (array) $invoice; - $invoiceData['client_id'] = $client->id; - $invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType); - - $account = Auth::user()->account; - if ($account->invoice_taxes != $input->invoice_taxes - || $account->invoice_item_taxes != $input->invoice_item_taxes - || $account->invoice_design_id != $input->invoice->invoice_design_id - || $account->show_item_taxes != $input->show_item_taxes) { - $account->invoice_taxes = $input->invoice_taxes; - $account->invoice_item_taxes = $input->invoice_item_taxes; - $account->invoice_design_id = $input->invoice->invoice_design_id; - $account->show_item_taxes = $input->show_item_taxes; - $account->save(); - } - - $client->load('contacts'); - $sendInvoiceIds = []; - - foreach ($client->contacts as $contact) { - if ($contact->send_invoice || count($client->contacts) == 1) { - $sendInvoiceIds[] = $contact->id; - } - } - - foreach ($client->contacts as $contact) { - $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first(); - - if (in_array($contact->id, $sendInvoiceIds) && !$invitation) { - $invitation = Invitation::createNew(); - $invitation->invoice_id = $invoice->id; - $invitation->contact_id = $contact->id; - $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH); - $invitation->save(); - } elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) { - $invitation->delete(); - } - } - + $invoice = $this->saveInvoice($publicId, $input, $entityType); + $url = "{$entityType}s/".$invoice->public_id.'/edit'; $message = trans($publicId ? "texts.updated_{$entityType}" : "texts.created_{$entityType}"); + + // check if we created a new client with the invoice if ($input->invoice->client->public_id == '-1') { $message = $message.' '.trans('texts.and_created_client'); - - $url = URL::to('clients/'.$client->public_id); + $url = URL::to('clients/'.$input->invoice->client->public_id); Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT, $url); } - if ($invoice->account->pdf_email_attachment && !$invoice->is_recurring) { - $pdfUpload = Input::get('pdfupload'); - if (!empty($pdfUpload) && strpos($pdfUpload, 'data:application/pdf;base64,') === 0) { - $invoice->updateCachedPDF($pdfUpload); - } - } - if ($action == 'clone') { return $this->cloneInvoice($publicId); } elseif ($action == 'convert') { return $this->convertQuote($publicId); } elseif ($action == 'email') { - if (Auth::user()->confirmed && !Auth::user()->isDemo()) { - if ($invoice->is_recurring) { - if ($invoice->shouldSendToday()) { - $invoice = $this->invoiceRepo->createRecurringInvoice($invoice); - // in case auto-bill is enabled - if ($invoice->isPaid()) { - $response = true; - } else { - $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); - } else { - Session::flash('error', $response); - } - } else { - $errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required'); - Session::flash('error', $errorMessage); - Session::flash('message', $message); - } - } else { - Session::flash('message', $message); + return $this->emailInvoice($invoice, Input::get('pdfupload')); } - - $url = "{$entityType}s/".$invoice->public_id.'/edit'; - + + Session::flash('message', $message); return Redirect::to($url); } } + private function emailInvoice($invoice, $pdfUpload) + { + $entityType = $invoice->getEntityType(); + $pdfUpload = Utils::decodePDF($pdfUpload); + + if (!Auth::user()->confirmed) { + $errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required'); + Session::flash('error', $errorMessage); + Session::flash('message', $message); + return Redirect::to($url); + } + + if ($invoice->is_recurring) { + $response = $this->emailRecurringInvoice($invoice); + } else { + $response = $this->mailer->sendInvoice($invoice, false, $pdfUpload); + } + + if ($response === true) { + $message = trans("texts.emailed_{$entityType}"); + Session::flash('message', $message); + } else { + Session::flash('error', $response); + } + + return Redirect::to("{$entityType}s/{$invoice->public_id}/edit"); + } + + private function emailRecurringInvoice(&$invoice) + { + if (!$invoice->shouldSendToday()) { + return trans('texts.recurring_too_soon'); + } + + // switch from the recurring invoice to the generated invoice + $invoice = $this->invoiceRepo->createRecurringInvoice($invoice); + + // in case auto-bill is enabled then a receipt has been sent + if ($invoice->isPaid()) { + return true; + } else { + return $this->mailer->sendInvoice($invoice); + } + } + + private function saveInvoice($publicId, $input, $entityType) + { + $invoice = $input->invoice; + + $this->taxRateRepo->save($input->tax_rates); + + $clientData = (array) $invoice->client; + $client = $this->clientRepo->save($invoice->client->public_id, $clientData); + + $invoiceData = (array) $invoice; + $invoiceData['client_id'] = $client->id; + $invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType); + + $account = Auth::user()->account; + if ($account->invoice_taxes != $input->invoice_taxes + || $account->invoice_item_taxes != $input->invoice_item_taxes + || $account->invoice_design_id != $input->invoice->invoice_design_id + || $account->show_item_taxes != $input->show_item_taxes) { + $account->invoice_taxes = $input->invoice_taxes; + $account->invoice_item_taxes = $input->invoice_item_taxes; + $account->invoice_design_id = $input->invoice->invoice_design_id; + $account->show_item_taxes = $input->show_item_taxes; + $account->save(); + } + + $client->load('contacts'); + $sendInvoiceIds = []; + + foreach ($client->contacts as $contact) { + if ($contact->send_invoice || count($client->contacts) == 1) { + $sendInvoiceIds[] = $contact->id; + } + } + + foreach ($client->contacts as $contact) { + $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first(); + + if (in_array($contact->id, $sendInvoiceIds) && !$invitation) { + $invitation = Invitation::createNew(); + $invitation->invoice_id = $invoice->id; + $invitation->contact_id = $contact->id; + $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH); + $invitation->save(); + } elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) { + $invitation->delete(); + } + } + + return $invoice; + } + /** * Display the specified resource. * diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 326f0be4ad82..daa32853ae03 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -47,28 +47,6 @@ class PaymentController extends BaseController )); } - public function clientIndex() - { - $invitationKey = Session::get('invitation_key'); - if (!$invitationKey) { - app()->abort(404); - } - - $invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first(); - $account = $invitation->account; - $color = $account->primary_color ? $account->primary_color : '#0b4d78'; - - $data = [ - 'color' => $color, - 'hideLogo' => $account->isWhiteLabel(), - 'entityType' => ENTITY_PAYMENT, - 'title' => trans('texts.payments'), - 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date']) - ]; - - return View::make('public_list', $data); - } - public function getDatatable($clientPublicId = null) { $payments = $this->paymentRepo->find($clientPublicId, Input::get('sSearch')); @@ -114,33 +92,6 @@ class PaymentController extends BaseController ->make(); } - public function getClientDatatable() - { - $search = Input::get('sSearch'); - $invitationKey = Session::get('invitation_key'); - $invitation = Invitation::where('invitation_key', '=', $invitationKey)->with('contact.client')->first(); - - if (!$invitation) { - return []; - } - - $invoice = $invitation->invoice; - - if (!$invoice || $invoice->is_deleted) { - return []; - } - - $payments = $this->paymentRepo->findForContact($invitation->contact->id, Input::get('sSearch')); - - return Datatable::query($payments) - ->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number) : $model->invoice_number; }) - ->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : 'Manual entry'; }) - ->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); }) - ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); }) - ->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); }) - ->make(); - } - public function create($clientPublicId = 0, $invoicePublicId = 0) { $invoices = Invoice::scope() @@ -549,14 +500,16 @@ class PaymentController extends BaseController $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail(); $invoice = $invitation->invoice; + $client = $invoice->client; + $account = $client->account; - $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type')); + $accountGateway = $account->getGatewayByType(Session::get('payment_type')); $gateway = $this->paymentService->createGateway($accountGateway); // Check for Dwolla payment error if ($accountGateway->isGateway(GATEWAY_DWOLLA) && Input::get('error')) { $this->error('Dwolla', Input::get('error_description'), $accountGateway); - return Redirect::to('view/'.$invitation->invitation_key); + return Redirect::to($invitation->getLink()); } try { @@ -569,20 +522,20 @@ class PaymentController extends BaseController $payment = $this->paymentService->createPayment($invitation, $ref, $payerId); Session::flash('message', trans('texts.applied_payment')); - return Redirect::to('view/'.$invitation->invitation_key); + return Redirect::to($invitation->getLink()); } else { $this->error('offsite', $response->getMessage(), $accountGateway); - return Redirect::to('view/'.$invitation->invitation_key); + return Redirect::to($invitation->getLink()); } } else { $payment = $this->paymentService->createPayment($invitation, $token, $payerId); Session::flash('message', trans('texts.applied_payment')); - return Redirect::to('view/'.$invitation->invitation_key); + return Redirect::to($invitation->getLink()); } } catch (\Exception $e) { $this->error('Offsite-uncaught', false, $accountGateway, $e); - return Redirect::to('view/'.$invitation->invitation_key); + return Redirect::to($invitation->getLink()); } } diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php new file mode 100644 index 000000000000..187a4eed9dd0 --- /dev/null +++ b/app/Http/Controllers/PublicClientController.php @@ -0,0 +1,163 @@ +invoiceRepo = $invoiceRepo; + $this->paymentRepo = $paymentRepo; + } + + public function dashboard() + { + $invitation = $this->getInvitation(); + $account = $invitation->account; + $invoice = $invitation->invoice; + $client = $invoice->client; + $color = $account->primary_color ? $account->primary_color : '#0b4d78'; + + $data = [ + 'color' => $color, + 'account' => $account, + 'client' => $client, + ]; + + return response()->view('invited.dashboard', $data); + } + + public function activityDatatable() + { + $invitation = $this->getInvitation(); + $invoice = $invitation->invoice; + + $query = DB::table('activities') + ->join('clients', 'clients.id', '=', 'activities.client_id') + ->where('activities.client_id', '=', $invoice->client_id) + ->where('activities.adjustment', '!=', 0) + ->select('activities.id', 'activities.message', 'activities.created_at', 'clients.currency_id', 'activities.balance', 'activities.adjustment'); + + return Datatable::query($query) + ->addColumn('activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); }) + ->addColumn('message', function ($model) { return strip_tags(Utils::decodeActivity($model->message)); }) + ->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); }) + ->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; }) + ->make(); + } + + public function invoiceIndex() + { + $invitation = $this->getInvitation(); + $account = $invitation->account; + $color = $account->primary_color ? $account->primary_color : '#0b4d78'; + + $data = [ + 'color' => $color, + 'hideLogo' => $account->isWhiteLabel(), + 'title' => trans('texts.invoices'), + 'entityType' => ENTITY_INVOICE, + 'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']), + ]; + + return response()->view('public_list', $data); + } + + public function invoiceDatatable() + { + $invitation = $this->getInvitation(); + + return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, Input::get('sSearch')); + } + + + public function paymentIndex() + { + $invitation = $this->getInvitation(); + $account = $invitation->account; + $color = $account->primary_color ? $account->primary_color : '#0b4d78'; + + $data = [ + 'color' => $color, + 'hideLogo' => $account->isWhiteLabel(), + 'entityType' => ENTITY_PAYMENT, + 'title' => trans('texts.payments'), + 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date']) + ]; + + return response()->view('public_list', $data); + } + + public function paymentDatatable() + { + $invitation = $this->getInvitation(); + $payments = $this->paymentRepo->findForContact($invitation->contact->id, Input::get('sSearch')); + + return Datatable::query($payments) + ->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number) : $model->invoice_number; }) + ->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : 'Manual entry'; }) + ->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); }) + ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); }) + ->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); }) + ->make(); + } + + public function quoteIndex() + { + $invitation = $this->getInvitation(); + $account = $invitation->account; + $color = $account->primary_color ? $account->primary_color : '#0b4d78'; + + $data = [ + 'color' => $color, + 'hideLogo' => $account->isWhiteLabel(), + 'title' => trans('texts.quotes'), + 'entityType' => ENTITY_QUOTE, + 'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']), + ]; + + return response()->view('public_list', $data); + } + + + public function quoteDatatable() + { + $invitation = $this->getInvitation(); + + return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, Input::get('sSearch')); + } + + private function getInvitation() + { + $invitationKey = session('invitation_key'); + + if (!$invitationKey) { + app()->abort(404); + } + + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first(); + + if (!$invitation || $invitation->is_deleted) { + app()->abort(404); + } + + $invoice = $invitation->invoice; + + if (!$invoice || $invoice->is_deleted) { + app()->abort(404); + } + + return $invitation; + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 07acaa7eb0b0..81445cc089db 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -67,28 +67,6 @@ class QuoteController extends BaseController return View::make('list', $data); } - public function clientIndex() - { - $invitationKey = Session::get('invitation_key'); - if (!$invitationKey) { - app()->abort(404); - } - - $invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first(); - $account = $invitation->account; - $color = $account->primary_color ? $account->primary_color : '#0b4d78'; - - $data = [ - 'color' => $color, - 'hideLogo' => $account->isWhiteLabel(), - 'title' => trans('texts.quotes'), - 'entityType' => ENTITY_QUOTE, - 'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']), - ]; - - return View::make('public_list', $data); - } - public function getDatatable($clientPublicId = null) { $accountId = Auth::user()->account_id; @@ -97,25 +75,6 @@ class QuoteController extends BaseController return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search); } - public function getClientDatatable() - { - $search = Input::get('sSearch'); - $invitationKey = Session::get('invitation_key'); - $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first(); - - if (!$invitation || $invitation->is_deleted) { - return []; - } - - $invoice = $invitation->invoice; - - if (!$invoice || $invoice->is_deleted) { - return []; - } - - return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, $search); - } - public function create($clientPublicId = 0) { if (!Utils::isPro()) { diff --git a/app/Http/Controllers/old/HomeController.php b/app/Http/Controllers/old/HomeController.php deleted file mode 100644 index 2050070ab5ef..000000000000 --- a/app/Http/Controllers/old/HomeController.php +++ /dev/null @@ -1,36 +0,0 @@ -middleware('auth'); - } - - /** - * Show the application dashboard to the user. - * - * @return Response - */ - public function index() - { - return view('home'); - } - -} diff --git a/app/Http/Controllers/old/WelcomeController.php b/app/Http/Controllers/old/WelcomeController.php deleted file mode 100644 index c7da91c94522..000000000000 --- a/app/Http/Controllers/old/WelcomeController.php +++ /dev/null @@ -1,36 +0,0 @@ -middleware('guest'); - } - - /** - * Show the application welcome screen to the user. - * - * @return Response - */ - public function index() - { - return view('welcome'); - } - -} diff --git a/app/Http/routes.php b/app/Http/routes.php index 2ec246b7ce42..1c914e18267c 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -48,12 +48,14 @@ Route::get('approve/{invitation_key}', 'QuoteController@approve'); Route::get('payment/{invitation_key}/{payment_type?}', 'PaymentController@show_payment'); Route::post('payment/{invitation_key}', 'PaymentController@do_payment'); Route::get('complete', 'PaymentController@offsite_payment'); -Route::get('client/quotes', 'QuoteController@clientIndex'); -Route::get('client/invoices', 'InvoiceController@clientIndex'); -Route::get('client/payments', 'PaymentController@clientIndex'); -Route::get('api/client.quotes', array('as'=>'api.client.quotes', 'uses'=>'QuoteController@getClientDatatable')); -Route::get('api/client.invoices', array('as'=>'api.client.invoices', 'uses'=>'InvoiceController@getClientDatatable')); -Route::get('api/client.payments', array('as'=>'api.client.payments', 'uses'=>'PaymentController@getClientDatatable')); +Route::get('client/quotes', 'PublicClientController@quoteIndex'); +Route::get('client/invoices', 'PublicClientController@invoiceIndex'); +Route::get('client/payments', 'PublicClientController@paymentIndex'); +Route::get('client/dashboard', 'PublicClientController@dashboard'); +Route::get('api/client.quotes', array('as'=>'api.client.quotes', 'uses'=>'PublicClientController@quoteDatatable')); +Route::get('api/client.invoices', array('as'=>'api.client.invoices', 'uses'=>'PublicClientController@invoiceDatatable')); +Route::get('api/client.payments', array('as'=>'api.client.payments', 'uses'=>'PublicClientController@paymentDatatable')); +Route::get('api/client.activity', array('as'=>'api.client.activity', 'uses'=>'PublicClientController@activityDatatable')); Route::get('license', 'PaymentController@show_license_payment'); Route::post('license', 'PaymentController@do_license_payment'); diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 4c50b1059955..65cbfb645a24 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -94,11 +94,6 @@ class Utils return isset($_ENV[DEMO_ACCOUNT_ID]) ? $_ENV[DEMO_ACCOUNT_ID] : false; } - public static function isDemo() - { - return Auth::check() && Auth::user()->isDemo(); - } - public static function getNewsFeedResponse($userType = false) { if (!$userType) { @@ -634,6 +629,11 @@ class Utils ]; } + public static function isEmpty($value) + { + return !$value || $value == '0.00' || $value == '0,00'; + } + public static function startsWith($haystack, $needle) { return $needle === "" || strpos($haystack, $needle) === 0; @@ -672,7 +672,8 @@ class Utils fwrite($output, "\n"); } - public static function getFirst($values) { + public static function getFirst($values) + { if (is_array($values)) { return count($values) ? $values[0] : false; } else { @@ -681,7 +682,8 @@ class Utils } // nouns in German and French should be uppercase - public static function transFlowText($key) { + public static function transFlowText($key) + { $str = trans("texts.$key"); if (!in_array(App::getLocale(), ['de', 'fr'])) { $str = strtolower($str); @@ -689,7 +691,8 @@ class Utils return $str; } - public static function getSubdomainPlaceholder() { + public static function getSubdomainPlaceholder() + { $parts = parse_url(SITE_URL); $subdomain = ''; if (isset($parts['host'])) { @@ -701,7 +704,8 @@ class Utils return $subdomain; } - public static function getDomainPlaceholder() { + public static function getDomainPlaceholder() + { $parts = parse_url(SITE_URL); $domain = ''; if (isset($parts['host'])) { @@ -719,7 +723,8 @@ class Utils return $domain; } - public static function replaceSubdomain($domain, $subdomain) { + public static function replaceSubdomain($domain, $subdomain) + { $parsedUrl = parse_url($domain); $host = explode('.', $parsedUrl['host']); if (count($host) > 0) { @@ -729,11 +734,61 @@ class Utils return $domain; } - public static function splitName($name) { + public static function splitName($name) + { $name = trim($name); $lastName = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name); - $firstName = trim( preg_replace('#'.$lastName.'#', '', $name ) ); + $firstName = trim(preg_replace('#'.$lastName.'#', '', $name)); return array($firstName, $lastName); } + public static function decodePDF($string) + { + $string = str_replace('data:application/pdf;base64,', '', $string); + return base64_decode($string); + } + + public static function cityStateZip($city, $state, $postalCode, $swap) + { + $str = $city; + + if ($state) { + if ($str) { + $str .= ', '; + } + $str .= $state; + } + + if ($swap) { + return $postalCode . ' ' . $str; + } else { + return $str . ' ' . $postalCode; + } + } + + public static function formatWebsite($website) + { + if (!$website) { + return ''; + } + + $link = $website; + $title = $website; + $prefix = 'http://'; + + if (strlen($link) > 7 && substr($link, 0, 7) === $prefix) { + $title = substr($title, 7); + } else { + $link = $prefix.$link; + } + + return link_to($link, $title, array('target' => '_blank')); + } + + public static function wrapAdjustment($adjustment, $currencyId) + { + $class = $adjustment <= 0 ? 'success' : 'default'; + $adjustment = Utils::formatMoney($adjustment, $currencyId); + return "

$adjustment

"; + } } diff --git a/app/Listeners/HandleUserSettingsChanged.php b/app/Listeners/HandleUserSettingsChanged.php index 993e30141db0..42598334990f 100644 --- a/app/Listeners/HandleUserSettingsChanged.php +++ b/app/Listeners/HandleUserSettingsChanged.php @@ -6,6 +6,7 @@ use App\Events\UserSettingsChanged; use App\Ninja\Repositories\AccountRepository; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldBeQueued; +use App\Ninja\Mailers\UserMailer; class HandleUserSettingsChanged { @@ -14,9 +15,10 @@ class HandleUserSettingsChanged { * * @return void */ - public function __construct(AccountRepository $accountRepo) + public function __construct(AccountRepository $accountRepo, UserMailer $userMailer) { $this->accountRepo = $accountRepo; + $this->userMailer = $userMailer; } /** @@ -27,12 +29,19 @@ class HandleUserSettingsChanged { */ public function handle(UserSettingsChanged $event) { - if (Auth::check()) { - $account = Auth::user()->account; - $account->loadLocalizationSettings(); + if (!Auth::check()) { + return; + } - $users = $this->accountRepo->loadAccounts(Auth::user()->id); - Session::put(SESSION_USER_ACCOUNTS, $users); + $account = Auth::user()->account; + $account->loadLocalizationSettings(); + + $users = $this->accountRepo->loadAccounts(Auth::user()->id); + Session::put(SESSION_USER_ACCOUNTS, $users); + + if ($event->user && $event->user->isEmailBeingChanged()) { + $this->userMailer->sendConfirmation($event->user); + Session::flash('warning', trans('texts.verify_email')); } } diff --git a/app/Models/Account.php b/app/Models/Account.php index 5d64c68deefb..58295bdd3c8e 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -114,6 +114,12 @@ class Account extends Eloquent return $user->getDisplayName(); } + public function getCityState() + { + $swap = $this->country && $this->country->swap_postal_code; + return Utils::cityStateZip($this->city, $this->state, $this->postal_code, $swap); + } + public function getMomentDateTimeFormat() { $format = $this->datetime_format ? $this->datetime_format->format_moment : DEFAULT_DATETIME_MOMENT_FORMAT; @@ -158,12 +164,10 @@ class Account extends Eloquent return false; } - /* public function hasLogo() { - file_exists($this->getLogoPath()); + return file_exists($this->getLogoPath()); } - */ public function getLogoPath() { @@ -426,11 +430,13 @@ class Account extends Eloquent public function getEmailSubject($entityType) { - $field = "email_subject_{$entityType}"; - $value = $this->$field; + if ($this->isPro()) { + $field = "email_subject_{$entityType}"; + $value = $this->$field; - if ($value) { - return $value; + if ($value) { + return $value; + } } return $this->getDefaultEmailSubject($entityType); @@ -455,13 +461,15 @@ class Account extends Eloquent public function getEmailTemplate($entityType, $message = false) { - $field = "email_template_{$entityType}"; - $template = $this->$field; + if ($this->isPro()) { + $field = "email_template_{$entityType}"; + $template = $this->$field; - if ($template) { - return $template; + if ($template) { + return $template; + } } - + return $this->getDefaultEmailTemplate($entityType, $message); } @@ -503,6 +511,43 @@ class Account extends Eloquent return $url; } + + public function checkSubdomain($host) + { + if (!$this->subdomain) { + return true; + } + + $server = explode('.', $host); + $subdomain = $server[0]; + + if (!in_array($subdomain, ['app', 'www']) && $subdomain != $this->subdomain) { + return false; + } + + return true; + } + + public function showCustomField($field, $entity) + { + if ($this->isPro()) { + return $this->$field ? true : false; + } + + if (!$entity) { + return false; + } + + // convert (for example) 'custom_invoice_label1' to 'invoice.custom_value1' + $field = str_replace(['invoice_', 'label'], ['', 'value'], $field); + + return Utils::isEmpty($entity->$field) ? false : true; + } + + public function attatchPDF() + { + return $this->isPro() && $this->pdf_email_attachment; + } } Account::updated(function ($account) { diff --git a/app/Models/Client.php b/app/Models/Client.php index 4cc960f77ecf..7fa606bd7664 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -1,5 +1,6 @@ getDisplayName(); } + public function getCityState() + { + $swap = $this->country && $this->country->swap_postal_code; + return Utils::cityStateZip($this->city, $this->state, $this->postal_code, $swap); + } + public function getEntityType() { return ENTITY_CLIENT; @@ -113,25 +120,6 @@ class Client extends EntityModel return false; } - public function getWebsite() - { - if (!$this->website) { - return ''; - } - - $link = $this->website; - $title = $this->website; - $prefix = 'http://'; - - if (strlen($link) > 7 && substr($link, 0, 7) === $prefix) { - $title = substr($title, 7); - } else { - $link = $prefix.$link; - } - - return link_to($link, $title, array('target' => '_blank')); - } - public function getDateCreated() { if ($this->created_at == '0000-00-00 00:00:00') { diff --git a/app/Models/Invitation.php b/app/Models/Invitation.php index b42bcfbaa80b..2d3c58f439e2 100644 --- a/app/Models/Invitation.php +++ b/app/Models/Invitation.php @@ -36,13 +36,15 @@ class Invitation extends EntityModel $url = SITE_URL; $iframe_url = $this->account->iframe_url; - - if ($iframe_url) { - return "{$iframe_url}/?{$this->invitation_key}"; - } elseif ($this->account->subdomain) { - $url = Utils::replaceSubdomain($url, $this->account->subdomain); + + if ($this->account->isPro()) { + if ($iframe_url) { + return "{$iframe_url}/?{$this->invitation_key}"; + } elseif ($this->account->subdomain) { + $url = Utils::replaceSubdomain($url, $this->account->subdomain); + } } - + return "{$url}/view/{$this->invitation_key}"; } diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 9233d3da2188..f407cc3a972f 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -285,37 +285,36 @@ class Invoice extends EntityModel return false; } - public function updateCachedPDF($encodedString = false) + public function getPDFString() { - if (!$encodedString && env('PHANTOMJS_CLOUD_KEY')) { - $invitation = $this->invitations[0]; - $link = $invitation->getLink(); - - $curl = curl_init(); - $jsonEncodedData = json_encode([ - 'targetUrl' => "{$link}?phantomjs=true", - 'requestType' => 'raw', - 'delayTime' => 3000, - ]); - - $opts = [ - CURLOPT_URL => PHANTOMJS_CLOUD . env('PHANTOMJS_CLOUD_KEY'), - CURLOPT_RETURNTRANSFER => true, - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_POST => 1, - CURLOPT_POSTFIELDS => $jsonEncodedData, - CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: '.strlen($jsonEncodedData)], - ]; - - curl_setopt_array($curl, $opts); - $encodedString = strip_tags(curl_exec($curl)); - curl_close($curl); - } - - $encodedString = str_replace('data:application/pdf;base64,', '', $encodedString); - if ($encodedString = base64_decode($encodedString)) { - file_put_contents($this->getPDFPath(), $encodedString); + if (!env('PHANTOMJS_CLOUD_KEY')) { + return false; } + + $invitation = $this->invitations[0]; + $link = $invitation->getLink(); + + $curl = curl_init(); + $jsonEncodedData = json_encode([ + 'targetUrl' => "{$link}?phantomjs=true", + 'requestType' => 'raw', + 'delayTime' => 1000, + ]); + + $opts = [ + CURLOPT_URL => PHANTOMJS_CLOUD . env('PHANTOMJS_CLOUD_KEY'), + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POST => 1, + CURLOPT_POSTFIELDS => $jsonEncodedData, + CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: '.strlen($jsonEncodedData)], + ]; + + curl_setopt_array($curl, $opts); + $encodedString = strip_tags(curl_exec($curl)); + curl_close($curl); + + return Utils::decodePDF($encodedString); } } diff --git a/app/Models/User.php b/app/Models/User.php index de750d4e71dc..1a469db403aa 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -96,11 +96,6 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon return $this->account->isPro(); } - public function isDemo() - { - return $this->account->id == Utils::getDemoAccountId(); - } - public function maxInvoiceDesignId() { return $this->isPro() ? 11 : (Utils::isNinja() ? COUNT_FREE_DESIGNS : COUNT_FREE_DESIGNS_SELF_HOST); @@ -135,27 +130,6 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon { return Session::get(SESSION_COUNTER, 0); } - - /* - public function getPopOverText() - { - if (!Utils::isNinja() || !Auth::check() || Session::has('error')) { - return false; - } - - $count = self::getRequestsCount(); - - if ($count == 1 || $count % 5 == 0) { - if (!Utils::isRegistered()) { - return trans('texts.sign_up_to_save'); - } elseif (!Auth::user()->account->name) { - return trans('texts.set_name'); - } - } - - return false; - } - */ public function afterSave($success = true, $forced = false) { @@ -209,6 +183,12 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon if ($user->password != $user->getOriginal('password')) { $user->failed_logins = 0; } + + // if the user changes their email then they need to reconfirm it + if ($user->isEmailBeingChanged()) { + $user->confirmed = 0; + $user->confirmation_code = str_random(RANDOM_KEY_LENGTH); + } } public static function onUpdatedUser($user) @@ -219,7 +199,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon event(new UserSignedUp()); } - event(new UserSettingsChanged()); + event(new UserSettingsChanged($user)); + } + + public function isEmailBeingChanged() + { + return Utils::isNinjaProd() + && $this->email != $this->getOriginal('email') + && $this->getOriginal('confirmed'); } } diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index e7200609c529..7cb322e01dcd 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -13,7 +13,7 @@ use App\Events\InvoiceSent; class ContactMailer extends Mailer { - public function sendInvoice(Invoice $invoice, $reminder = false) + public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false) { $invoice->load('invitations', 'client.language', 'account'); $entityType = $invoice->getEntityType(); @@ -26,18 +26,17 @@ class ContactMailer extends Mailer } $account->loadLocalizationSettings($client); - - if ($account->pdf_email_attachment) { - $invoice->updateCachedPDF(); - } - $emailTemplate = $account->getEmailTemplate($reminder ?: $entityType); $emailSubject = $account->getEmailSubject($reminder ?: $entityType); $sent = false; + if ($account->attatchPDF() && !$pdfString) { + $pdfString = $invoice->getPDFString(); + } + foreach ($invoice->invitations as $invitation) { - if ($this->sendInvitation($invitation, $invoice, $emailTemplate, $emailSubject)) { + if ($this->sendInvitation($invitation, $invoice, $emailTemplate, $emailSubject, $pdfString)) { $sent = true; } } @@ -51,7 +50,7 @@ class ContactMailer extends Mailer return $sent ?: trans('texts.email_error'); } - private function sendInvitation($invitation, $invoice, $body, $subject) + private function sendInvitation($invitation, $invoice, $body, $subject, $pdfString) { $client = $invoice->client; $account = $invoice->account; @@ -80,11 +79,18 @@ class ContactMailer extends Mailer 'amount' => $invoice->getRequestedAmount() ]; - $data['body'] = $this->processVariables($body, $variables); - $data['link'] = $invitation->getLink(); - $data['entityType'] = $invoice->getEntityType(); - $data['invoiceId'] = $invoice->id; - $data['invitation'] = $invitation; + $data = [ + 'body' => $this->processVariables($body, $variables), + 'link' => $invitation->getLink(), + 'entityType' => $invoice->getEntityType(), + 'invoiceId' => $invoice->id, + 'invitation' => $invitation, + ]; + + if ($account->attatchPDF()) { + $data['pdfString'] = $pdfString; + $data['pdfFileName'] = $invoice->getFileName(); + } $subject = $this->processVariables($subject, $variables); $fromEmail = $user->email; @@ -131,13 +137,16 @@ class ContactMailer extends Mailer $data = [ 'body' => $this->processVariables($emailTemplate, $variables) ]; - $subject = $this->processVariables($emailSubject, $variables); - $data['invoice_id'] = $payment->invoice->id; - if ($invoice->account->pdf_email_attachment) { - $invoice->updateCachedPDF(); + if ($account->attatchPDF()) { + $data['pdfString'] = $invoice->getPDFString(); + $data['pdfFileName'] = $invoice->getFileName(); } + $subject = $this->processVariables($emailSubject, $variables); + $data['invoice_id'] = $payment->invoice->id; + $invoice->updateCachedPDF(); + if ($user->email && $contact->email) { $this->sendTo($contact->email, $user->email, $accountName, $subject, $view, $data); } diff --git a/app/Ninja/Mailers/Mailer.php b/app/Ninja/Mailers/Mailer.php index dfe44015d24a..c258216b33ea 100644 --- a/app/Ninja/Mailers/Mailer.php +++ b/app/Ninja/Mailers/Mailer.php @@ -31,14 +31,8 @@ class Mailer ->subject($subject); // Attach the PDF to the email - if (isset($data['invoiceId'])) { - $invoice = Invoice::with('account')->where('id', '=', $data['invoiceId'])->first(); - if ($invoice->account->pdf_email_attachment && file_exists($invoice->getPDFPath())) { - $message->attach( - $invoice->getPDFPath(), - array('as' => $invoice->getFileName(), 'mime' => 'application/pdf') - ); - } + if (!empty($data['pdfString']) && !empty($data['pdfFileName'])) { + $message->attachData($data['pdfString'], $data['pdfFileName']); } }); @@ -54,7 +48,7 @@ class Mailer $invitation = $data['invitation']; // Track the Postmark message id - if (isset($_ENV['POSTMARK_API_TOKEN'])) { + if (isset($_ENV['POSTMARK_API_TOKEN']) && $response) { $json = $response->json(); $invitation->message_id = $json['MessageID']; } diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index ea5d2251240e..69a9b137d929 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -285,7 +285,7 @@ class InvoiceRepository if (!$publicId) { $invoice->client_id = $data['client_id']; - $invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false; + $invoice->is_recurring = $data['is_recurring'] ? true : false; } if ($invoice->is_recurring) { @@ -576,6 +576,28 @@ class InvoiceRepository return count($invoices); } + public function findInvoiceByInvitation($invitationKey) + { + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first(); + if (!$invitation) { + app()->abort(404, trans('texts.invoice_not_found')); + } + + $invoice = $invitation->invoice; + if (!$invoice || $invoice->is_deleted) { + app()->abort(404, trans('texts.invoice_not_found')); + } + + $invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country'); + $client = $invoice->client; + + if (!$client || $client->is_deleted) { + app()->abort(404, trans('texts.invoice_not_found')); + } + + return $invitation; + } + public function findOpenInvoices($clientId) { return Invoice::scope() @@ -666,10 +688,6 @@ class InvoiceRepository } } - if ($recurInvoice->account->pdf_email_attachment) { - $invoice->updateCachedPDF(); - } - return $invoice; } diff --git a/bootstrap/app.php b/bootstrap/app.php index f50a3f720632..354e5dd90538 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -52,4 +52,10 @@ $app->singleton( | */ +/* +if (strstr($_SERVER['HTTP_USER_AGENT'], 'PhantomJS') && Utils::isNinjaDev()) { + $app->loadEnvironmentFrom('.env.testing'); +} +*/ + return $app; diff --git a/composer.lock b/composer.lock index fa625eb6b2cd..7c1534c5c2ea 100644 --- a/composer.lock +++ b/composer.lock @@ -1646,12 +1646,12 @@ "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "44c9a6bb292e50cf8a1e4b5030c7954c2709c089" + "reference": "e6c9cd03d6b2a870e74da03332feeb97d477fc87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/44c9a6bb292e50cf8a1e4b5030c7954c2709c089", - "reference": "44c9a6bb292e50cf8a1e4b5030c7954c2709c089", + "url": "https://api.github.com/repos/Intervention/image/zipball/e6c9cd03d6b2a870e74da03332feeb97d477fc87", + "reference": "e6c9cd03d6b2a870e74da03332feeb97d477fc87", "shasum": "" }, "require": { @@ -1700,7 +1700,7 @@ "thumbnail", "watermark" ], - "time": "2015-08-30 15:37:50" + "time": "2015-10-12 08:42:50" }, { "name": "ircmaxell/password-compat", @@ -2312,12 +2312,12 @@ "source": { "type": "git", "url": "https://github.com/lokielse/omnipay-alipay.git", - "reference": "87622e8549b50773a8db83c93c3ad9a22e618991" + "reference": "cbfbee089e0a84a58c73e9d3794894b81a6a82d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/87622e8549b50773a8db83c93c3ad9a22e618991", - "reference": "87622e8549b50773a8db83c93c3ad9a22e618991", + "url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/cbfbee089e0a84a58c73e9d3794894b81a6a82d6", + "reference": "cbfbee089e0a84a58c73e9d3794894b81a6a82d6", "shasum": "" }, "require": { @@ -2353,7 +2353,7 @@ "payment", "purchase" ], - "time": "2015-09-15 16:43:43" + "time": "2015-10-07 09:33:48" }, { "name": "maximebf/debugbar", @@ -6199,16 +6199,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "2.2.3", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef1ca6835468857944d5c3b48fa503d5554cff2f" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef1ca6835468857944d5c3b48fa503d5554cff2f", - "reference": "ef1ca6835468857944d5c3b48fa503d5554cff2f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -6257,7 +6257,7 @@ "testing", "xunit" ], - "time": "2015-09-14 06:51:16" + "time": "2015-10-06 15:47:00" }, { "name": "phpunit/php-file-iterator", @@ -6439,16 +6439,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.10", + "version": "4.8.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "463163747474815c5ccd4ae12b5b355ec12158e8" + "reference": "00194eb95989190a73198390ceca081ad3441a7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/463163747474815c5ccd4ae12b5b355ec12158e8", - "reference": "463163747474815c5ccd4ae12b5b355ec12158e8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00194eb95989190a73198390ceca081ad3441a7f", + "reference": "00194eb95989190a73198390ceca081ad3441a7f", "shasum": "" }, "require": { @@ -6507,7 +6507,7 @@ "testing", "xunit" ], - "time": "2015-10-01 09:14:30" + "time": "2015-10-12 03:36:47" }, { "name": "phpunit/phpunit-mock-objects", @@ -6799,16 +6799,16 @@ }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -6846,7 +6846,7 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12 03:26:01" }, { "name": "sebastian/recursion-context", diff --git a/config/queue.php b/config/queue.php index 9c39a13644a1..30e8e8b9d10b 100644 --- a/config/queue.php +++ b/config/queue.php @@ -59,10 +59,10 @@ return [ 'iron' => [ 'driver' => 'iron', - 'host' => 'mq-aws-us-east-1.iron.io', - 'token' => 'your-token', - 'project' => 'your-project-id', - 'queue' => 'your-queue-name', + 'host' => env('QUEUE_HOST', 'mq-aws-us-east-1.iron.io'), + 'token' => env('QUEUE_TOKEN'), + 'project' => env('QUEUE_PROJECT'), + 'queue' => env('QUEUE_NAME'), 'encrypt' => true, ], diff --git a/public/css/bootstrap.splash.css b/public/css/bootstrap.splash.css deleted file mode 100644 index f4d6a1e3b90e..000000000000 --- a/public/css/bootstrap.splash.css +++ /dev/null @@ -1,11 +0,0 @@ -/*! - * Bootstrap v3.0.3 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden],template{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a{background:transparent;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace, serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important;} a,a:visited{text-decoration:underline;} a[href]:after{content:" (" attr(href) ")";} abbr[title]:after{content:" (" attr(title) ")";} a[href^="javascript:"]:after,a[href^="#"]:after{content:"";} pre,blockquote{border:1px solid #999;page-break-inside:avoid;} thead{display:table-header-group;} tr,img{page-break-inside:avoid;} img{max-width:100% !important;} @page {margin:2cm .5cm;}p,h2,h3{orphans:3;widows:3;} h2,h3{page-break-after:avoid;} select{background:#fff !important;} .navbar{display:none;} .table td,.table th{background-color:#fff !important;} .btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important;} .label{border:1px solid #000;} .table{border-collapse:collapse !important;} .table-bordered th,.table-bordered td{border:1px solid #ddd !important;}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0, 0, 0, 0);}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#4f4747;background-color:#f1f1f1;}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;}a{color:#2299c0;text-decoration:none;}a:hover,a:focus{color:#16657f;text-decoration:underline;}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}img{vertical-align:middle;}.img-responsive{display:block;max-width:100%;height:auto;}.img-rounded{border-radius:6px;}.img-thumbnail{padding:4px;line-height:1.428571429;background-color:#f1f1f1;border:1px solid #dddddd;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;display:inline-block;max-width:100%;height:auto;}.img-circle{border-radius:50%;}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee;}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999999;}h1,h2,h3{margin-top:20px;margin-bottom:10px;}h1 small,h2 small,h3 small,h1 .small,h2 .small,h3 .small{font-size:65%;}h4,h5,h6{margin-top:10px;margin-bottom:10px;}h4 small,h5 small,h6 small,h4 .small,h5 .small,h6 .small{font-size:75%;}h1,.h1{font-size:36px;}h2,.h2{font-size:30px;}h3,.h3{font-size:24px;}h4,.h4{font-size:18px;}h5,.h5{font-size:14px;}h6,.h6{font-size:12px;}p{margin:0 0 10px;}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4;}@media (min-width:768px){.lead{font-size:21px;}}small,.small{font-size:85%;}cite{font-style:normal;}.text-muted{color:#999999;}.text-primary{color:#edd71e;}.text-primary:hover{color:#c8b410;}.text-warning{color:#8a6d3b;}.text-warning:hover{color:#66512c;}.text-danger{color:#a94442;}.text-danger:hover{color:#843534;}.text-success{color:#3c763d;}.text-success:hover{color:#2b542c;}.text-info{color:#31708f;}.text-info:hover{color:#245269;}.text-left{text-align:left;}.text-right{text-align:right;}.text-center{text-align:center;}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eeeeee;}ul,ol{margin-top:0;margin-bottom:10px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:0;}.list-unstyled{padding-left:0;list-style:none;}.list-inline{padding-left:0;list-style:none;}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px;}.list-inline>li:first-child{padding-left:0;}dl{margin-top:0;margin-bottom:20px;}dt,dd{line-height:1.428571429;}dt{font-weight:bold;}dd{margin-left:0;}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} .dl-horizontal dd{margin-left:180px;}.dl-horizontal dd:before,.dl-horizontal dd:after{content:" ";display:table;} .dl-horizontal dd:after{clear:both;} .dl-horizontal dd:before,.dl-horizontal dd:after{content:" ";display:table;} .dl-horizontal dd:after{clear:both;}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999;}.initialism{font-size:90%;text-transform:uppercase;}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eeeeee;}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25;}blockquote p:last-child{margin-bottom:0;}blockquote small,blockquote .small{display:block;line-height:1.428571429;color:#999999;}blockquote small:before,blockquote .small:before{content:'\2014 \00A0';}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small,blockquote.pull-right .small{text-align:right;}blockquote.pull-right small:before,blockquote.pull-right .small:before{content:'';}blockquote.pull-right small:after,blockquote.pull-right .small:after{content:'\00A0 \2014';}blockquote:before,blockquote:after{content:"";}address{margin-bottom:20px;font-style:normal;line-height:1.428571429;}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px;}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:4px;}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0;}.pre-scrollable{max-height:340px;overflow-y:scroll;}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px;}.container:before,.container:after{content:" ";display:table;}.container:after{clear:both;}.container:before,.container:after{content:" ";display:table;}.container:after{clear:both;}@media (min-width:768px){.container{width:750px;}}@media (min-width:992px){.container{width:970px;}}@media (min-width:1200px){.container{width:1170px;}}.row{margin-left:-15px;margin-right:-15px;}.row:before,.row:after{content:" ";display:table;}.row:after{clear:both;}.row:before,.row:after{content:" ";display:table;}.row:after{clear:both;}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px;}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left;}.col-xs-12{width:100%;}.col-xs-11{width:91.66666666666666%;}.col-xs-10{width:83.33333333333334%;}.col-xs-9{width:75%;}.col-xs-8{width:66.66666666666666%;}.col-xs-7{width:58.333333333333336%;}.col-xs-6{width:50%;}.col-xs-5{width:41.66666666666667%;}.col-xs-4{width:33.33333333333333%;}.col-xs-3{width:25%;}.col-xs-2{width:16.666666666666664%;}.col-xs-1{width:8.333333333333332%;}.col-xs-pull-12{right:100%;}.col-xs-pull-11{right:91.66666666666666%;}.col-xs-pull-10{right:83.33333333333334%;}.col-xs-pull-9{right:75%;}.col-xs-pull-8{right:66.66666666666666%;}.col-xs-pull-7{right:58.333333333333336%;}.col-xs-pull-6{right:50%;}.col-xs-pull-5{right:41.66666666666667%;}.col-xs-pull-4{right:33.33333333333333%;}.col-xs-pull-3{right:25%;}.col-xs-pull-2{right:16.666666666666664%;}.col-xs-pull-1{right:8.333333333333332%;}.col-xs-pull-0{right:0%;}.col-xs-push-12{left:100%;}.col-xs-push-11{left:91.66666666666666%;}.col-xs-push-10{left:83.33333333333334%;}.col-xs-push-9{left:75%;}.col-xs-push-8{left:66.66666666666666%;}.col-xs-push-7{left:58.333333333333336%;}.col-xs-push-6{left:50%;}.col-xs-push-5{left:41.66666666666667%;}.col-xs-push-4{left:33.33333333333333%;}.col-xs-push-3{left:25%;}.col-xs-push-2{left:16.666666666666664%;}.col-xs-push-1{left:8.333333333333332%;}.col-xs-push-0{left:0%;}.col-xs-offset-12{margin-left:100%;}.col-xs-offset-11{margin-left:91.66666666666666%;}.col-xs-offset-10{margin-left:83.33333333333334%;}.col-xs-offset-9{margin-left:75%;}.col-xs-offset-8{margin-left:66.66666666666666%;}.col-xs-offset-7{margin-left:58.333333333333336%;}.col-xs-offset-6{margin-left:50%;}.col-xs-offset-5{margin-left:41.66666666666667%;}.col-xs-offset-4{margin-left:33.33333333333333%;}.col-xs-offset-3{margin-left:25%;}.col-xs-offset-2{margin-left:16.666666666666664%;}.col-xs-offset-1{margin-left:8.333333333333332%;}.col-xs-offset-0{margin-left:0%;}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left;} .col-sm-12{width:100%;} .col-sm-11{width:91.66666666666666%;} .col-sm-10{width:83.33333333333334%;} .col-sm-9{width:75%;} .col-sm-8{width:66.66666666666666%;} .col-sm-7{width:58.333333333333336%;} .col-sm-6{width:50%;} .col-sm-5{width:41.66666666666667%;} .col-sm-4{width:33.33333333333333%;} .col-sm-3{width:25%;} .col-sm-2{width:16.666666666666664%;} .col-sm-1{width:8.333333333333332%;} .col-sm-pull-12{right:100%;} .col-sm-pull-11{right:91.66666666666666%;} .col-sm-pull-10{right:83.33333333333334%;} .col-sm-pull-9{right:75%;} .col-sm-pull-8{right:66.66666666666666%;} .col-sm-pull-7{right:58.333333333333336%;} .col-sm-pull-6{right:50%;} .col-sm-pull-5{right:41.66666666666667%;} .col-sm-pull-4{right:33.33333333333333%;} .col-sm-pull-3{right:25%;} .col-sm-pull-2{right:16.666666666666664%;} .col-sm-pull-1{right:8.333333333333332%;} .col-sm-pull-0{right:0%;} .col-sm-push-12{left:100%;} .col-sm-push-11{left:91.66666666666666%;} .col-sm-push-10{left:83.33333333333334%;} .col-sm-push-9{left:75%;} .col-sm-push-8{left:66.66666666666666%;} .col-sm-push-7{left:58.333333333333336%;} .col-sm-push-6{left:50%;} .col-sm-push-5{left:41.66666666666667%;} .col-sm-push-4{left:33.33333333333333%;} .col-sm-push-3{left:25%;} .col-sm-push-2{left:16.666666666666664%;} .col-sm-push-1{left:8.333333333333332%;} .col-sm-push-0{left:0%;} .col-sm-offset-12{margin-left:100%;} .col-sm-offset-11{margin-left:91.66666666666666%;} .col-sm-offset-10{margin-left:83.33333333333334%;} .col-sm-offset-9{margin-left:75%;} .col-sm-offset-8{margin-left:66.66666666666666%;} .col-sm-offset-7{margin-left:58.333333333333336%;} .col-sm-offset-6{margin-left:50%;} .col-sm-offset-5{margin-left:41.66666666666667%;} .col-sm-offset-4{margin-left:33.33333333333333%;} .col-sm-offset-3{margin-left:25%;} .col-sm-offset-2{margin-left:16.666666666666664%;} .col-sm-offset-1{margin-left:8.333333333333332%;} .col-sm-offset-0{margin-left:0%;}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left;} .col-md-12{width:100%;} .col-md-11{width:91.66666666666666%;} .col-md-10{width:83.33333333333334%;} .col-md-9{width:75%;} .col-md-8{width:66.66666666666666%;} .col-md-7{width:58.333333333333336%;} .col-md-6{width:50%;} .col-md-5{width:41.66666666666667%;} .col-md-4{width:33.33333333333333%;} .col-md-3{width:25%;} .col-md-2{width:16.666666666666664%;} .col-md-1{width:8.333333333333332%;} .col-md-pull-12{right:100%;} .col-md-pull-11{right:91.66666666666666%;} .col-md-pull-10{right:83.33333333333334%;} .col-md-pull-9{right:75%;} .col-md-pull-8{right:66.66666666666666%;} .col-md-pull-7{right:58.333333333333336%;} .col-md-pull-6{right:50%;} .col-md-pull-5{right:41.66666666666667%;} .col-md-pull-4{right:33.33333333333333%;} .col-md-pull-3{right:25%;} .col-md-pull-2{right:16.666666666666664%;} .col-md-pull-1{right:8.333333333333332%;} .col-md-pull-0{right:0%;} .col-md-push-12{left:100%;} .col-md-push-11{left:91.66666666666666%;} .col-md-push-10{left:83.33333333333334%;} .col-md-push-9{left:75%;} .col-md-push-8{left:66.66666666666666%;} .col-md-push-7{left:58.333333333333336%;} .col-md-push-6{left:50%;} .col-md-push-5{left:41.66666666666667%;} .col-md-push-4{left:33.33333333333333%;} .col-md-push-3{left:25%;} .col-md-push-2{left:16.666666666666664%;} .col-md-push-1{left:8.333333333333332%;} .col-md-push-0{left:0%;} .col-md-offset-12{margin-left:100%;} .col-md-offset-11{margin-left:91.66666666666666%;} .col-md-offset-10{margin-left:83.33333333333334%;} .col-md-offset-9{margin-left:75%;} .col-md-offset-8{margin-left:66.66666666666666%;} .col-md-offset-7{margin-left:58.333333333333336%;} .col-md-offset-6{margin-left:50%;} .col-md-offset-5{margin-left:41.66666666666667%;} .col-md-offset-4{margin-left:33.33333333333333%;} .col-md-offset-3{margin-left:25%;} .col-md-offset-2{margin-left:16.666666666666664%;} .col-md-offset-1{margin-left:8.333333333333332%;} .col-md-offset-0{margin-left:0%;}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left;} .col-lg-12{width:100%;} .col-lg-11{width:91.66666666666666%;} .col-lg-10{width:83.33333333333334%;} .col-lg-9{width:75%;} .col-lg-8{width:66.66666666666666%;} .col-lg-7{width:58.333333333333336%;} .col-lg-6{width:50%;} .col-lg-5{width:41.66666666666667%;} .col-lg-4{width:33.33333333333333%;} .col-lg-3{width:25%;} .col-lg-2{width:16.666666666666664%;} .col-lg-1{width:8.333333333333332%;} .col-lg-pull-12{right:100%;} .col-lg-pull-11{right:91.66666666666666%;} .col-lg-pull-10{right:83.33333333333334%;} .col-lg-pull-9{right:75%;} .col-lg-pull-8{right:66.66666666666666%;} .col-lg-pull-7{right:58.333333333333336%;} .col-lg-pull-6{right:50%;} .col-lg-pull-5{right:41.66666666666667%;} .col-lg-pull-4{right:33.33333333333333%;} .col-lg-pull-3{right:25%;} .col-lg-pull-2{right:16.666666666666664%;} .col-lg-pull-1{right:8.333333333333332%;} .col-lg-pull-0{right:0%;} .col-lg-push-12{left:100%;} .col-lg-push-11{left:91.66666666666666%;} .col-lg-push-10{left:83.33333333333334%;} .col-lg-push-9{left:75%;} .col-lg-push-8{left:66.66666666666666%;} .col-lg-push-7{left:58.333333333333336%;} .col-lg-push-6{left:50%;} .col-lg-push-5{left:41.66666666666667%;} .col-lg-push-4{left:33.33333333333333%;} .col-lg-push-3{left:25%;} .col-lg-push-2{left:16.666666666666664%;} .col-lg-push-1{left:8.333333333333332%;} .col-lg-push-0{left:0%;} .col-lg-offset-12{margin-left:100%;} .col-lg-offset-11{margin-left:91.66666666666666%;} .col-lg-offset-10{margin-left:83.33333333333334%;} .col-lg-offset-9{margin-left:75%;} .col-lg-offset-8{margin-left:66.66666666666666%;} .col-lg-offset-7{margin-left:58.333333333333336%;} .col-lg-offset-6{margin-left:50%;} .col-lg-offset-5{margin-left:41.66666666666667%;} .col-lg-offset-4{margin-left:33.33333333333333%;} .col-lg-offset-3{margin-left:25%;} .col-lg-offset-2{margin-left:16.666666666666664%;} .col-lg-offset-1{margin-left:8.333333333333332%;} .col-lg-offset-0{margin-left:0%;}}.clearfix:before,.clearfix:after{content:" ";display:table;}.clearfix:after{clear:both;}.center-block{display:block;margin-left:auto;margin-right:auto;}.pull-right{float:right !important;}.pull-left{float:left !important;}.hide{display:none !important;}.show{display:block !important;}.invisible{visibility:hidden;}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}.hidden{display:none !important;visibility:hidden !important;}.affix{position:fixed;}@-ms-viewport{width:device-width;}.visible-xs,tr.visible-xs,th.visible-xs,td.visible-xs{display:none !important;}@media (max-width:767px){.visible-xs{display:block !important;}table.visible-xs{display:table;} tr.visible-xs{display:table-row !important;} th.visible-xs,td.visible-xs{display:table-cell !important;}}@media (min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block !important;}table.visible-xs.visible-sm{display:table;} tr.visible-xs.visible-sm{display:table-row !important;} th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell !important;}}@media (min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block !important;}table.visible-xs.visible-md{display:table;} tr.visible-xs.visible-md{display:table-row !important;} th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell !important;}}@media (min-width:1200px){.visible-xs.visible-lg{display:block !important;}table.visible-xs.visible-lg{display:table;} tr.visible-xs.visible-lg{display:table-row !important;} th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell !important;}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none !important;}@media (max-width:767px){.visible-sm.visible-xs{display:block !important;}table.visible-sm.visible-xs{display:table;} tr.visible-sm.visible-xs{display:table-row !important;} th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell !important;}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important;}table.visible-sm{display:table;} tr.visible-sm{display:table-row !important;} th.visible-sm,td.visible-sm{display:table-cell !important;}}@media (min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block !important;}table.visible-sm.visible-md{display:table;} tr.visible-sm.visible-md{display:table-row !important;} th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell !important;}}@media (min-width:1200px){.visible-sm.visible-lg{display:block !important;}table.visible-sm.visible-lg{display:table;} tr.visible-sm.visible-lg{display:table-row !important;} th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell !important;}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none !important;}@media (max-width:767px){.visible-md.visible-xs{display:block !important;}table.visible-md.visible-xs{display:table;} tr.visible-md.visible-xs{display:table-row !important;} th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell !important;}}@media (min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block !important;}table.visible-md.visible-sm{display:table;} tr.visible-md.visible-sm{display:table-row !important;} th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell !important;}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important;}table.visible-md{display:table;} tr.visible-md{display:table-row !important;} th.visible-md,td.visible-md{display:table-cell !important;}}@media (min-width:1200px){.visible-md.visible-lg{display:block !important;}table.visible-md.visible-lg{display:table;} tr.visible-md.visible-lg{display:table-row !important;} th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell !important;}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none !important;}@media (max-width:767px){.visible-lg.visible-xs{display:block !important;}table.visible-lg.visible-xs{display:table;} tr.visible-lg.visible-xs{display:table-row !important;} th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell !important;}}@media (min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block !important;}table.visible-lg.visible-sm{display:table;} tr.visible-lg.visible-sm{display:table-row !important;} th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell !important;}}@media (min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block !important;}table.visible-lg.visible-md{display:table;} tr.visible-lg.visible-md{display:table-row !important;} th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell !important;}}@media (min-width:1200px){.visible-lg{display:block !important;}table.visible-lg{display:table;} tr.visible-lg{display:table-row !important;} th.visible-lg,td.visible-lg{display:table-cell !important;}}.hidden-xs{display:block !important;}table.hidden-xs{display:table;}tr.hidden-xs{display:table-row !important;}th.hidden-xs,td.hidden-xs{display:table-cell !important;}@media (max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none !important;}}@media (min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none !important;}}@media (min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,tr.hidden-xs.hidden-md,th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none !important;}}@media (min-width:1200px){.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none !important;}}.hidden-sm{display:block !important;}table.hidden-sm{display:table;}tr.hidden-sm{display:table-row !important;}th.hidden-sm,td.hidden-sm{display:table-cell !important;}@media (max-width:767px){.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none !important;}}@media (min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none !important;}}@media (min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,tr.hidden-sm.hidden-md,th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none !important;}}@media (min-width:1200px){.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none !important;}}.hidden-md{display:block !important;}table.hidden-md{display:table;}tr.hidden-md{display:table-row !important;}th.hidden-md,td.hidden-md{display:table-cell !important;}@media (max-width:767px){.hidden-md.hidden-xs,tr.hidden-md.hidden-xs,th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none !important;}}@media (min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,tr.hidden-md.hidden-sm,th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none !important;}}@media (min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none !important;}}@media (min-width:1200px){.hidden-md.hidden-lg,tr.hidden-md.hidden-lg,th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none !important;}}.hidden-lg{display:block !important;}table.hidden-lg{display:table;}tr.hidden-lg{display:table-row !important;}th.hidden-lg,td.hidden-lg{display:table-cell !important;}@media (max-width:767px){.hidden-lg.hidden-xs,tr.hidden-lg.hidden-xs,th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none !important;}}@media (min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm,tr.hidden-lg.hidden-sm,th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none !important;}}@media (min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md,tr.hidden-lg.hidden-md,th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none !important;}}@media (min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none !important;}}.visible-print,tr.visible-print,th.visible-print,td.visible-print{display:none !important;}@media print{.visible-print{display:block !important;}table.visible-print{display:table;} tr.visible-print{display:table-row !important;} th.visible-print,td.visible-print{display:table-cell !important;} .hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none !important;}} \ No newline at end of file diff --git a/public/css/built.css b/public/css/built.css index 22367aad6388..ca50e4b7f2a6 100644 --- a/public/css/built.css +++ b/public/css/built.css @@ -2464,6 +2464,11 @@ table.dataTable tbody th, table.dataTable tbody td { padding: 10px; } +table.data-table tr { + border-bottom: 1px solid #d0d0d0; + border-top: 1px solid #d0d0d0; +} + .datepicker { padding: 4px !important; margin-top: 1px; diff --git a/public/css/built.public.css b/public/css/built.public.css index 05f86e3361a6..3c54cc6ace64 100644 --- a/public/css/built.public.css +++ b/public/css/built.public.css @@ -779,4 +779,181 @@ div.DTFC_LeftBodyWrapper tbody tr:first-child td { div.DTFC_LeftFootWrapper table { border-top: none; -} \ No newline at end of file +} +body { + font-family: 'Roboto', sans-serif; + font-size: 14px; + background-color: #f8f8f8; +} + + +@media screen and (min-width: 700px) { + .navbar-header { + padding-top: 16px; + padding-bottom: 16px; + } + .navbar li a { + padding: 31px 20px 31px 20px; + } +} + +#footer { + text-align: center +} + +#footer .top { + background: #2e2b2b; + font-size: 12px; + font-weight: 900; + text-transform: uppercase; + padding: 40px 0 27px; +} + +#footer .top li { + display: inline-block; + margin: 0 30px 10px; +} + +#footer .top a { + color: #fff; + text-decoration: none; +} + +#footer .bottom { + border-top: 1px solid #5f5d5d; + background: #211f1f; + font-size: 11px; + font-weight: 400; + color: #636262; + padding: 28px 0; +} + +#footer .bottom a { + color: #636262; +} + +#footer .menu-item-31 a:before { + content: ''; + display: inline-block; + width: 9px; + height: 15px; + background: url({{ asset('images/social/facebook.svg') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +#footer .menu-item-32 a:before { + content: ''; + display: inline-block; + width: 19px; + height: 16px; + background: url({{ asset('images/social/twitter.svg') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +#footer .menu-item-33 a:before { + content: ''; + display: inline-block; + width: 19px; + height: 16px; + background: url({{ asset('images/social/github.png') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +/* Hide bootstrap sort header icons */ +table.data-table thead .sorting:after { content: '' !important } +table.data-table thead .sorting_asc:after { content: '' !important } +table.data-table thead .sorting_desc:after { content: '' !important} +table.data-table thead .sorting_asc_disabled:after { content: '' !important } +table.data-table thead .sorting_desc_disabled:after { content: '' !important } + +.dataTables_length { + padding-left: 20px; + padding-top: 8px; +} + +.dataTables_length label { + font-weight: 500; +} + +@media screen and (min-width: 700px) { + #footer .top { + padding: 27px 0; + } + + #footer .bottom { + padding: 25px 0; + } +} + + + +table.dataTable { border-radius: 3px; border-collapse: collapse; +/*border-spacing: 0;*/} +table.dataTable thead > tr > th, table.invoice-table thead > tr > th { + color:#fff; +} +th:first-child { + border-radius: 3px 0 0 0; + border-left: none; +} +th:last-child { + border-radius: 0 3px 0 0; +} + +tr {border: none;} +td { + padding-top: 16px !important; + padding-bottom: 16px !important; +} + +/*th {border-left: 1px solid #d26b26; }*/ +th {border-left: 1px solid #FFFFFF; } +.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { + vertical-align: middle; + border-top: none; + border-bottom: 1px solid #dfe0e1; +} +table.dataTable.no-footer { + border-bottom: none; +} +.table-striped>tbody>tr:nth-child(odd)>td, +.table-striped>tbody>tr:nth-child(odd)>th { + background-color: #FDFDFD; +} +table.table thead .sorting_asc { + background: url('../images/sort_asc.png') no-repeat 90% 50%; +} +table.table thead .sorting_desc { + background: url('../images/sort_desc.png') no-repeat 90% 50%; +} +table.dataTable thead th, table.dataTable thead td, table.invoice-table thead th, table.invoice-table thead td { + padding: 12px 10px; +} +table.dataTable tbody th, table.dataTable tbody td { + padding: 10px; +} + +.dataTables_wrapper { + padding-top: 16px; +} + +table.table thead > tr > th { + border-bottom-width: 0px; +} + +table td { + max-width: 250px; +} +.pagination>li:first-child>a, .pagination>li:first-child>span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + +/* hide table sorting indicators */ +table.data-table thead .sorting { background: url('') no-repeat center right; } \ No newline at end of file diff --git a/public/css/public.style.css b/public/css/public.style.css new file mode 100644 index 000000000000..59444f3e8b69 --- /dev/null +++ b/public/css/public.style.css @@ -0,0 +1,177 @@ +body { + font-family: 'Roboto', sans-serif; + font-size: 14px; + background-color: #f8f8f8; +} + + +@media screen and (min-width: 700px) { + .navbar-header { + padding-top: 16px; + padding-bottom: 16px; + } + .navbar li a { + padding: 31px 20px 31px 20px; + } +} + +#footer { + text-align: center +} + +#footer .top { + background: #2e2b2b; + font-size: 12px; + font-weight: 900; + text-transform: uppercase; + padding: 40px 0 27px; +} + +#footer .top li { + display: inline-block; + margin: 0 30px 10px; +} + +#footer .top a { + color: #fff; + text-decoration: none; +} + +#footer .bottom { + border-top: 1px solid #5f5d5d; + background: #211f1f; + font-size: 11px; + font-weight: 400; + color: #636262; + padding: 28px 0; +} + +#footer .bottom a { + color: #636262; +} + +#footer .menu-item-31 a:before { + content: ''; + display: inline-block; + width: 9px; + height: 15px; + background: url({{ asset('images/social/facebook.svg') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +#footer .menu-item-32 a:before { + content: ''; + display: inline-block; + width: 19px; + height: 16px; + background: url({{ asset('images/social/twitter.svg') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +#footer .menu-item-33 a:before { + content: ''; + display: inline-block; + width: 19px; + height: 16px; + background: url({{ asset('images/social/github.png') }}) no-repeat; + margin: 0 6px 0 0; + position: relative; + top: 3px; +} + +/* Hide bootstrap sort header icons */ +table.table thead .sorting:after { content: '' !important } +table.table thead .sorting_asc:after { content: '' !important } +table.table thead .sorting_desc:after { content: '' !important } +table.table thead .sorting_asc_disabled:after { content: '' !important } +table.table thead .sorting_desc_disabled:after { content: '' !important } + +.dataTables_length { + padding-left: 20px; + padding-top: 8px; +} + +.dataTables_length label { + font-weight: 500; +} + +@media screen and (min-width: 700px) { + #footer .top { + padding: 27px 0; + } + + #footer .bottom { + padding: 25px 0; + } +} + + + +table.dataTable { border-radius: 3px; border-collapse: collapse; +/*border-spacing: 0;*/} +table.dataTable thead > tr > th, table.invoice-table thead > tr > th { + color:#fff; +} +th:first-child { + border-radius: 3px 0 0 0; + border-left: none; +} +th:last-child { + border-radius: 0 3px 0 0; +} + +tr {border: none;} +td { + padding-top: 16px !important; + padding-bottom: 16px !important; +} + +/*th {border-left: 1px solid #d26b26; }*/ +th {border-left: 1px solid #FFFFFF; } +.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { + vertical-align: middle; + border-top: none; + border-bottom: 1px solid #dfe0e1; +} +table.dataTable.no-footer { + border-bottom: none; +} +.table-striped>tbody>tr:nth-child(odd)>td, +.table-striped>tbody>tr:nth-child(odd)>th { + background-color: #FDFDFD; +} +table.table thead .sorting_asc { + background: url('../images/sort_asc.png') no-repeat 90% 50%; +} +table.table thead .sorting_desc { + background: url('../images/sort_desc.png') no-repeat 90% 50%; +} +table.dataTable thead th, table.dataTable thead td, table.invoice-table thead th, table.invoice-table thead td { + padding: 12px 10px; +} +table.dataTable tbody th, table.dataTable tbody td { + padding: 10px; +} + +.dataTables_wrapper { + padding-top: 16px; +} + +table.table thead > tr > th { + border-bottom-width: 0px; +} + +table td { + max-width: 250px; +} +.pagination>li:first-child>a, .pagination>li:first-child>span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + +/* hide table sorting indicators */ +table.data-table thead .sorting { background: url('') no-repeat center right; } \ No newline at end of file diff --git a/public/css/splash.css b/public/css/splash.css deleted file mode 100644 index bfa1be306403..000000000000 --- a/public/css/splash.css +++ /dev/null @@ -1,1378 +0,0 @@ -body { - font-family: Roboto, sans-serif; - line-height: 1.6; - background-color: #fff; - overflow-x: hidden; - color: #2e2b2b; -} -.center-block { - margin: 0 auto !important; - float: none; -} -.valgin {padding: 0; margin: 0;} -h1, -h2, -.btn { - font-family: Roboto, sans-serif; - font-weight: 900; - line-height: 1.1; - color: #2e2b2b; -} -h1 { - font-size: 56px; - text-transform: uppercase; - color: #fff; -} -h1 img { - margin-right: 10px; - margin-top: -10px; -} -h2 { - font-size: 25px; -} -h3 { - font-size: 16px; - margin-top: 0; - font-weight: 700; - font-family: Roboto, sans-serif; -} -.headline { - border-bottom: 1px solid #eee; - padding-bottom: 10px; - margin-bottom: 15px; -} -.thin { - font-weight: 300; -} -p.first { - font-size: 17px; -} -a, -a .cta h2, -.socicon, -.btn, -a img -{ - -webkit-transition: all .3s ease-in-out; - -moz-transition: all .3s ease-in-out; - -o-transition: all .3s ease-in-out; - transition: all .3s ease-in-out; -} -a:hover { - text-decoration: none; -} -.blue-text { - color: #2299c0; -} -.center { - text-align: center; -} -.white-bg { - background-color: #fff; -} -.form-group { -margin-bottom: 25px; -} -.form-group .glyphicon { - position: absolute; -top: 28px; -left: 15px; -display: block; -width: 50px; -height: 50px; -line-height: 50px; -text-align: center; - color: #bfbfbf; -} -.form-control.with-icon {padding-left: 50px !important;} - -/* Navigation */ - -.navbar { - background: #211f1f; - padding: 40px 0; - border: none; - border-radius: 0; -} -.navbar-brand { - padding: 0; - line-height: 1; - height: auto; -} - .navbar>.container .navbar-brand { - margin-left: 0 !important; - } -ul.navbar-nav { - float: right; - list-style-type: none; - margin: 0; - padding: 0; -} -ul.navbar-nav li { - display: inline; - font-family: Roboto, sans-serif; - font-weight: 900; - text-transform: uppercase; - height: 26px; - line-height: 26px; -} -ul.navbar-nav li a { - color: #fff; - margin-left: 45px; -} -ul.navbar-nav .glyphicon { - color: #ebbe09; -} -ul.navbar-nav li:last-child a { - color: #ebbe09; - margin-left: 5px; -} -ul.navbar-nav li:last-child { - border-left: 1px solid #4f4b4b; - padding-left: 45px; - margin-left: 45px; -} -ul.navbar-nav li:first-child a { - border-left: none; - margin: 0; - padding-left: 0; -} -ul.navbar-nav li a:hover { - color: #ebbe09; - text-decoration: none; -} - -.navbar-nav>li { - float: right; -} -.navbar-nav>li>a { - padding: 0; - display: inline-block; -} -.nav>li>a:hover, .nav>li>a:focus { - background-color: transparent; -} -z.container>.navbar-collapse { - margin-right: -15px; -} -.navbar-top { - padding: 5px 0 0 0; - background: #fff; - border-top: 1px solid #211f1f; -} -.navbar-top ul { - float: right; - margin: 0; -} -.navbar-top ul li { - display: inline-block; - font-size: 12px; - text-transform: uppercase; - margin-left: 30px; - height: 40px; - line-height: 40px; - vertical-align: middle; - float: left; -} -.navbar-top ul li .socicon { - text-transform: none; - margin-top: 1px; -} -.navbar-top ul li a .socicon { - font-size: 13px; - color: #a6a5a5; - display: inline-block; -} -.navbar-top ul li a .socicon:hover { - color: #ebbe09; -} -.navbar-top ul li a { - color: #2e2b2b; -} -.navbar-top ul li a:hover { - color: #ebbe09; -} - - -a .cta h2 { - width: 100%; - height: 63px; - line-height: 63px; - background: #edd71e; - display: inline-block; - color: #1a1818; - text-align: center; - float: left; - margin: 0; - text-transform: uppercase; - font-size: 20px; - font-weight: 900; -} -a .cta h2 span { - width: 63px; - height: 63px; - line-height: 63px; - color: #fff; - background: #ebbe09; - text-align: center; - float: right; - font-weight: 700; - font-size: 20px; - font-family: Roboto, sans-serif; - -webkit-transition: all .1s ease-in-out; - -moz-transition: all .1s ease-in-out; - -o-transition: all .1s ease-in-out; - transition: all .1s ease-in-out; -} -a .cta:hover span { - font-size: 40px; - background: #f2c40a; -} -.hero h1 { - margin: 0; -} -.hero { - text-align: center; - padding: 150px 0; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; -} -.hero4 { - padding: 150px 0; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; -} -.hero5 { - text-align: center; - padding: 150px 0; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; -} -.hero1.background { - background-repeat: no-repeat; - background-position: center center; - /*background-attachment: fixed;*/ - background-size: cover; - min-height: 500px; -} -.hero1 {padding: 0;} -.hero1 h1 { - font-size: 45px; - margin-top: 20px; - margin-bottom: 10px; - color: #1a1818; -} -.hero .caption-side { - background: #fff; - width: 50%; - padding-right: 15px; - position: absolute; - left: 0; - height: 212px; - margin-top: 100px; -} -.hero .caption { - width: 61.5%; - background: #fff; - padding-right: 15px; - position: relative; - padding: 10px 35px 20px 35px; - height: 212px; - border-left: 1px dotted #ccc; - margin-top: 100px; - text-align: left; - color: #1a1818; -} -.hero-secure p {font-size: 20px; text-transform: uppercase; color: #fff;} -.hero-secure p img { vertical-align: baseline; padding-right: 5px;} -section.features-splash, -section.upper-footer { - margin: 70px 0; -} -section.features, section.about, section.team, section.testi { - margin: 0; - padding: 100px 0; -} -section.secure { - padding: 50px 0 100px 0; -} -section.features1 { - padding-bottom: 0; -} -section.features3, section.features5 { - padding-bottom: 100px; -} -section.features1 .col-md-5, section.features4 .col-md-5{ - padding-bottom: 100px; -} -section.features4 { - padding-bottom: 0; -} - -section.features.upper-footer { - background-color: #fad129; - padding: 40px 0; - text-align: center; - } -section.features.upper-footer a .cta h2 { - background-color: #211f1f; - color: #fff; - padding: 0; - } -section.features.upper-footer h2.thin { - line-height: 63px; - float: right; - margin:0; - } - -section.features4, section.team, .card { -background-color: #f4f3f3; -} -section.features4 .col-md-7 img { -float: right; - margin-right: 40px; -} -section.features1 .col-md-7 img, section.features3 .col-md-7 img { - margin-left: 40px; -} -.upper-footer { - background-color: #f8f8f8; - border-top: 1px solid #e6e6e6; -} - -section.upper-footer.white-bg { - margin: 0; - padding: 60px 0; -} -section.features-splash .box { - padding: 20px; - text-align: center; -} -/*Icons*/ - -section.features-splash .icon { - background: #2599c0; - width: 94px; - height: 94px; - border: 8px solid #1d8db3; - text-align: center; - display: table; - margin: 0 auto; -} -section.features .icon { - background: #2599c0; - width: 35px; - height: 35px; - border: 4px solid #1d8db3; - text-align: center; - display: table; - float: left; - line-height: 1; -} - -section.testi.blue { - background-size: auto; - background-repeat:no-repeat; - background-position:bottom; -} - -.twitter-tweet {margin: 0 auto !important; margin-bottom: 30px !important;} - -.icon.open { - background: #32ba8d !important; - border-color: #28ae82 !important; -} -.icon.secure { - background: #2e2b2b !important; - border-color: #161414 !important; -} -section.features .icon.free img { - width: 23px; -} -section.features .icon.open img { - width: 23px; -} -section.features .icon.pdf img { - width: 16px; - float: none; -} -section.features .icon.pay img { - width: 23px; -} -section.blue .icon.free { - background-color: #fff; - border-color: #fff; -} -section.features-splash .two .box h2 { - color: #32ba8d; -} -.icon.pdf { - background: #d2462d !important; - border-color: #c23b23 !important; -} -section.features-splash .three .box h2 { - color: #d2462d; -} -.icon.pay { - background: #fad129 !important; - border-color: #f0c824 !important; -} -section.features-splash .four .box h2 { - color: #f0c824; -} -section.features-splash h2 { - margin: 20px 0 15px; - color: #2599c0; -} -section.features h2 { - display: inline-block; - margin-top: 5px; - padding-left: 15px; - color: #1a1818; -} -.icon .img-wrap { - display: table-cell; - vertical-align: middle; - height: 100%; - padding: 0; -} -.icon img { - vertical-align: middle; -} -section.blue { - background-image: url('../images/bg-blue.jpg'); - background-color: #2387a9; - background-size: cover; - color: #fff; - padding: 140px 0; -} -section.blue .col-md-7 { - text-align: left; -} -section.blue h1 span { - font-size: 30px; - display: block; -} -section.blue h1 { - color: #fff; - line-height: 1.2; - margin-bottom: 20px; - margin-top: 30px; - font-size: 65px; -} -section.blue h2 { - color: #fff; -} -section.blue a { - color: #ffffff; - text-decoration: underline; -} -section.blue p { - margin-top: 15px; -} -section.blue img { - max-width: 100%; -} -section.plans { - padding: 70px 0; -} -section.team h2, -section.plans h2 { - font-size: 25px; - margin: 0 0 25px; - text-transform: none; -} -section.team .col-md-3 h2 { - margin-top: 20px; - margin-bottom: 3px; - font-size: 20px; -} -section.about .screendump { - height: 220px; -} -section.about.white-bg .col-md-5 { - padding-right: 43px; - padding-left: 15px; -} -section.about img, -section.team img { - width: 100%; - min-width: 100%; -} -section.team .col-md-3 { - margin-top: 25px; - padding: 0 20px; -} -section.team .col-md-3 p { - font-size: 12px; - margin-bottom: 20px; -} -section.team .social { - margin: 3px 3px 0 3px; -} -section.team .social.blue {background-color: #2599c0;} -section.team .social.green {background-color: #30ab82;} -section.team .social.red {background-color: #d2462d;} -section.team .social.yellow {background-color: #ebbe09;} -section.team .social img { - margin: 12px 7px; - height: 15px; - display: inline-block; - width: auto; - min-width: 1px; - padding: 0; -} -section.team .img-team:before { - -webkit-box-shadow: inset 0 0 10px 0 rgba(255, 255, 255, 0.3); - box-shadow: inset 0 0 0 7px rgba(255, 255, 255, 0.3); - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - content: ""; -} -section.team .img-team { - z-index: 1000; position: relative; -} -section.team .img-team img {} -section.contact .address .glyphicon, section.contact .address .socicon { - background: #edd71e; - height: 40px; - width: 40px; - line-height: 40px; - text-align: center; - border-radius: 50px; - color: #1a1818; - margin-right: 15px; - display: inline-block; -} - -section.contact .address p { - margin-top: 20px; -} -section.contact .address span.push { - margin-left: 55px; - line-height: 25px; -} - -section.contact .form-control, section.secure .form-control, footer.footer .form-control { - display: block; - width: 100%; - height: 50px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - background-color: #fff; - background-image: none; - border: 1px solid #e0e0e1; - border-radius: 0; - -webkit-box-shadow: inset 0px 0px 8px 5px rgba(50, 50, 50, 0.25); - -moz-box-shadow: inset 0px 0px 8px 5px rgba(50, 50, 50, 0.25); - box-shadow: inset 0px 0px 5px 2px rgba(50, 50, 50, 0.05); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -section.contact textarea.form-control { - height: auto; -} -section.contact form { - margin-top: 30px; -} - -section.secure label { text-transform: uppercase; font-size: 12px; font-weight: 800; margin-bottom: 10px; display: block;} - -section.secure .card {padding: 30px; margin-bottom: 50px;} -section.secure .card p {padding-top: 26px; padding-right: 15px; line-height: 50px;} -section.secure .info {padding-top: 30px;} - - - -section.faq { - padding: 70px 0; -} -section.faq a.expander { - display: block; - font-size: 18px; - font-family: Roboto, sans-serif; - font-weight: 700; - margin-bottom: 10px; -} -/*section.faq .content{display:none;}*/ -section.faq .question { - padding-bottom: 20px; - margin-bottom: 30px; - border-bottom: 1px solid #e0e0e0; -} -section.faq .contact-box { - margin-top: 30px; - padding: 40px; - color: #4f4747; - background: #fad129; -} -section.faq .contact-box h2 { - text-transform: uppercase; - display: block; - float: left; - width: 60%; - margin-top: 0; - margin-bottom: 0; - padding: 2px 0; -} -section.faq .contact-box img { - float: left; - display: block; - margin-right: 20px; - margin-left: 30px; - height: 57px; -} -section.faq .contact-box .col-md-8 { - padding-left: 5px; -} -section.faq .contact-box h2 { - border-right: 1px solid #e4bf28; -} - -section.faq .contact-box a { - color: #2e2b2b; -} -section.faq .contact-box p { - -} - -.btn-primary { - color: #fff; - background-color: #2299c0; - border: none; - text-align: center; - border-radius: 0; - height: 63px; - line-height: 63px; - padding: 0; - width: 100%; - text-align: center; -} -.btn-primary:hover { - background-color: #2299c0; -} - -.btn.green { - background-color: #30ab82; -} -.btn.green:hover { - background-color: #2daa81; -} -.btn-lg { -font-size: 18px; -} -section.contact button span.glyphicon { - background-color: transparent; - color: #fff; - float: right; -} -section.contact .btn span.glyphicon { - background-color: #1e84a5; - height: 63px; - line-height: 63px; - width: 63px; - margin-top: -1px; - -webkit-transition: all .1s ease-in-out; - -moz-transition: all .1s ease-in-out; - -o-transition: all .1s ease-in-out; - transition: all .1s ease-in-out; -} -section.contact .btn:hover span.glyphicon { - font-size: 25px; -} -section.contact textarea:focus, section.secure textarea:focus, -select:focus, -input[type=text]:focus, -input[type=password]:focus, -input[type=datetime]:focus, -input[type=datetime-local]:focus, -input[type=date]:focus, -input[type=month]:focus, -input[type=time]:focus, -input[type=week]:focus, -input[type=number]:focus, -input[type=email]:focus, -input[type=url]:focus, -input[type=search]:focus, -input[type=tel]:focus, -input[type=color]:focus, -.uneditable-input:focus { - -} -section.contact address { - display: inline-block; -} -footer.footer { - background: #211f1f; - padding: 50px 0; - text-align: center; -} -footer.footer h3 { text-align: left; color: #fff; padding-bottom: 12px; margin-bottom: 25px; border-bottom: 1px solid #2c2a2a;} -footer.footer hr { -margin-top: 25px; -margin-bottom: 25px; -border: 0; -border-top: 1px solid #2c2a2a; -} -footer.footer .glyphicon {margin-right: 8px; color: #ebbe09; width: 15px; font-size: 14px;} -footer ul.navbar-vertical { - margin: 0; - padding: 0; - margin-bottom: 30px; -} -footer ul.navbar-vertical li { - display: block; - padding: 2px 0; -} -footer ul.navbar-vertical li a { - color: #a3a2a2; - font-size: 12px; - font-weight: 800; - text-transform: uppercase; -} -footer ul.navbar-vertical li a:hover { - color: #e5e5e5; -} - -footer.footer .social { - margin-bottom: 30px; - width: 100%; - clear: both; - text-align: center; -} - -footer.footer .social img { - margin: 0 3px; -} -footer.footer .social a img:hover { - opacity: 0.6; -} - -footer.footer .social .row1 { - margin-bottom: -8px; -} - -footer.footer form#mad_mimi_signup_form button { - position: absolute; - right: 0; - top: 0; - width: 50px; - height: 50px; - background: #b7b7b6; - border: none; - padding: 0; - border-radius: 0; - text-align: center; - margin-bottom: 30px; -} -footer.footer form#mad_mimi_signup_form button:hover { - background: #7b7a79; -} -footer.footer form#mad_mimi_signup_form button .glyphicon { - position: static; - color: #fff; - font-size: 15px; -width: auto; - margin: 0; -} -footer.footer form#mad_mimi_signup_form .form-group { - position: relative; -} -footer.footer form#mad_mimi_signup_form input { - padding-right: 60px; - background: #393636; - border: none; - color: #b7b7b6; -} - -/* Fonts */ - -.socicon { - font-family: 'socicon' !important; -} -@font-face { - font-family: socicon; - src: url(../fonts/socicon-webfont.eot); - src: url(../fonts/socicon-webfont.eot?#iefix) format(embedded-opentype), url(../fonts/socicon-webfont.woff) format(woff), url(../fonts/socicon-webfont.ttf) format(truetype), url(../fonts/socicon-webfont.svg#sociconregular) format(svg); - font-weight: 400; - font-style: normal; -} - -@media (max-width: 768px) { - - /* Responsive actions */ - .hidden-desktop { - display: block !important; - } - .hidden-phone { - display: none !important; - } - - /* Typo */ - p { - font-size: 12px; - } - p.first { - font-size: 14px; - margin: 0; - } - h1 { - font-size: 30px; - } - h2 { - font-size: 20px; - } - .headline h2 { - margin-top: 0; - } - .headline { - border-bottom: none; - padding-bottom: 0; - margin-bottom: 15px; - } - section.team h2, section.plans h2 { - font-size: 20px; - margin: 0 0 15px; - } - - /* Mobile navigation */ - .navbar { - text-align: center; - padding: 0; - } - .navbar-header { - padding: 15px 0; - } - ul.navbar-nav { - width: 100%; - } - .navbar li.hidden-desktop { - font-weight: 400; - font-size: 11px; - } - ul.navbar-nav li { - float: none; - margin: 0; - height: 30px; - line-height: 30px; - font-size: 12px; - display: block !important; - } - ul.navbar-nav li a { - margin: 0; - display: inline; - width: 100%; - float: none; - padding: 0; - } - ul.navbar-nav li:first-child { - margin-top: 12px; - } - ul.navbar-nav li:first-child a { - margin: 0; - padding: 0; - } - ul.navbar-nav li:last-child { - border-left: none; - padding-left: 0; - margin-left: 0; - margin-bottom: 12px; - } - .navbar-collapse { - border-top: none; - box-shadow: none; - background: #282525; - } - .navbar-toggle { - border: 1px solid #ddd; - margin: 0; - } - .navbar-toggle .icon-bar { - background: #ddd; - } - - ul.navbar-list { - float: none; - margin-top: 10px; - } - .navbar-brand { - margin-top: 6px; - } - .container>.navbar-header { - margin: 0; - } - - /* Sections */ - section.features, section.blue, section, section.secure, section.about, section.team, section.contact, section.faq, section.testi, section.plans { - padding: 40px 0; - margin: 0 !important; - } - - section.features-splash .icon { - width: 50px; - height: 50px; - border: 4px solid #1d8db3; - } - section.features-splash .icon img { - width: 30px; - } - - section.about .col-md-5 { - padding-left: 15px !important; - } - section.faq .question { - padding-bottom: 10px; - margin-bottom: 20px; - } - section.faq a.expander { - font-size: 14px; - } - section.faq .contact-box { - margin-top: 20px; - padding: 25px; - text-align: center; - } - section.faq .contact-box h2 { - float: none; - width: 100%; - margin: 10px 0; - } - section.faq .contact-box img { - float: none; - display: inline-block; - margin-right: 0; - margin-left: 0; - height: 57px; - } - section.faq .contact-box .col-md-8 { - padding-left: 15px; - } - section.faq .contact-box h2 { - border-right: none; - } - section.faq .contact-box p { - margin: 0; - } - section.plans .plans-table { - margin-top: 30px; - font-size: 12px; - } - .plans-table .free .cell { - border-left: 1px solid #dfe0e1; - border-right: 1px solid #dfe0e1; - } - .plans-table .free .cell:first-child { - border-left: 1px solid #9b9b9b; - border-right: 1px solid #9b9b9b; - } - section.plans .plans-table .cell { - display: block; - width: 100%; - } - section.plans .plans-table span { - display: inline-block !important; - } - section.plans .plans-table .hidden-desktop { - display: inline-block !important; - margin-bottom: 0; - margin-right: 10px; - } - section.plans .plans-table .cell { - height: auto; - padding: 14px 0; - } - section.plans .plans-table .free .cell { - padding-right: 0; - } - section.plans .plans-table .free .cell:first-child { - margin-right: 0; - } - section.plans .plans-table .cell .cta { - margin-bottom: 0 !important; - } - section.plans .plans-table .pro { - margin-top: 30px; - } - .plans-table .pro .cell:last-child, .plans-table .free .cell:last-child { - padding: 14px 0 0 0 !important; - } - .plans-table .pro .cell:last-child p { - margin: 0; - padding: 0; - } - section.about img { - margin-top: 20px; - } - section.team .img-team { - width: 60%; - min-width: 60%; - margin: 0 auto; - } - - section.team .col-md-3:last-child p:last-child { - margin-bottom: 0; - } - - /* Heros */ - .hero1.background { - min-height: 100px; - } - .hero .caption { - width: 100%; - background: #fff; - padding: 10px 35px 20px 35px; - height: auto; - border-left: none; - margin-top: 0px; - margin-bottom: 10px; - text-align: center; - } - .hero .caption-side { - display:none; - } - .hero1 h1 { - font-size: 30px; - } - .hero{ - padding: 50px 0; - } - .background { - background-attachment: scroll; - background-size: cover; - background-position: bottom center; - background-repeat: repeat; - min-height: 1px; - padding: 50px 0; - } - section.upper-footer.white-bg { - padding: 30px 0; - } - section.features .col-md-3 .box { - margin-bottom: 10px; - } - - - section.secure .info { - padding-top: 0; - } - section.secure .card { - padding: 15px; - margin-bottom: 40px; - } - section.secure .card p { - padding-top: 0; - padding-right: 15px; - line-height: 1; - } - section.blue h1 { - line-height: 1.2; - margin-bottom: 20px; - margin-top: 0; - font-size: 30px; - } - section.blue h1 span { -font-size: 20px; -} - section.features-splash .box { -padding: 20px 0 0 0; -} - section.features-splash { -margin-top: -20px !important; -} - section.features .col-md-7 img{ - max-width: 100%; - margin: 0; - } - section.features.blue .col-md-7 img, section.features4 .col-md-7 img { - margin-bottom: 30px; - } - section.features1 .col-md-7 img, section.features3 .col-md-7 img, section.features5 .col-md-7 img { - margin-top: 30px; - } - section.features1 .col-md-5, section.features4 .col-md-5, section.features5 .col-md-5 { -padding-bottom: - 0; -} - section.features.upper-footer { -text-align: center; -padding: 20px 0 40px 0; -} - section.features.upper-footer h2.thin { -line-height: 63px; -float: none; - -} -.nitinh-vAlign{ - position: static !important; - } - section.blue .col-md-6 h1 { - border-left: none; - border-right: none; - border-top: 1px dotted #46b9df; - padding: 30px 0; - } - section.blue .col-md-6 h1 span { - font-size: 25px; - font-weight: 100; - display: block; - text-transform: lowercase; - } - section.contact .address { - margin: 0; - text-align: center; - } - section.contact .address p { - text-align: center; - } - section.contact .address .glyphicon, section.contact .address .socicon { - display: block; - margin: 0 auto 7px; - float: none; - } - section.contact .address span.push { - margin-left: 0; - } - section.contact .btn { - margin-bottom: 5px; - } - section.about p { - margin-bottom: 0; - margin-top: 10px; - } - section.about .screendump { - margin-top: 25px; - } - section.about.white-bg .screendump { - margin-top: 0; - margin-top: 0; - margin-bottom: 20px; - } - #contact_form { - margin: 0; - } - #feedbackForm { - margin-top: 15px; - } - - /* Footer */ - footer .navbar-inner { - float: none; - } - footer ul.navbar-list:last-child { - height: auto; - } - footer .social { - float: none; - margin-bottom: 10px; - } - footer .social .socicon { - margin-right: 8px; - } -} -.github { - background-image: url(../images/GitHub.png); - background-size: contain; - background-repeat: no-repeat; - width: 40px; - height: 40px; - display: inline-block; - margin-right: 10px; - float: left; -} -div.fb_iframe_widget { - display: inline; -} -div.fb_iframe_widget > span { - vertical-align: top !important; -} -::selection { - color: #fff; - background: #2e2b2b; -} -::-moz-selection { - color: #fff; - background: #2e2b2b; -} -.plans-table { - text-align: center; - margin: 0 auto; - float: none; - margin-top: 60px; -} -.plans-table .free, -.plans-table .desc { - padding: 0; -} -.plans-table .free .cell { - padding-right: 15px; -} -.plans-table .desc .cell { - text-align: right; - padding-right: 15px; - border-left: 1px solid #dfe0e1; - font-size: 13px; - font-weight: 800; -} -.plans-table .pro .cell { - border-left: 1px solid #cccccc; - border-right: 1px solid #cccccc; -} -.plans-table .cell { - background-color: #fff; - border-top: 1px solid #dfe0e1; - padding: 18px 0; - font-family: Roboto, sans-serif; - height: 60px; -} -.plans-table .cell:nth-child(odd) { - background-color: #fbfbfb; -} -.plans-table .pro .cell:nth-child(odd) { - background-color: #f4f4f4; -} -.plans-table .pro { - background-color: #2299c0; - overflow: hidden; - padding: 0; - -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2); - -moz-box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2); - box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2); -} -.plans-table .free .cell:first-child, -.plans-table .pro .cell:first-child { - color: #fff; - text-transform: uppercase; - font-size: 24px; - font-weight: 800; - line-height: 60px; - padding: 0; - position: relative; - bottom: -1px; - border: none; -} -.plans-table .free .cell:first-child { - background-color: #9b9b9b; - margin-right: 15px; - padding-right: 0; -} -.plans-table .free, -.plans-table .desc, .plans-table .pro { - border-bottom: 1px solid #dfe0e1; -} -.plans-table .pro .cell:first-child { - background-color: #2299c0; -} -.plans-table .pro .cell:last-child { - padding: 0; -} -.plans-table .desc .cell:first-child { - background-color: transparent; - border: none; -} - -.compare-table .glyphicon, -.plans-table .glyphicon { - color: #fff; - border-radius: 50px; - padding: 5px; - font-size: 10px; -} -.compare-table .glyphicon-remove, -.plans-table .glyphicon-remove { - background-color: #da4830; -} -.compare-table .glyphicon-ok, -.plans-table .glyphicon-ok { - background-color: #35c156; -} -.plans-table .glyphicon-star { - border-radius: 0; - background-color: #2e2b2b; - display: block; - width: 60px; - height: 30px; - position: absolute; - top: -5px; - right: -20px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); - padding: 13px 0 0 1px; -} -.plans-table .price { - padding: 0; -} -.plans-table .free .price p { - color: #35c156; -} -.plans-table .pro .price p { - color: #2299c0; -} -.plans-table .price p { - font-size: 40px; - text-transform: uppercase; - font-weight: 800; - margin: 0; - line-height: 55px; -} -.plans-table .price p span { - font-size: 16px; - text-transform: none; - font-weight: 400; -} -.plans-table a .cta h2 { - background: #2299c0; - color: #fff; - margin: 0; -} -.plans-table a .cta h2 span { - background: #1e84a5; -} - - -table.compare-table td { - height: 70px; - vertical-align: middle !important; -} -table.compare-table th { - height: 70px; - vertical-align: middle !important; - text-align: center; - color: white; -} -table.compare-table td:first-child { - text-align: left; -} -table.compare-table-free th { - background-color: #0b4d78; -} -table.compare-table-paid th { - background-color: #e37329; -} - - -@media (min-width: 992px) { - .hide-desktop {display: none !important;} -} - -@media (max-width: 992px) { - .hide-phone { - display: none !important; - } -} - -/* Hide bootstrap sort header icons */ -table.table thead .sorting:after { content: '' !important } -table.table thead .sorting_asc:after { content: '' !important } -table.table thead .sorting_desc:after { content: '' !important} -table.table thead .sorting_asc_disabled:after { content: '' !important } -table.table thead .sorting_desc_disabled:after { content: '' !important } \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css index ddabc40c4928..b9714e2da294 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -114,6 +114,11 @@ table.dataTable tbody th, table.dataTable tbody td { padding: 10px; } +table.data-table tr { + border-bottom: 1px solid #d0d0d0; + border-top: 1px solid #d0d0d0; +} + .datepicker { padding: 4px !important; margin-top: 1px; diff --git a/public/js/built.js b/public/js/built.js index 3b1be8b9d74f..df28ee641dd5 100644 --- a/public/js/built.js +++ b/public/js/built.js @@ -31988,9 +31988,13 @@ NINJA.accountAddress = function(invoice) { {text: account.address2}, {text: cityStatePostal}, {text: account.country ? account.country.name : ''}, - {text: invoice.account.custom_value1 ? invoice.account.custom_label1 + ' ' + invoice.account.custom_value1 : false}, - {text: invoice.account.custom_value2 ? invoice.account.custom_label2 + ' ' + invoice.account.custom_value2 : false} ]; + + if (invoice.is_pro) { + data.push({text: invoice.account.custom_value1 ? invoice.account.custom_label1 + ' ' + invoice.account.custom_value1 : false}); + data.push({text: invoice.account.custom_value2 ? invoice.account.custom_label2 + ' ' + invoice.account.custom_value2 : false}); + } + return NINJA.prepareDataList(data, 'accountAddress'); } diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js index fb0588113fc5..2980f26fa97e 100644 --- a/public/js/pdf.pdfmake.js +++ b/public/js/pdf.pdfmake.js @@ -415,9 +415,13 @@ NINJA.accountAddress = function(invoice) { {text: account.address2}, {text: cityStatePostal}, {text: account.country ? account.country.name : ''}, - {text: invoice.account.custom_value1 ? invoice.account.custom_label1 + ' ' + invoice.account.custom_value1 : false}, - {text: invoice.account.custom_value2 ? invoice.account.custom_label2 + ' ' + invoice.account.custom_value2 : false} ]; + + if (invoice.is_pro) { + data.push({text: invoice.account.custom_value1 ? invoice.account.custom_label1 + ' ' + invoice.account.custom_value1 : false}); + data.push({text: invoice.account.custom_value2 ? invoice.account.custom_label2 + ' ' + invoice.account.custom_value2 : false}); + } + return NINJA.prepareDataList(data, 'accountAddress'); } diff --git a/resources/lang/da/texts.php b/resources/lang/da/texts.php index 34fe4f51939f..1c1aa173ae6c 100644 --- a/resources/lang/da/texts.php +++ b/resources/lang/da/texts.php @@ -815,5 +815,9 @@ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); \ No newline at end of file diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php index 0ab602f7279c..b570c290ddbc 100644 --- a/resources/lang/de/texts.php +++ b/resources/lang/de/texts.php @@ -814,5 +814,9 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 84e9e16fc785..8e6cc99cc112 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -769,7 +769,7 @@ return array( 'iframe_url' => 'Website', 'iframe_url_help1' => 'Copy the following code to a page on your site.', - 'iframe_url_help2' => 'Currently only supported with on-site gateways (ie, Stripe and Authorize.net). You can test the feature by clicking \'View as recipient\' for an invoice.', + 'iframe_url_help2' => 'You can test the feature by clicking \'View as recipient\' for an invoice.', 'auto_bill' => 'Auto Bill', 'military_time' => '24 Hour Time', @@ -814,5 +814,10 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + 'verify_email' => 'Please visit the link in the account confirmation email to verify your email address.', + ); diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php index 4b8071a8fd71..bec202bb0722 100644 --- a/resources/lang/es/texts.php +++ b/resources/lang/es/texts.php @@ -792,5 +792,9 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); diff --git a/resources/lang/es_ES/texts.php b/resources/lang/es_ES/texts.php index af97cee24fd6..b8b9ea552357 100644 --- a/resources/lang/es_ES/texts.php +++ b/resources/lang/es_ES/texts.php @@ -814,5 +814,9 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); \ No newline at end of file diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php index d97faea24311..d37ed36bfe6f 100644 --- a/resources/lang/fr/texts.php +++ b/resources/lang/fr/texts.php @@ -806,5 +806,9 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); diff --git a/resources/lang/fr_CA/texts.php b/resources/lang/fr_CA/texts.php index dd014c28161c..25e1163ef5b4 100644 --- a/resources/lang/fr_CA/texts.php +++ b/resources/lang/fr_CA/texts.php @@ -807,5 +807,9 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index a3022fd5d9da..495c16da9bb5 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -808,5 +808,9 @@ return array( 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', ); diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php index baa7f7c9e3dd..78f1d3f375ad 100644 --- a/resources/lang/lt/texts.php +++ b/resources/lang/lt/texts.php @@ -815,6 +815,10 @@ return array( 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', ); diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php index ae0f3691c751..087ff544e72d 100644 --- a/resources/lang/nb_NO/texts.php +++ b/resources/lang/nb_NO/texts.php @@ -814,4 +814,8 @@ return array( 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + ); \ No newline at end of file diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php index e72ec1aefc20..9813923b9f22 100644 --- a/resources/lang/nl/texts.php +++ b/resources/lang/nl/texts.php @@ -808,5 +808,9 @@ return array( 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', ); diff --git a/resources/lang/pt_BR/texts.php b/resources/lang/pt_BR/texts.php index 29f7084859aa..8bcfab53c6c1 100644 --- a/resources/lang/pt_BR/texts.php +++ b/resources/lang/pt_BR/texts.php @@ -808,5 +808,9 @@ return array( 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', ); diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php index 5754ba7647e0..34c670c66d75 100644 --- a/resources/lang/sv/texts.php +++ b/resources/lang/sv/texts.php @@ -811,5 +811,9 @@ return array( 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', ); diff --git a/resources/views/accounts/details.blade.php b/resources/views/accounts/details.blade.php index ccbda5019553..b47f544140a6 100644 --- a/resources/views/accounts/details.blade.php +++ b/resources/views/accounts/details.blade.php @@ -42,7 +42,7 @@ {!! Former::text('work_phone') !!} {!! Former::file('logo')->max(2, 'MB')->accept('image')->inlineHelp(trans('texts.logo_help')) !!} - @if (file_exists($account->getLogoPath())) + @if ($account->hasLogo())
{!! HTML::image($account->getLogoPath().'?no_cache='.time(), 'Logo', ['width' => 200]) !!}   {{ trans('texts.remove_logo') }} diff --git a/resources/views/accounts/email_templates.blade.php b/resources/views/accounts/email_templates.blade.php deleted file mode 100644 index 71c5a2fcd021..000000000000 --- a/resources/views/accounts/email_templates.blade.php +++ /dev/null @@ -1,187 +0,0 @@ -@extends('accounts.nav') - -@section('head') - @parent - - - -@stop - -@section('content') - @parent - @include('accounts.nav_advanced') - - {!! Former::open()->addClass('col-md-10 col-md-offset-1 warn-on-exit') !!} - {!! Former::populateField('email_template_invoice', $invoiceEmail) !!} - {!! Former::populateField('email_template_quote', $quoteEmail) !!} - {!! Former::populateField('email_template_payment', $paymentEmail) !!} - -
-
-

{!! trans('texts.email_templates') !!}

-
-
-
- -
- - -
-
-
-
- {!! Former::textarea('email_template_invoice')->raw() !!} -
-
-
-
- -
-
-
- {!! Former::textarea('email_template_quote')->raw() !!} -
-
-
-
- - -
-
-
- {!! Former::textarea('email_template_payment')->raw() !!} -
-
-
-
-
- -
-
-
-
- -

 

- -
-
-

{!! trans('texts.reminder_emails') !!}

-
-
-
- -
- - -
-
-
-
- {!! Former::textarea('email_template_invoice')->raw() !!} -
-
-
-
- -
-
-
- {!! Former::textarea('email_template_quote')->raw() !!} -
-
-
-
- - -
-
-
- {!! Former::textarea('email_template_payment')->raw() !!} -
-
-
-
-
- -
-
-
-
- - - - @if (Auth::user()->isPro()) -
- {!! Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk')) !!} -
- @else - - @endif - - {!! Former::close() !!} - - - -@stop diff --git a/resources/views/accounts/invoice_settings.blade.php b/resources/views/accounts/invoice_settings.blade.php index ea878b361bfc..590373bcef60 100644 --- a/resources/views/accounts/invoice_settings.blade.php +++ b/resources/views/accounts/invoice_settings.blade.php @@ -4,6 +4,9 @@ @parent + +@stop + +@section('content') + +
+ +
+ +
+ @if ($account->address1) + {{ $account->address1 }}
+ @endif + @if ($account->address2) + {{ $account->address2 }}
+ @endif + @if ($account->getCityState()) + {{ $account->getCityState() }}
+ @endif +
+
+ @if ($account->work_phone) + {{ $account->work_phone }}
+ @endif + @if ($account->work_email) + {!! HTML::mailto($account->work_email, $account->work_email) !!}
+ @endif +
+
+ +
+
+
+
+
+ {{ trans('texts.total_invoiced') }} +
+
+ {{ Utils::formatMoney($client->paid_to_date + $client->balance, $client->currency_id ?: $account->currency_id) }} +
+
+
+
+
+
+
+ {{ trans('texts.paid_to_date') }} +
+
+ {{ Utils::formatMoney($client->paid_to_date, $client->currency_id ?: $account->currency_id) }} +
+
+
+
+
+
+
+ {{ trans('texts.open_balance') }} +
+
+ {{ Utils::formatMoney($client->balance, $client->currency_id ?: $account->currency_id) }} +
+
+
+
+ + {!! Datatable::table() + ->addColumn( + trans('texts.date'), + trans('texts.message'), + trans('texts.balance'), + trans('texts.adjustment')) + ->setUrl(route('api.client.activity')) + ->setOptions('bFilter', false) + ->setOptions('aaSorting', [['0', 'desc']]) + ->setOptions('sPaginationType', 'bootstrap') + ->render('datatable') !!} + +
+ +@stop \ No newline at end of file diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 126f65d2ab6f..593745585cb5 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -104,7 +104,7 @@ @endif - @if ($account->custom_invoice_text_label1 || $invoice && $account->custom_text_value1) + @if ($account->showCustomField('custom_invoice_text_label1', $invoice)) {!! Former::text('custom_text_value1')->label($account->custom_invoice_text_label1)->data_bind("value: custom_text_value1, valueUpdate: 'afterkeydown'") !!} @endif @@ -115,7 +115,7 @@ @elseif ($invoice && isset($lastSent) && $lastSent)
- {!! trans('texts.last_sent_on', ['date' => link_to('/invoices/'.$lastSent->public_id, Utils::dateToString($invoice->last_sent_date))]) !!} + {!! trans('texts.last_sent_on', ['date' => link_to('/invoices/'.$lastSent->public_id, Utils::dateToString($invoice->last_sent_date), ['id' => 'lastSent'])]) !!}
@endif @endif @@ -141,7 +141,7 @@ ->addOption(trans('texts.discount_amount'), '1')->data_bind("value: is_amount_discount")->raw() ) !!} - @if ($account->custom_invoice_text_label2 || $invoice && $account->custom_text_value2) + @if ($account->showCustomField('custom_invoice_text_label2', $invoice)) {!! Former::text('custom_text_value2')->label($account->custom_invoice_text_label2)->data_bind("value: custom_text_value2, valueUpdate: 'afterkeydown'") !!} @endif @@ -261,7 +261,7 @@ - @if (($account->custom_invoice_label1 || ($invoice && floatval($invoice->custom_value1)) != 0) && $account->custom_invoice_taxes1) + @if ($account->showCustomField('custom_invoice_label1', $invoice) && $account->custom_invoice_taxes1) @@ -270,7 +270,7 @@ @endif - @if (($account->custom_invoice_label2 || ($invoice && floatval($invoice->custom_value2)) != 0) && $account->custom_invoice_taxes2) + @if ($account->showCustomField('custom_invoice_label2', $invoice) && $account->custom_invoice_taxes2) @@ -298,7 +298,7 @@ - @if (($account->custom_invoice_label1 || ($invoice && floatval($invoice->custom_value1)) != 0) && !$account->custom_invoice_taxes1) + @if ($account->showCustomField('custom_invoice_label1', $invoice) && !$account->custom_invoice_taxes1) @@ -307,7 +307,7 @@ @endif - @if (($account->custom_invoice_label2 || ($invoice && floatval($invoice->custom_value2)) != 0) && !$account->custom_invoice_taxes2) + @if ($account->showCustomField('custom_invoice_label2', $invoice) && !$account->custom_invoice_taxes2) diff --git a/resources/views/invoices/pdf.blade.php b/resources/views/invoices/pdf.blade.php index 311346274752..3dcd365f9e6b 100644 --- a/resources/views/invoices/pdf.blade.php +++ b/resources/views/invoices/pdf.blade.php @@ -72,10 +72,11 @@ @endif var NINJA = NINJA || {}; - NINJA.primaryColor = "{{ $account->primary_color }}"; - NINJA.secondaryColor = "{{ $account->secondary_color }}"; - NINJA.fontSize = {{ $account->font_size }}; - + @if (Utils::isPro()) + NINJA.primaryColor = "{{ $account->primary_color }}"; + NINJA.secondaryColor = "{{ $account->secondary_color }}"; + NINJA.fontSize = {{ $account->font_size }}; + @endif var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!}; if (window.invoice) { diff --git a/resources/views/invoices/view.blade.php b/resources/views/invoices/view.blade.php index 64fdac4f76e4..9b96c0d44103 100644 --- a/resources/views/invoices/view.blade.php +++ b/resources/views/invoices/view.blade.php @@ -33,7 +33,7 @@ @if (count($paymentTypes) > 1) {!! DropdownButton::success(trans('texts.pay_now'))->withContents($paymentTypes)->large() !!} @else - {!! link_to(URL::to($paymentURL), trans('texts.pay_now'), ['class' => 'btn btn-success btn-lg']) !!} + {{ trans('texts.pay_now') }} @endif @else {!! Button::normal('Download PDF')->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!} diff --git a/resources/views/partials/fb_pixel_checkout.blade.php b/resources/views/partials/fb_pixel_checkout.blade.php deleted file mode 100644 index 66c36c883203..000000000000 --- a/resources/views/partials/fb_pixel_checkout.blade.php +++ /dev/null @@ -1,15 +0,0 @@ - - \ No newline at end of file diff --git a/resources/views/public/header.blade.php b/resources/views/public/header.blade.php index 36752c2fd4d5..2375f27301c8 100644 --- a/resources/views/public/header.blade.php +++ b/resources/views/public/header.blade.php @@ -1,123 +1,7 @@ @extends('master') @section('head') - - - - + @stop @section('body') @@ -184,6 +68,9 @@ table.table thead .sorting_desc_disabled:after { content: '' !important }