1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 12:42:36 +01:00

Add credits to the client portal

This commit is contained in:
Hillel Coren 2016-09-23 12:02:48 +03:00
parent 456ab445c5
commit 5d04bdab21
7 changed files with 123 additions and 8 deletions

View File

@ -22,6 +22,7 @@ use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\PaymentRepository;
use App\Ninja\Repositories\ActivityRepository;
use App\Ninja\Repositories\DocumentRepository;
use App\Ninja\Repositories\CreditRepository;
use App\Events\InvoiceInvitationWasViewed;
use App\Events\QuoteInvitationWasViewed;
use App\Services\PaymentService;
@ -33,13 +34,14 @@ class ClientPortalController extends BaseController
private $paymentRepo;
private $documentRepo;
public function __construct(InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo, ActivityRepository $activityRepo, DocumentRepository $documentRepo, PaymentService $paymentService)
public function __construct(InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo, ActivityRepository $activityRepo, DocumentRepository $documentRepo, PaymentService $paymentService, CreditRepository $creditRepo)
{
$this->invoiceRepo = $invoiceRepo;
$this->paymentRepo = $paymentRepo;
$this->activityRepo = $activityRepo;
$this->documentRepo = $documentRepo;
$this->paymentService = $paymentService;
$this->creditRepo = $creditRepo;
}
public function view($invitationKey)
@ -439,6 +441,40 @@ class ClientPortalController extends BaseController
return $this->invoiceRepo->getClientDatatable($contact->id, ENTITY_QUOTE, Input::get('sSearch'));
}
public function creditIndex()
{
if (!$contact = $this->getContact()) {
return $this->returnError();
}
$account = $contact->account;
if (!$account->enable_client_portal) {
return $this->returnError();
}
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
$data = [
'color' => $color,
'account' => $account,
'clientFontUrl' => $account->getFontsUrl(),
'title' => trans('texts.credits'),
'entityType' => ENTITY_CREDIT,
'columns' => Utils::trans(['credit_date', 'credit_amount', 'credit_balance']),
];
return response()->view('public_list', $data);
}
public function creditDatatable()
{
if (!$contact = $this->getContact()) {
return false;
}
return $this->creditRepo->getClientDatatable($contact->client_id);
}
public function documentIndex()
{
if (!$contact = $this->getContact()) {

View File

@ -2,8 +2,10 @@
namespace App\Http\ViewComposers;
use DB;
use Cache;
use Illuminate\View\View;
use App\Models\Contact;
/**
* ClientPortalHeaderComposer.php.
@ -21,6 +23,30 @@ class ClientPortalHeaderComposer
*/
public function compose(View $view)
{
$view->with('testing', 'value');
$contactKey = session('contact_key');
if ( ! $contactKey) {
return false;
}
$contact = Contact::where('contact_key', '=', $contactKey)
->with('client')
->first();
if ( ! $contact || $contact->is_deleted) {
return false;
}
$client = $contact->client;
$hasDocuments = DB::table('invoices')
->where('invoices.client_id', '=', $client->id)
->whereNull('invoices.deleted_at')
->join('documents', 'documents.invoice_id', '=', 'invoices.id')
->count();
$view->with('hasQuotes', $client->quotes->count());
$view->with('hasCredits', $client->creditsWithBalance->count());
$view->with('hasDocuments', $hasDocuments);
}
}

View File

@ -52,6 +52,7 @@ Route::group(['middleware' => 'auth:client'], function() {
Route::post('client/payment_methods/default', 'ClientPortalController@setDefaultPaymentMethod');
Route::post('client/payment_methods/{source_id}/remove', 'ClientPortalController@removePaymentMethod');
Route::get('client/quotes', 'ClientPortalController@quoteIndex');
Route::get('client/credits', 'ClientPortalController@creditIndex');
Route::get('client/invoices', 'ClientPortalController@invoiceIndex');
Route::get('client/invoices/recurring', 'ClientPortalController@recurringInvoiceIndex');
Route::post('client/invoices/auto_bill', 'ClientPortalController@setAutoBill');
@ -63,6 +64,7 @@ Route::group(['middleware' => 'auth:client'], function() {
Route::get('client/documents/{invitation_key}/{filename?}', 'ClientPortalController@getInvoiceDocumentsZip');
Route::get('api/client.quotes', ['as'=>'api.client.quotes', 'uses'=>'ClientPortalController@quoteDatatable']);
Route::get('api/client.credits', ['as'=>'api.client.credits', 'uses'=>'ClientPortalController@creditDatatable']);
Route::get('api/client.invoices', ['as'=>'api.client.invoices', 'uses'=>'ClientPortalController@invoiceDatatable']);
Route::get('api/client.recurring_invoices', ['as'=>'api.client.recurring_invoices', 'uses'=>'ClientPortalController@recurringInvoiceDatatable']);
Route::get('api/client.documents', ['as'=>'api.client.documents', 'uses'=>'ClientPortalController@documentDatatable']);

View File

@ -159,6 +159,14 @@ class Client extends EntityModel
return $this->hasMany('App\Models\Invoice');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function quotes()
{
return $this->hasMany('App\Models\Invoice')->where('invoice_type_id', '=', INVOICE_TYPE_QUOTE);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
@ -223,6 +231,14 @@ class Client extends EntityModel
return $this->hasMany('App\Models\Credit');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function creditsWithBalance()
{
return $this->hasMany('App\Models\Credit')->where('balance', '>', 0);
}
/**
* @return mixed
*/

View File

@ -58,10 +58,36 @@ class CreditRepository extends BaseRepository
return $query;
}
public function getClientDatatable($clientId)
{
$query = DB::table('credits')
->join('accounts', 'accounts.id', '=', 'credits.account_id')
->join('clients', 'clients.id', '=', 'credits.client_id')
->where('credits.client_id', '=', $clientId)
->where('clients.deleted_at', '=', null)
->where('credits.deleted_at', '=', null)
->where('credits.balance', '>', 0)
->select(
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'),
'credits.amount',
'credits.balance',
'credits.credit_date'
);
$table = \Datatable::query($query)
->addColumn('credit_date', function ($model) { return Utils::fromSqlDate($model->credit_date); })
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); })
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); })
->make();
return $table;
}
public function save($input, $credit = null)
{
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
if ($credit) {
// do nothing
} elseif ($publicId) {

View File

@ -34,7 +34,7 @@ class ComposerServiceProvider extends ServiceProvider
view()->composer(
[
'invited.dashboard',
'public.header'
],
'App\Http\ViewComposers\ClientPortalHeaderComposer'
);

View File

@ -76,13 +76,17 @@
{!! link_to('/client/dashboard', trans('texts.dashboard') ) !!}
</li>
@endif
<li {!! Request::is('*client/quotes') ? 'class="active"' : '' !!}>
{!! link_to('/client/quotes', trans('texts.quotes') ) !!}
</li>
@if (isset($hasQuotes) && $hasQuotes)
<li {!! Request::is('*client/quotes') ? 'class="active"' : '' !!}>
{!! link_to('/client/quotes', trans('texts.quotes') ) !!}
</li>
@endif
<li {!! Request::is('*client/invoices') ? 'class="active"' : '' !!}>
{!! link_to('/client/invoices', trans('texts.invoices') ) !!}
</li>
@if (isset($account) && $account->hasFeature(FEATURE_DOCUMENTS))
@if (isset($account)
&& $account->hasFeature(FEATURE_DOCUMENTS)
&& (isset($hasDocuments) && $hasDocuments))
<li {!! Request::is('*client/documents') ? 'class="active"' : '' !!}>
{!! link_to('/client/documents', trans('texts.documents') ) !!}
</li>
@ -95,6 +99,11 @@
<li {!! Request::is('*client/payments') ? 'class="active"' : '' !!}>
{!! link_to('/client/payments', trans('texts.payments') ) !!}
</li>
@if (isset($hasCredits) && $hasCredits)
<li {!! Request::is('*client/credits') ? 'class="active"' : '' !!}>
{!! link_to('/client/credits', trans('texts.credits') ) !!}
</li>
@endif
</ul>
@endif
</div><!--/.nav-collapse -->