diff --git a/app/Http/Controllers/AccountApiController.php b/app/Http/Controllers/AccountApiController.php index 02697ba039de..65175cdd5ba1 100644 --- a/app/Http/Controllers/AccountApiController.php +++ b/app/Http/Controllers/AccountApiController.php @@ -34,6 +34,13 @@ class AccountApiController extends BaseAPIController $this->accountRepo = $accountRepo; } + public function ping() + { + $headers = Utils::getApiHeaders(); + + return Response::make(RESULT_SUCCESS, 200, $headers); + } + public function register(RegisterRequest $request) { diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index 9dcf243fbe02..568cb4d45f5b 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -306,7 +306,7 @@ class AppController extends BaseController public function stats() { - if (Input::get('password') != env('RESELLER_PASSWORD')) { + if ( ! hash_equals(Input::get('password'), env('RESELLER_PASSWORD'))) { sleep(3); return ''; } diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index 4d03dea14b1d..489053d055f0 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -68,7 +68,19 @@ class BaseAPIController extends Controller } } - protected function returnList($query) + protected function handleAction($request) + { + $entity = $request->entity(); + $action = $request->action; + + $repo = Utils::toCamelCase($this->entityType) . 'Repo'; + + $this->$repo->$action($entity); + + return $this->itemResponse($entity); + } + + protected function listResponse($query) { //\DB::enableQueryLog(); if ($clientPublicId = Input::get('client_id')) { @@ -95,6 +107,16 @@ class BaseAPIController extends Controller return $this->response($data); } + protected function itemResponse($item) + { + $transformerClass = EntityModel::getTransformerName($this->entityType); + $transformer = new $transformerClass(Auth::user()->account, Input::get('serializer')); + + $data = $this->createItem($item, $transformer, $this->entityType); + + return $this->response($data); + } + protected function createItem($data, $transformer, $entityType) { if ($this->serializer && $this->serializer != API_SERIALIZER_JSON) { @@ -112,8 +134,9 @@ class BaseAPIController extends Controller } if (is_a($query, "Illuminate\Database\Eloquent\Builder")) { + $limit = min(MAX_API_PAGE_SIZE, Input::get('per_page', DEFAULT_API_PAGE_SIZE)); $resource = new Collection($query->get(), $transformer, $entityType); - $resource->setPaginator(new IlluminatePaginatorAdapter($query->paginate())); + $resource->setPaginator(new IlluminatePaginatorAdapter($query->paginate($limit))); } else { $resource = new Collection($query, $transformer, $entityType); } @@ -155,7 +178,6 @@ class BaseAPIController extends Controller } - protected function getIncluded() { $data = ['user']; diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 4a33946c7631..2ce7a633f179 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -24,28 +24,4 @@ class BaseController extends Controller $this->layout = View::make($this->layout); } } - - protected function authorizeCreate() { - $this->authorize('create', $this->entityType); - } - - /* - protected function authorizeUpdate($entity) { - $this->authorize('edit', $entity); - } - */ - - protected function authorizeUpdate($input){ - $creating = empty($input['public_id']) || $input['public_id'] == '-1'; - - if($creating){ - $this->authorize('create', $this->entityType); - } - else{ - $className = Utils::getEntityName($this->entityType); - - $object = call_user_func(array("App\\Models\\{$className}", 'scope'), $input['public_id'])->firstOrFail(); - $this->authorize('edit', $object); - } - } } diff --git a/app/Http/Controllers/ClientApiController.php b/app/Http/Controllers/ClientApiController.php index 4457973c7031..ba6b56c952fa 100644 --- a/app/Http/Controllers/ClientApiController.php +++ b/app/Http/Controllers/ClientApiController.php @@ -10,29 +10,19 @@ use App\Ninja\Repositories\ClientRepository; use App\Http\Requests\CreateClientRequest; use App\Http\Controllers\BaseAPIController; use App\Ninja\Transformers\ClientTransformer; -use App\Services\ClientService; use App\Http\Requests\UpdateClientRequest; class ClientApiController extends BaseAPIController { protected $clientRepo; - protected $clientService; protected $entityType = ENTITY_CLIENT; - public function __construct(ClientRepository $clientRepo, ClientService $clientService) + public function __construct(ClientRepository $clientRepo) { parent::__construct(); $this->clientRepo = $clientRepo; - $this->clientService = $clientService; - } - - public function ping() - { - $headers = Utils::getApiHeaders(); - - return Response::make('', 200, $headers); } /** @@ -65,7 +55,7 @@ class ClientApiController extends BaseAPIController }); } - return $this->returnList($clients); + return $this->listResponse($clients); } /** @@ -93,14 +83,7 @@ class ClientApiController extends BaseAPIController { $client = $this->clientRepo->save($request->input()); - $client = Client::scope($client->public_id) - ->with('country', 'contacts', 'industry', 'size', 'currency') - ->first(); - - $transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($client, $transformer, ENTITY_CLIENT); - - return $this->response($data); + return $this->itemResponse($client); } /** @@ -127,51 +110,15 @@ class ClientApiController extends BaseAPIController public function update(UpdateClientRequest $request, $publicId) { - if ($request->action == ACTION_ARCHIVE) { - - - $client = Client::scope($publicId)->withTrashed()->first(); - - if(!$client) - return $this->errorResponse(['message'=>'Record not found'], 400); - - $this->clientRepo->archive($client); - - $transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($client, $transformer, ENTITY_CLIENT); - - return $this->response($data); + if ($request->action) { + return $this->handleAction($request); } - else if ($request->action == ACTION_RESTORE){ - - $client = Client::scope($publicId)->withTrashed()->first(); - - if(!$client) - return $this->errorResponse(['message'=>'Client not found.'], 400); - - $this->clientRepo->restore($client); - - $transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($client, $transformer, ENTITY_CLIENT); - - return $this->response($data); - } - + $data = $request->input(); $data['public_id'] = $publicId; - $this->clientRepo->save($data); + $client = $this->clientRepo->save($data, $request->entity()); - $client = Client::scope($publicId) - ->with('country', 'contacts', 'industry', 'size', 'currency') - ->first(); - - if(!$client) - return $this->errorResponse(['message'=>'Client not found.'],400); - - $transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($client, $transformer, ENTITY_CLIENT); - - return $this->response($data); + return $this->itemResponse($client); } diff --git a/app/Http/Controllers/ExpenseApiController.php b/app/Http/Controllers/ExpenseApiController.php index 9b1a7e906244..44722f2a18ce 100644 --- a/app/Http/Controllers/ExpenseApiController.php +++ b/app/Http/Controllers/ExpenseApiController.php @@ -32,7 +32,7 @@ class ExpenseApiController extends BaseAPIController ->withTrashed() ->orderBy('created_at','desc'); - return $this->returnList($expenses); + return $this->listResponse($expenses); } public function update() diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index 406613489c6b..3da123c2d972 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -146,7 +146,7 @@ class ExpenseController extends BaseController $data = $request->input(); $data['documents'] = $request->file('documents'); - $expense = $this->expenseService->save($data); + $expense = $this->expenseService->save($data, $request->entity()); Session::flash('message', trans('texts.updated_expense')); diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 6eb6df367e71..c9282cd95bd2 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -19,6 +19,7 @@ use App\Ninja\Repositories\InvoiceRepository; use App\Ninja\Mailers\ContactMailer as Mailer; use App\Http\Controllers\BaseAPIController; use App\Ninja\Transformers\InvoiceTransformer; +use App\Http\Requests\InvoiceRequest; use App\Http\Requests\CreateInvoiceAPIRequest; use App\Http\Requests\UpdateInvoiceAPIRequest; use App\Services\InvoiceService; @@ -63,7 +64,7 @@ class InvoiceApiController extends BaseAPIController ->with(array_merge(['invoice_items'], $this->getIncluded())) ->orderBy('created_at', 'desc'); - return $this->returnList($invoices); + return $this->listResponse($invoices); } /** @@ -83,17 +84,9 @@ class InvoiceApiController extends BaseAPIController * ) */ - public function show($publicId) + public function show(InvoiceRequest $request) { - $invoice = Invoice::scope($publicId)->withTrashed()->first(); - - if(!$invoice) - return $this->errorResponse(['message'=>'Invoice does not exist!'], 404); - - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); + return $this->itemResponse($request->entity()); } /** @@ -188,11 +181,11 @@ class InvoiceApiController extends BaseAPIController } } - $invoice = Invoice::scope($invoice->public_id)->with('client', 'invoice_items', 'invitations')->first(); - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); + $invoice = Invoice::scope($invoice->public_id) + ->with('client', 'invoice_items', 'invitations') + ->first(); + + return $this->itemResponse($invoice); } private function prepareData($data, $client) @@ -278,36 +271,21 @@ class InvoiceApiController extends BaseAPIController $item[$key] = $val; } } - + return $item; } - public function emailInvoice() + public function emailInvoice(InvoiceRequest $request) { - $data = Input::all(); - $error = null; + $invoice = $request->entity(); - $invoice = Invoice::scope($data['id'])->withTrashed()->first(); - - if(!$invoice) - return $this->errorResponse(['message'=>'Invoice does not exist.'], 400); - - - $this->mailer->sendInvoice($invoice, false, false); - - - if($error) { - return $this->errorResponse(['message'=>'There was an error sending the invoice'], 400); - } - else { - $response = json_encode(RESULT_SUCCESS, JSON_PRETTY_PRINT); - } + $this->mailer->sendInvoice($invoice); + $response = json_encode(RESULT_SUCCESS, JSON_PRETTY_PRINT); $headers = Utils::getApiHeaders(); - return Response::make($response, $error ? 400 : 200, $headers); + return Response::make($response, 200, $headers); } - /** * @SWG\Put( * path="/invoices", @@ -331,32 +309,12 @@ class InvoiceApiController extends BaseAPIController */ public function update(UpdateInvoiceAPIRequest $request, $publicId) { - if ($request->action == ACTION_ARCHIVE) { - $invoice = Invoice::scope($publicId)->firstOrFail(); - $this->invoiceRepo->archive($invoice); - - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); - } - else if ($request->action == ACTION_CONVERT) { - $quote = Invoice::scope($publicId)->firstOrFail(); + if ($request->action == ACTION_CONVERT) { + $quote = $request->entity(); $invoice = $this->invoiceRepo->cloneInvoice($quote, $quote->id); - - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); - } - else if ($request->action == ACTION_RESTORE) { - $invoice = Invoice::scope($publicId)->withTrashed()->firstOrFail(); - $this->invoiceRepo->restore($invoice); - - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); + return $this->itemResponse($invoice); + } elseif ($request->action) { + return $this->handleAction($request); } else if ($request->action == ACTION_CLONE) { @@ -370,13 +328,13 @@ class InvoiceApiController extends BaseAPIController } $data = $request->input(); $data['public_id'] = $publicId; - $this->invoiceService->save($data); + $this->invoiceService->save($data, $request->entity()); - $invoice = Invoice::scope($publicId)->with('client', 'invoice_items', 'invitations')->firstOrFail(); - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); + $invoice = Invoice::scope($publicId) + ->with('client', 'invoice_items', 'invitations') + ->firstOrFail(); + + return $this->itemResponse($invoice); } /** diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 1a652ae8962c..270cc10b96ac 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -396,9 +396,7 @@ class InvoiceController extends BaseController { $data = $request->input(); $data['documents'] = $request->file('documents'); - - $this->authorizeUpdate($data); - + $action = Input::get('action'); $entityType = Input::get('entityType'); @@ -435,13 +433,11 @@ class InvoiceController extends BaseController { $data = $request->input(); $data['documents'] = $request->file('documents'); - - $this->authorizeUpdate($data); - + $action = Input::get('action'); $entityType = Input::get('entityType'); - $invoice = $this->invoiceService->save($data); + $invoice = $this->invoiceService->save($data, $request->entity()); $entityType = $invoice->getEntityType(); $message = trans("texts.updated_{$entityType}"); Session::flash('message', $message); diff --git a/app/Http/Controllers/PaymentApiController.php b/app/Http/Controllers/PaymentApiController.php index a7cab011fc36..5cea7f23641a 100644 --- a/app/Http/Controllers/PaymentApiController.php +++ b/app/Http/Controllers/PaymentApiController.php @@ -12,6 +12,8 @@ use App\Ninja\Repositories\PaymentRepository; use App\Http\Controllers\BaseAPIController; use App\Ninja\Transformers\PaymentTransformer; use App\Ninja\Transformers\InvoiceTransformer; +use App\Http\Requests\UpdatePaymentRequest; +use App\Http\Requests\CreatePaymentAPIRequest; class PaymentApiController extends BaseAPIController { @@ -50,7 +52,7 @@ class PaymentApiController extends BaseAPIController ->with(array_merge(['client.contacts', 'invitation', 'user', 'invoice'], $this->getIncluded())) ->orderBy('created_at', 'desc'); - return $this->returnList($payments); + return $this->listResponse($payments); } /** @@ -75,39 +77,17 @@ class PaymentApiController extends BaseAPIController * ) */ - public function update(Request $request, $publicId) + public function update(UpdatePaymentRequest $request, $publicId) { - $data = Input::all(); + if ($request->action) { + return $this->handleAction($request); + } + + $data = $request->input(); $data['public_id'] = $publicId; - $error = false; - - if ($request->action == ACTION_ARCHIVE) { - $payment = Payment::scope($publicId)->withTrashed()->firstOrFail(); - $this->paymentRepo->archive($payment); - - $transformer = new PaymentTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($payment, $transformer, 'invoice'); - - return $this->response($data); - } - - $payment = $this->paymentRepo->save($data); - - if ($error) { - return $error; - } - - /* - $invoice = Invoice::scope($data['invoice_id'])->with('client', 'invoice_items', 'invitations')->with(['payments' => function($query) { - $query->withTrashed(); - }])->withTrashed()->first(); - */ - - $transformer = new PaymentTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($payment, $transformer, 'invoice'); - - return $this->response($data); + $payment = $this->paymentRepo->save($data, $request->entity()); + return $this->itemResponse($payment); } @@ -132,49 +112,15 @@ class PaymentApiController extends BaseAPIController * ) * ) */ - public function store() + public function store(CreatePaymentAPIRequest $request) { - $data = Input::all(); - $error = false; - - if (isset($data['invoice_id'])) { - $invoice = Invoice::scope($data['invoice_id'])->with('client')->first(); - - if ($invoice) { - $data['invoice_id'] = $invoice->id; - $data['client_id'] = $invoice->client->id; - } else { - $error = trans('validation.not_in', ['attribute' => 'invoice_id']); - } - } else { - $error = trans('validation.not_in', ['attribute' => 'invoice_id']); - } - - if (!isset($data['transaction_reference'])) { - $data['transaction_reference'] = ''; - } - - if ($error) { - return $error; - } - - $payment = $this->paymentRepo->save($data); + $payment = $this->paymentRepo->save($request->input()); if (Input::get('email_receipt')) { $this->contactMailer->sendPaymentConfirmation($payment); } - /* - $invoice = Invoice::scope($invoice->public_id)->with('client', 'invoice_items', 'invitations')->with(['payments' => function($query) { - $query->withTrashed(); - }])->first(); - */ - - $transformer = new PaymentTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($payment, $transformer, 'invoice'); - - return $this->response($data); - + return $this->itemResponse($payment); } /** @@ -207,11 +153,6 @@ class PaymentApiController extends BaseAPIController $this->paymentRepo->delete($payment); - /* - $invoice = Invoice::scope($invoiceId)->with('client', 'invoice_items', 'invitations')->with(['payments' => function($query) { - $query->withTrashed(); - }])->first(); - */ $transformer = new PaymentTransformer(\Auth::user()->account, Input::get('serializer')); $data = $this->createItem($payment, $transformer, 'invoice'); diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index e3307f6f47e5..12537dbebaa1 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -603,7 +603,7 @@ class PaymentController extends BaseController public function update(UpdatePaymentRequest $request) { - $payment = $this->paymentRepo->save($request->input()); + $payment = $this->paymentRepo->save($request->input(), $request->entity()); Session::flash('message', trans('texts.updated_payment')); diff --git a/app/Http/Controllers/ProductApiController.php b/app/Http/Controllers/ProductApiController.php index 26736f5ef5c2..6a8756eda4b6 100644 --- a/app/Http/Controllers/ProductApiController.php +++ b/app/Http/Controllers/ProductApiController.php @@ -1,34 +1,20 @@ productService = $productService; $this->productRepo = $productRepo; } @@ -38,61 +24,31 @@ class ProductApiController extends BaseAPIController ->withTrashed() ->orderBy('created_at', 'desc'); - return $this->returnList($products); + return $this->listResponse($products); } - public function getDatatable() + public function store(CreateProductRequest $request) { - return $this->productService->getDatatable(Auth::user()->account_id); + $product = $this->productRepo->save($request->input()); + + return $this->itemResponse($product); } - public function store() + public function update(UpdateProductRequest $request, $publicId) { - return $this->save(); - } - - public function update(\Illuminate\Http\Request $request, $publicId) - { - - if ($request->action == ACTION_ARCHIVE) { - $product = Product::scope($publicId)->withTrashed()->firstOrFail(); - $this->productRepo->archive($product); - - $transformer = new ProductTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($product, $transformer, 'products'); - - return $this->response($data); + if ($request->action) { + return $this->handleAction($request); } - else - return $this->save($publicId); + + $data = $request->input(); + $data['public_id'] = $publicId; + $product = $this->productRepo->save($data, $request->entity()); + + return $this->itemResponse($product); } public function destroy($publicId) { //stub } - - private function save($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->default_tax_rate_id = Input::get('default_tax_rate_id'); - - $product->save(); - - $transformer = new ProductTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($product, $transformer, 'products'); - - return $this->response($data); - - } - - } diff --git a/app/Http/Controllers/TaskApiController.php b/app/Http/Controllers/TaskApiController.php index cb39e0a1f369..5e5e05ef80e9 100644 --- a/app/Http/Controllers/TaskApiController.php +++ b/app/Http/Controllers/TaskApiController.php @@ -45,7 +45,7 @@ class TaskApiController extends BaseAPIController ->with($this->getIncluded()) ->orderBy('created_at', 'desc'); - return $this->returnList($payments); + return $this->listResponse($payments); } /** diff --git a/app/Http/Controllers/TaxRateApiController.php b/app/Http/Controllers/TaxRateApiController.php index ddc0ab4aa968..85756205d9a1 100644 --- a/app/Http/Controllers/TaxRateApiController.php +++ b/app/Http/Controllers/TaxRateApiController.php @@ -1,26 +1,20 @@ taxRateService = $taxRateService; $this->taxRateRepo = $taxRateRepo; } @@ -29,38 +23,32 @@ class TaxRateApiController extends BaseAPIController $taxRates = TaxRate::scope() ->withTrashed() ->orderBy('created_at', 'desc'); - - return $this->returnList($taxRates); + + return $this->listResponse($taxRates); } public function store(CreateTaxRateRequest $request) { - return $this->save($request); + $taxRate = $this->taxRateRepo->save($request->input()); + + return $this->itemResponse($taxRate); } - public function update(UpdateTaxRateRequest $request, $taxRatePublicId) + public function update(UpdateTaxRateRequest $request, $publicId) { - $taxRate = TaxRate::scope($taxRatePublicId)->firstOrFail(); - - if ($request->action == ACTION_ARCHIVE) { - $this->taxRateRepo->archive($taxRate); - - $transformer = new TaxRateTransformer(Auth::user()->account, $request->serializer); - $data = $this->createItem($taxRate, $transformer, 'tax_rates'); - - return $this->response($data); - } else { - return $this->save($request, $taxRate); + if ($request->action) { + return $this->handleAction($request); } + + $data = $request->input(); + $data['public_id'] = $publicId; + $taxRate = $this->taxRateRepo->save($data, $request->entity()); + + return $this->itemResponse($taxRate); } - private function save($request, $taxRate = false) + public function destroy($publicId) { - $taxRate = $this->taxRateRepo->save($request->input(), $taxRate); - - $transformer = new TaxRateTransformer(\Auth::user()->account, $request->serializer); - $data = $this->createItem($taxRate, $transformer, 'tax_rates'); - - return $this->response($data); + //stub } } diff --git a/app/Http/Controllers/TaxRateController.php b/app/Http/Controllers/TaxRateController.php index 223f7491092e..cba4058756de 100644 --- a/app/Http/Controllers/TaxRateController.php +++ b/app/Http/Controllers/TaxRateController.php @@ -75,9 +75,7 @@ class TaxRateController extends BaseController public function update(UpdateTaxRateRequest $request, $publicId) { - $taxRate = TaxRate::scope($publicId)->firstOrFail(); - - $this->taxRateRepo->save($request->input(), $taxRate); + $this->taxRateRepo->save($request->input(), $request->entity()); Session::flash('message', trans('texts.updated_tax_rate')); return Redirect::to('settings/' . ACCOUNT_TAX_RATES); diff --git a/app/Http/Controllers/UserApiController.php b/app/Http/Controllers/UserApiController.php index 8fda74b33cbd..2869c3512f5a 100644 --- a/app/Http/Controllers/UserApiController.php +++ b/app/Http/Controllers/UserApiController.php @@ -30,7 +30,7 @@ class UserApiController extends BaseAPIController ->withTrashed() ->orderBy('created_at', 'desc'); - return $this->returnList($users); + return $this->listResponse($users); } /* @@ -42,11 +42,6 @@ class UserApiController extends BaseAPIController public function update(UpdateUserRequest $request, $userPublicId) { - /* - // temporary fix for ids starting at 0 - $userPublicId -= 1; - $user = User::scope($userPublicId)->firstOrFail(); - */ $user = Auth::user(); if ($request->action == ACTION_ARCHIVE) { diff --git a/app/Http/Controllers/VendorApiController.php b/app/Http/Controllers/VendorApiController.php index b2487dfda2d3..d3cc27094760 100644 --- a/app/Http/Controllers/VendorApiController.php +++ b/app/Http/Controllers/VendorApiController.php @@ -53,7 +53,7 @@ class VendorApiController extends BaseAPIController ->withTrashed() ->orderBy('created_at', 'desc'); - return $this->returnList($vendors); + return $this->listResponse($vendors); } /** @@ -85,8 +85,6 @@ class VendorApiController extends BaseAPIController ->with('country', 'vendorcontacts', 'industry', 'size', 'currency') ->first(); - $transformer = new VendorTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($vendor, $transformer, ENTITY_VENDOR); - return $this->response($data); + return $this->itemResponse($vendor); } } diff --git a/app/Http/Controllers/VendorController.php b/app/Http/Controllers/VendorController.php index 10c7f7f03e89..f1952e20dee3 100644 --- a/app/Http/Controllers/VendorController.php +++ b/app/Http/Controllers/VendorController.php @@ -182,7 +182,7 @@ class VendorController extends BaseController */ public function update(UpdateVendorRequest $request) { - $vendor = $this->vendorService->save($request->input()); + $vendor = $this->vendorService->save($request->input(), $request->entity()); Session::flash('message', trans('texts.updated_vendor')); diff --git a/app/Http/Requests/CreatePaymentAPIRequest.php b/app/Http/Requests/CreatePaymentAPIRequest.php new file mode 100644 index 000000000000..08a520c16655 --- /dev/null +++ b/app/Http/Requests/CreatePaymentAPIRequest.php @@ -0,0 +1,48 @@ +user()->can('create', ENTITY_PAYMENT); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + if ( ! $this->invoice_id || ! $this->amount) { + return [ + 'invoice_id' => 'required', + 'amount' => 'required', + ]; + } + + $invoice = Invoice::scope($this->invoice_id)->firstOrFail(); + + $this->merge([ + 'invoice_id' => $invoice->id, + 'client_id' => $invoice->client->id, + ]); + + $rules = array( + 'amount' => "required|less_than:{$invoice->balance}|positive", + ); + + if ($this->payment_type_id == PAYMENT_TYPE_CREDIT) { + $rules['payment_type_id'] = 'has_credit:' . $invoice->client->public_id . ',' . $this->amount; + } + + return $rules; + } +} diff --git a/app/Http/Requests/CreateProductRequest.php b/app/Http/Requests/CreateProductRequest.php new file mode 100644 index 000000000000..0fad2af14a23 --- /dev/null +++ b/app/Http/Requests/CreateProductRequest.php @@ -0,0 +1,26 @@ +user()->can('create', ENTITY_PRODUCT); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'product_key' => 'required', + ]; + } +} diff --git a/app/Http/Requests/CreateTaxRateRequest.php b/app/Http/Requests/CreateTaxRateRequest.php index 1596c814f127..d8fef50093b7 100644 --- a/app/Http/Requests/CreateTaxRateRequest.php +++ b/app/Http/Requests/CreateTaxRateRequest.php @@ -3,7 +3,7 @@ use App\Http\Requests\Request; use Illuminate\Validation\Factory; -class CreateTaxRateRequest extends Request +class CreateTaxRateRequest extends TaxRateRequest { // Expenses /** @@ -13,7 +13,7 @@ class CreateTaxRateRequest extends Request */ public function authorize() { - return true; + return $this->user()->can('create', ENTITY_TAX_RATE); } /** diff --git a/app/Http/Requests/ProductRequest.php b/app/Http/Requests/ProductRequest.php new file mode 100644 index 000000000000..2420bdcfcaf0 --- /dev/null +++ b/app/Http/Requests/ProductRequest.php @@ -0,0 +1,6 @@ +user()->can('edit', $this->entity()); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'product_key' => 'required', + ]; + } +} diff --git a/app/Http/Requests/UpdateTaxRateRequest.php b/app/Http/Requests/UpdateTaxRateRequest.php index bcfa298e06c5..a4bdc6301ca2 100644 --- a/app/Http/Requests/UpdateTaxRateRequest.php +++ b/app/Http/Requests/UpdateTaxRateRequest.php @@ -3,7 +3,7 @@ use App\Http\Requests\Request; use Illuminate\Validation\Factory; -class UpdateTaxRateRequest extends Request +class UpdateTaxRateRequest extends TaxRateRequest { // Expenses /** @@ -13,7 +13,7 @@ class UpdateTaxRateRequest extends Request */ public function authorize() { - return true; + return $this->user()->can('edit', $this->entity()); } /** diff --git a/app/Http/Requests/UpdateUserRequest.php b/app/Http/Requests/UpdateUserRequest.php index 91d7a73bc568..b3149d2b61ff 100644 --- a/app/Http/Requests/UpdateUserRequest.php +++ b/app/Http/Requests/UpdateUserRequest.php @@ -14,7 +14,7 @@ class UpdateUserRequest extends Request */ public function authorize() { - return true; + return $this->user()->can('edit', $this->entity()); } /** diff --git a/app/Http/routes.php b/app/Http/routes.php index bfeed103a99a..a70b38cc707b 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -246,7 +246,7 @@ Route::group([ // Route groups for API Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function() { - Route::get('ping', 'ClientApiController@ping'); + Route::get('ping', 'AccountApiController@ping'); Route::post('login', 'AccountApiController@login'); Route::post('register', 'AccountApiController@register'); Route::get('static', 'AccountApiController@getStaticData'); @@ -600,6 +600,8 @@ if (!defined('CONTACT_EMAIL')) { define('TEST_USERNAME', 'user@example.com'); define('TEST_PASSWORD', 'password'); define('API_SECRET', 'API_SECRET'); + define('DEFAULT_API_PAGE_SIZE', 15); + define('MAX_API_PAGE_SIZE', 100); define('IOS_PRODUCTION_PUSH', env('IOS_PRODUCTION_PUSH', 'ninjaIOS')); define('IOS_DEV_PUSH', env('IOS_DEV_PUSH', 'devNinjaIOS')); diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 86107acfcd59..141eacfc3058 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -676,7 +676,7 @@ class Utils public static function getEntityName($entityType) { - return ucwords(str_replace('_', ' ', $entityType)); + return ucwords(Utils::toCamelCase($entityType)); } public static function getClientDisplayName($model) diff --git a/app/Models/EntityModel.php b/app/Models/EntityModel.php index c2c9110fe306..95e85e6acef4 100644 --- a/app/Models/EntityModel.php +++ b/app/Models/EntityModel.php @@ -110,7 +110,7 @@ class EntityModel extends Eloquent { return 'App\\Ninja\\Transformers\\' . ucwords(Utils::toCamelCase($entityType)) . 'Transformer'; } - + public function setNullValues() { foreach ($this->fillable as $field) { diff --git a/app/Models/Product.php b/app/Models/Product.php index 8de7c7ac5b2c..0d3221f2a1ea 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -8,6 +8,14 @@ class Product extends EntityModel use SoftDeletes; protected $dates = ['deleted_at']; + protected $fillable = [ + 'product_key', + 'notes', + 'cost', + 'qty', + 'default_tax_rate_id', + ]; + public function getEntityType() { return ENTITY_PRODUCT; diff --git a/app/Ninja/Repositories/ClientRepository.php b/app/Ninja/Repositories/ClientRepository.php index 77ebcb7fd736..8d8c3ed527d4 100644 --- a/app/Ninja/Repositories/ClientRepository.php +++ b/app/Ninja/Repositories/ClientRepository.php @@ -72,12 +72,13 @@ class ClientRepository extends BaseRepository if ($client) { // do nothing - } if (!$publicId || $publicId == '-1') { + } elseif (!$publicId || $publicId == '-1') { $client = Client::createNew(); } else { $client = Client::scope($publicId)->with('contacts')->firstOrFail(); + \Log::warning('Entity not set in client repo save'); } - + // convert currency code to id if (isset($data['currency_code'])) { $currencyCode = strtolower($data['currency_code']); diff --git a/app/Ninja/Repositories/CreditRepository.php b/app/Ninja/Repositories/CreditRepository.php index 4381ae25771c..068707ace02b 100644 --- a/app/Ninja/Repositories/CreditRepository.php +++ b/app/Ninja/Repositories/CreditRepository.php @@ -59,12 +59,15 @@ class CreditRepository extends BaseRepository return $query; } - public function save($input) + public function save($input, $credit = null) { $publicId = isset($data['public_id']) ? $data['public_id'] : false; - - if ($publicId) { + + if ($credit) { + // do nothing + } elseif ($publicId) { $credit = Credit::scope($publicId)->firstOrFail(); + \Log::warning('Entity not set in credit repo save'); } else { $credit = Credit::createNew(); } diff --git a/app/Ninja/Repositories/ExpenseRepository.php b/app/Ninja/Repositories/ExpenseRepository.php index 4c67c0e7c91c..442af74bd32b 100644 --- a/app/Ninja/Repositories/ExpenseRepository.php +++ b/app/Ninja/Repositories/ExpenseRepository.php @@ -122,12 +122,15 @@ class ExpenseRepository extends BaseRepository return $query; } - public function save($input) + public function save($input, $expense = null) { $publicId = isset($input['public_id']) ? $input['public_id'] : false; - if ($publicId) { + if ($expense) { + // do nothing + } elseif ($publicId) { $expense = Expense::scope($publicId)->firstOrFail(); + \Log::warning('Entity not set in expense repo save'); } else { $expense = Expense::createNew(); } diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 2ae18a738bd8..bbf58ca16c71 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -201,14 +201,16 @@ class InvoiceRepository extends BaseRepository ->make(); } - public function save($data) + public function save($data, $invoice = null) { $account = \Auth::user()->account; $publicId = isset($data['public_id']) ? $data['public_id'] : false; $isNew = !$publicId || $publicId == '-1'; - if ($isNew) { + if ($invoice) { + // do nothing + } elseif ($isNew) { $entityType = ENTITY_INVOICE; if (isset($data['is_recurring']) && filter_var($data['is_recurring'], FILTER_VALIDATE_BOOLEAN)) { $entityType = ENTITY_RECURRING_INVOICE; @@ -224,6 +226,7 @@ class InvoiceRepository extends BaseRepository } } else { $invoice = Invoice::scope($publicId)->firstOrFail(); + \Log::warning('Entity not set in invoice repo save'); } $invoice->fill($data); diff --git a/app/Ninja/Repositories/PaymentRepository.php b/app/Ninja/Repositories/PaymentRepository.php index 9b7d9787b457..dd99fccdfdd4 100644 --- a/app/Ninja/Repositories/PaymentRepository.php +++ b/app/Ninja/Repositories/PaymentRepository.php @@ -123,12 +123,15 @@ class PaymentRepository extends BaseRepository return $query; } - public function save($input) + public function save($input, $payment = null) { $publicId = isset($input['public_id']) ? $input['public_id'] : false; - if ($publicId) { + if ($payment) { + // do nothing + } elseif ($publicId) { $payment = Payment::scope($publicId)->firstOrFail(); + \Log::warning('Entity not set in payment repo save'); } else { $payment = Payment::createNew(); } diff --git a/app/Ninja/Repositories/ProductRepository.php b/app/Ninja/Repositories/ProductRepository.php index 417b49f23640..eb0e7383e9e5 100644 --- a/app/Ninja/Repositories/ProductRepository.php +++ b/app/Ninja/Repositories/ProductRepository.php @@ -1,6 +1,7 @@ firstOrFail(); + \Log::warning('Entity not set in product repo save'); + } else { + $product = Product::createNew(); + } + + $product->fill($data); + $product->save(); + + return $product; + } + } \ No newline at end of file diff --git a/app/Ninja/Repositories/TaskRepository.php b/app/Ninja/Repositories/TaskRepository.php index 1bd0e38cb6b7..3a5eca04a112 100644 --- a/app/Ninja/Repositories/TaskRepository.php +++ b/app/Ninja/Repositories/TaskRepository.php @@ -64,10 +64,13 @@ class TaskRepository return $query; } - public function save($publicId, $data) + public function save($publicId, $data, $task = null) { - if ($publicId) { + if ($task) { + // do nothing + } elseif ($publicId) { $task = Task::scope($publicId)->firstOrFail(); + \Log::warning('Entity not set in task repo save'); } else { $task = Task::createNew(); } diff --git a/app/Ninja/Repositories/TaxRateRepository.php b/app/Ninja/Repositories/TaxRateRepository.php index 2e325100a016..8f1ad7f6550f 100644 --- a/app/Ninja/Repositories/TaxRateRepository.php +++ b/app/Ninja/Repositories/TaxRateRepository.php @@ -20,14 +20,15 @@ class TaxRateRepository extends BaseRepository ->select('tax_rates.public_id', 'tax_rates.name', 'tax_rates.rate', 'tax_rates.deleted_at'); } - public function save($data, $taxRate = false) + public function save($data, $taxRate = null) { - if ( ! $taxRate) { - if (isset($data['public_id'])) { - $taxRate = TaxRate::scope($data['public_id'])->firstOrFail(); - } else { - $taxRate = TaxRate::createNew(); - } + if ($taxRate) { + // do nothing + } elseif (isset($data['public_id'])) { + $taxRate = TaxRate::scope($data['public_id'])->firstOrFail(); + \Log::warning('Entity not set in tax rate repo save'); + } else { + $taxRate = TaxRate::createNew(); } $taxRate->fill($data); diff --git a/app/Ninja/Repositories/VendorRepository.php b/app/Ninja/Repositories/VendorRepository.php index df885f62e12e..ef5648f47d81 100644 --- a/app/Ninja/Repositories/VendorRepository.php +++ b/app/Ninja/Repositories/VendorRepository.php @@ -62,14 +62,17 @@ class VendorRepository extends BaseRepository return $query; } - public function save($data) + public function save($data, $vendor = null) { $publicId = isset($data['public_id']) ? $data['public_id'] : false; - if (!$publicId || $publicId == '-1') { + if ($vendor) { + // do nothing + } elseif (!$publicId || $publicId == '-1') { $vendor = Vendor::createNew(); } else { $vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail(); + \Log::warning('Entity not set in vendor repo save'); } $vendor->fill($data); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 884c2587503d..02aba3e1d6d3 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -21,6 +21,8 @@ class AuthServiceProvider extends ServiceProvider \App\Models\Payment::class => \App\Policies\PaymentPolicy::class, \App\Models\Task::class => \App\Policies\TaskPolicy::class, \App\Models\Vendor::class => \App\Policies\VendorPolicy::class, + \App\Models\Product::class => \App\Policies\ProductPolicy::class, + \App\Models\TaxRate::class => \App\Policies\TaxRatePolicy::class, ]; /** diff --git a/app/Services/ExpenseService.php b/app/Services/ExpenseService.php index 0b28a7c4d6b1..671648ea32a5 100644 --- a/app/Services/ExpenseService.php +++ b/app/Services/ExpenseService.php @@ -28,7 +28,7 @@ class ExpenseService extends BaseService return $this->expenseRepo; } - public function save($data) + public function save($data, $expense = null) { if (isset($data['client_id']) && $data['client_id']) { $data['client_id'] = Client::getPrivateId($data['client_id']); @@ -38,7 +38,7 @@ class ExpenseService extends BaseService $data['vendor_id'] = Vendor::getPrivateId($data['vendor_id']); } - return $this->expenseRepo->save($data); + return $this->expenseRepo->save($data, $expense); } public function getDatatable($search) diff --git a/app/Services/InvoiceService.php b/app/Services/InvoiceService.php index ecf0ad2fab0b..edbee8caf84c 100644 --- a/app/Services/InvoiceService.php +++ b/app/Services/InvoiceService.php @@ -30,7 +30,7 @@ class InvoiceService extends BaseService return $this->invoiceRepo; } - public function save($data) + public function save($data, $invoice = null) { if (isset($data['client'])) { $canSaveClient = false; @@ -46,7 +46,7 @@ class InvoiceService extends BaseService } } - $invoice = $this->invoiceRepo->save($data); + $invoice = $this->invoiceRepo->save($data, $invoice); $client = $invoice->client; $client->load('contacts'); diff --git a/app/Services/VendorService.php b/app/Services/VendorService.php index 6022507b452e..41f5fd4664bb 100644 --- a/app/Services/VendorService.php +++ b/app/Services/VendorService.php @@ -26,13 +26,13 @@ class VendorService extends BaseService return $this->vendorRepo; } - public function save($data) + public function save($data, $vendor = null) { if (Auth::user()->account->isNinjaAccount() && isset($data['plan'])) { $this->ninjaRepo->updatePlanDetails($data['public_id'], $data); } - return $this->vendorRepo->save($data); + return $this->vendorRepo->save($data, $vendor); } public function getDatatable($search) diff --git a/tests/_support/_generated/AcceptanceTesterActions.php b/tests/_support/_generated/AcceptanceTesterActions.php index d219111f887c..82427d1e2a5e 100644 --- a/tests/_support/_generated/AcceptanceTesterActions.php +++ b/tests/_support/_generated/AcceptanceTesterActions.php @@ -1,4 +1,4 @@ -createEntity('tax_rate', $data); $this->listEntities('tax_rate'); + $data = new stdClass; + $data->product_key = $this->faker->word; + $data->notes = $this->faker->realText(100); + $this->createEntity('product', $data); + $this->listEntities('product'); + + $data = new stdClass; + $data->name = $this->faker->word; + $data->vendorcontacts = []; + $this->createEntity('vendor', $data); + $this->listEntities('vendor'); + $this->listEntities('account'); } @@ -79,6 +91,7 @@ class APICest $response = $this->sendRequest("{$entityType}s", $data); $entityId = $response->data->id; + PHPUnit_Framework_Assert::assertGreaterThan(0, $entityId); return $entityId; diff --git a/tests/acceptance/ExpenseCest.php b/tests/acceptance/ExpenseCest.php index 01cc3112d83f..72d7666aab9d 100644 --- a/tests/acceptance/ExpenseCest.php +++ b/tests/acceptance/ExpenseCest.php @@ -49,7 +49,7 @@ class ExpenseCest // invoice expense $I->executeJS('submitAction(\'invoice\')'); $I->click('Save'); - $I->wait(1); + $I->wait(3); $I->see($clientEmail); $I->see($amount); }