mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 11:04:41 -04:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
f7da00ff27
@ -3,7 +3,7 @@ language: php
|
|||||||
sudo: true
|
sudo: true
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.5
|
- 5.5.9
|
||||||
# - 5.6
|
# - 5.6
|
||||||
# - 7.0
|
# - 7.0
|
||||||
# - hhvm
|
# - hhvm
|
||||||
|
@ -117,4 +117,77 @@ class AccountApiController extends BaseAPIController
|
|||||||
|
|
||||||
return $this->response($account);
|
return $this->response($account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addDeviceToken(Request $request)
|
||||||
|
{
|
||||||
|
$account = Auth::user()->account;
|
||||||
|
|
||||||
|
//scan if this user has a token already registered (tokens can change, so we need to use the users email as key)
|
||||||
|
$devices = json_decode($account->devices,TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
for($x=0; $x<count($devices); $x++)
|
||||||
|
{
|
||||||
|
if ($devices[$x]['email'] == Auth::user()->username) {
|
||||||
|
$devices[$x]['token'] = $request->token; //update
|
||||||
|
$account->devices = json_encode($devices);
|
||||||
|
$account->save();
|
||||||
|
return $this->response($account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//User does not have a device, create new record
|
||||||
|
|
||||||
|
$newDevice = [
|
||||||
|
'token' => $request->token,
|
||||||
|
'email' => $request->email,
|
||||||
|
'device' => $request->device,
|
||||||
|
'notify_sent' => TRUE,
|
||||||
|
'notify_viewed' => TRUE,
|
||||||
|
'notify_approved' => TRUE,
|
||||||
|
'notify_paid' => TRUE,
|
||||||
|
];
|
||||||
|
|
||||||
|
$devices[] = $newDevice;
|
||||||
|
$account->devices = json_encode($devices);
|
||||||
|
$account->save();
|
||||||
|
|
||||||
|
return $this->response($account);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePushNotifications(Request $request)
|
||||||
|
{
|
||||||
|
$account = Auth::user()->account;
|
||||||
|
|
||||||
|
$devices = json_decode($account->devices, TRUE);
|
||||||
|
|
||||||
|
if(count($devices)<1)
|
||||||
|
return $this->errorResponse(['message'=>'no devices exist'], 400);
|
||||||
|
|
||||||
|
for($x=0; $x<count($devices); $x++)
|
||||||
|
{
|
||||||
|
if($devices[$x]['email'] == Auth::user()->username)
|
||||||
|
{
|
||||||
|
unset($devices[$x]);
|
||||||
|
|
||||||
|
$newDevice = [
|
||||||
|
'token' => $request->token,
|
||||||
|
'email' => $request->email,
|
||||||
|
'device' => $request->device,
|
||||||
|
'notify_sent' => $request->notify_sent,
|
||||||
|
'notify_viewed' => $request->notify_viewed,
|
||||||
|
'notify_approved' => $request->notify_approved,
|
||||||
|
'notify_paid' => $request->notify_paid,
|
||||||
|
];
|
||||||
|
|
||||||
|
$devices[] = $newDevice;
|
||||||
|
$account->devices = json_encode($devices);
|
||||||
|
$account->save();
|
||||||
|
|
||||||
|
return $this->response($account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,6 +432,7 @@ class AccountController extends BaseController
|
|||||||
'client_view_css' => $css,
|
'client_view_css' => $css,
|
||||||
'title' => trans("texts.client_portal"),
|
'title' => trans("texts.client_portal"),
|
||||||
'section' => ACCOUNT_CLIENT_PORTAL,
|
'section' => ACCOUNT_CLIENT_PORTAL,
|
||||||
|
'account' => $account,
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make("accounts.client_portal", $data);
|
return View::make("accounts.client_portal", $data);
|
||||||
@ -544,6 +545,7 @@ class AccountController extends BaseController
|
|||||||
|
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
$account->client_view_css = $sanitized_css;
|
$account->client_view_css = $sanitized_css;
|
||||||
|
$account->enable_client_portal = Input::get('enable_client_portal') ? true : false;
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
Session::flash('message', trans('texts.updated_settings'));
|
Session::flash('message', trans('texts.updated_settings'));
|
||||||
|
@ -34,10 +34,7 @@ class PublicClientController extends BaseController
|
|||||||
public function view($invitationKey)
|
public function view($invitationKey)
|
||||||
{
|
{
|
||||||
if (!$invitation = $this->invoiceRepo->findInvoiceByInvitation($invitationKey)) {
|
if (!$invitation = $this->invoiceRepo->findInvoiceByInvitation($invitationKey)) {
|
||||||
return response()->view('error', [
|
return $this->returnError();
|
||||||
'error' => trans('texts.invoice_not_found'),
|
|
||||||
'hideHeader' => true,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
@ -118,6 +115,7 @@ class PublicClientController extends BaseController
|
|||||||
'showBreadcrumbs' => false,
|
'showBreadcrumbs' => false,
|
||||||
'hideLogo' => $account->isWhiteLabel(),
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
'hideHeader' => $account->isNinjaAccount(),
|
'hideHeader' => $account->isNinjaAccount(),
|
||||||
|
'hideDashboard' => !$account->enable_client_portal,
|
||||||
'clientViewCSS' => $account->clientViewCSS(),
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
'clientFontUrl' => $account->getFontsUrl(),
|
'clientFontUrl' => $account->getFontsUrl(),
|
||||||
'invoice' => $invoice->hidePrivateFields(),
|
'invoice' => $invoice->hidePrivateFields(),
|
||||||
@ -188,11 +186,16 @@ class PublicClientController extends BaseController
|
|||||||
if (!$invitation = $this->getInvitation()) {
|
if (!$invitation = $this->getInvitation()) {
|
||||||
return $this->returnError();
|
return $this->returnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
$account = $invitation->account;
|
$account = $invitation->account;
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||||
|
|
||||||
|
if (!$account->enable_client_portal) {
|
||||||
|
return $this->returnError();
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'color' => $color,
|
'color' => $color,
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
@ -244,6 +247,7 @@ class PublicClientController extends BaseController
|
|||||||
$data = [
|
$data = [
|
||||||
'color' => $color,
|
'color' => $color,
|
||||||
'hideLogo' => $account->isWhiteLabel(),
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'hideDashboard' => !$account->enable_client_portal,
|
||||||
'clientViewCSS' => $account->clientViewCSS(),
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
'clientFontUrl' => $account->getFontsUrl(),
|
'clientFontUrl' => $account->getFontsUrl(),
|
||||||
'title' => trans('texts.invoices'),
|
'title' => trans('texts.invoices'),
|
||||||
@ -275,6 +279,7 @@ class PublicClientController extends BaseController
|
|||||||
$data = [
|
$data = [
|
||||||
'color' => $color,
|
'color' => $color,
|
||||||
'hideLogo' => $account->isWhiteLabel(),
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'hideDashboard' => !$account->enable_client_portal,
|
||||||
'clientViewCSS' => $account->clientViewCSS(),
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
'clientFontUrl' => $account->getFontsUrl(),
|
'clientFontUrl' => $account->getFontsUrl(),
|
||||||
'entityType' => ENTITY_PAYMENT,
|
'entityType' => ENTITY_PAYMENT,
|
||||||
@ -312,6 +317,7 @@ class PublicClientController extends BaseController
|
|||||||
$data = [
|
$data = [
|
||||||
'color' => $color,
|
'color' => $color,
|
||||||
'hideLogo' => $account->isWhiteLabel(),
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'hideDashboard' => !$account->enable_client_portal,
|
||||||
'clientViewCSS' => $account->clientViewCSS(),
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
'clientFontUrl' => $account->getFontsUrl(),
|
'clientFontUrl' => $account->getFontsUrl(),
|
||||||
'title' => trans('texts.quotes'),
|
'title' => trans('texts.quotes'),
|
||||||
@ -332,13 +338,11 @@ class PublicClientController extends BaseController
|
|||||||
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, Input::get('sSearch'));
|
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, Input::get('sSearch'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function returnError()
|
private function returnError($error = false)
|
||||||
{
|
{
|
||||||
return response()->view('error', [
|
return response()->view('error', [
|
||||||
'error' => trans('texts.invoice_not_found'),
|
'error' => $error ?: trans('texts.invoice_not_found'),
|
||||||
'hideHeader' => true,
|
'hideHeader' => true,
|
||||||
'clientViewCSS' => $account->clientViewCSS(),
|
|
||||||
'clientFontUrl' => $account->getFontsUrl(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +235,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
|
|||||||
Route::resource('tax_rates', 'TaxRateApiController');
|
Route::resource('tax_rates', 'TaxRateApiController');
|
||||||
Route::resource('users', 'UserApiController');
|
Route::resource('users', 'UserApiController');
|
||||||
Route::resource('expenses','ExpenseApiController');
|
Route::resource('expenses','ExpenseApiController');
|
||||||
|
Route::post('add_token', 'AccountApiController@addDeviceToken');
|
||||||
|
Route::post('update_notifications', 'AccountApiController@updatePushNotifications');
|
||||||
|
|
||||||
// Vendor
|
// Vendor
|
||||||
Route::resource('vendors', 'VendorApiController');
|
Route::resource('vendors', 'VendorApiController');
|
||||||
@ -552,6 +554,9 @@ if (!defined('CONTACT_EMAIL')) {
|
|||||||
define('TEST_PASSWORD', 'password');
|
define('TEST_PASSWORD', 'password');
|
||||||
define('API_SECRET', 'API_SECRET');
|
define('API_SECRET', 'API_SECRET');
|
||||||
|
|
||||||
|
define('IOS_PRODUCTION_PUSH','ninjaIOS');
|
||||||
|
define('IOS_DEV_PUSH','devNinjaIOS');
|
||||||
|
|
||||||
define('TOKEN_BILLING_DISABLED', 1);
|
define('TOKEN_BILLING_DISABLED', 1);
|
||||||
define('TOKEN_BILLING_OPT_IN', 2);
|
define('TOKEN_BILLING_OPT_IN', 2);
|
||||||
define('TOKEN_BILLING_OPT_OUT', 3);
|
define('TOKEN_BILLING_OPT_OUT', 3);
|
||||||
|
@ -9,16 +9,19 @@ use App\Events\InvoiceInvitationWasViewed;
|
|||||||
use App\Events\QuoteInvitationWasViewed;
|
use App\Events\QuoteInvitationWasViewed;
|
||||||
use App\Events\QuoteInvitationWasApproved;
|
use App\Events\QuoteInvitationWasApproved;
|
||||||
use App\Events\PaymentWasCreated;
|
use App\Events\PaymentWasCreated;
|
||||||
|
use App\Ninja\Notifications;
|
||||||
|
|
||||||
class NotificationListener
|
class NotificationListener
|
||||||
{
|
{
|
||||||
protected $userMailer;
|
protected $userMailer;
|
||||||
protected $contactMailer;
|
protected $contactMailer;
|
||||||
|
protected $pushService;
|
||||||
|
|
||||||
public function __construct(UserMailer $userMailer, ContactMailer $contactMailer)
|
public function __construct(UserMailer $userMailer, ContactMailer $contactMailer, Notifications\PushService $pushService)
|
||||||
{
|
{
|
||||||
$this->userMailer = $userMailer;
|
$this->userMailer = $userMailer;
|
||||||
$this->contactMailer = $contactMailer;
|
$this->contactMailer = $contactMailer;
|
||||||
|
$this->pushService = $pushService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sendEmails($invoice, $type, $payment = null)
|
private function sendEmails($invoice, $type, $payment = null)
|
||||||
@ -35,26 +38,31 @@ class NotificationListener
|
|||||||
public function emailedInvoice(InvoiceWasEmailed $event)
|
public function emailedInvoice(InvoiceWasEmailed $event)
|
||||||
{
|
{
|
||||||
$this->sendEmails($event->invoice, 'sent');
|
$this->sendEmails($event->invoice, 'sent');
|
||||||
|
$this->pushService->sendNotification($event->invoice, 'sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function emailedQuote(QuoteWasEmailed $event)
|
public function emailedQuote(QuoteWasEmailed $event)
|
||||||
{
|
{
|
||||||
$this->sendEmails($event->quote, 'sent');
|
$this->sendEmails($event->quote, 'sent');
|
||||||
|
$this->pushService->sendNotification($event->quote, 'sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function viewedInvoice(InvoiceInvitationWasViewed $event)
|
public function viewedInvoice(InvoiceInvitationWasViewed $event)
|
||||||
{
|
{
|
||||||
$this->sendEmails($event->invoice, 'viewed');
|
$this->sendEmails($event->invoice, 'viewed');
|
||||||
|
$this->pushService->sendNotification($event->invoice, 'viewed');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function viewedQuote(QuoteInvitationWasViewed $event)
|
public function viewedQuote(QuoteInvitationWasViewed $event)
|
||||||
{
|
{
|
||||||
$this->sendEmails($event->quote, 'viewed');
|
$this->sendEmails($event->quote, 'viewed');
|
||||||
|
$this->pushService->sendNotification($event->quote, 'viewed');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function approvedQuote(QuoteInvitationWasApproved $event)
|
public function approvedQuote(QuoteInvitationWasApproved $event)
|
||||||
{
|
{
|
||||||
$this->sendEmails($event->quote, 'approved');
|
$this->sendEmails($event->quote, 'approved');
|
||||||
|
$this->pushService->sendNotification($event->quote, 'approved');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createdPayment(PaymentWasCreated $event)
|
public function createdPayment(PaymentWasCreated $event)
|
||||||
@ -66,6 +74,8 @@ class NotificationListener
|
|||||||
|
|
||||||
$this->contactMailer->sendPaymentConfirmation($event->payment);
|
$this->contactMailer->sendPaymentConfirmation($event->payment);
|
||||||
$this->sendEmails($event->payment->invoice, 'paid', $event->payment);
|
$this->sendEmails($event->payment->invoice, 'paid', $event->payment);
|
||||||
|
|
||||||
|
$this->pushService->sendNotification($event->payment->invoice, 'paid');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
96
app/Ninja/Notifications/PushFactory.php
Normal file
96
app/Ninja/Notifications/PushFactory.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Ninja\Notifications;
|
||||||
|
|
||||||
|
use Davibennun\LaravelPushNotification\Facades\PushNotification;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PushFactory
|
||||||
|
* @package App\Ninja\Notifications
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PushFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* PushFactory constructor.
|
||||||
|
*
|
||||||
|
* @param $this->certificate - Development or production.
|
||||||
|
*
|
||||||
|
* Static variables defined in routes.php
|
||||||
|
*
|
||||||
|
* IOS_PRODUCTION_PUSH
|
||||||
|
* IOS_DEV_PUSH
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->certificate = IOS_DEV_PUSH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* customMessage function
|
||||||
|
*
|
||||||
|
* Send a message with a nested custom payload to perform additional trickery within application
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
* @param $token
|
||||||
|
* @param $message
|
||||||
|
* @param $messageArray
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function customMessage($token, $message, $messageArray)
|
||||||
|
{
|
||||||
|
$customMessage = PushNotification::Message($message, $messageArray);
|
||||||
|
|
||||||
|
$this->message($token, $customMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message function
|
||||||
|
*
|
||||||
|
* Send a plain text only message to a single device.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
* @param $token - device token
|
||||||
|
* @param $message - user specific message
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function message($token, $message)
|
||||||
|
{
|
||||||
|
PushNotification::app($this->certificate)
|
||||||
|
->to($token)
|
||||||
|
->send($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getFeedback function
|
||||||
|
*
|
||||||
|
* Returns an array of expired/invalid tokens to be removed from iOS PUSH notifications.
|
||||||
|
*
|
||||||
|
* We need to run this once ~ 24hrs
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
* @param string $token - A valid token (can be any valid token)
|
||||||
|
* @param string $message - Nil value for message
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFeedback($token, $message = '')
|
||||||
|
{
|
||||||
|
|
||||||
|
$feedback = PushNotification::app($this->certificate)
|
||||||
|
->to($token)
|
||||||
|
->send($message);
|
||||||
|
|
||||||
|
return $feedback->getFeedback();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
171
app/Services/PushService.php
Normal file
171
app/Services/PushService.php
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Ninja\Notifications\PushFactory;
|
||||||
|
/**
|
||||||
|
* Class PushService
|
||||||
|
* @package App\Ninja\Notifications
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $account->devices Definition
|
||||||
|
*
|
||||||
|
* @param string token (push notification device token)
|
||||||
|
* @param string email (user email address - required for use as key)
|
||||||
|
* @param string device (ios, gcm etc etc)
|
||||||
|
* @param bool notify_sent
|
||||||
|
* @param bool notify_paid
|
||||||
|
* @param bool notify_approved
|
||||||
|
* @param bool notify_viewed
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PushService
|
||||||
|
{
|
||||||
|
protected $pushFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PushFactory $pushFactory
|
||||||
|
*/
|
||||||
|
public function __construct(PushFactory $pushFactory)
|
||||||
|
{
|
||||||
|
$this->pushFactory = $pushFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invoice - Invoice object
|
||||||
|
* @param $type - Type of notification, ie. Quote APPROVED, Invoice PAID, Invoice/Quote SENT, Invoice/Quote VIEWED
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function sendNotification($invoice, $type)
|
||||||
|
{
|
||||||
|
//check user has registered for push notifications
|
||||||
|
if(!$this->checkDeviceExists($invoice->account))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Harvest an array of devices that are registered for this notification type
|
||||||
|
$devices = json_decode($invoice->account->devices, TRUE);
|
||||||
|
|
||||||
|
foreach($devices as $device)
|
||||||
|
{
|
||||||
|
if(($device["notify_{$type}"] == TRUE) && ($device['device'] == 'ios'))
|
||||||
|
$this->pushMessage($invoice, $device['token'], $device["notify_{$type}"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pushMessage function
|
||||||
|
*
|
||||||
|
* method to dispatch iOS notifications
|
||||||
|
*
|
||||||
|
* @param $invoice
|
||||||
|
* @param $token
|
||||||
|
* @param $type
|
||||||
|
*/
|
||||||
|
private function pushMessage($invoice, $token, $type)
|
||||||
|
{
|
||||||
|
$this->pushFactory->message($token, $this->messageType($invoice, $type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkDeviceExists function
|
||||||
|
*
|
||||||
|
* Returns a boolean if this account has devices registered for PUSH notifications
|
||||||
|
*
|
||||||
|
* @param $account
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkDeviceExists($account)
|
||||||
|
{
|
||||||
|
$devices = json_decode($account->devices, TRUE);
|
||||||
|
|
||||||
|
if(count($devices) >= 1)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* messageType function
|
||||||
|
*
|
||||||
|
* method which formats an appropriate message depending on message type
|
||||||
|
*
|
||||||
|
* @param $invoice
|
||||||
|
* @param $type
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function messageType($invoice, $type)
|
||||||
|
{
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case 'notify_sent':
|
||||||
|
return $this->entitySentMessage($invoice);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'notify_paid':
|
||||||
|
return $this->invoicePaidMessage($invoice);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'notify_approved':
|
||||||
|
return $this->quoteApprovedMessage($invoice);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'notify_viewed':
|
||||||
|
return $this->entityViewedMessage($invoice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invoice
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function entitySentMessage($invoice)
|
||||||
|
{
|
||||||
|
if($invoice->is_quote)
|
||||||
|
return 'Quote #{$invoice->invoice_number} sent!';
|
||||||
|
else
|
||||||
|
return 'Invoice #{$invoice->invoice_number} sent!';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invoice
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function invoicePaidMessage($invoice)
|
||||||
|
{
|
||||||
|
return 'Invoice #{$invoice->invoice_number} paid!';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invoice
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function quoteApprovedMessage($invoice)
|
||||||
|
{
|
||||||
|
return 'Quote #{$invoice->invoice_number} approved!';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invoice
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function entityViewedMessage($invoice)
|
||||||
|
{
|
||||||
|
if($invoice->is_quote)
|
||||||
|
return 'Quote #{$invoice->invoice_number} viewed!';
|
||||||
|
else
|
||||||
|
return 'Invoice #{$invoice->invoice_number} viewed!';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
|
"turbo124/laravel-push-notification": "dev-laravel5",
|
||||||
"omnipay/mollie": "dev-master#22956c1a62a9662afa5f5d119723b413770ac525",
|
"omnipay/mollie": "dev-master#22956c1a62a9662afa5f5d119723b413770ac525",
|
||||||
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
|
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
|
||||||
"omnipay/gocardless": "dev-master",
|
"omnipay/gocardless": "dev-master",
|
||||||
@ -27,7 +28,6 @@
|
|||||||
"jsanc623/phpbenchtime": "2.x",
|
"jsanc623/phpbenchtime": "2.x",
|
||||||
"lokielse/omnipay-alipay": "dev-master",
|
"lokielse/omnipay-alipay": "dev-master",
|
||||||
"coatesap/omnipay-datacash": "~2.0",
|
"coatesap/omnipay-datacash": "~2.0",
|
||||||
"alfaproject/omnipay-neteller": "1.0.*@dev",
|
|
||||||
"mfauveau/omnipay-pacnet": "~2.0",
|
"mfauveau/omnipay-pacnet": "~2.0",
|
||||||
"coatesap/omnipay-paymentsense": "2.0.0",
|
"coatesap/omnipay-paymentsense": "2.0.0",
|
||||||
"coatesap/omnipay-realex": "~2.0",
|
"coatesap/omnipay-realex": "~2.0",
|
||||||
|
927
composer.lock
generated
927
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -164,6 +164,7 @@ return [
|
|||||||
'App\Providers\RouteServiceProvider',
|
'App\Providers\RouteServiceProvider',
|
||||||
|
|
||||||
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
|
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
|
||||||
|
'Davibennun\LaravelPushNotification\LaravelPushNotificationServiceProvider',
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -249,6 +250,7 @@ return [
|
|||||||
'Rocketeer' => 'Rocketeer\Facades\Rocketeer',
|
'Rocketeer' => 'Rocketeer\Facades\Rocketeer',
|
||||||
'Socialite' => 'Laravel\Socialite\Facades\Socialite',
|
'Socialite' => 'Laravel\Socialite\Facades\Socialite',
|
||||||
'Excel' => 'Maatwebsite\Excel\Facades\Excel',
|
'Excel' => 'Maatwebsite\Excel\Facades\Excel',
|
||||||
|
'PushNotification' => 'Davibennun\LaravelPushNotification\Facades\PushNotification',
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
23
config/push-notification.php
Normal file
23
config/push-notification.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
'devNinjaIOS' => [
|
||||||
|
'environment' =>'development',
|
||||||
|
'certificate'=>app_path().'/certs/ninjaIOS.pem',
|
||||||
|
'passPhrase' =>'',
|
||||||
|
'service' =>'apns'
|
||||||
|
],
|
||||||
|
'ninjaIOS' => [
|
||||||
|
'environment' =>'production',
|
||||||
|
'certificate'=>app_path().'/certs/productionNinjaIOS.pem',
|
||||||
|
'passPhrase' =>'',
|
||||||
|
'service' =>'apns'
|
||||||
|
],
|
||||||
|
'ninjaAndroid' => [
|
||||||
|
'environment' =>'production',
|
||||||
|
'apiKey' =>'yourAPIKey',
|
||||||
|
'service' =>'gcm'
|
||||||
|
]
|
||||||
|
|
||||||
|
];
|
@ -22,7 +22,7 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
['name' => 'Buckaroo', 'provider' => 'Buckaroo_CreditCard', 'payment_library_id' => 1],
|
['name' => 'Buckaroo', 'provider' => 'Buckaroo_CreditCard', 'payment_library_id' => 1],
|
||||||
['name' => 'Coinbase', 'provider' => 'Coinbase', 'payment_library_id' => 1],
|
['name' => 'Coinbase', 'provider' => 'Coinbase', 'payment_library_id' => 1],
|
||||||
['name' => 'DataCash', 'provider' => 'DataCash', 'payment_library_id' => 1],
|
['name' => 'DataCash', 'provider' => 'DataCash', 'payment_library_id' => 1],
|
||||||
['name' => 'Neteller', 'provider' => 'Neteller', 'payment_library_id' => 1],
|
['name' => 'Neteller', 'provider' => 'Neteller', 'payment_library_id' => 2],
|
||||||
['name' => 'Pacnet', 'provider' => 'Pacnet', 'payment_library_id' => 1],
|
['name' => 'Pacnet', 'provider' => 'Pacnet', 'payment_library_id' => 1],
|
||||||
['name' => 'PaymentSense', 'provider' => 'PaymentSense', 'payment_library_id' => 1],
|
['name' => 'PaymentSense', 'provider' => 'PaymentSense', 'payment_library_id' => 1],
|
||||||
['name' => 'Realex', 'provider' => 'Realex_Remote', 'payment_library_id' => 1],
|
['name' => 'Realex', 'provider' => 'Realex_Remote', 'payment_library_id' => 1],
|
||||||
|
@ -1048,7 +1048,10 @@ $LANG = array(
|
|||||||
'invoice_item_fields' => 'Invoice Item Fields',
|
'invoice_item_fields' => 'Invoice Item Fields',
|
||||||
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
|
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
|
||||||
'recurring_invoice_number' => 'Recurring Invoice Number',
|
'recurring_invoice_number' => 'Recurring Invoice Number',
|
||||||
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.'
|
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
|
||||||
|
'enable_client_portal' => 'Dashboard',
|
||||||
|
'enable_client_portal_help' => 'Show/hide the dashboard page in the client portal.',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
{!! Former::open_for_files()
|
{!! Former::open_for_files()
|
||||||
->addClass('warn-on-exit') !!}
|
->addClass('warn-on-exit') !!}
|
||||||
|
|
||||||
|
{!! Former::populateField('enable_client_portal', intval($account->enable_client_portal)) !!}
|
||||||
{!! Former::populateField('client_view_css', $client_view_css) !!}
|
{!! Former::populateField('client_view_css', $client_view_css) !!}
|
||||||
|
|
||||||
@if (!Utils::isNinja() && !Auth::user()->account->isWhiteLabel())
|
@if (!Utils::isNinja() && !Auth::user()->account->isWhiteLabel())
|
||||||
@ -25,7 +26,20 @@
|
|||||||
@include('accounts.nav', ['selected' => ACCOUNT_CLIENT_PORTAL])
|
@include('accounts.nav', ['selected' => ACCOUNT_CLIENT_PORTAL])
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.client_portal') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('enable_client_portal')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.enable_client_portal_help')) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
@ -43,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
|
@ -22,10 +22,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
@foreach ($settings as $section)
|
@foreach ($settings as $section)
|
||||||
@if ($section != ACCOUNT_CLIENT_PORTAL || !Utils::isNinjaProd())
|
<a href="{{ URL::to("settings/{$section}") }}" class="list-group-item {{ $selected === $section ? 'selected' : '' }}"
|
||||||
<a href="{{ URL::to("settings/{$section}") }}" class="list-group-item {{ $selected === $section ? 'selected' : '' }}"
|
style="width:100%;text-align:left">{{ trans("texts.{$section}") }}</a>
|
||||||
style="width:100%;text-align:left">{{ trans("texts.{$section}") }}</a>
|
|
||||||
@endif
|
|
||||||
@endforeach
|
@endforeach
|
||||||
@if ($type === ADVANCED_SETTINGS && !Utils::isNinjaProd())
|
@if ($type === ADVANCED_SETTINGS && !Utils::isNinjaProd())
|
||||||
<a href="{{ URL::to("settings/system_settings") }}" class="list-group-item {{ $selected === 'system_settings' ? 'selected' : '' }}"
|
<a href="{{ URL::to("settings/system_settings") }}" class="list-group-item {{ $selected === 'system_settings' ? 'selected' : '' }}"
|
||||||
|
@ -76,9 +76,11 @@
|
|||||||
<div id="navbar" class="collapse navbar-collapse">
|
<div id="navbar" class="collapse navbar-collapse">
|
||||||
@if (!isset($hideHeader) || !$hideHeader)
|
@if (!isset($hideHeader) || !$hideHeader)
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li {{ Request::is('*client/dashboard') ? 'class="active"' : '' }}>
|
@if (!isset($hideDashboard) || !$hideDashboard)
|
||||||
{!! link_to('/client/dashboard', trans('texts.dashboard') ) !!}
|
<li {{ Request::is('*client/dashboard') ? 'class="active"' : '' }}>
|
||||||
</li>
|
{!! link_to('/client/dashboard', trans('texts.dashboard') ) !!}
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
<li {{ Request::is('*client/quotes') ? 'class="active"' : '' }}>
|
<li {{ Request::is('*client/quotes') ? 'class="active"' : '' }}>
|
||||||
{!! link_to('/client/quotes', trans('texts.quotes') ) !!}
|
{!! link_to('/client/quotes', trans('texts.quotes') ) !!}
|
||||||
</li>
|
</li>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user