mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Added products to main navigation
This commit is contained in:
parent
7de1ffc13f
commit
249c89dbfd
@ -475,16 +475,9 @@ class AccountController extends BaseController
|
|||||||
*/
|
*/
|
||||||
private function showProducts()
|
private function showProducts()
|
||||||
{
|
{
|
||||||
$columns = ['product', 'description', 'unit_cost'];
|
|
||||||
if (Auth::user()->account->invoice_item_taxes) {
|
|
||||||
$columns[] = 'tax_rate';
|
|
||||||
}
|
|
||||||
$columns[] = 'action';
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'account' => Auth::user()->account,
|
'account' => Auth::user()->account,
|
||||||
'title' => trans('texts.product_library'),
|
'title' => trans('texts.product_library'),
|
||||||
'columns' => Utils::trans($columns),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('accounts.products', $data);
|
return View::make('accounts.products', $data);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use Auth;
|
use Auth;
|
||||||
use URL;
|
use URL;
|
||||||
use View;
|
use View;
|
||||||
|
use Utils;
|
||||||
use Input;
|
use Input;
|
||||||
use Session;
|
use Session;
|
||||||
use Redirect;
|
use Redirect;
|
||||||
@ -37,8 +38,33 @@ class ProductController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return Redirect::to('settings/' . ACCOUNT_PRODUCTS);
|
$columns = [
|
||||||
|
'checkbox',
|
||||||
|
'product',
|
||||||
|
'description',
|
||||||
|
'unit_cost'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (Auth::user()->account->invoice_item_taxes) {
|
||||||
|
$columns[] = 'tax_rate';
|
||||||
}
|
}
|
||||||
|
$columns[] = 'action';
|
||||||
|
|
||||||
|
return View::make('list', [
|
||||||
|
'entityType' => ENTITY_PRODUCT,
|
||||||
|
'title' => trans('texts.products'),
|
||||||
|
'sortCol' => '4',
|
||||||
|
'columns' => Utils::trans($columns),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($publicId)
|
||||||
|
{
|
||||||
|
Session::reflash();
|
||||||
|
|
||||||
|
return Redirect::to("products/$publicId/edit");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
@ -126,7 +152,7 @@ class ProductController extends BaseController
|
|||||||
$message = $productPublicId ? trans('texts.updated_product') : trans('texts.created_product');
|
$message = $productPublicId ? trans('texts.updated_product') : trans('texts.created_product');
|
||||||
Session::flash('message', $message);
|
Session::flash('message', $message);
|
||||||
|
|
||||||
return Redirect::to('settings/' . ACCOUNT_PRODUCTS);
|
return Redirect::to(ACCOUNT_PRODUCTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,12 +160,12 @@ class ProductController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function bulk()
|
public function bulk()
|
||||||
{
|
{
|
||||||
$action = Input::get('bulk_action');
|
$action = Input::get('action');
|
||||||
$ids = Input::get('bulk_public_id');
|
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||||
$count = $this->productService->bulk($ids, $action);
|
$count = $this->productService->bulk($ids, $action);
|
||||||
|
|
||||||
Session::flash('message', trans('texts.archived_product'));
|
Session::flash('message', trans('texts.archived_product'));
|
||||||
|
|
||||||
return Redirect::to('settings/' . ACCOUNT_PRODUCTS);
|
return $this->returnBulk(ENTITY_PRODUCT, $action, $ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,6 +188,11 @@ Route::group(['middleware' => 'auth:user'], function() {
|
|||||||
Route::get('api/credits/{client_id?}', ['as'=>'api.credits', 'uses'=>'CreditController@getDatatable']);
|
Route::get('api/credits/{client_id?}', ['as'=>'api.credits', 'uses'=>'CreditController@getDatatable']);
|
||||||
Route::post('credits/bulk', 'CreditController@bulk');
|
Route::post('credits/bulk', 'CreditController@bulk');
|
||||||
|
|
||||||
|
Route::get('api/products', ['as'=>'api.products', 'uses'=>'ProductController@getDatatable']);
|
||||||
|
Route::resource('products', 'ProductController');
|
||||||
|
Route::post('products/bulk', 'ProductController@bulk');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/resend_confirmation', 'AccountController@resendConfirmation');
|
Route::get('/resend_confirmation', 'AccountController@resendConfirmation');
|
||||||
Route::post('/update_setup', 'AppController@updateSetup');
|
Route::post('/update_setup', 'AppController@updateSetup');
|
||||||
|
|
||||||
@ -230,10 +235,6 @@ Route::group([
|
|||||||
Route::resource('tokens', 'TokenController');
|
Route::resource('tokens', 'TokenController');
|
||||||
Route::post('tokens/bulk', 'TokenController@bulk');
|
Route::post('tokens/bulk', 'TokenController@bulk');
|
||||||
|
|
||||||
Route::get('api/products', ['as'=>'api.products', 'uses'=>'ProductController@getDatatable']);
|
|
||||||
Route::resource('products', 'ProductController');
|
|
||||||
Route::post('products/bulk', 'ProductController@bulk');
|
|
||||||
|
|
||||||
Route::get('api/tax_rates', ['as'=>'api.tax_rates', 'uses'=>'TaxRateController@getDatatable']);
|
Route::get('api/tax_rates', ['as'=>'api.tax_rates', 'uses'=>'TaxRateController@getDatatable']);
|
||||||
Route::resource('tax_rates', 'TaxRateController');
|
Route::resource('tax_rates', 'TaxRateController');
|
||||||
Route::post('tax_rates/bulk', 'TaxRateController@bulk');
|
Route::post('tax_rates/bulk', 'TaxRateController@bulk');
|
||||||
|
@ -254,6 +254,7 @@ class EntityModel extends Eloquent
|
|||||||
$icons = [
|
$icons = [
|
||||||
'dashboard' => 'tachometer',
|
'dashboard' => 'tachometer',
|
||||||
'clients' => 'users',
|
'clients' => 'users',
|
||||||
|
'products' => 'cube',
|
||||||
'invoices' => 'file-pdf-o',
|
'invoices' => 'file-pdf-o',
|
||||||
'payments' => 'credit-card',
|
'payments' => 'credit-card',
|
||||||
'recurring_invoices' => 'files-o',
|
'recurring_invoices' => 'files-o',
|
||||||
|
@ -19,13 +19,12 @@ class ProductRepository extends BaseRepository
|
|||||||
|
|
||||||
public function find($accountId)
|
public function find($accountId)
|
||||||
{
|
{
|
||||||
return DB::table('products')
|
$query = DB::table('products')
|
||||||
->leftJoin('tax_rates', function($join) {
|
->leftJoin('tax_rates', function($join) {
|
||||||
$join->on('tax_rates.id', '=', 'products.default_tax_rate_id')
|
$join->on('tax_rates.id', '=', 'products.default_tax_rate_id')
|
||||||
->whereNull('tax_rates.deleted_at');
|
->whereNull('tax_rates.deleted_at');
|
||||||
})
|
})
|
||||||
->where('products.account_id', '=', $accountId)
|
->where('products.account_id', '=', $accountId)
|
||||||
->where('products.deleted_at', '=', null)
|
|
||||||
->select(
|
->select(
|
||||||
'products.public_id',
|
'products.public_id',
|
||||||
'products.product_key',
|
'products.product_key',
|
||||||
@ -35,6 +34,12 @@ class ProductRepository extends BaseRepository
|
|||||||
'tax_rates.rate as tax_rate',
|
'tax_rates.rate as tax_rate',
|
||||||
'products.deleted_at'
|
'products.deleted_at'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!\Session::get('show_trash:product')) {
|
||||||
|
$query->where('products.deleted_at', '=', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save($data, $product = null)
|
public function save($data, $product = null)
|
||||||
|
@ -10,20 +10,4 @@ use App\Models\User;
|
|||||||
class ProductPolicy extends EntityPolicy
|
class ProductPolicy extends EntityPolicy
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @param User $user
|
|
||||||
* @param $item
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function edit(User $user, $item) {
|
|
||||||
return $user->hasPermission('admin');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param User $user
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function create(User $user) {
|
|
||||||
return $user->hasPermission('admin');
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<?php namespace App\Services;
|
<?php namespace App\Services;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use Utils;
|
||||||
use App\Ninja\Repositories\ProductRepository;
|
use App\Ninja\Repositories\ProductRepository;
|
||||||
use App\Ninja\Datatables\ProductDatatable;
|
use App\Ninja\Datatables\ProductDatatable;
|
||||||
|
|
||||||
@ -41,9 +43,13 @@ class ProductService extends BaseService
|
|||||||
*/
|
*/
|
||||||
public function getDatatable($accountId)
|
public function getDatatable($accountId)
|
||||||
{
|
{
|
||||||
$datatable = new ProductDatatable(false);
|
$datatable = new ProductDatatable(true);
|
||||||
$query = $this->productRepo->find($accountId);
|
$query = $this->productRepo->find($accountId);
|
||||||
|
|
||||||
|
if(!Utils::hasPermission('view_all')){
|
||||||
|
$query->where('products.user_id', '=', Auth::user()->id);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->datatableService->createDatatable($datatable, $query);
|
return $this->datatableService->createDatatable($datatable, $query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ $LANG = array(
|
|||||||
'view_as_recipient' => 'View as recipient',
|
'view_as_recipient' => 'View as recipient',
|
||||||
'product_library' => 'Product Library',
|
'product_library' => 'Product Library',
|
||||||
'product' => 'Product',
|
'product' => 'Product',
|
||||||
'products' => 'Product Library',
|
'products' => 'Products',
|
||||||
'fill_products' => 'Auto-fill products',
|
'fill_products' => 'Auto-fill products',
|
||||||
'fill_products_help' => 'Selecting a product will automatically <b>fill in the description and cost</b>',
|
'fill_products_help' => 'Selecting a product will automatically <b>fill in the description and cost</b>',
|
||||||
'update_products' => 'Auto-update products',
|
'update_products' => 'Auto-update products',
|
||||||
@ -2136,7 +2136,7 @@ $LANG = array(
|
|||||||
'update' => 'Update',
|
'update' => 'Update',
|
||||||
'invoice_fields_help' => 'Drag and drop fields to change their order and location',
|
'invoice_fields_help' => 'Drag and drop fields to change their order and location',
|
||||||
'new_category' => 'New Category',
|
'new_category' => 'New Category',
|
||||||
|
'restore_product' => 'Restore Product',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3,11 +3,9 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
@parent
|
@parent
|
||||||
|
|
||||||
@include('accounts.nav', ['selected' => ACCOUNT_PRODUCTS])
|
|
||||||
|
|
||||||
{!! Former::open($url)->method($method)
|
{!! Former::open($url)->method($method)
|
||||||
->rules(['product_key' => 'required|max:255'])
|
->rules(['product_key' => 'required|max:255'])
|
||||||
->addClass('warn-on-exit') !!}
|
->addClass('col-md-10 col-md-offset-1 warn-on-exit') !!}
|
||||||
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
@ -22,7 +20,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
{!! Former::text('product_key')->label('texts.product') !!}
|
{!! Former::text('product_key')->label('texts.product') !!}
|
||||||
{!! Former::textarea('notes') !!}
|
{!! Former::textarea('notes')->rows(6) !!}
|
||||||
{!! Former::text('cost') !!}
|
{!! Former::text('cost') !!}
|
||||||
|
|
||||||
@if ($account->invoice_item_taxes)
|
@if ($account->invoice_item_taxes)
|
||||||
@ -36,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! Former::actions(
|
{!! Former::actions(
|
||||||
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/products'))->appendIcon(Icon::create('remove-circle')),
|
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/products'))->appendIcon(Icon::create('remove-circle')),
|
||||||
Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))
|
Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))
|
||||||
) !!}
|
) !!}
|
||||||
|
|
||||||
|
@ -24,26 +24,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! Button::primary(trans('texts.create_product'))
|
|
||||||
->asLinkTo(URL::to('/products/create'))
|
|
||||||
->withAttributes(['class' => 'pull-right'])
|
|
||||||
->appendIcon(Icon::create('plus-sign')) !!}
|
|
||||||
|
|
||||||
@include('partials.bulk_form', ['entityType' => ENTITY_PRODUCT])
|
|
||||||
|
|
||||||
{!! Datatable::table()
|
|
||||||
->addColumn($columns)
|
|
||||||
->setUrl(url('api/products/'))
|
|
||||||
->setOptions('sPaginationType', 'bootstrap')
|
|
||||||
->setOptions('bFilter', false)
|
|
||||||
->setOptions('bAutoWidth', false)
|
|
||||||
//->setOptions('aoColumns', [[ "sWidth"=> "15%" ], [ "sWidth"=> "35%" ]])
|
|
||||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[3]]])
|
|
||||||
->render('datatable') !!}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
window.onDatatableReady = actionListHandler;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
@stop
|
@stop
|
@ -484,14 +484,15 @@
|
|||||||
@foreach ([
|
@foreach ([
|
||||||
'dashboard' => false,
|
'dashboard' => false,
|
||||||
'clients' => false,
|
'clients' => false,
|
||||||
|
'products' => false,
|
||||||
|
'invoices' => false,
|
||||||
|
'payments' => false,
|
||||||
|
'recurring_invoices' => 'recurring',
|
||||||
'credits' => false,
|
'credits' => false,
|
||||||
|
'quotes' => false,
|
||||||
'tasks' => false,
|
'tasks' => false,
|
||||||
'expenses' => false,
|
'expenses' => false,
|
||||||
'vendors' => false,
|
'vendors' => false,
|
||||||
'quotes' => false,
|
|
||||||
'invoices' => false,
|
|
||||||
'recurring_invoices' => 'recurring',
|
|
||||||
'payments' => false,
|
|
||||||
'settings' => false,
|
'settings' => false,
|
||||||
] as $key => $value)
|
] as $key => $value)
|
||||||
{!! Form::nav_link($key, $value ?: $key) !!}
|
{!! Form::nav_link($key, $value ?: $key) !!}
|
||||||
@ -509,6 +510,7 @@
|
|||||||
@foreach([
|
@foreach([
|
||||||
'dashboard',
|
'dashboard',
|
||||||
'clients',
|
'clients',
|
||||||
|
'products',
|
||||||
'invoices',
|
'invoices',
|
||||||
'payments',
|
'payments',
|
||||||
'recurring_invoices',
|
'recurring_invoices',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user