diff --git a/app/Filters/ProductFilters.php b/app/Filters/ProductFilters.php new file mode 100644 index 000000000000..ea7de7901c05 --- /dev/null +++ b/app/Filters/ProductFilters.php @@ -0,0 +1,113 @@ +builder; + + return $this->builder->where(function ($query) use ($filter) { + $query->where('products.product_key', 'like', '%'.$filter.'%') + ->orWhere('products.notes', 'like', '%'.$filter.'%') + ->orWhere('products.custom_value1', 'like' , '%'.$filter.'%') + ->orWhere('products.custom_value2', 'like' , '%'.$filter.'%') + ->orWhere('products.custom_value3', 'like' , '%'.$filter.'%') + ->orWhere('products.custom_value4', 'like' , '%'.$filter.'%'); + }); + } + + /** + * Filters the list based on the status + * archived, active, deleted + * + * @param string filter + * @return Illuminate\Database\Query\Builder + */ + public function status(string $filter = '') : Builder + { + if(strlen($filter) == 0) + return $this->builder; + + $table = 'products'; + $filters = explode(',', $filter); + + return $this->builder->where(function ($query) use ($filters, $table) { + $query->whereNull($table . '.id'); + + if (in_array(parent::STATUS_ACTIVE, $filters)) { + $query->orWhereNull($table . '.deleted_at'); + } + + if (in_array(parent::STATUS_ARCHIVED, $filters)) { + $query->orWhere(function ($query) use ($table) { + $query->whereNotNull($table . '.deleted_at'); + + if (! in_array($table, ['users'])) { + $query->where($table . '.is_deleted', '=', 0); + } + }); + } + + if (in_array(parent::STATUS_DELETED, $filters)) { + $query->orWhere($table . '.is_deleted', '=', 1); + } + }); + } + + /** + * Sorts the list based on $sort + * + * @param string sort formatted as column|asc + * @return Illuminate\Database\Query\Builder + */ + public function sort(string $sort) : Builder + { + $sort_col = explode("|", $sort); + return $this->builder->orderBy($sort_col[0], $sort_col[1]); + } + + /** + * Returns the base query + * + * @param int company_id + * @return Illuminate\Database\Query\Builder + * @deprecated + */ + public function baseQuery(int $company_id, User $user) : Builder + { + + } + + /** + * Filters the query by the users company ID + * + * @param $company_id The company Id + * @return Illuminate\Database\Query\Builder + */ + public function entityFilter() + { + + return $this->builder->whereCompanyId(auth()->user()->company()->id); + + } + +} \ No newline at end of file diff --git a/app/Filters/QueryFilters.php b/app/Filters/QueryFilters.php index 7f44bb74965c..01ba296961fa 100644 --- a/app/Filters/QueryFilters.php +++ b/app/Filters/QueryFilters.php @@ -50,7 +50,9 @@ abstract class QueryFilters */ public function __construct(Request $request) { + $this->request = $request; + } /** @@ -87,7 +89,9 @@ abstract class QueryFilters */ public function filters() { + return $this->request->all(); + } /** @@ -98,6 +102,7 @@ abstract class QueryFilters */ public function split($value) : stdClass { + $exploded_array = explode(":", $value); $parts = new stdClass; @@ -106,6 +111,7 @@ abstract class QueryFilters $parts->operator = $this->operatorConvertor($exploded_array[1]); return $parts; + } /** @@ -116,6 +122,7 @@ abstract class QueryFilters */ private function operatorConvertor(string $operator) : string { + switch ($operator) { case 'lt': return '<'; @@ -135,6 +142,7 @@ abstract class QueryFilters default: return '='; break; + } } } \ No newline at end of file diff --git a/app/Helpers/Invoice/InvoiceHelper.php b/app/Helpers/Invoice/InvoiceCalc.php similarity index 87% rename from app/Helpers/Invoice/InvoiceHelper.php rename to app/Helpers/Invoice/InvoiceCalc.php index c2ff320260e9..63f5a649f6d6 100644 --- a/app/Helpers/Invoice/InvoiceHelper.php +++ b/app/Helpers/Invoice/InvoiceCalc.php @@ -4,10 +4,12 @@ namespace App\Helpers\Invoice; use App\Models\Invoice; -class InvoiceHelper +class InvoiceCalc { + public function __construct(Invoice $invoice) { $this->invoice = $invoice; } + } \ No newline at end of file diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 370aaeedd331..cdc0c9baf9fa 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -16,7 +16,7 @@ class AccountController extends BaseController { parent::__construct(); - $this->middleware('guest'); + //$this->middleware('guest'); } /** @@ -26,7 +26,7 @@ class AccountController extends BaseController */ public function index() { - return view('signup.index'); + // return view('signup.index'); } diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index dd487bd1d8e8..832fd3d325dd 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -54,7 +54,6 @@ class ClientController extends BaseController } /** - * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View */ public function index(ClientFilters $filters) { diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index c7022468cfa9..6fa07e3562d7 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -36,7 +36,7 @@ class CompanyController extends BaseController */ public function index() { - return view('signup.index'); +// return view('signup.index'); } diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php new file mode 100644 index 000000000000..004968665d51 --- /dev/null +++ b/app/Http/Controllers/ProductController.php @@ -0,0 +1,97 @@ +listResponse($products); + + } + + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + // + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + // + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + // + } +} diff --git a/app/Models/Product.php b/app/Models/Product.php index 2f47c9b85954..3d053bf6a88e 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -2,26 +2,30 @@ namespace App\Models; +use App\Models\Filterable; use App\Utils\Traits\MakesHash; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; class Product extends BaseModel { use MakesHash; - + use SoftDeletes; + use Filterable; + protected $guarded = [ 'id', ]; - protected $appends = ['product_id']; - - public function getRouteKeyName() + public function company() { - return 'product_id'; + return $this->belongsTo(Company::class); } - public function getProductIdAttribute() + public function user() { - return $this->encodePrimaryKey($this->id); + return $this->belongsTo(User::class); } + + } diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index bb26e29bfe41..b3b85a858fa5 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -4,13 +4,14 @@ namespace App\Transformers; use App\Models\Account; use App\Models\Payment; +use App\Utils\Traits\MakesHash; /** * Class AccountTransformer. */ class AccountTransformer extends EntityTransformer { - + use MakesHash; /** * @SWG\Property(property="account_key", type="string", example="123456") */ @@ -39,7 +40,7 @@ class AccountTransformer extends EntityTransformer public function transform(Account $account) { return [ - 'id' => $account->id, + 'id' => $this->encodePrimaryKey($account->id), ]; } diff --git a/app/Transformers/ClientContactTransformer.php b/app/Transformers/ClientContactTransformer.php index c64376efc4b4..095274799647 100644 --- a/app/Transformers/ClientContactTransformer.php +++ b/app/Transformers/ClientContactTransformer.php @@ -3,6 +3,7 @@ namespace App\Transformers; use App\Models\ClientContact; +use App\Utils\Traits\MakesHash; /** * Class ContactTransformer. @@ -11,6 +12,7 @@ use App\Models\ClientContact; */ class ClientContactTransformer extends EntityTransformer { + use MakesHash; /** * @param ClientContact $contact * @@ -20,7 +22,7 @@ class ClientContactTransformer extends EntityTransformer public function transform(ClientContact $contact) { return [ - 'id' => (int) $contact->public_id, + 'id' => $this->encodePrimaryKey($contact->id), 'first_name' => $contact->first_name ?: '', 'last_name' => $contact->last_name ?: '', 'email' => $contact->email ?: '', diff --git a/app/Transformers/ClientTransformer.php b/app/Transformers/ClientTransformer.php index 7624d33bad9b..01eb77be8a40 100644 --- a/app/Transformers/ClientTransformer.php +++ b/app/Transformers/ClientTransformer.php @@ -4,12 +4,14 @@ namespace App\Transformers; use App\Models\Client; use App\Models\ClientContact; +use App\Utils\Traits\MakesHash; /** * @SWG\Definition(definition="Client", @SWG\Xml(name="Client")) */ class ClientTransformer extends EntityTransformer { + use MakesHash; /** * @SWG\Property(property="id", type="integer", example=1, readOnly=true) */ @@ -45,7 +47,7 @@ class ClientTransformer extends EntityTransformer public function transform(Client $client) { return [ - 'id' => (int) $client->id, + 'id' => $this->encodePrimaryKey($client->id), 'name' => $client->name ?: '', 'website' => $client->website ?: '', 'private_notes' => $client->private_notes ?: '', diff --git a/app/Transformers/InvoiceItemTransformer.php b/app/Transformers/InvoiceItemTransformer.php index 434a53b24914..ece31d1fe040 100644 --- a/app/Transformers/InvoiceItemTransformer.php +++ b/app/Transformers/InvoiceItemTransformer.php @@ -24,7 +24,7 @@ class InvoiceItemTransformer extends EntityTransformer public function transform($item) { return [ - 'id' => (int) $item->public_id, + 'id' => (int) $item->id, 'product_key' => $item->product_key, 'updated_at' => $item->updated_at, 'archived_at' => $item->deleted_at, diff --git a/app/Transformers/InvoiceTransformer.php b/app/Transformers/InvoiceTransformer.php index 8a6f208fac7b..a4a3ad695b93 100644 --- a/app/Transformers/InvoiceTransformer.php +++ b/app/Transformers/InvoiceTransformer.php @@ -9,6 +9,7 @@ use App\Models\Invoice; */ class InvoiceTransformer extends EntityTransformer { + use MakesHash; /** * @SWG\Property(property="id", type="integer", example=1, readOnly=true) * @SWG\Property(property="amount", type="number", format="float", example=10, readOnly=true) @@ -75,7 +76,7 @@ class InvoiceTransformer extends EntityTransformer public function includeInvoiceItems(Invoice $invoice) { - $transformer = new InvoiceItemTransformer($this->account, $this->serializer); + $transformer = new InvoiceItemTransformer($this->serializer); return $this->includeCollection($invoice->invoice_items, $transformer, ENTITY_INVOICE_ITEM); } @@ -122,7 +123,7 @@ class InvoiceTransformer extends EntityTransformer public function transform(Invoice $invoice) { return [ - 'id' => (int) $invoice->public_id, + 'id' => $this->encodePrimaryKey($invoice->id), 'amount' => (float) $invoice->amount, 'balance' => (float) $invoice->balance, 'client_id' => (int) ($this->client ? $this->client->public_id : $invoice->client->public_id), diff --git a/app/Transformers/PaymentTransformer.php b/app/Transformers/PaymentTransformer.php index 1351109eab75..0e21d97dcc33 100644 --- a/app/Transformers/PaymentTransformer.php +++ b/app/Transformers/PaymentTransformer.php @@ -6,12 +6,14 @@ use App\Models\Account; use App\Models\Client; use App\Models\Invoice; use App\Models\Payment; +use App\Utils\Traits\MakesHash; /** * @SWG\Definition(definition="Payment", required={"invoice_id"}, @SWG\Xml(name="Payment")) */ class PaymentTransformer extends EntityTransformer { + use MakesHash; /** * @SWG\Property(property="id", type="integer", example=1, readOnly=true) * @SWG\Property(property="amount", type="number", format="float", example=10, readOnly=true) @@ -60,7 +62,7 @@ class PaymentTransformer extends EntityTransformer public function transform(Payment $payment) { return [ - 'id' => (int) $payment->id, + 'id' => $this->encodePrimaryKey($payment->id), 'amount' => (float) $payment->amount, 'transaction_reference' => $payment->transaction_reference ?: '', 'payment_date' => $payment->payment_date ?: '', diff --git a/app/Transformers/ProductTransformer.php b/app/Transformers/ProductTransformer.php new file mode 100644 index 000000000000..696a30eaae23 --- /dev/null +++ b/app/Transformers/ProductTransformer.php @@ -0,0 +1,44 @@ + $this->encodePrimaryKey($product->id), + 'product_key' => $product->product_key, + 'notes' => $product->notes, + 'cost' => (float) $product->cost, + 'qty' => (float) ($product->qty ?: 0.0), + 'tax_name1' => $product->tax_name1 ?: '', + 'tax_rate1' => (float) $product->tax_rate1, + 'tax_name2' => $product->tax_name2 ?: '', + 'tax_rate2' => (float) $product->tax_rate2, + 'updated_at' => $product->updated_at, + 'archived_at' => $product->deleted_at, + 'custom_value1' => $product->custom_value1 ?: '', + 'custom_value2' => $product->custom_value2 ?: '', + 'custom_value3' => $product->custom_value2 ?: '', + 'custom_value4' => $product->custom_value2 ?: '', + 'is_deleted' => (bool) $product->is_deleted, + ]; + } +} diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index 106416fed8a4..72a7dab6a9eb 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -4,12 +4,14 @@ namespace App\Transformers; use App\Models\Account; use App\Models\User; +use App\Utils\Traits\MakesHash; /** * @SWG\Definition(definition="User", @SWG\Xml(name="User")) */ class UserTransformer extends EntityTransformer { + use MakesHash; /** * @SWG\Property(property="id", type="integer", example=1, readOnly=true) * @SWG\Property(property="first_name", type="string", example="John") @@ -48,7 +50,7 @@ class UserTransformer extends EntityTransformer public function transform(User $user) { return [ - 'id' => (int) $user->id, + 'id' => $this->encodePrimaryKey($user->id), 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'email' => $user->email, diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php new file mode 100644 index 000000000000..62607abb1cfd --- /dev/null +++ b/database/factories/ProductFactory.php @@ -0,0 +1,21 @@ +define(App\Models\Product::class, function (Faker $faker) { + return [ + 'product_key' => $faker->text(7), + 'notes' => $faker->text(20), + 'cost' => $faker->numberBetween(1,1000), + 'qty' => $faker->numberBetween(1,100), + 'tax_name1' => 'GST', + 'tax_rate1' => 10, + 'tax_name2' => 'VAT', + 'tax_rate2' => 17.5, + 'custom_value1' => $faker->text(20), + 'custom_value2' => $faker->text(20), + 'custom_value3' => $faker->text(20), + 'custom_value4' => $faker->text(20), + 'is_deleted' => false, + ]; +}); diff --git a/database/migrations/2014_10_13_000000_create_users_table.php b/database/migrations/2014_10_13_000000_create_users_table.php index b8bb4238af45..e632fb67d85b 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -428,14 +428,20 @@ class CreateUsersTable extends Migration $t->string('custom_value1')->nullable(); $t->string('custom_value2')->nullable(); + $t->string('custom_value3')->nullable(); + $t->string('custom_value4')->nullable(); $t->string('product_key'); $t->text('notes'); $t->decimal('cost', 13, 2); $t->decimal('qty', 13, 2)->nullable(); - $t->unsignedInteger('stock_level'); - $t->unsignedInteger('min_stock_level'); + $t->string('tax_name1')->nullable(); + $t->decimal('tax_rate1', 13, 3); + $t->string('tax_name2')->nullable(); + $t->decimal('tax_rate2', 13, 3); + + $t->boolean('is_deleted')->default(false); $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index d6617845bbdb..7bc187b14e49 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -88,6 +88,9 @@ class RandomDataSeeder extends Seeder }); + /** Product Factory */ + factory(\App\Models\Product::class,50)->create(['user_id' => $user->id, 'company_id' => $company->id]); + } } diff --git a/routes/api.php b/routes/api.php index fa082f04df4f..93a8b04d16b0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -20,7 +20,7 @@ Route::middleware('auth:api')->get('/user', function (Request $request) { Route::group(['middleware' => ['api_secret_check']], function () { - Route::post('signup', 'AccountController@store')->name('signup.submit'); + Route::post('api/v1/signup', 'AccountController@store')->name('signup.submit'); }); @@ -35,6 +35,10 @@ Route::group(['middleware' => ['db','api_secret_check','token_auth'], 'prefix' = Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk'); + Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit + + Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk'); + Route::resource('quotes', 'QuoteController'); // name = (quotes. index / create / show / update / destroy / edit Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk'); diff --git a/routes/web.php b/routes/web.php index 3921cd54e00d..aef6e3c1a249 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,9 +11,13 @@ Route::post('logout', 'Auth\LoginController@logout')->name('logout'); * Signup Routes */ -Route::redirect('/', '/login', 301); -Route::get('signup', 'AccountController@index')->name('signup'); -Route::post('signup', 'AccountController@store')->name('signup.submit'); +//Route::redirect('/', '/login', 301); +//Route::get('signup', 'AccountController@index')->name('signup'); +//Route::post('signup', 'AccountController@store')->name('signup.submit'); + + +Auth::routes(['register' => false]); + Route::get('contact/login', 'Auth\ContactLoginController@showLoginForm')->name('contact.login'); Route::post('contact/login', 'Auth\ContactLoginController@login')->name('contact.login.submit'); diff --git a/tests/Feature/AccountTest.php b/tests/Feature/AccountTest.php index 2ee3aec4e681..e8c9a152857b 100644 --- a/tests/Feature/AccountTest.php +++ b/tests/Feature/AccountTest.php @@ -64,7 +64,7 @@ class AccountTest extends TestCase 'last_name' => $this->faker->lastName, 'email' => $this->faker->unique()->safeEmail, 'password' => 'ALongAndBrilliantPassword123', - '_token' => csrf_token(), + //'_token' => csrf_token(), 'privacy_policy' => 1, 'terms_of_service' => 1 ]; diff --git a/tests/Feature/ClientTest.php b/tests/Feature/ClientTest.php index 87a68b1dc29b..207c31cf3297 100644 --- a/tests/Feature/ClientTest.php +++ b/tests/Feature/ClientTest.php @@ -137,7 +137,7 @@ class ClientTest extends TestCase 'X-API-TOKEN' => $token, ])->get('/api/v1/clients/'.$this->encodePrimaryKey($client->id)); - $response->assertStatus(302); + $response->assertStatus(200); $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'),