Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
David Bomba 2016-05-02 19:31:15 +10:00
commit afae9e8289
101 changed files with 1431 additions and 939 deletions

View File

@ -89,7 +89,8 @@ after_script:
- mysql -u root -e 'select * from invoice_items;' ninja
- mysql -u root -e 'select * from payments;' ninja
- mysql -u root -e 'select * from credits;' ninja
- cat storage/logs/laravel.log
- cat storage/logs/laravel-error.log
- cat storage/logs/laravel-info.log
notifications:
email:

View File

@ -1,4 +1,4 @@
<?php namespace app\Commands;
<?php namespace App\Commands;
abstract class Command
{

View File

@ -1,4 +1,4 @@
<?php namespace app\Console\Commands;
<?php namespace App\Console\Commands;
use File;
use Illuminate\Console\Command;

View File

@ -1,4 +1,4 @@
<?php namespace app\Console\Commands;
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Services\BankAccountService;

View File

@ -1,4 +1,4 @@
<?php namespace app\Console;
<?php namespace App\Console;
use Utils;
use Illuminate\Console\Scheduling\Schedule;

View File

@ -2,6 +2,8 @@
use Session;
use Utils;
use Auth;
use Input;
use Response;
use Request;
use League\Fractal;
@ -9,8 +11,10 @@ use League\Fractal\Manager;
use League\Fractal\Resource\Item;
use League\Fractal\Resource\Collection;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Models\EntityModel;
use App\Ninja\Serializers\ArraySerializer;
use League\Fractal\Serializer\JsonApiSerializer;
use Illuminate\Pagination\LengthAwarePaginator;
/**
* @SWG\Swagger(
@ -64,6 +68,33 @@ class BaseAPIController extends Controller
}
}
protected function returnList($query)
{
//\DB::enableQueryLog();
if ($clientPublicId = Input::get('client_id')) {
$filter = function($query) use ($clientPublicId) {
$query->where('public_id', '=', $clientPublicId);
};
$query->whereHas('client', $filter);
}
if ( ! Utils::hasPermission('view_all')){
if ($this->entityType == ENTITY_USER) {
$query->where('id', '=', Auth::user()->id);
} else {
$query->where('user_id', '=', Auth::user()->id);
}
}
$transformerClass = EntityModel::getTransformerName($this->entityType);
$transformer = new $transformerClass(Auth::user()->account, Input::get('serializer'));
$data = $this->createCollection($query, $transformer, $this->entityType);
//return \DB::getQueryLog();
return $this->response($data);
}
protected function createItem($data, $transformer, $entityType)
{
if ($this->serializer && $this->serializer != API_SERIALIZER_JSON) {
@ -74,18 +105,19 @@ class BaseAPIController extends Controller
return $this->manager->createData($resource)->toArray();
}
protected function createCollection($data, $transformer, $entityType, $paginator = false)
protected function createCollection($query, $transformer, $entityType)
{
if ($this->serializer && $this->serializer != API_SERIALIZER_JSON) {
$entityType = null;
}
$resource = new Collection($data, $transformer, $entityType);
if ($paginator) {
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
if (is_a($query, "Illuminate\Database\Eloquent\Builder")) {
$resource = new Collection($query->get(), $transformer, $entityType);
$resource->setPaginator(new IlluminatePaginatorAdapter($query->paginate()));
} else {
$resource = new Collection($query, $transformer, $entityType);
}
return $this->manager->createData($resource)->toArray();
}

View File

@ -3,13 +3,15 @@
use App\Http\Middleware\PermissionsRequired;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Input;
use Auth;
use Utils;
class BaseController extends Controller
{
use DispatchesJobs, AuthorizesRequests;
protected $entity;
protected $entityType;
/**
* Setup the layout used by the controller.
@ -24,17 +26,23 @@ class BaseController extends Controller
}
protected function authorizeCreate() {
$this->authorize('create', $this->entity);
$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->entity);
$this->authorize('create', $this->entityType);
}
else{
$className = ucwords($this->entity, '_');
$className = Utils::getEntityName($this->entityType);
$object = call_user_func(array("App\\Models\\{$className}", 'scope'), $input['public_id'])->firstOrFail();
$this->authorize('edit', $object);

View File

@ -18,6 +18,8 @@ class ClientApiController extends BaseAPIController
protected $clientRepo;
protected $clientService;
protected $entityType = ENTITY_CLIENT;
public function __construct(ClientRepository $clientRepo, ClientService $clientService)
{
parent::__construct();
@ -53,26 +55,17 @@ class ClientApiController extends BaseAPIController
{
$clients = Client::scope()
->with($this->getIncluded())
->orderBy('created_at', 'desc')->withTrashed();
->orderBy('created_at', 'desc')
->withTrashed();
// Filter by email
if (Input::has('email')) {
$email = Input::get('email');
if ($email = Input::get('email')) {
$clients = $clients->whereHas('contacts', function ($query) use ($email) {
$query->where('email', $email);
});
}
$clients = $clients->paginate();
$transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer'));
$paginator = Client::scope()->withTrashed()->paginate();
$data = $this->createCollection($clients, $transformer, ENTITY_CLIENT, $paginator);
return $this->response($data);
return $this->returnList($clients);
}
/**
@ -206,7 +199,6 @@ class ClientApiController extends BaseAPIController
public function destroy($publicId)
{
$client = Client::scope($publicId)->withTrashed()->first();
$this->clientRepo->delete($client);
@ -219,8 +211,6 @@ class ClientApiController extends BaseAPIController
$data = $this->createItem($client, $transformer, ENTITY_CLIENT);
return $this->response($data);
}
}
}

View File

@ -28,6 +28,7 @@ use App\Models\Task;
use App\Ninja\Repositories\ClientRepository;
use App\Services\ClientService;
use App\Http\Requests\ClientRequest;
use App\Http\Requests\CreateClientRequest;
use App\Http\Requests\UpdateClientRequest;
@ -35,7 +36,7 @@ class ClientController extends BaseController
{
protected $clientService;
protected $clientRepo;
protected $entity = ENTITY_CLIENT;
protected $entityType = ENTITY_CLIENT;
public function __construct(ClientRepository $clientRepo, ClientService $clientService)
{
@ -81,11 +82,7 @@ class ClientController extends BaseController
*/
public function store(CreateClientRequest $request)
{
$data = $request->input();
$this->authorizeUpdate($data);
$client = $this->clientService->save($data);
$client = $this->clientService->save($request->input());
Session::flash('message', trans('texts.created_client'));
@ -98,11 +95,9 @@ class ClientController extends BaseController
* @param int $id
* @return Response
*/
public function show($publicId)
public function show(ClientRequest $request)
{
$client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail();
$this->authorize('view', $client);
$client = $request->entity();
$user = Auth::user();
Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT);
@ -151,10 +146,8 @@ class ClientController extends BaseController
*
* @return Response
*/
public function create()
public function create(ClientRequest $request)
{
$this->authorizeCreate();
if (Client::scope()->withTrashed()->count() > Auth::user()->getMaxNumClients()) {
return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumClients()." clients"]);
}
@ -177,16 +170,14 @@ class ClientController extends BaseController
* @param int $id
* @return Response
*/
public function edit($publicId)
public function edit(ClientRequest $request)
{
$client = Client::scope($publicId)->with('contacts')->firstOrFail();
$this->authorize('edit', $client);
$client = $request->entity();
$data = [
'client' => $client,
'method' => 'PUT',
'url' => 'clients/'.$publicId,
'url' => 'clients/'.$client->public_id,
'title' => trans('texts.edit_client'),
];
@ -225,11 +216,7 @@ class ClientController extends BaseController
*/
public function update(UpdateClientRequest $request)
{
$data = $request->input();
$this->authorizeUpdate($data);
$client = $this->clientService->save($data);
$client = $this->clientService->save($request->input(), $request->entity());
Session::flash('message', trans('texts.updated_client'));

View File

@ -12,12 +12,13 @@ use App\Models\Client;
use App\Services\CreditService;
use App\Ninja\Repositories\CreditRepository;
use App\Http\Requests\CreateCreditRequest;
use App\Http\Requests\CreditRequest;
class CreditController extends BaseController
{
protected $creditRepo;
protected $creditService;
protected $entity = ENTITY_CREDIT;
protected $entityType = ENTITY_CREDIT;
public function __construct(CreditRepository $creditRepo, CreditService $creditService)
{
@ -55,23 +56,21 @@ class CreditController extends BaseController
return $this->creditService->getDatatable($clientPublicId, Input::get('sSearch'));
}
public function create($clientPublicId = 0)
public function create(CreditRequest $request)
{
$this->authorizeCreate();
$data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
//'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
'clientPublicId' => Input::old('client') ? Input::old('client') : ($request->client_id ?: 0),
'credit' => null,
'method' => 'POST',
'url' => 'credits',
'title' => trans('texts.new_credit'),
//'invoices' => Invoice::scope()->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
);
return View::make('credits.edit', $data);
}
/*
public function edit($publicId)
{
$credit = Credit::scope($publicId)->firstOrFail();
@ -90,7 +89,8 @@ class CreditController extends BaseController
return View::make('credit.edit', $data);
}
*/
public function store(CreateCreditRequest $request)
{
$credit = $this->creditRepo->save($request->input());

View File

@ -12,10 +12,13 @@ use Response;
use App\Models\Document;
use App\Ninja\Repositories\DocumentRepository;
use App\Http\Requests\DocumentRequest;
use App\Http\Requests\CreateDocumentRequest;
class DocumentController extends BaseController
{
protected $documentRepo;
protected $entity = ENTITY_DOCUMENT;
protected $entityType = ENTITY_DOCUMENT;
public function __construct(DocumentRepository $documentRepo)
{
@ -24,14 +27,9 @@ class DocumentController extends BaseController
$this->documentRepo = $documentRepo;
}
public function get($publicId)
public function get(DocumentRequest $request)
{
$document = Document::scope($publicId)
->firstOrFail();
$this->authorize('view', $document);
return static::getDownloadResponse($document);
return static::getDownloadResponse($request->entity());
}
public static function getDownloadResponse($document){
@ -60,12 +58,9 @@ class DocumentController extends BaseController
return $response;
}
public function getPreview($publicId)
public function getPreview(DocumentRequest $request)
{
$document = Document::scope($publicId)
->firstOrFail();
$this->authorize('view', $document);
$document = $request->entity();
if(empty($document->preview)){
return Response::view('error', array('error'=>'Preview does not exist!'), 404);
@ -83,16 +78,14 @@ class DocumentController extends BaseController
return $response;
}
public function getVFSJS($publicId, $name){
$document = Document::scope($publicId)
->firstOrFail();
public function getVFSJS(DocumentRequest $request, $publicId, $name)
{
$document = $request->entity();
if(substr($name, -3)=='.js'){
$name = substr($name, 0, -3);
}
$this->authorize('view', $document);
if(!$document->isPDFEmbeddable()){
return Response::view('error', array('error'=>'Image does not exist!'), 404);
}
@ -106,14 +99,12 @@ class DocumentController extends BaseController
return $response;
}
public function postUpload()
public function postUpload(CreateDocumentRequest $request)
{
if (!Utils::hasFeature(FEATURE_DOCUMENTS)) {
return;
}
$this->authorizeCreate();
$result = $this->documentRepo->upload(Input::all()['file'], $doc_array);
if(is_string($result)){

View File

@ -1,5 +1,5 @@
<?php namespace App\Http\Controllers;
// vendor
use App\Models\Expense;
use app\Ninja\Repositories\ExpenseRepository;
use App\Ninja\Transformers\ExpenseTransformer;
@ -16,6 +16,8 @@ class ExpenseApiController extends BaseAPIController
protected $expenseRepo;
protected $expenseService;
protected $entityType = ENTITY_EXPENSE;
public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService)
{
parent::__construct();
@ -26,20 +28,11 @@ class ExpenseApiController extends BaseAPIController
public function index()
{
$expenses = Expense::scope()
->withTrashed()
->orderBy('created_at','desc');
$expenses = $expenses->paginate();
$transformer = new ExpenseTransformer(Auth::user()->account, Input::get('serializer'));
$paginator = Expense::scope()->withTrashed()->paginate();
$data = $this->createCollection($expenses, $transformer, ENTITY_EXPENSE, $paginator);
return $this->response($data);
return $this->returnList($expenses);
}
public function update()

View File

@ -17,6 +17,8 @@ use App\Models\Expense;
use App\Models\Client;
use App\Services\ExpenseService;
use App\Ninja\Repositories\ExpenseRepository;
use App\Http\Requests\ExpenseRequest;
use App\Http\Requests\CreateExpenseRequest;
use App\Http\Requests\UpdateExpenseRequest;
@ -25,7 +27,7 @@ class ExpenseController extends BaseController
// Expenses
protected $expenseRepo;
protected $expenseService;
protected $entity = ENTITY_EXPENSE;
protected $entityType = ENTITY_EXPENSE;
public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService)
{
@ -69,17 +71,16 @@ class ExpenseController extends BaseController
return $this->expenseService->getDatatableVendor($vendorPublicId);
}
public function create($vendorPublicId = null, $clientPublicId = null)
public function create(ExpenseRequest $request)
{
$this->authorizeCreate();
if($vendorPublicId != 0) {
$vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail();
if ($request->vendor_id != 0) {
$vendor = Vendor::scope($request->vendor_id)->with('vendorcontacts')->firstOrFail();
} else {
$vendor = null;
}
$data = array(
'vendorPublicId' => Input::old('vendor') ? Input::old('vendor') : $vendorPublicId,
'vendorPublicId' => Input::old('vendor') ? Input::old('vendor') : $request->vendor_id,
'expense' => null,
'method' => 'POST',
'url' => 'expenses',
@ -87,20 +88,18 @@ class ExpenseController extends BaseController
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
'vendor' => $vendor,
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
'clientPublicId' => $clientPublicId,
);
'clientPublicId' => $request->client_id,
);
$data = array_merge($data, self::getViewModel());
return View::make('expenses.edit', $data);
}
public function edit($publicId)
public function edit(ExpenseRequest $request)
{
$expense = Expense::scope($publicId)->with('documents')->firstOrFail();
$this->authorize('edit', $expense);
$expense = $request->entity();
$expense->expense_date = Utils::fromSqlDate($expense->expense_date);
$actions = [];
@ -108,15 +107,6 @@ class ExpenseController extends BaseController
$actions[] = ['url' => URL::to("invoices/{$expense->invoice->public_id}/edit"), 'label' => trans("texts.view_invoice")];
} else {
$actions[] = ['url' => 'javascript:submitAction("invoice")', 'label' => trans("texts.invoice_expense")];
/*
// check for any open invoices
$invoices = $task->client_id ? $this->invoiceRepo->findOpenInvoices($task->client_id) : [];
foreach ($invoices as $invoice) {
$actions[] = ['url' => 'javascript:submitAction("add_to_invoice", '.$invoice->public_id.')', 'label' => trans("texts.add_to_invoice", ["invoice" => $invoice->invoice_number])];
}
*/
}
$actions[] = \DropdownButton::DIVIDER;
@ -131,7 +121,7 @@ class ExpenseController extends BaseController
'vendor' => null,
'expense' => $expense,
'method' => 'PUT',
'url' => 'expenses/'.$publicId,
'url' => 'expenses/'.$expense->public_id,
'title' => 'Edit Expense',
'actions' => $actions,
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
@ -155,10 +145,8 @@ class ExpenseController extends BaseController
{
$data = $request->input();
$data['documents'] = $request->file('documents');
$this->authorizeUpdate($data);
$expense = $this->expenseService->save($data, true);
$expense = $this->expenseService->save($data);
Session::flash('message', trans('texts.updated_expense'));
@ -174,9 +162,7 @@ class ExpenseController extends BaseController
{
$data = $request->input();
$data['documents'] = $request->file('documents');
$this->authorizeUpdate($data);
$expense = $this->expenseService->save($data);
Session::flash('message', trans('texts.created_expense'));

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Controllers;
<?php namespace App\Http\Controllers;
use Utils;
use View;

View File

@ -18,14 +18,16 @@ 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\CreateInvoiceRequest;
use App\Http\Requests\UpdateInvoiceRequest;
use App\Http\Requests\CreateInvoiceAPIRequest;
use App\Http\Requests\UpdateInvoiceAPIRequest;
use App\Services\InvoiceService;
class InvoiceApiController extends BaseAPIController
{
protected $invoiceRepo;
protected $entityType = ENTITY_INVOICE;
public function __construct(InvoiceService $invoiceService, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, PaymentRepository $paymentRepo, Mailer $mailer)
{
parent::__construct();
@ -55,36 +57,12 @@ class InvoiceApiController extends BaseAPIController
*/
public function index()
{
$paginator = Invoice::scope()->withTrashed();
$invoices = Invoice::scope()->withTrashed()
->with(array_merge(['invoice_items'], $this->getIncluded()));
$invoices = Invoice::scope()
->withTrashed()
->with(array_merge(['invoice_items'], $this->getIncluded()))
->orderBy('created_at', 'desc');
if ($clientPublicId = Input::get('client_id')) {
$filter = function($query) use ($clientPublicId) {
$query->where('public_id', '=', $clientPublicId);
};
$invoices->whereHas('client', $filter);
$paginator->whereHas('client', $filter);
}
$invoices = $invoices->orderBy('created_at', 'desc')->paginate();
/*
// Add the first invitation link to the data
foreach ($invoices as $key => $invoice) {
foreach ($invoice->invitations as $subKey => $invitation) {
$invoices[$key]['link'] = $invitation->getLink();
}
unset($invoice['invitations']);
}
*/
$transformer = new InvoiceTransformer(Auth::user()->account, Input::get('serializer'));
$paginator = $paginator->paginate();
$data = $this->createCollection($invoices, $transformer, 'invoices', $paginator);
return $this->response($data);
return $this->returnList($invoices);
}
/**
@ -106,7 +84,6 @@ class InvoiceApiController extends BaseAPIController
public function show($publicId)
{
$invoice = Invoice::scope($publicId)->withTrashed()->first();
if(!$invoice)
@ -139,7 +116,7 @@ class InvoiceApiController extends BaseAPIController
* )
* )
*/
public function store(CreateInvoiceRequest $request)
public function store(CreateInvoiceAPIRequest $request)
{
$data = Input::all();
$error = null;
@ -351,7 +328,7 @@ class InvoiceApiController extends BaseAPIController
* )
* )
*/
public function update(UpdateInvoiceRequest $request, $publicId)
public function update(UpdateInvoiceAPIRequest $request, $publicId)
{
if ($request->action == ACTION_ARCHIVE) {
$invoice = Invoice::scope($publicId)->firstOrFail();

View File

@ -27,7 +27,10 @@ use App\Ninja\Repositories\ClientRepository;
use App\Ninja\Repositories\DocumentRepository;
use App\Services\InvoiceService;
use App\Services\RecurringInvoiceService;
use App\Http\Requests\SaveInvoiceWithClientRequest;
use App\Http\Requests\InvoiceRequest;
use App\Http\Requests\CreateInvoiceRequest;
use App\Http\Requests\UpdateInvoiceRequest;
class InvoiceController extends BaseController
{
@ -37,7 +40,7 @@ class InvoiceController extends BaseController
protected $documentRepo;
protected $invoiceService;
protected $recurringInvoiceService;
protected $entity = ENTITY_INVOICE;
protected $entityType = ENTITY_INVOICE;
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService, DocumentRepository $documentRepo, RecurringInvoiceService $recurringInvoiceService)
{
@ -88,18 +91,13 @@ class InvoiceController extends BaseController
return $this->recurringInvoiceService->getDatatable($accountId, $clientPublicId, ENTITY_RECURRING_INVOICE, $search);
}
public function edit($publicId, $clone = false)
public function edit(InvoiceRequest $request, $publicId, $clone = false)
{
$account = Auth::user()->account;
$invoice = Invoice::scope($publicId)
->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'payments')
->withTrashed()
->firstOrFail();
$this->authorize('edit', $invoice);
$invoice = $request->entity()->load('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'payments');
$entityType = $invoice->getEntityType();
$contactIds = DB::table('invitations')
->join('contacts', 'contacts.id', '=', 'invitations.contact_id')
->where('invitations.invoice_id', '=', $invoice->id)
@ -120,7 +118,7 @@ class InvoiceController extends BaseController
} else {
Utils::trackViewed($invoice->getDisplayName().' - '.$invoice->client->getDisplayName(), $invoice->getEntityType());
$method = 'PUT';
$url = "{$entityType}s/{$publicId}";
$url = "{$entityType}s/{$invoice->public_id}";
$clients->whereId($invoice->client_id);
}
@ -229,28 +227,27 @@ class InvoiceController extends BaseController
return View::make('invoices.edit', $data);
}
public function create($clientPublicId = 0, $isRecurring = false)
public function create(InvoiceRequest $request, $clientPublicId = 0, $isRecurring = false)
{
$this->authorizeCreate();
$account = Auth::user()->account;
$entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE;
$clientId = null;
if ($clientPublicId) {
$clientId = Client::getPrivateId($clientPublicId);
if ($request->client_id) {
$clientId = Client::getPrivateId($request->client_id);
}
$invoice = $account->createInvoice($entityType, $clientId);
$invoice->public_id = 0;
if(Session::get('expenses')){
if (Session::get('expenses')) {
$invoice->expenses = Expense::scope(Session::get('expenses'))->with('documents')->get();
}
$clients = Client::scope()->with('contacts', 'country')->orderBy('name');
if(!Auth::user()->hasPermission('view_all')){
if (!Auth::user()->hasPermission('view_all')) {
$clients = $clients->where('clients.user_id', '=', Auth::user()->id);
}
@ -267,9 +264,9 @@ class InvoiceController extends BaseController
return View::make('invoices.edit', $data);
}
public function createRecurring($clientPublicId = 0)
public function createRecurring(InvoiceRequest $request, $clientPublicId = 0)
{
return self::create($clientPublicId, true);
return self::create($request, $clientPublicId, true);
}
private static function getViewModel($invoice)
@ -395,7 +392,7 @@ class InvoiceController extends BaseController
*
* @return Response
*/
public function store(SaveInvoiceWithClientRequest $request)
public function store(CreateInvoiceRequest $request)
{
$data = $request->input();
$data['documents'] = $request->file('documents');
@ -405,7 +402,7 @@ class InvoiceController extends BaseController
$action = Input::get('action');
$entityType = Input::get('entityType');
$invoice = $this->invoiceService->save($data, true);
$invoice = $this->invoiceService->save($data);
$entityType = $invoice->getEntityType();
$message = trans("texts.created_{$entityType}");
@ -434,7 +431,7 @@ class InvoiceController extends BaseController
* @param int $id
* @return Response
*/
public function update(SaveInvoiceWithClientRequest $request)
public function update(UpdateInvoiceRequest $request)
{
$data = $request->input();
$data['documents'] = $request->file('documents');
@ -444,15 +441,15 @@ class InvoiceController extends BaseController
$action = Input::get('action');
$entityType = Input::get('entityType');
$invoice = $this->invoiceService->save($data, true);
$invoice = $this->invoiceService->save($data);
$entityType = $invoice->getEntityType();
$message = trans("texts.updated_{$entityType}");
Session::flash('message', $message);
if ($action == 'clone') {
return $this->cloneInvoice($invoice->public_id);
return $this->cloneInvoice($request, $invoice->public_id);
} elseif ($action == 'convert') {
return $this->convertQuote($invoice->public_id);
return $this->convertQuote($request, $invoice->public_id);
} elseif ($action == 'email') {
return $this->emailInvoice($invoice, Input::get('pdfupload'));
}
@ -521,7 +518,7 @@ class InvoiceController extends BaseController
{
Session::reflash();
return Redirect::to("invoices/{$publicId}/edit");
return Redirect::to("invoices/$publicId/edit");
}
/**
@ -549,18 +546,18 @@ class InvoiceController extends BaseController
}
}
public function convertQuote($publicId)
public function convertQuote(InvoiceRequest $request)
{
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
$clone = $this->invoiceService->convertQuote($invoice);
$clone = $this->invoiceService->convertQuote($request->entity());
Session::flash('message', trans('texts.converted_to_invoice'));
return Redirect::to('invoices/'.$clone->public_id);
return Redirect::to('invoices/' . $clone->public_id);
}
public function cloneInvoice($publicId)
public function cloneInvoice(InvoiceRequest $request, $publicId)
{
return self::edit($publicId, true);
return self::edit($request, $publicId, true);
}
public function invoiceHistory($publicId)

View File

@ -17,13 +17,14 @@ class PaymentApiController extends BaseAPIController
{
protected $paymentRepo;
protected $entityType = ENTITY_PAYMENT;
public function __construct(PaymentRepository $paymentRepo, ContactMailer $contactMailer)
{
parent::__construct();
$this->paymentRepo = $paymentRepo;
$this->contactMailer = $contactMailer;
}
/**
@ -44,85 +45,71 @@ class PaymentApiController extends BaseAPIController
*/
public function index()
{
$paginator = Payment::scope();
$payments = Payment::scope()
->with('client.contacts', 'invitation', 'user', 'invoice')->withTrashed();
->withTrashed()
->with(array_merge(['client.contacts', 'invitation', 'user', 'invoice'], $this->getIncluded()))
->orderBy('created_at', 'desc');
if ($clientPublicId = Input::get('client_id')) {
$filter = function($query) use ($clientPublicId) {
$query->where('public_id', '=', $clientPublicId);
};
$payments->whereHas('client', $filter);
$paginator->whereHas('client', $filter);
}
$payments = $payments->orderBy('created_at', 'desc')->paginate();
$paginator = $paginator->paginate();
$transformer = new PaymentTransformer(Auth::user()->account, Input::get('serializer'));
$data = $this->createCollection($payments, $transformer, 'payments', $paginator);
return $this->response($data);
return $this->returnList($payments);
}
/**
* @SWG\Put(
* path="/payments/{payment_id",
* summary="Update a payment",
* tags={"payment"},
* @SWG\Parameter(
* in="body",
* name="body",
* @SWG\Schema(ref="#/definitions/Payment")
* ),
* @SWG\Response(
* response=200,
* description="Update payment",
* @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Payment"))
* ),
* @SWG\Response(
* response="default",
* description="an ""unexpected"" error"
* )
* )
*/
/**
* @SWG\Put(
* path="/payments/{payment_id",
* summary="Update a payment",
* tags={"payment"},
* @SWG\Parameter(
* in="body",
* name="body",
* @SWG\Schema(ref="#/definitions/Payment")
* ),
* @SWG\Response(
* response=200,
* description="Update payment",
* @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Payment"))
* ),
* @SWG\Response(
* response="default",
* description="an ""unexpected"" error"
* )
* )
*/
public function update(Request $request, $publicId)
{
$data = Input::all();
$data['public_id'] = $publicId;
$error = false;
public function update(Request $request, $publicId)
{
$data = Input::all();
$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();
*/
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);
}
/**
* @SWG\Post(
@ -190,44 +177,44 @@ class PaymentApiController extends BaseAPIController
}
/**
* @SWG\Delete(
* path="/payments/{payment_id}",
* summary="Delete a payment",
* tags={"payment"},
* @SWG\Parameter(
* in="body",
* name="body",
* @SWG\Schema(ref="#/definitions/Payment")
* ),
* @SWG\Response(
* response=200,
* description="Delete payment",
* @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Payment"))
* ),
* @SWG\Response(
* response="default",
* description="an ""unexpected"" error"
* )
* )
*/
/**
* @SWG\Delete(
* path="/payments/{payment_id}",
* summary="Delete a payment",
* tags={"payment"},
* @SWG\Parameter(
* in="body",
* name="body",
* @SWG\Schema(ref="#/definitions/Payment")
* ),
* @SWG\Response(
* response=200,
* description="Delete payment",
* @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Payment"))
* ),
* @SWG\Response(
* response="default",
* description="an ""unexpected"" error"
* )
* )
*/
public function destroy($publicId)
{
public function destroy($publicId)
{
$payment = Payment::scope($publicId)->withTrashed()->first();
$invoiceId = $payment->invoice->public_id;
$payment = Payment::scope($publicId)->withTrashed()->first();
$invoiceId = $payment->invoice->public_id;
$this->paymentRepo->delete($payment);
$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');
/*
$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');
return $this->response($data);
}
return $this->response($data);
}
}

View File

@ -25,12 +25,13 @@ use App\Ninja\Repositories\AccountRepository;
use App\Ninja\Mailers\ContactMailer;
use App\Services\PaymentService;
use App\Http\Requests\PaymentRequest;
use App\Http\Requests\CreatePaymentRequest;
use App\Http\Requests\UpdatePaymentRequest;
class PaymentController extends BaseController
{
protected $entity = ENTITY_PAYMENT;
protected $entityType = ENTITY_PAYMENT;
public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer, PaymentService $paymentService)
{
@ -67,10 +68,8 @@ class PaymentController extends BaseController
return $this->paymentService->getDatatable($clientPublicId, Input::get('sSearch'));
}
public function create($clientPublicId = 0, $invoicePublicId = 0)
public function create(PaymentRequest $request)
{
$this->authorizeCreate();
$invoices = Invoice::scope()
->where('is_recurring', '=', false)
->where('is_quote', '=', false)
@ -79,8 +78,8 @@ class PaymentController extends BaseController
->orderBy('invoice_number')->get();
$data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
'clientPublicId' => Input::old('client') ? Input::old('client') : ($request->client_id ?: 0),
'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : ($request->invoice_id ?: 0),
'invoice' => null,
'invoices' => $invoices,
'payment' => null,
@ -94,12 +93,10 @@ class PaymentController extends BaseController
return View::make('payments.edit', $data);
}
public function edit($publicId)
public function edit(PaymentRequest $request)
{
$payment = Payment::scope($publicId)->firstOrFail();
$this->authorize('edit', $payment);
$payment = $request->entity();
$payment->payment_date = Utils::fromSqlDate($payment->payment_date);
$data = array(
@ -109,7 +106,7 @@ class PaymentController extends BaseController
->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'payment' => $payment,
'method' => 'PUT',
'url' => 'payments/'.$publicId,
'url' => 'payments/'.$payment->public_id,
'title' => trans('texts.edit_payment'),
'paymentTypes' => Cache::get('paymentTypes'),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
@ -589,9 +586,7 @@ class PaymentController extends BaseController
public function store(CreatePaymentRequest $request)
{
$input = $request->input();
$this->authorizeUpdate($data);
$input['invoice_id'] = Invoice::getPrivateId($input['invoice']);
$input['client_id'] = Client::getPrivateId($input['client']);
$payment = $this->paymentRepo->save($input);
@ -608,11 +603,7 @@ class PaymentController extends BaseController
public function update(UpdatePaymentRequest $request)
{
$input = $request->input();
$this->authorizeUpdate($data);
$payment = $this->paymentRepo->save($input);
$payment = $this->paymentRepo->save($request->input());
Session::flash('message', trans('texts.updated_payment'));

View File

@ -20,8 +20,9 @@ use App\Services\ProductService;
class ProductApiController extends BaseAPIController
{
protected $productService;
protected $productRepo;
protected $productRepo;
protected $entityType = ENTITY_PRODUCT;
public function __construct(ProductService $productService, ProductRepository $productRepo)
{
@ -33,17 +34,11 @@ class ProductApiController extends BaseAPIController
public function index()
{
$products = Product::scope()
->withTrashed()
->orderBy('created_at', 'desc');
$products = Product::scope()->withTrashed();
$products = $products->paginate();
$paginator = Product::scope()->withTrashed()->paginate();
$transformer = new ProductTransformer(\Auth::user()->account, $this->serializer);
$data = $this->createCollection($products, $transformer, 'products', $paginator);
return $this->response($data);
return $this->returnList($products);
}
public function getDatatable()

View File

@ -1,75 +0,0 @@
<?php namespace App\Http\Controllers;
use Auth;
use Input;
use Utils;
use Response;
use App\Models\Invoice;
use App\Ninja\Repositories\InvoiceRepository;
use App\Http\Controllers\BaseAPIController;
use App\Ninja\Transformers\InvoiceTransformer;
class QuoteApiController extends BaseAPIController
{
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo)
{
parent::__construct();
$this->invoiceRepo = $invoiceRepo;
}
/**
* @SWG\Get(
* path="/quotes",
* tags={"quote"},
* summary="List of quotes",
* @SWG\Response(
* response=200,
* description="A list with quotes",
* @SWG\Schema(type="array", @SWG\Items(ref="#/definitions/Invoice"))
* ),
* @SWG\Response(
* response="default",
* description="an ""unexpected"" error"
* )
* )
*/
public function index()
{
$paginator = Invoice::scope();
$invoices = Invoice::scope()
->with('client', 'invitations', 'user', 'invoice_items')
->where('invoices.is_quote', '=', true);
if ($clientPublicId = Input::get('client_id')) {
$filter = function($query) use ($clientPublicId) {
$query->where('public_id', '=', $clientPublicId);
};
$invoices->whereHas('client', $filter);
$paginator->whereHas('client', $filter);
}
$invoices = $invoices->orderBy('created_at', 'desc')->paginate();
$transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer'));
$paginator = $paginator->paginate();
$data = $this->createCollection($invoices, $transformer, 'quotes', $paginator);
return $this->response($data);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -26,6 +26,7 @@ use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\ClientRepository;
use App\Events\QuoteInvitationWasApproved;
use App\Services\InvoiceService;
use App\Http\Requests\InvoiceRequest;
class QuoteController extends BaseController
{
@ -33,7 +34,7 @@ class QuoteController extends BaseController
protected $invoiceRepo;
protected $clientRepo;
protected $invoiceService;
protected $entity = ENTITY_INVOICE;
protected $entityType = ENTITY_INVOICE;
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService)
{
@ -78,10 +79,8 @@ class QuoteController extends BaseController
return $this->invoiceService->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search);
}
public function create($clientPublicId = 0)
public function create(InvoiceRequest $request, $clientPublicId = 0)
{
$this->authorizeCreate();
if (!Utils::hasFeature(FEATURE_QUOTES)) {
return Redirect::to('/invoices/create');
}

View File

@ -13,6 +13,8 @@ class TaskApiController extends BaseAPIController
{
protected $taskRepo;
protected $entityType = ENTITY_TASK;
public function __construct(TaskRepository $taskRepo)
{
parent::__construct();
@ -38,25 +40,12 @@ class TaskApiController extends BaseAPIController
*/
public function index()
{
$paginator = Task::scope();
$tasks = Task::scope()
->with($this->getIncluded());
$payments = Task::scope()
->withTrashed()
->with($this->getIncluded())
->orderBy('created_at', 'desc');
if ($clientPublicId = Input::get('client_id')) {
$filter = function($query) use ($clientPublicId) {
$query->where('public_id', '=', $clientPublicId);
};
$tasks->whereHas('client', $filter);
$paginator->whereHas('client', $filter);
}
$tasks = $tasks->orderBy('created_at', 'desc')->paginate();
$paginator = $paginator->paginate();
$transformer = new TaskTransformer(\Auth::user()->account, Input::get('serializer'));
$data = $this->createCollection($tasks, $transformer, 'tasks', $paginator);
return $this->response($data);
return $this->returnList($payments);
}
/**

View File

@ -18,11 +18,15 @@ use App\Ninja\Repositories\TaskRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Services\TaskService;
use App\Http\Requests\TaskRequest;
use App\Http\Requests\CreateTaskRequest;
use App\Http\Requests\UpdateTaskRequest;
class TaskController extends BaseController
{
protected $taskRepo;
protected $taskService;
protected $entity = ENTITY_TASK;
protected $entityType = ENTITY_TASK;
public function __construct(TaskRepository $taskRepo, InvoiceRepository $invoiceRepo, TaskService $taskService)
{
@ -66,7 +70,7 @@ class TaskController extends BaseController
*
* @return Response
*/
public function store()
public function store(CreateTaskRequest $request)
{
return $this->save();
}
@ -83,14 +87,13 @@ class TaskController extends BaseController
*
* @return Response
*/
public function create($clientPublicId = 0)
public function create(TaskRequest $request)
{
$this->authorizeCreate();
$this->checkTimezone();
$data = [
'task' => null,
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
'clientPublicId' => Input::old('client') ? Input::old('client') : ($request->client_id ?: 0),
'method' => 'POST',
'url' => 'tasks',
'title' => trans('texts.new_task'),
@ -109,13 +112,11 @@ class TaskController extends BaseController
* @param int $id
* @return Response
*/
public function edit($publicId)
public function edit(TaskRequest $request)
{
$this->checkTimezone();
$task = Task::scope($publicId)->with('client', 'invoice')->withTrashed()->firstOrFail();
$this->authorize('edit', $task);
$task = $request->entity();
$actions = [];
if ($task->invoice) {
@ -143,7 +144,7 @@ class TaskController extends BaseController
'task' => $task,
'clientPublicId' => $task->client ? $task->client->public_id : 0,
'method' => 'PUT',
'url' => 'tasks/'.$publicId,
'url' => 'tasks/'.$task->public_id,
'title' => trans('texts.edit_task'),
'duration' => $task->is_running ? $task->getCurrentDuration() : $task->getDuration(),
'actions' => $actions,
@ -163,9 +164,11 @@ class TaskController extends BaseController
* @param int $id
* @return Response
*/
public function update($publicId)
public function update(UpdateTaskRequest $request)
{
return $this->save($publicId);
$task = $request->entity();
return $this->save($task->public_id);
}
private static function getViewModel()
@ -180,20 +183,10 @@ class TaskController extends BaseController
{
$action = Input::get('action');
$this->authorizeUpdate(array('public_id'=>$publicId)/* Hacky, but works */);
if (in_array($action, ['archive', 'delete', 'restore'])) {
return self::bulk();
}
if ($validator = $this->taskRepo->getErrors(Input::all())) {
$url = $publicId ? 'tasks/'.$publicId.'/edit' : 'tasks/create';
Session::flash('error', trans('texts.task_errors'));
return Redirect::to($url)
->withErrors($validator)
->withInput();
}
$task = $this->taskRepo->save($publicId, Input::all());
Session::flash('message', trans($publicId ? 'texts.updated_task' : 'texts.created_task'));

View File

@ -14,6 +14,8 @@ class TaxRateApiController extends BaseAPIController
protected $taxRateService;
protected $taxRateRepo;
protected $entityType = ENTITY_TAX_RATE;
public function __construct(TaxRateService $taxRateService, TaxRateRepository $taxRateRepo)
{
parent::__construct();
@ -24,15 +26,11 @@ class TaxRateApiController extends BaseAPIController
public function index()
{
$taxRates = TaxRate::scope()->withTrashed();
$taxRates = $taxRates->paginate();
$paginator = TaxRate::scope()->withTrashed()->paginate();
$transformer = new TaxRateTransformer(Auth::user()->account, $this->serializer);
$data = $this->createCollection($taxRates, $transformer, 'tax_rates', $paginator);
return $this->response($data);
$taxRates = TaxRate::scope()
->withTrashed()
->orderBy('created_at', 'desc');
return $this->returnList($taxRates);
}
public function store(CreateTaxRateRequest $request)

View File

@ -14,6 +14,8 @@ class UserApiController extends BaseAPIController
protected $userService;
protected $userRepo;
protected $entityType = ENTITY_USER;
public function __construct(UserService $userService, UserRepository $userRepo)
{
parent::__construct();
@ -24,16 +26,11 @@ class UserApiController extends BaseAPIController
public function index()
{
$user = Auth::user();
$users = User::whereAccountId($user->account_id)->withTrashed();
$users = $users->paginate();
$paginator = User::whereAccountId($user->account_id)->withTrashed()->paginate();
$transformer = new UserTransformer(Auth::user()->account, $this->serializer);
$data = $this->createCollection($users, $transformer, 'users', $paginator);
return $this->response($data);
$users = User::whereAccountId(Auth::user()->account_id)
->withTrashed()
->orderBy('created_at', 'desc');
return $this->returnList($users);
}
/*

View File

@ -14,6 +14,8 @@ class VendorApiController extends BaseAPIController
{
protected $vendorRepo;
protected $entityType = ENTITY_VENDOR;
public function __construct(VendorRepository $vendorRepo)
{
parent::__construct();
@ -46,17 +48,12 @@ class VendorApiController extends BaseAPIController
*/
public function index()
{
$vendors = Vendor::scope()
$vendors = Vendor::scope()
->with($this->getIncluded())
->withTrashed()
->orderBy('created_at', 'desc')
->paginate();
->orderBy('created_at', 'desc');
$transformer = new VendorTransformer(Auth::user()->account, Input::get('serializer'));
$paginator = Vendor::scope()->paginate();
$data = $this->createCollection($vendors, $transformer, ENTITY_VENDOR, $paginator);
return $this->response($data);
return $this->returnList($vendors);
}
/**

View File

@ -23,14 +23,15 @@ use App\Models\Country;
use App\Ninja\Repositories\VendorRepository;
use App\Services\VendorService;
use App\Http\Requests\VendorRequest;
use App\Http\Requests\CreateVendorRequest;
use App\Http\Requests\UpdateVendorRequest;
// vendor
class VendorController extends BaseController
{
protected $vendorService;
protected $vendorRepo;
protected $entity = ENTITY_VENDOR;
protected $entityType = ENTITY_VENDOR;
public function __construct(VendorRepository $vendorRepo, VendorService $vendorService)
{
@ -38,8 +39,6 @@ class VendorController extends BaseController
$this->vendorRepo = $vendorRepo;
$this->vendorService = $vendorService;
}
/**
@ -77,11 +76,7 @@ class VendorController extends BaseController
*/
public function store(CreateVendorRequest $request)
{
$data = $request->input();
$this->authorizeUpdate($data);
$vendor = $this->vendorService->save($data);
$vendor = $this->vendorService->save($request->input());
Session::flash('message', trans('texts.created_vendor'));
@ -94,12 +89,10 @@ class VendorController extends BaseController
* @param int $id
* @return Response
*/
public function show($publicId)
public function show(VendorRequest $request)
{
$vendor = Vendor::withTrashed()->scope($publicId)->with('vendorcontacts', 'size', 'industry')->firstOrFail();
$this->authorize('view', $vendor);
$vendor = $request->entity();
Utils::trackViewed($vendor->getDisplayName(), 'vendor');
$actionLinks = [
@ -125,10 +118,8 @@ class VendorController extends BaseController
*
* @return Response
*/
public function create()
public function create(VendorRequest $request)
{
$this->authorizeCreate();
if (Vendor::scope()->count() > Auth::user()->getMaxNumVendors()) {
return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumVendors()." vendors"]);
}
@ -151,16 +142,14 @@ class VendorController extends BaseController
* @param int $id
* @return Response
*/
public function edit($publicId)
public function edit(VendorRequest $request)
{
$vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail();
$this->authorize('edit', $vendor)
$vendor = $request->entity();
$data = [
'vendor' => $vendor,
'method' => 'PUT',
'url' => 'vendors/'.$publicId,
'url' => 'vendors/'.$vendor->public_id,
'title' => trans('texts.edit_vendor'),
];
@ -193,11 +182,7 @@ class VendorController extends BaseController
*/
public function update(UpdateVendorRequest $request)
{
$data = $request->input();
$this->authorizeUpdate($data);
$vendor = $this->vendorService->save($data);
$vendor = $this->vendorService->save($request->input());
Session::flash('message', trans('texts.updated_vendor'));

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Middleware;
<?php namespace App\Http\Middleware;
use Closure;

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Middleware;
<?php namespace App\Http\Middleware;
use Request;
use Closure;

View File

@ -0,0 +1,18 @@
<?php namespace App\Http\Requests;
class ClientRequest extends EntityRequest {
protected $entityType = ENTITY_CLIENT;
public function entity()
{
$client = parent::entity();
// eager load the contacts
if ($client && ! count($client->contacts)) {
$client->load('contacts');
}
return $client;
}
}

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class CreateClientRequest extends Request
class CreateClientRequest extends ClientRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class CreateClientRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_CLIENT);
}
/**

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class CreateCreditRequest extends Request
class CreateCreditRequest extends CreditRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class CreateCreditRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_CREDIT);
}
/**

View File

@ -0,0 +1,26 @@
<?php namespace App\Http\Requests;
class CreateDocumentRequest extends DocumentRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return $this->user()->can('create', ENTITY_DOCUMENT);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
];
}
}

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class CreateExpenseRequest extends Request
class CreateExpenseRequest extends ExpenseRequest
{
// Expenses
/**
@ -13,7 +10,7 @@ class CreateExpenseRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_EXPENSE);
}
/**

View File

@ -0,0 +1,32 @@
<?php namespace App\Http\Requests;
class CreateInvoiceAPIRequest extends InvoiceRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return $this->user()->can('create', ENTITY_INVOICE);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
'email' => 'required_without:client_id',
'client_id' => 'required_without:email',
'invoice_items' => 'valid_invoice_items',
'invoice_number' => 'unique:invoices,invoice_number,,id,account_id,' . $this->user()->account_id,
'discount' => 'positive',
];
return $rules;
}
}

View File

@ -1,11 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use Auth;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
use App\Models\Invoice;
class CreateInvoiceRequest extends Request
class CreateInvoiceRequest extends InvoiceRequest
{
/**
* Determine if the user is authorized to make this request.
@ -14,7 +9,7 @@ class CreateInvoiceRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_INVOICE);
}
/**
@ -25,13 +20,18 @@ class CreateInvoiceRequest extends Request
public function rules()
{
$rules = [
'email' => 'required_without:client_id',
'client_id' => 'required_without:email',
'client.contacts' => 'valid_contacts',
'invoice_items' => 'valid_invoice_items',
'invoice_number' => 'unique:invoices,invoice_number,,id,account_id,'.Auth::user()->account_id,
'invoice_number' => 'required|unique:invoices,invoice_number,,id,account_id,' . $this->user()->account_id,
'discount' => 'positive',
];
/* There's a problem parsing the dates
if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) {
$rules['end_date'] = 'after' . Request::get('start_date');
}
*/
return $rules;
}
}

View File

@ -1,10 +1,8 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
use App\Models\Invoice;
class CreatePaymentRequest extends Request
class CreatePaymentRequest extends PaymentRequest
{
/**
* Determine if the user is authorized to make this request.
@ -13,7 +11,7 @@ class CreatePaymentRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_PAYMENT);
}
/**

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -0,0 +1,26 @@
<?php namespace App\Http\Requests;
class CreateTaskRequest extends TaskRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return $this->user()->can('create', ENTITY_TASK);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'time_log' => 'time_log',
];
}
}

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
// vendor
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
<?php namespace App\Http\Requests;
class CreateVendorRequest extends Request
class CreateVendorRequest extends VendorRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class CreateVendorRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('create', ENTITY_VENDOR);
}
/**

View File

@ -0,0 +1,7 @@
<?php namespace App\Http\Requests;
class CreditRequest extends EntityRequest {
protected $entityType = ENTITY_CREDIT;
}

View File

@ -0,0 +1,7 @@
<?php namespace App\Http\Requests;
class DocumentRequest extends EntityRequest {
protected $entityType = ENTITY_DOCUMENT;
}

View File

@ -0,0 +1,49 @@
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Input;
use Utils;
class EntityRequest extends Request {
protected $entityType;
private $entity;
public function entity()
{
if ($this->entity) {
return $this->entity;
}
$paramName = $this->entityType . 's';
$publicId = $this->$paramName ?: (Input::get('public_id') ?: Input::get('id'));
if ( ! $publicId) {
return null;
}
$class = Utils::getEntityClass($this->entityType);
if (method_exists($class, 'withTrashed')) {
$this->entity = $class::scope($publicId)->withTrashed()->firstOrFail();
} else {
$this->entity = $class::scope($publicId)->firstOrFail();
}
return $this->entity;
}
public function authorize()
{
if ($this->entity()) {
return $this->user()->can('view', $this->entity());
} else {
return $this->user()->can('create', $this->entityType);
}
}
public function rules()
{
return [];
}
}

View File

@ -0,0 +1,18 @@
<?php namespace App\Http\Requests;
class ExpenseRequest extends EntityRequest {
protected $entityType = ENTITY_EXPENSE;
public function entity()
{
$expense = parent::entity();
// eager load the contacts
if ($expense && ! count($expense->documents)) {
$expense->load('documents');
}
return $expense;
}
}

View File

@ -0,0 +1,19 @@
<?php namespace App\Http\Requests;
class InvoiceRequest extends EntityRequest {
protected $entityType = ENTITY_INVOICE;
public function entity()
{
$invoice = parent::entity();
// eager load the contacts
if ($invoice && ! count($invoice->invoice_items)) {
$invoice->load('invoice_items');
}
return $invoice;
}
}

View File

@ -0,0 +1,7 @@
<?php namespace App\Http\Requests;
class PaymentRequest extends EntityRequest {
protected $entityType = ENTITY_PAYMENT;
}

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use Auth;
use App\Http\Requests\Request;

View File

@ -1,45 +0,0 @@
<?php namespace app\Http\Requests;
use Auth;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
use App\Models\Invoice;
class SaveInvoiceWithClientRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$publicId = Request::get('public_id');
$invoiceId = $publicId ? Invoice::getPrivateId($publicId) : '';
$rules = [
'client.contacts' => 'valid_contacts',
'invoice_items' => 'valid_invoice_items',
'invoice_number' => 'required|unique:invoices,invoice_number,'.$invoiceId.',id,account_id,'.Auth::user()->account_id,
'discount' => 'positive',
];
/* There's a problem parsing the dates
if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) {
$rules['end_date'] = 'after' . Request::get('start_date');
}
*/
return $rules;
}
}

View File

@ -0,0 +1,7 @@
<?php namespace App\Http\Requests;
class TaskRequest extends EntityRequest {
protected $entityType = ENTITY_TASK;
}

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class UpdateClientRequest extends Request
class UpdateClientRequest extends ClientRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class UpdateClientRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('edit', $this->entity());
}
/**

View File

@ -1,10 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class UpdateExpenseRequest extends Request
class UpdateExpenseRequest extends ExpenseRequest
{
/**
* Determine if the user is authorized to make this request.
@ -13,7 +9,7 @@ class UpdateExpenseRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('edit', $this->entity());
}
/**

View File

@ -0,0 +1,36 @@
<?php namespace App\Http\Requests;
class UpdateInvoiceAPIRequest extends InvoiceRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return $this->user()->can('edit', $this->entity());
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
if ($this->action == ACTION_ARCHIVE) {
return [];
}
$invoiceId = $this->entity()->id;
$rules = [
'invoice_items' => 'valid_invoice_items',
'invoice_number' => 'unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . $this->user()->account_id,
'discount' => 'positive',
];
return $rules;
}
}

View File

@ -1,11 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use Auth;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
use App\Models\Invoice;
class UpdateInvoiceRequest extends Request
class UpdateInvoiceRequest extends InvoiceRequest
{
/**
* Determine if the user is authorized to make this request.
@ -14,7 +9,7 @@ class UpdateInvoiceRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('edit', $this->entity());
}
/**
@ -24,19 +19,21 @@ class UpdateInvoiceRequest extends Request
*/
public function rules()
{
if ($this->action == ACTION_ARCHIVE) {
return [];
}
$publicId = $this->route('invoices');
$invoiceId = Invoice::getPrivateId($publicId);
$invoiceId = $this->entity()->id;
$rules = [
'client.contacts' => 'valid_contacts',
'invoice_items' => 'valid_invoice_items',
'invoice_number' => 'unique:invoices,invoice_number,'.$invoiceId.',id,account_id,'.Auth::user()->account_id,
'invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . $this->user()->account_id,
'discount' => 'positive',
];
/* There's a problem parsing the dates
if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) {
$rules['end_date'] = 'after' . Request::get('start_date');
}
*/
return $rules;
}
}

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
class UpdatePaymentRequest extends Request
class UpdatePaymentRequest extends PaymentRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class UpdatePaymentRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('edit', $this->entity());
}
/**

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -0,0 +1,26 @@
<?php namespace App\Http\Requests;
class UpdateTaskRequest extends TaskRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return $this->user()->can('edit', $this->entity());
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'time_log' => 'time_log',
];
}
}

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;

View File

@ -1,4 +1,4 @@
<?php namespace app\Http\Requests;
<?php namespace App\Http\Requests;
use Auth;
use App\Http\Requests\Request;

View File

@ -1,9 +1,6 @@
<?php namespace app\Http\Requests;
// vendor
use App\Http\Requests\Request;
use Illuminate\Validation\Factory;
<?php namespace App\Http\Requests;
class UpdateVendorRequest extends Request
class UpdateVendorRequest extends VendorRequest
{
/**
* Determine if the user is authorized to make this request.
@ -12,7 +9,7 @@ class UpdateVendorRequest extends Request
*/
public function authorize()
{
return true;
return $this->user()->can('edit', $this->entity());
}
/**

View File

@ -0,0 +1,19 @@
<?php namespace App\Http\Requests;
class VendorRequest extends EntityRequest {
protected $entityType = ENTITY_VENDOR;
public function entity()
{
$vendor = parent::entity();
// eager load the contacts
if ($vendor && ! count($vendor->vendorcontacts)) {
$vendor->load('vendorcontacts');
}
return $vendor;
}
}

View File

@ -48,8 +48,8 @@ Route::group(['middleware' => 'auth:client'], function() {
Route::get('client/documents', 'PublicClientController@documentIndex');
Route::get('client/payments', 'PublicClientController@paymentIndex');
Route::get('client/dashboard', 'PublicClientController@dashboard');
Route::get('client/document/js/{public_id}/{filename}', 'PublicClientController@getDocumentVFSJS');
Route::get('client/document/{invitation_key}/{public_id}/{filename?}', 'PublicClientController@getDocument');
Route::get('client/documents/js/{documents}/{filename}', 'PublicClientController@getDocumentVFSJS');
Route::get('client/documents/{invitation_key}/{documents}/{filename?}', 'PublicClientController@getDocument');
Route::get('client/documents/{invitation_key}/{filename?}', 'PublicClientController@getInvoiceDocumentsZip');
Route::get('api/client.quotes', array('as'=>'api.client.quotes', 'uses'=>'PublicClientController@quoteDatatable'));
@ -134,20 +134,20 @@ Route::group(['middleware' => 'auth:user'], function() {
Route::get('invoices/create/{client_id?}', 'InvoiceController@create');
Route::get('recurring_invoices/create/{client_id?}', 'InvoiceController@createRecurring');
Route::get('recurring_invoices', 'RecurringInvoiceController@index');
Route::get('invoices/{public_id}/clone', 'InvoiceController@cloneInvoice');
Route::get('invoices/{invoices}/clone', 'InvoiceController@cloneInvoice');
Route::post('invoices/bulk', 'InvoiceController@bulk');
Route::post('recurring_invoices/bulk', 'InvoiceController@bulk');
Route::get('document/{public_id}/{filename?}', 'DocumentController@get');
Route::get('document/js/{public_id}/{filename}', 'DocumentController@getVFSJS');
Route::get('document/preview/{public_id}/{filename?}', 'DocumentController@getPreview');
Route::get('documents/{documents}/{filename?}', 'DocumentController@get');
Route::get('documents/js/{documents}/{filename}', 'DocumentController@getVFSJS');
Route::get('documents/preview/{documents}/{filename?}', 'DocumentController@getPreview');
Route::post('document', 'DocumentController@postUpload');
Route::get('quotes/create/{client_id?}', 'QuoteController@create');
Route::get('quotes/{public_id}/clone', 'InvoiceController@cloneInvoice');
Route::get('quotes/{public_id}/edit', 'InvoiceController@edit');
Route::put('quotes/{public_id}', 'InvoiceController@update');
Route::get('quotes/{public_id}', 'InvoiceController@edit');
Route::get('quotes/{invoices}/clone', 'InvoiceController@cloneInvoice');
Route::get('quotes/{invoices}/edit', 'InvoiceController@edit');
Route::put('quotes/{invoices}', 'InvoiceController@update');
Route::get('quotes/{invoices}', 'InvoiceController@edit');
Route::post('quotes', 'InvoiceController@store');
Route::get('quotes', 'QuoteController@index');
Route::get('api/quotes/{client_id?}', array('as'=>'api.quotes', 'uses'=>'QuoteController@getDatatable'));
@ -253,8 +253,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
Route::get('accounts', 'AccountApiController@show');
Route::put('accounts', 'AccountApiController@update');
Route::resource('clients', 'ClientApiController');
Route::get('quotes', 'QuoteApiController@index');
Route::resource('quotes', 'QuoteApiController');
//Route::get('quotes', 'QuoteApiController@index');
//Route::resource('quotes', 'QuoteApiController');
Route::get('invoices', 'InvoiceApiController@index');
Route::resource('invoices', 'InvoiceApiController');
Route::get('payments', 'PaymentApiController@index');
@ -552,25 +552,25 @@ if (!defined('CONTACT_EMAIL')) {
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
define('NINJA_GATEWAY_ID', GATEWAY_STRIPE);
define('NINJA_GATEWAY_CONFIG', 'NINJA_GATEWAY_CONFIG');
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
define('NINJA_WEB_URL', env('NINJA_WEB_URL', 'https://www.invoiceninja.com'));
define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com'));
define('NINJA_DATE', '2000-01-01');
define('NINJA_VERSION', '2.5.1.3');
define('NINJA_VERSION', '2.5.1.3' . env('NINJA_VERSION_SUFFIX'));
define('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja');
define('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja');
define('SOCIAL_LINK_GITHUB', 'https://github.com/invoiceninja/invoiceninja/');
define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja'));
define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja'));
define('SOCIAL_LINK_GITHUB', env('SOCIAL_LINK_GITHUB', 'https://github.com/invoiceninja/invoiceninja/'));
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
define('RELEASES_URL', 'https://trello.com/b/63BbiVVe/invoice-ninja');
define('ZAPIER_URL', 'https://zapier.com/zapbook/invoice-ninja');
define('OUTDATE_BROWSER_URL', 'http://browsehappy.com/');
define('PDFMAKE_DOCS', 'http://pdfmake.org/playground.html');
define('PHANTOMJS_CLOUD', 'http://api.phantomjscloud.com/api/browser/v2/');
define('PHP_DATE_FORMATS', 'http://php.net/manual/en/function.date.php');
define('REFERRAL_PROGRAM_URL', 'https://www.invoiceninja.com/referral-program/');
define('EMAIL_MARKUP_URL', 'https://developers.google.com/gmail/markup');
define('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all');
define('NINJA_FROM_EMAIL', env('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com'));
define('RELEASES_URL', env('RELEASES_URL', 'https://trello.com/b/63BbiVVe/invoice-ninja'));
define('ZAPIER_URL', env('ZAPIER_URL', 'https://zapier.com/zapbook/invoice-ninja'));
define('OUTDATE_BROWSER_URL', env('OUTDATE_BROWSER_URL', 'http://browsehappy.com/'));
define('PDFMAKE_DOCS', env('PDFMAKE_DOCS', 'http://pdfmake.org/playground.html'));
define('PHANTOMJS_CLOUD', env('PHANTOMJS_CLOUD', 'http://api.phantomjscloud.com/api/browser/v2/'));
define('PHP_DATE_FORMATS', env('PHP_DATE_FORMATS', 'http://php.net/manual/en/function.date.php'));
define('REFERRAL_PROGRAM_URL', env('REFERRAL_PROGRAM_URL', 'https://www.invoiceninja.com/referral-program/'));
define('EMAIL_MARKUP_URL', env('EMAIL_MARKUP_URL', 'https://developers.google.com/gmail/markup'));
define('OFX_HOME_URL', env('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all'));
define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=');
@ -584,13 +584,13 @@ if (!defined('CONTACT_EMAIL')) {
define('INVOICE_DESIGNS_AFFILIATE_KEY', 'T3RS74');
define('SELF_HOST_AFFILIATE_KEY', '8S69AD');
define('PRO_PLAN_PRICE', 50);
define('PLAN_PRICE_PRO_MONTHLY', 5);
define('PLAN_PRICE_PRO_YEARLY', 50);
define('PLAN_PRICE_ENTERPRISE_MONTHLY', 10);
define('PLAN_PRICE_ENTERPRISE_YEARLY', 100);
define('WHITE_LABEL_PRICE', 20);
define('INVOICE_DESIGNS_PRICE', 10);
define('PRO_PLAN_PRICE', env('PRO_PLAN_PRICE', 50));
define('PLAN_PRICE_PRO_MONTHLY', env('PLAN_PRICE_PRO_MONTHLY', 5));
define('PLAN_PRICE_PRO_YEARLY', env('PLAN_PRICE_PRO_YEARLY', 50));
define('PLAN_PRICE_ENTERPRISE_MONTHLY', env('PLAN_PRICE_ENTERPRISE_MONTHLY', 10));
define('PLAN_PRICE_ENTERPRISE_YEARLY', env('PLAN_PRICE_ENTERPRISE_YEARLY', 100));
define('WHITE_LABEL_PRICE', env('WHITE_LABEL_PRICE', 20));
define('INVOICE_DESIGNS_PRICE', env('INVOICE_DESIGNS_PRICE', 10));
define('USER_TYPE_SELF_HOST', 'SELF_HOST');
define('USER_TYPE_CLOUD_HOST', 'CLOUD_HOST');
@ -600,8 +600,8 @@ if (!defined('CONTACT_EMAIL')) {
define('TEST_PASSWORD', 'password');
define('API_SECRET', 'API_SECRET');
define('IOS_PRODUCTION_PUSH','ninjaIOS');
define('IOS_DEV_PUSH','devNinjaIOS');
define('IOS_PRODUCTION_PUSH', env('IOS_PRODUCTION_PUSH', 'ninjaIOS'));
define('IOS_DEV_PUSH', env('IOS_DEV_PUSH', 'devNinjaIOS'));
define('TOKEN_BILLING_DISABLED', 1);
define('TOKEN_BILLING_OPT_IN', 2);
@ -770,4 +770,4 @@ if (Utils::isNinjaDev())
//ini_set('memory_limit','1024M');
//Auth::loginUsingId(1);
}
*/
*/

View File

@ -669,6 +669,11 @@ class Utils
return $year + $offset;
}
public static function getEntityClass($entityType)
{
return 'App\\Models\\' . static::getEntityName($entityType);
}
public static function getEntityName($entityType)
{
return ucwords(str_replace('_', ' ', $entityType));

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use App\Models\Invoice;
use App\Events\ClientWasCreated;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Carbon;
use App\Models\Credit;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Carbon;
use App\Models\Expense;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Utils;
use Auth;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Utils;
use Auth;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use App\Ninja\Mailers\UserMailer;
use App\Ninja\Mailers\ContactMailer;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Carbon;
use App\Events\QuoteWasEmailed;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use Auth;
use Utils;

View File

@ -1,4 +1,4 @@
<?php namespace app\Listeners;
<?php namespace App\Listeners;
use App\Models\Task;
use App\Events\InvoiceWasDeleted;

View File

@ -796,6 +796,10 @@ class Account extends Eloquent
public function hasFeature($feature)
{
if (Utils::isNinjaDev()) {
return true;
}
$planDetails = $this->getPlanDetails();
$selfHost = !Utils::isNinjaProd();

View File

@ -173,11 +173,11 @@ class Document extends EntityModel
}
public function getUrl(){
return url('document/'.$this->public_id.'/'.$this->name);
return url('documents/'.$this->public_id.'/'.$this->name);
}
public function getClientUrl($invitation){
return url('client/document/'.$invitation->invitation_key.'/'.$this->public_id.'/'.$this->name);
return url('client/documents/'.$invitation->invitation_key.'/'.$this->public_id.'/'.$this->name);
}
public function isPDFEmbeddable(){
@ -186,16 +186,16 @@ class Document extends EntityModel
public function getVFSJSUrl(){
if(!$this->isPDFEmbeddable())return null;
return url('document/js/'.$this->public_id.'/'.$this->name.'.js');
return url('documents/js/'.$this->public_id.'/'.$this->name.'.js');
}
public function getClientVFSJSUrl(){
if(!$this->isPDFEmbeddable())return null;
return url('client/document/js/'.$this->public_id.'/'.$this->name.'.js');
return url('client/documents/js/'.$this->public_id.'/'.$this->name.'.js');
}
public function getPreviewUrl(){
return $this->preview?url('document/preview/'.$this->public_id.'/'.$this->name.'.'.pathinfo($this->preview, PATHINFO_EXTENSION)):null;
return $this->preview?url('documents/preview/'.$this->public_id.'/'.$this->name.'.'.pathinfo($this->preview, PATHINFO_EXTENSION)):null;
}
public function toArray()

View File

@ -101,6 +101,16 @@ class EntityModel extends Eloquent
return $this->getName();
}
public static function getClassName($entityType)
{
return 'App\\Models\\' . ucwords(Utils::toCamelCase($entityType));
}
public static function getTransformerName($entityType)
{
return 'App\\Ninja\\Transformers\\' . ucwords(Utils::toCamelCase($entityType)) . 'Transformer';
}
public function setNullValues()
{
foreach ($this->fillable as $field) {

View File

@ -436,6 +436,7 @@ class Invoice extends EntityModel implements BalanceAffecting
'contacts',
'country',
'currency_id',
'country_id',
'custom_value1',
'custom_value2',
]);

View File

@ -1,4 +1,4 @@
<?php namespace app\Models;
<?php namespace App\Models;
use Eloquent;
use Auth;

View File

@ -66,11 +66,13 @@ class ClientRepository extends BaseRepository
return $query;
}
public function save($data)
public function save($data, $client = null)
{
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
if (!$publicId || $publicId == '-1') {
if ($client) {
// do nothing
} if (!$publicId || $publicId == '-1') {
$client = Client::createNew();
} else {
$client = Client::scope($publicId)->with('contacts')->firstOrFail();

View File

@ -27,7 +27,7 @@ class CreditRepository extends BaseRepository
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'),
'credits.public_id',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'credits.amount',

View File

@ -1,4 +1,4 @@
<?php namespace app\Ninja\Repositories;
<?php namespace App\Ninja\Repositories;
use DB;
use Utils;
@ -211,7 +211,7 @@ class DocumentRepository extends BaseRepository
})
->addColumn('name', function ($model) {
return link_to(
'/client/document/'.$model->invitation_key.'/'.$model->public_id.'/'.$model->name,
'/client/documents/'.$model->invitation_key.'/'.$model->public_id.'/'.$model->name,
$model->name,
['target'=>'_blank']
)->toHtml();

View File

@ -1,4 +1,4 @@
<?php namespace app\Ninja\Repositories;
<?php namespace App\Ninja\Repositories;
use DB;
use Utils;
@ -96,7 +96,7 @@ class ExpenseRepository extends BaseRepository
'vendors.name as vendor_name',
'vendors.public_id as vendor_public_id',
'vendors.user_id as vendor_user_id',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'contacts.first_name',
@ -122,7 +122,7 @@ class ExpenseRepository extends BaseRepository
return $query;
}
public function save($input, $checkSubPermissions=false)
public function save($input)
{
$publicId = isset($input['public_id']) ? $input['public_id'] : false;
@ -160,7 +160,7 @@ class ExpenseRepository extends BaseRepository
$document_ids = !empty($input['document_ids'])?array_map('intval', $input['document_ids']):array();;
foreach ($document_ids as $document_id){
$document = Document::scope($document_id)->first();
if($document && !$checkSubPermissions || Auth::user()->can('edit', $document)){
if($document && Auth::user()->can('edit', $document)){
$document->invoice_id = null;
$document->expense_id = $expense->id;
$document->save();

View File

@ -1,4 +1,4 @@
<?php namespace app\Ninja\Repositories;
<?php namespace App\Ninja\Repositories;
use DB;
use Utils;
@ -58,7 +58,7 @@ class InvoiceRepository extends BaseRepository
'clients.user_id as client_user_id',
'invoice_number',
'invoice_status_id',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'invoices.public_id',
'invoices.amount',
'invoices.balance',
@ -115,7 +115,7 @@ class InvoiceRepository extends BaseRepository
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'),
'clients.public_id as client_public_id',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'invoices.public_id',
'invoices.amount',
'frequencies.name as frequency',
@ -125,7 +125,8 @@ class InvoiceRepository extends BaseRepository
'contacts.last_name',
'contacts.email',
'invoices.deleted_at',
'invoices.is_deleted'
'invoices.is_deleted',
'invoices.user_id'
);
if ($clientPublicId) {
@ -152,11 +153,14 @@ class InvoiceRepository extends BaseRepository
->join('accounts', 'accounts.id', '=', 'invitations.account_id')
->join('invoices', 'invoices.id', '=', 'invitations.invoice_id')
->join('clients', 'clients.id', '=', 'invoices.client_id')
->join('contacts', 'contacts.client_id', '=', 'clients.id')
->where('invitations.contact_id', '=', $contactId)
->where('invitations.deleted_at', '=', null)
->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE)
->where('invoices.is_deleted', '=', false)
->where('clients.deleted_at', '=', null)
->where('contacts.deleted_at', '=', null)
->where('contacts.is_primary', '=', true)
->where('invoices.is_recurring', '=', false)
// This needs to be a setting to also hide the activity on the dashboard page
//->where('invoices.invoice_status_id', '>=', INVOICE_STATUS_SENT)
@ -169,7 +173,7 @@ class InvoiceRepository extends BaseRepository
'invoices.balance as balance',
'invoices.due_date',
'clients.public_id as client_public_id',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'invoices.public_id',
'invoices.amount',
'invoices.start_date',
@ -197,7 +201,7 @@ class InvoiceRepository extends BaseRepository
->make();
}
public function save($data, $checkSubPermissions = false)
public function save($data)
{
$account = \Auth::user()->account;
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
@ -419,7 +423,7 @@ class InvoiceRepository extends BaseRepository
$document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();;
foreach ($document_ids as $document_id){
$document = Document::scope($document_id)->first();
if($document && !$checkSubPermissions || Auth::user()->can('edit', $document)){
if($document && Auth::user()->can('edit', $document)){
if($document->invoice_id && $document->invoice_id != $invoice->id){
// From a clone
@ -472,7 +476,7 @@ class InvoiceRepository extends BaseRepository
$task = false;
if (isset($item['task_public_id']) && $item['task_public_id']) {
$task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail();
if(!$checkSubPermissions || Auth::user()->can('edit', $task)){
if(Auth::user()->can('edit', $task)){
$task->invoice_id = $invoice->id;
$task->client_id = $invoice->client_id;
$task->save();
@ -482,7 +486,7 @@ class InvoiceRepository extends BaseRepository
$expense = false;
if (isset($item['expense_public_id']) && $item['expense_public_id']) {
$expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail();
if(!$checkSubPermissions || Auth::user()->can('edit', $expense)){
if(Auth::user()->can('edit', $expense)){
$expense->invoice_id = $invoice->id;
$expense->client_id = $invoice->client_id;
$expense->save();
@ -493,7 +497,7 @@ class InvoiceRepository extends BaseRepository
if (\Auth::user()->account->update_products && ! strtotime($productKey)) {
$product = Product::findProductByKey($productKey);
if (!$product) {
if(!$checkSubPermissions || Auth::user()->can('create', ENTITY_PRODUCT)){
if (Auth::user()->can('create', ENTITY_PRODUCT)) {
$product = Product::createNew();
$product->product_key = trim($item['product_key']);
}
@ -501,7 +505,7 @@ class InvoiceRepository extends BaseRepository
$product = null;
}
}
if($product && (!$checkSubPermissions || Auth::user()->can('edit', $product))){
if ($product && (Auth::user()->can('edit', $product))) {
$product->notes = ($task || $expense) ? '' : $item['notes'];
$product->cost = $expense ? 0 : $item['cost'];
$product->save();
@ -515,7 +519,6 @@ class InvoiceRepository extends BaseRepository
$invoiceItem->notes = trim($invoice->is_recurring ? $item['notes'] : Utils::processVariables($item['notes']));
$invoiceItem->cost = Utils::parseFloat($item['cost']);
$invoiceItem->qty = Utils::parseFloat($item['qty']);
//$invoiceItem->tax_rate = 0;
if (isset($item['custom_value1'])) {
$invoiceItem->custom_value1 = $item['custom_value1'];

View File

@ -34,7 +34,7 @@ class PaymentRepository extends BaseRepository
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'),
'payments.transaction_reference',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'payments.amount',
@ -101,7 +101,7 @@ class PaymentRepository extends BaseRepository
'invitations.invitation_key',
'payments.public_id',
'payments.transaction_reference',
'clients.name as client_name',
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'clients.public_id as client_public_id',
'payments.amount',
'payments.payment_date',

View File

@ -25,7 +25,7 @@ class TaskRepository
->where('clients.deleted_at', '=', null)
->select(
'tasks.public_id',
'clients.name as client_name',
\DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'contacts.first_name',
@ -64,20 +64,6 @@ class TaskRepository
return $query;
}
public function getErrors($input)
{
$rules = [
'time_log' => 'time_log',
];
$validator = \Validator::make($input, $rules);
if ($validator->fails()) {
return $validator;
}
return false;
}
public function save($publicId, $data)
{
if ($publicId) {

View File

@ -3,6 +3,7 @@
namespace App\Policies;
use App\Models\User;
use Utils;
use Illuminate\Auth\Access\HandlesAuthorization;
@ -11,7 +12,7 @@ class GenericEntityPolicy
use HandlesAuthorization;
public static function editByOwner($user, $itemType, $ownerUserId) {
$itemType = ucwords($itemType, '_');
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'editByOwner')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'editByOwner'), $user, $ownerUserId);
}
@ -20,7 +21,7 @@ class GenericEntityPolicy
}
public static function viewByOwner($user, $itemType, $ownerUserId) {
$itemType = ucwords($itemType, '_');
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'viewByOwner')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'viewByOwner'), $user, $ownerUserId);
}
@ -29,7 +30,7 @@ class GenericEntityPolicy
}
public static function create($user, $itemType) {
$itemType = ucwords($itemType, '_');
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'create')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'create'), $user);
}

View File

@ -2,7 +2,7 @@
namespace App\Policies;
class VendorPolicy extends EntityPolicy {
class ProductPolicy extends EntityPolicy {
public static function edit($user, $item) {
return $user->hasPermission('admin');
}

View File

@ -1,5 +1,6 @@
<?php namespace App\Services;
use Auth;
use Illuminate\Foundation\Bus\DispatchesJobs;
use App\Services\DatatableService;

View File

@ -30,13 +30,13 @@ class ClientService extends BaseService
return $this->clientRepo;
}
public function save($data)
public function save($data, $client = null)
{
if (Auth::user()->account->isNinjaAccount() && isset($data['plan'])) {
$this->ninjaRepo->updatePlanDetails($data['public_id'], $data);
}
return $this->clientRepo->save($data);
return $this->clientRepo->save($data, $client);
}
public function getDatatable($search)

View File

@ -28,7 +28,7 @@ class ExpenseService extends BaseService
return $this->expenseRepo;
}
public function save($data, $checkSubPermissions=false)
public function save($data)
{
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, $checkSubPermissions);
return $this->expenseRepo->save($data);
}
public function getDatatable($search)

View File

@ -30,26 +30,23 @@ class InvoiceService extends BaseService
return $this->invoiceRepo;
}
public function save($data, $checkSubPermissions = false)
public function save($data)
{
if (isset($data['client'])) {
$canSaveClient = !$checkSubPermissions;
if( ! $canSaveClient){
$clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id');
if (empty($clientPublicId) || $clientPublicId == '-1') {
$canSaveClient = Auth::user()->can('create', ENTITY_CLIENT);
} else {
$canSaveClient = Auth::user()->can('edit', Client::scope($clientPublicId)->first());
}
}
$canSaveClient = false;
$clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id');
if (empty($clientPublicId) || $clientPublicId == '-1') {
$canSaveClient = Auth::user()->can('create', ENTITY_CLIENT);
} else {
$canSaveClient = Auth::user()->can('edit', Client::scope($clientPublicId)->first());
}
if ($canSaveClient) {
$client = $this->clientRepo->save($data['client']);
$data['client_id'] = $client->id;
}
}
$invoice = $this->invoiceRepo->save($data, $checkSubPermissions);
$invoice = $this->invoiceRepo->save($data);
$client = $invoice->client;
$client->load('contacts');

View File

@ -63,7 +63,6 @@ class PaymentService extends BaseService
if ($input) {
$data = self::convertInputForOmnipay($input);
$data['email'] = $invitation->contact->email;
Session::put($key, $data);
} elseif (Session::get($key)) {
$data = Session::get($key);
@ -95,6 +94,7 @@ class PaymentService extends BaseService
$data = [
'firstName' => $input['first_name'],
'lastName' => $input['last_name'],
'email' => $input['email'],
'number' => isset($input['card_number']) ? $input['card_number'] : null,
'expiryMonth' => isset($input['expiration_month']) ? $input['expiration_month'] : null,
'expiryYear' => isset($input['expiration_year']) ? $input['expiration_year'] : null,

View File

@ -1118,8 +1118,8 @@ return array(
'first_page' => 'Erste Seite',
'all_pages' => 'Alle Seiten',
'last_page' => 'Letzte Seite',
'all_pages_header' => 'Show header on',
'all_pages_footer' => 'Show footer on',
'all_pages_header' => 'Zeige Header auf',
'all_pages_footer' => 'Zeige Footer auf',
'invoice_currency' => 'Rechnungs-Währung',
'enable_https' => 'Wir empfehlen dringend HTTPS zu verwenden, um Kreditkarten online zu akzeptieren.',
'quote_issued_to' => 'Quote issued to',
@ -1133,72 +1133,72 @@ return array(
'white_label_text' => 'Purchase a ONE YEAR white label license for $'.WHITE_LABEL_PRICE.' to remove the Invoice Ninja branding from the client portal and help support our project.',
'navigation' => 'Navigation',
'list_invoices' => 'List Invoices',
'list_clients' => 'List Clients',
'list_quotes' => 'List Quotes',
'list_tasks' => 'List Tasks',
'list_expenses' => 'List Expenses',
'list_recurring_invoices' => 'List Recurring Invoices',
'list_payments' => 'List Payments',
'list_invoices' => 'Rechnungen Auflisten',
'list_clients' => 'Kunden Auflisten',
'list_quotes' => 'Angebote Auflisten',
'list_tasks' => 'Aufgaben Auflisten',
'list_expenses' => 'Ausgaben Auflisten',
'list_recurring_invoices' => 'Wiederkehrende Rechnungen Auflisten',
'list_payments' => 'Zahlungen Aufllisten',
'list_credits' => 'List Credits',
'tax_name' => 'Tax Name',
'report_settings' => 'Report Settings',
'tax_name' => 'Steuer-Name',
'report_settings' => 'Bericht-Einstellungen',
'search_hotkey' => 'shortcut is /',
'new_user' => 'New User',
'new_product' => 'New Product',
'new_tax_rate' => 'New Tax Rate',
'new_user' => 'Neuer Benutzer',
'new_product' => 'Neues Produkt',
'new_tax_rate' => 'Neue Steuersatz',
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'custom_invoice_item_fields_help' => 'Feld bei Erstellung eines Rechnungs-Elements hinzufügen, und dessen Bezeichnung und Wert im PDF anzeigen.',
'recurring_invoice_number' => 'Wiederkehrende Rechnungsnummer',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
'enable_client_portal' => 'Dashboard',
'enable_client_portal_help' => 'Show/hide the dashboard page in the client portal.',
'enable_client_portal_help' => 'Dashboard-Seite im Kunden-Portal anzeigen/verbergen.',
// Client Passwords
'enable_portal_password'=>'Password protect invoices',
'enable_portal_password_help'=>'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.',
'send_portal_password'=>'Generate password automatically',
'send_portal_password_help'=>'If no password is set, one will be generated and sent with the first invoice.',
'enable_portal_password'=>'Sichere Rechnungen mit einem Passwort ab',
'enable_portal_password_help'=>'Erlaubt, ein Passwort für jeden Kontakt zu setzen. Wenn ein Passwort gesetzt ist, wird dieses vom Kontakt benötigt, um Rechnungen anzusehen.',
'send_portal_password'=>'Passwort automatisch generieren',
'send_portal_password_help'=>'Wenn kein Passwort gesetzt ist, wird eines erstellt und mit der ersten Rechnung mit versendet.',
'expired' => 'Expired',
'invalid_card_number' => 'The credit card number is not valid.',
'invalid_expiry' => 'The expiration date is not valid.',
'invalid_cvv' => 'The CVV is not valid.',
'cost' => 'Cost',
'create_invoice_for_sample' => 'Note: create your first invoice to see a preview here.',
'expired' => 'Abgelaufen',
'invalid_card_number' => 'Die Kreditkartennummer ist nicht gültig.',
'invalid_expiry' => 'Das Ablaufdatum ist nicht gültig.',
'invalid_cvv' => 'Das CVV ist nicht gültig.',
'cost' => 'Kosten',
'create_invoice_for_sample' => 'Info: Erstelle deine erste Rechnung, um hier eine Voransicht zu sehen.',
// User Permissions
'owner' => 'Owner',
'owner' => 'Eigentümer',
'administrator' => 'Administrator',
'administrator_help' => 'Allow user to manage users, change settings and modify all records',
'user_create_all' => 'Create clients, invoices, etc.',
'user_view_all' => 'View all clients, invoices, etc.',
'user_edit_all' => 'Edit all clients, invoices, etc.',
'gateway_help_20' => ':link to sign up for Sage Pay.',
'gateway_help_21' => ':link to sign up for Sage Pay.',
'partial_due' => 'Partial Due',
'restore_vendor' => 'Restore Vendor',
'restored_vendor' => 'Successfully restored vendor',
'restored_expense' => 'Successfully restored expense',
'permissions' => 'Permissions',
'create_all_help' => 'Allow user to create and modify records',
'view_all_help' => 'Allow user to view records they didn\'t create',
'edit_all_help' => 'Allow user to modify records they didn\'t create',
'view_payment' => 'View Payment',
'administrator_help' => 'Erlaube Benutzern, andere Benutzer zu administrieren, Einstellungen und alle Einträge zu verändern',
'user_create_all' => 'Kunden, Rechnungen, etc. erstellen',
'user_view_all' => 'Kunden, Rechnungen, etc. ansehen',
'user_edit_all' => 'Kunden, Rechnungen, etc. bearbeiten',
'gateway_help_20' => ':link um sich bei Sage Pay zu registrieren.',
'gateway_help_21' => ':link um sich bei Sage Pay zu registrieren.',
'partial_due' => 'Offener Teilbetrag',
'restore_vendor' => 'Anbieter Wiederherstellen',
'restored_vendor' => 'Anbieter erfolgreich wiederhergestellt',
'restored_expense' => 'Ausgabe erfolgreich wiederhergestellt',
'permissions' => 'Berechtigungen',
'create_all_help' => 'Erlaube Benutzer, Einträge zu erstellen und zu verändern',
'view_all_help' => 'Erlaube Benutzer, Einträge zu sehen, die er nicht selbst erstellt hat',
'edit_all_help' => 'Erlaube Benutzer, Einträge zu verändern, die er nicht selbst erstellt hat',
'view_payment' => 'Zahlung Ansehen',
'january' => 'January',
'february' => 'February',
'march' => 'March',
'january' => 'Jänner',
'february' => 'Februar',
'march' => 'März',
'april' => 'April',
'may' => 'May',
'june' => 'June',
'july' => 'July',
'may' => 'Mai',
'june' => 'Juni',
'july' => 'Juli',
'august' => 'August',
'september' => 'September',
'october' => 'October',
'october' => 'Oktober',
'november' => 'November',
'december' => 'December',
'december' => 'Dezember',
);

View File

@ -13,6 +13,7 @@
var data = {
name: $('#first_name').val() + ' ' + $('#last_name').val(),
email: $('#email').val(),
address_line1: $('#address1').val(),
address_line2: $('#address2').val(),
address_city: $('#city').val(),
@ -117,6 +118,7 @@
{{ Former::populate($client) }}
{{ Former::populateField('first_name', $contact->first_name) }}
{{ Former::populateField('last_name', $contact->last_name) }}
{{ Former::populateField('email', $contact->email) }}
@if (!$client->country_id && $client->account->country_id)
{{ Former::populateField('country_id', $client->account->country_id) }}
@endif
@ -178,8 +180,7 @@
->label('') !!}
</div>
</div>
@if (isset($paymentTitle))
<div class="row">
<div class="row" style="display:{{ isset($paymentTitle) ? 'block' : 'none' }}">
<div class="col-md-12">
{!! Former::text('email')
->placeholder(trans('texts.email'))
@ -187,7 +188,6 @@
->label('') !!}
</div>
</div>
@endif
<p>&nbsp;<br/>&nbsp;</p>

View File

@ -19,6 +19,11 @@
</style>
@if ($errors->first('time_log'))
<div class="alert alert-danger"><li>{{ trans('texts.task_errors') }} </li></div>
@endif
{!! Former::open($url)->addClass('col-md-10 col-md-offset-1 warn-on-exit task-form')->method($method)->rules(array()) !!}
@if ($task)
{!! Former::populate($task) !!}
@ -455,7 +460,7 @@
@endif
@endif
@if (Session::has('error'))
@if ($errors->first('time_log'))
loadTimeLog({!! json_encode(Input::old('time_log')) !!});
model.showTimeOverlaps();
showTimeDetails();

View File

@ -1,4 +1,4 @@
<?php //[STAMP] a3cf36879dbbec28f15389e7d8d325a2
<?php //[STAMP] 33bf8261bed0f36cf769e15182e6d905
namespace _generated;
// This class was automatically generated by build task

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@ class CheckBalanceCest
$I->fillField('table.invoice-table tbody tr:nth-child(1) #product_key', $productKey);
$I->click('table.invoice-table tbody tr:nth-child(1) .tt-selectable');
$I->click('Save');
$I->wait(1);
$I->wait(2);
$I->see($clientEmail);
$invoiceId = $I->grabFromCurrentUrl('~invoices/(\d+)~');
$I->amOnPage("/clients/{$clientId}");

View File

@ -64,7 +64,7 @@ class InvoiceCest
$this->fillItems($I);
$I->executeJS("submitAction('email')");
$I->wait(1);
$I->wait(2);
$I->see($clientEmail);
$invoiceNumber = $I->grabAttributeFrom('#invoice_number', 'value');

Some files were not shown because too many files have changed in this diff Show More