mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
Working on product management
This commit is contained in:
parent
9b149189fb
commit
6e86f1904a
@ -189,6 +189,42 @@ class AccountController extends \BaseController {
|
||||
|
||||
return View::make('accounts.custom_fields', $data);
|
||||
}
|
||||
else if ($section == ACCOUNT_PRODUCTS)
|
||||
{
|
||||
$data = [
|
||||
'account' => Auth::user()->account
|
||||
];
|
||||
|
||||
return View::make('accounts.products', $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function getProducts()
|
||||
{
|
||||
$query = DB::table('products')
|
||||
->where('products.account_id', '=', Auth::user()->account_id)
|
||||
->where('products.deleted_at', '=', null)
|
||||
->select('products.public_id', 'products.product_key', 'products.notes', 'products.cost');
|
||||
|
||||
|
||||
return Datatable::query($query)
|
||||
->addColumn('product_key', function($model) { return link_to('company/products/' . $model->public_id . '/edit', $model->product_key); })
|
||||
->addColumn('notes', function($model) { return $model->notes; })
|
||||
->addColumn('cost', function($model) { return Utils::formatMoney($model->cost); })
|
||||
->addColumn('dropdown', function($model)
|
||||
{
|
||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
'.trans('texts.select').' <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('company/products/'.$model->public_id) . '/edit">'.uctrans('texts.edit_product').'</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="' . URL::to('company/products/'.$model->public_id) . '/archive">'.uctrans('texts.archive_product').'</a></li>
|
||||
</ul>
|
||||
</div>';
|
||||
})
|
||||
->make();
|
||||
}
|
||||
|
||||
public function doSection($section = ACCOUNT_DETAILS)
|
||||
@ -221,6 +257,75 @@ class AccountController extends \BaseController {
|
||||
{
|
||||
return AccountController::saveCustomFields();
|
||||
}
|
||||
else if ($section == ACCOUNT_PRODUCTS)
|
||||
{
|
||||
return AccountController::saveProducts();
|
||||
}
|
||||
}
|
||||
|
||||
public function showProduct($productPublicId)
|
||||
{
|
||||
$data = [
|
||||
'product' => Product::scope($productPublicId)->firstOrFail(),
|
||||
'url' => 'company/products/' . $productPublicId,
|
||||
'title' => trans('texts.edit_product')
|
||||
];
|
||||
|
||||
return View::make('accounts.product', $data);
|
||||
}
|
||||
|
||||
public function createProduct()
|
||||
{
|
||||
$data = [
|
||||
'product' => null,
|
||||
'url' => 'company/products/',
|
||||
'title' => trans('texts.create_product')
|
||||
];
|
||||
|
||||
return View::make('accounts.product', $data);
|
||||
}
|
||||
|
||||
public function saveProduct($productPublicId = false)
|
||||
{
|
||||
if ($productPublicId)
|
||||
{
|
||||
$product = Product::scope($productPublicId)->firstOrFail();
|
||||
}
|
||||
else
|
||||
{
|
||||
$product = Product::createNew();
|
||||
}
|
||||
|
||||
$product->product_key = trim(Input::get('product_key'));
|
||||
$product->notes = trim(Input::get('notes'));
|
||||
$product->cost = trim(Input::get('cost'));
|
||||
$product->save();
|
||||
|
||||
$message = $productPublicId ? trans('texts.updated_product') : trans('texts.created_product');
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('company/products');
|
||||
}
|
||||
|
||||
public function archiveProduct($productPublicId)
|
||||
{
|
||||
$product = Product::scope($productPublicId)->firstOrFail();
|
||||
$product->delete();
|
||||
|
||||
Session::flash('message', trans('texts.archived_product'));
|
||||
return Redirect::to('company/products');
|
||||
}
|
||||
|
||||
private function saveProducts()
|
||||
{
|
||||
$account = Auth::user()->account;
|
||||
|
||||
$account->fill_products = Input::get('fill_products') ? true : false;
|
||||
$account->update_products = Input::get('update_products') ? true : false;
|
||||
$account->save();
|
||||
|
||||
Session::flash('message', trans('texts.updated_settings'));
|
||||
return Redirect::to('company/products');
|
||||
}
|
||||
|
||||
private function saveCustomFields()
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddProductsSettings extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
$table->boolean('fill_products')->default(true);
|
||||
$table->boolean('update_products')->default(true);
|
||||
});
|
||||
|
||||
DB::table('accounts')->update(['fill_products' => true]);
|
||||
DB::table('accounts')->update(['update_products' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
$table->dropColumn('fill_products');
|
||||
$table->dropColumn('update_products');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -326,6 +326,17 @@ return array(
|
||||
'set_name' => 'Set your company name',
|
||||
'view_as_recipient' => 'View as recipient',
|
||||
|
||||
|
||||
|
||||
'product' => 'Product',
|
||||
'products' => 'Products',
|
||||
'fill_products' => 'Auto-fill products',
|
||||
'fill_products_help' => 'Selecting a product will automatically <b>set the description and cost</b>',
|
||||
'update_products' => 'Auto-update products',
|
||||
'update_products_help' => 'Updating an invoice will automatically <b>update the products</b>',
|
||||
'create_product' => 'Create Product',
|
||||
'edit_product' => 'Edit Product',
|
||||
'archive_product' => 'Archive Product',
|
||||
'updated_product' => 'Successfully updated product',
|
||||
'created_product' => 'Successfully created product',
|
||||
'archived_product' => 'Successfully archived product',
|
||||
|
||||
);
|
||||
|
@ -147,8 +147,13 @@ class Utils
|
||||
return $phoneNumber;
|
||||
}
|
||||
|
||||
public static function formatMoney($value, $currencyId)
|
||||
public static function formatMoney($value, $currencyId = false)
|
||||
{
|
||||
if (!$currencyId)
|
||||
{
|
||||
$currencyId = Session::get(SESSION_CURRENCY);
|
||||
}
|
||||
|
||||
$currency = Currency::remember(DEFAULT_QUERY_CACHE)->find($currencyId);
|
||||
|
||||
if (!$currency)
|
||||
|
@ -207,12 +207,9 @@ class InvoiceRepository
|
||||
$product->product_key = trim($item->product_key);
|
||||
}
|
||||
|
||||
/*
|
||||
$product->notes = $item->notes;
|
||||
$product->cost = $item->cost;
|
||||
$product->qty = $item->qty;
|
||||
*/
|
||||
|
||||
//$product->qty = $item->qty;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,12 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::get('dashboard', 'DashboardController@index');
|
||||
Route::get('view_archive/{entity_type}/{visible}', 'AccountController@setTrashVisible');
|
||||
Route::get('force_inline_pdf', 'UserController@forcePDFJS');
|
||||
|
||||
Route::get('api/products', array('as'=>'api.products', 'uses'=>'AccountController@getProducts'));
|
||||
Route::get('company/products/{product_id}/edit', 'AccountController@showProduct');
|
||||
Route::get('company/products/{product_id}/archive', 'AccountController@archiveProduct');
|
||||
Route::get('company/products/create', 'AccountController@createProduct');
|
||||
Route::post('company/products/{product_id?}', 'AccountController@saveProduct');
|
||||
|
||||
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
||||
Route::get('company/{section?}', 'AccountController@showSection');
|
||||
@ -67,7 +73,7 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::post('user/setTheme', 'UserController@setTheme');
|
||||
Route::post('remove_logo', 'AccountController@removeLogo');
|
||||
Route::post('account/go_pro', 'AccountController@enableProPlan');
|
||||
|
||||
|
||||
Route::resource('clients', 'ClientController');
|
||||
Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable'));
|
||||
Route::get('api/activities/{client_id?}', array('as'=>'api.activities', 'uses'=>'ActivityController@getDatatable'));
|
||||
@ -124,6 +130,7 @@ define('ACCOUNT_PAYMENTS', 'payments');
|
||||
define('ACCOUNT_MAP', 'import_map');
|
||||
define('ACCOUNT_EXPORT', 'export');
|
||||
define('ACCOUNT_CUSTOM_FIELDS', 'custom_fields');
|
||||
define('ACCOUNT_PRODUCTS', 'products');
|
||||
|
||||
define('DEFAULT_INVOICE_NUMBER', '0001');
|
||||
define('RECENTLY_VIEWED_LIMIT', 8);
|
||||
|
@ -4,10 +4,11 @@
|
||||
|
||||
<ul class="nav nav-tabs nav nav-justified">
|
||||
{{ HTML::nav_link('company/details', 'company_details') }}
|
||||
{{ HTML::nav_link('company/payments', 'online_payments') }}
|
||||
{{ HTML::nav_link('company/notifications', 'notifications') }}
|
||||
{{ HTML::nav_link('company/payments', 'online_payments') }}
|
||||
{{-- HTML::nav_link('company/products', 'products') --}}
|
||||
{{ HTML::nav_link('company/notifications', 'notifications') }}
|
||||
{{ HTML::nav_link('company/import_export', 'import_export', 'company/import_map') }}
|
||||
{{-- HTML::nav_link('company/custom_fields', 'custom_fields') --}}
|
||||
{{-- HTML::nav_link('company/custom_fields', 'custom_fields') --}}
|
||||
</ul>
|
||||
<p> </p>
|
||||
|
||||
|
27
app/views/accounts/product.blade.php
Normal file
27
app/views/accounts/product.blade.php
Normal file
@ -0,0 +1,27 @@
|
||||
@extends('accounts.nav')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
|
||||
{{ Former::open($url)->addClass('col-md-8 col-md-offset-2 warn-on-exit') }}
|
||||
|
||||
|
||||
{{ Former::legend($title) }}
|
||||
|
||||
@if ($product)
|
||||
{{ Former::populate($product) }}
|
||||
{{ Former::populateField('cost', number_format($product->cost, 2)) }}
|
||||
@endif
|
||||
|
||||
{{ Former::text('product_key') }}
|
||||
{{ Former::textarea('notes') }}
|
||||
{{ Former::text('cost') }}
|
||||
|
||||
{{ Former::actions(
|
||||
Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk'),
|
||||
Button::lg_default_link('company/products', 'Cancel')->append_with_icon('remove-circle')
|
||||
) }}
|
||||
|
||||
{{ Former::close() }}
|
||||
|
||||
@stop
|
48
app/views/accounts/products.blade.php
Normal file
48
app/views/accounts/products.blade.php
Normal file
@ -0,0 +1,48 @@
|
||||
@extends('accounts.nav')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
|
||||
{{ Former::open()->addClass('col-md-10 col-md-offset-1 warn-on-exit') }}
|
||||
{{ Former::populateField('fill_products', intval($account->fill_products)) }}
|
||||
{{ Former::populateField('update_products', intval($account->update_products)) }}
|
||||
|
||||
|
||||
{{ Former::legend('products') }}
|
||||
{{ Former::checkbox('fill_products')->text(trans('texts.fill_products_help')) }}
|
||||
{{ Former::checkbox('update_products')->text(trans('texts.update_products_help')) }}
|
||||
|
||||
{{ Former::actions( Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk') ) }}
|
||||
{{ Former::close() }}
|
||||
|
||||
{{ Button::success_link(URL::to('company/products/create'), trans("texts.create_product"), array('class' => 'pull-right'))->append_with_icon('plus-sign') }}
|
||||
|
||||
{{ Datatable::table()
|
||||
->addColumn(
|
||||
trans('texts.product'),
|
||||
trans('texts.description'),
|
||||
trans('texts.unit_cost'),
|
||||
trans('texts.action'))
|
||||
->setUrl(url('api/products/'))
|
||||
->setOptions('sPaginationType', 'bootstrap')
|
||||
->setOptions('bFilter', false)
|
||||
->render('datatable') }}
|
||||
|
||||
<script>
|
||||
|
||||
window.onDatatableReady = function() {
|
||||
$('tbody tr').mouseover(function() {
|
||||
$(this).closest('tr').find('.tr-action').css('visibility','visible');
|
||||
}).mouseout(function() {
|
||||
$dropdown = $(this).closest('tr').find('.tr-action');
|
||||
if (!$dropdown.hasClass('open')) {
|
||||
$dropdown.css('visibility','hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@stop
|
@ -158,7 +158,7 @@
|
||||
|
||||
<center class="buttons">
|
||||
{{ Button::lg_primary_submit_success('Save')->append_with_icon('floppy-disk') }}
|
||||
{{ Button::lg_default_link('clients/' . ($client ? $client->public_id : ''), 'Cancel')->append_with_icon('remove-circle'); }}
|
||||
{{ Button::lg_default_link('clients/' . ($client ? $client->public_id : ''), 'Cancel')->append_with_icon('remove-circle'); }}
|
||||
</center>
|
||||
|
||||
{{ Former::close() }}
|
||||
|
@ -137,6 +137,7 @@
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>{{ link_to('company/details', uctrans('texts.company_details')) }}</li>
|
||||
<li>{{ link_to('company/payments', uctrans('texts.online_payments')) }}</li>
|
||||
<!--<li>{{ link_to('company/products', uctrans('texts.products')) }}</li>-->
|
||||
<li>{{ link_to('company/notifications', uctrans('texts.notifications')) }}</li>
|
||||
<li>{{ link_to('company/import_export', uctrans('texts.import_export')) }}</li>
|
||||
<!--<li><a href="{{ url('company/custom_fields') }}">{{ uctrans('texts.custom_fields') . Utils::getProLabel(ACCOUNT_CUSTOM_FIELDS) }}</a></li>-->
|
||||
|
@ -1198,9 +1198,7 @@
|
||||
|
||||
self.addContact = function() {
|
||||
var contact = new ContactModel();
|
||||
if (self.contacts().length == 0) {
|
||||
contact.send_invoice(true);
|
||||
}
|
||||
contact.send_invoice(true);
|
||||
self.contacts.push(contact);
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user