From 6e86f1904a0f7902e2d4336a097bb10799551e25 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 23 Apr 2014 23:30:54 +0300 Subject: [PATCH] Working on product management --- app/controllers/AccountController.php | 105 ++++++++++++++++++ ...014_04_23_170909_add_products_settings.php | 39 +++++++ app/lang/en/texts.php | 15 ++- app/libraries/utils.php | 7 +- app/ninja/repositories/InvoiceRepository.php | 5 +- app/routes.php | 9 +- app/views/accounts/nav.blade.php | 7 +- app/views/accounts/product.blade.php | 27 +++++ app/views/accounts/products.blade.php | 48 ++++++++ app/views/clients/edit.blade.php | 2 +- app/views/header.blade.php | 1 + app/views/invoices/edit.blade.php | 4 +- 12 files changed, 254 insertions(+), 15 deletions(-) create mode 100644 app/database/migrations/2014_04_23_170909_add_products_settings.php create mode 100644 app/views/accounts/product.blade.php create mode 100644 app/views/accounts/products.blade.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 35e6a03c44..3ba4c31f08 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -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 ''; + }) + ->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() diff --git a/app/database/migrations/2014_04_23_170909_add_products_settings.php b/app/database/migrations/2014_04_23_170909_add_products_settings.php new file mode 100644 index 0000000000..a5e5541177 --- /dev/null +++ b/app/database/migrations/2014_04_23_170909_add_products_settings.php @@ -0,0 +1,39 @@ +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'); + }); + } + +} diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index feb37ad86f..fbe066aa9f 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -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 set the description and cost', + 'update_products' => 'Auto-update products', + 'update_products_help' => 'Updating an invoice will automatically update the products', + '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', + ); diff --git a/app/libraries/utils.php b/app/libraries/utils.php index c0fe155957..73408ddfba 100755 --- a/app/libraries/utils.php +++ b/app/libraries/utils.php @@ -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) diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php index c02aa9ae94..1b9b7a9e52 100755 --- a/app/ninja/repositories/InvoiceRepository.php +++ b/app/ninja/repositories/InvoiceRepository.php @@ -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(); } diff --git a/app/routes.php b/app/routes.php index 0128609f73..104360e028 100755 --- a/app/routes.php +++ b/app/routes.php @@ -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); diff --git a/app/views/accounts/nav.blade.php b/app/views/accounts/nav.blade.php index 65d62812ef..35f2cb8235 100755 --- a/app/views/accounts/nav.blade.php +++ b/app/views/accounts/nav.blade.php @@ -4,10 +4,11 @@

 

diff --git a/app/views/accounts/product.blade.php b/app/views/accounts/product.blade.php new file mode 100644 index 0000000000..fb4bf5df2d --- /dev/null +++ b/app/views/accounts/product.blade.php @@ -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 \ No newline at end of file diff --git a/app/views/accounts/products.blade.php b/app/views/accounts/products.blade.php new file mode 100644 index 0000000000..01e1780122 --- /dev/null +++ b/app/views/accounts/products.blade.php @@ -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') }} + + + + +@stop \ No newline at end of file diff --git a/app/views/clients/edit.blade.php b/app/views/clients/edit.blade.php index 657bbf3021..f4b1ff4622 100755 --- a/app/views/clients/edit.blade.php +++ b/app/views/clients/edit.blade.php @@ -158,7 +158,7 @@
{{ 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'); }}
{{ Former::close() }} diff --git a/app/views/header.blade.php b/app/views/header.blade.php index 0004220022..eadcd8fb06 100755 --- a/app/views/header.blade.php +++ b/app/views/header.blade.php @@ -137,6 +137,7 @@