mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Merge branch 'v2' of https://github.com/invoiceninja/invoiceninja into v2
This commit is contained in:
commit
ecc4975e5c
@ -59,9 +59,6 @@ class ClientSettings extends BaseSettings
|
||||
public $quote_number_prefix;
|
||||
public $quote_number_pattern;
|
||||
public $quote_number_counter;
|
||||
|
||||
//public $client_number_prefix;
|
||||
//public $client_number_pattern;
|
||||
|
||||
public $credit_number_prefix;
|
||||
public $credit_number_pattern;
|
||||
|
35
app/Factory/PaymentFactory.php
Normal file
35
app/Factory/PaymentFactory.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PaymentFactory
|
||||
{
|
||||
public static function create(int $company_id, int $user_id) :Payment
|
||||
{
|
||||
$payment = new Payment();
|
||||
|
||||
$payment->company_id = $company_id;
|
||||
$payment->user_id = $user_id;
|
||||
$payment->client_id = 0;
|
||||
$payment->client_contact_id = null;
|
||||
$payment->invitation_id = null;
|
||||
$payment->account_gateway_id = null;
|
||||
$payment->payment_type_id = null;
|
||||
$payment->is_deleted = false;
|
||||
$payment->amount = 0;
|
||||
$payment->payment_date = null;
|
||||
$payment->transaction_reference = null;
|
||||
$payment->payer_id = null;
|
||||
$payment->invoice_id = 0;
|
||||
|
||||
return $payment;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
51
app/Factory/RecurringInvoiceFactory.php
Normal file
51
app/Factory/RecurringInvoiceFactory.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class RecurringInvoiceFactory
|
||||
{
|
||||
public static function create(int $company_id, int $user_id) :RecurringInvoice
|
||||
{
|
||||
$invoice = new RecurringInvoice();
|
||||
$invoice->status_id = RecurringInvoice::STATUS_DRAFT;
|
||||
$invoice->discount = 0;
|
||||
$invoice->is_amount_discount = true;
|
||||
$invoice->po_number = '';
|
||||
$invoice->footer = '';
|
||||
$invoice->terms = '';
|
||||
$invoice->public_notes = '';
|
||||
$invoice->private_notes = '';
|
||||
$invoice->invoice_date = null;
|
||||
$invoice->due_date = null;
|
||||
$invoice->partial_due_date = null;
|
||||
$invoice->is_deleted = false;
|
||||
$invoice->line_items = json_encode([]);
|
||||
$invoice->settings = ClientSettings::buildClientSettings(new CompanySettings(CompanySettings::defaults()), new ClientSettings(ClientSettings::defaults())); //todo need to embed the settings here
|
||||
$invoice->backup = json_encode([]);
|
||||
$invoice->tax_name1 = '';
|
||||
$invoice->tax_rate1 = 0;
|
||||
$invoice->tax_name2 = '';
|
||||
$invoice->tax_rate2 = 0;
|
||||
$invoice->custom_value1 = 0;
|
||||
$invoice->custom_value2 = 0;
|
||||
$invoice->custom_value3 = 0;
|
||||
$invoice->custom_value4 = 0;
|
||||
$invoice->amount = 0;
|
||||
$invoice->balance = 0;
|
||||
$invoice->partial = 0;
|
||||
$invoice->user_id = $user_id;
|
||||
$invoice->company_id = $company_id;
|
||||
$invoice->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY;
|
||||
$invoice->start_date = null;
|
||||
$invoice->last_sent_date = null;
|
||||
$invoice->next_send_date = null;
|
||||
$invoice->remaining_cycles = 0;
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
}
|
111
app/Filters/PaymentFilters.php
Normal file
111
app/Filters/PaymentFilters.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
/**
|
||||
* PaymentFilters
|
||||
*/
|
||||
class PaymentFilters extends QueryFilters
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Filter based on search text
|
||||
*
|
||||
* @param string query filter
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
{
|
||||
if(strlen($filter) == 0)
|
||||
return $this->builder;
|
||||
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
$query->where('payments.custom_value1', 'like', '%'.$filter.'%')
|
||||
->orWhere('payments.custom_value2', 'like' , '%'.$filter.'%')
|
||||
->orWhere('payments.custom_value3', 'like' , '%'.$filter.'%')
|
||||
->orWhere('payments.custom_value4', 'like' , '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list based on the status
|
||||
* archived, active, deleted
|
||||
*
|
||||
* @param string filter
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function status(string $filter = '') : Builder
|
||||
{
|
||||
if(strlen($filter) == 0)
|
||||
return $this->builder;
|
||||
|
||||
$table = 'payments';
|
||||
$filters = explode(',', $filter);
|
||||
|
||||
return $this->builder->where(function ($query) use ($filters, $table) {
|
||||
$query->whereNull($table . '.id');
|
||||
|
||||
if (in_array(parent::STATUS_ACTIVE, $filters)) {
|
||||
$query->orWhereNull($table . '.deleted_at');
|
||||
}
|
||||
|
||||
if (in_array(parent::STATUS_ARCHIVED, $filters)) {
|
||||
$query->orWhere(function ($query) use ($table) {
|
||||
$query->whereNotNull($table . '.deleted_at');
|
||||
|
||||
if (! in_array($table, ['users'])) {
|
||||
$query->where($table . '.is_deleted', '=', 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (in_array(parent::STATUS_DELETED, $filters)) {
|
||||
$query->orWhere($table . '.is_deleted', '=', 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
{
|
||||
$sort_col = explode("|", $sort);
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base query
|
||||
*
|
||||
* @param int company_id
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function baseQuery(int $company_id, User $user) : Builder
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the query by the users company ID
|
||||
*
|
||||
* @param $company_id The company Id
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function entityFilter()
|
||||
{
|
||||
|
||||
return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||
|
||||
}
|
||||
|
||||
}
|
111
app/Filters/RecurringInvoiceFilters.php
Normal file
111
app/Filters/RecurringInvoiceFilters.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
/**
|
||||
* RecurringInvoiceFilters
|
||||
*/
|
||||
class RecurringInvoiceFilters extends QueryFilters
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Filter based on search text
|
||||
*
|
||||
* @param string query filter
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
{
|
||||
if(strlen($filter) == 0)
|
||||
return $this->builder;
|
||||
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
$query->where('recurring_invoices.custom_value1', 'like', '%'.$filter.'%')
|
||||
->orWhere('recurring_invoices.custom_value2', 'like' , '%'.$filter.'%')
|
||||
->orWhere('recurring_invoices.custom_value3', 'like' , '%'.$filter.'%')
|
||||
->orWhere('recurring_invoices.custom_value4', 'like' , '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list based on the status
|
||||
* archived, active, deleted
|
||||
*
|
||||
* @param string filter
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function status(string $filter = '') : Builder
|
||||
{
|
||||
if(strlen($filter) == 0)
|
||||
return $this->builder;
|
||||
|
||||
$table = 'recurring_';
|
||||
$filters = explode(',', $filter);
|
||||
|
||||
return $this->builder->where(function ($query) use ($filters, $table) {
|
||||
$query->whereNull($table . '.id');
|
||||
|
||||
if (in_array(parent::STATUS_ACTIVE, $filters)) {
|
||||
$query->orWhereNull($table . '.deleted_at');
|
||||
}
|
||||
|
||||
if (in_array(parent::STATUS_ARCHIVED, $filters)) {
|
||||
$query->orWhere(function ($query) use ($table) {
|
||||
$query->whereNotNull($table . '.deleted_at');
|
||||
|
||||
if (! in_array($table, ['users'])) {
|
||||
$query->where($table . '.is_deleted', '=', 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (in_array(parent::STATUS_DELETED, $filters)) {
|
||||
$query->orWhere($table . '.is_deleted', '=', 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
{
|
||||
$sort_col = explode("|", $sort);
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base query
|
||||
*
|
||||
* @param int company_id
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function baseQuery(int $company_id, User $user) : Builder
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the query by the users company ID
|
||||
*
|
||||
* @param $company_id The company Id
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function entityFilter()
|
||||
{
|
||||
|
||||
return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||
|
||||
}
|
||||
|
||||
}
|
233
app/Http/Controllers/PaymentController.php
Normal file
233
app/Http/Controllers/PaymentController.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Filters\PaymentFilters;
|
||||
use App\Http\Requests\Payment\ActionPaymentRequest;
|
||||
use App\Http\Requests\Payment\CreatePaymentRequest;
|
||||
use App\Http\Requests\Payment\DestroyPaymentRequest;
|
||||
use App\Http\Requests\Payment\EditPaymentRequest;
|
||||
use App\Http\Requests\Payment\ShowPaymentRequest;
|
||||
use App\Http\Requests\Payment\StorePaymentRequest;
|
||||
use App\Http\Requests\Payment\UpdatePaymentRequest;
|
||||
use App\Jobs\Entity\ActionEntity;
|
||||
use App\Models\Payment;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Repositories\PaymentRepository;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class PaymentController
|
||||
* @package App\Http\Controllers\PaymentController
|
||||
*/
|
||||
|
||||
class PaymentController extends BaseController
|
||||
{
|
||||
|
||||
use MakesHash;
|
||||
|
||||
protected $entity_type = Payment::class;
|
||||
|
||||
protected $entity_transformer = PaymentTransformer::class;
|
||||
|
||||
/**
|
||||
* @var PaymentRepository
|
||||
*/
|
||||
protected $payment_repo;
|
||||
|
||||
|
||||
/**
|
||||
* PaymentController constructor.
|
||||
*
|
||||
* @param \App\Repositories\PaymentRepository $payment_repo The invoice repo
|
||||
*/
|
||||
public function __construct(PaymentRepository $payment_repo)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->payment_repo = $payment_repo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the list of Invoices
|
||||
*
|
||||
* @param \App\Filters\PaymentFilters $filters The filters
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(PaymentFilters $filters)
|
||||
{
|
||||
|
||||
$payments = Payment::filter($filters);
|
||||
|
||||
return $this->listResponse($payments);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\CreatePaymentRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create(CreatePaymentRequest $request)
|
||||
{
|
||||
|
||||
$payment = PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\StorePaymentRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StorePaymentRequest $request)
|
||||
{
|
||||
|
||||
$payment = $this->payment_repo->save($request, PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\ShowPaymentRequest $request The request
|
||||
* @param \App\Models\Invoice $payment The invoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(ShowPaymentRequest $request, Payment $payment)
|
||||
{
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\EditPaymentRequest $request The request
|
||||
* @param \App\Models\Invoice $payment The invoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(EditPaymentRequest $request, Payment $payment)
|
||||
{
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\UpdatePaymentRequest $request The request
|
||||
* @param \App\Models\Invoice $payment The invoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdatePaymentRequest $request, Payment $payment)
|
||||
{
|
||||
|
||||
$payment = $this->payment_repo->save(request(), $payment);
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\DestroyPaymentRequest $request
|
||||
* @param \App\Models\Invoice $payment
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(DestroyPaymentRequest $request, Payment $payment)
|
||||
{
|
||||
|
||||
$payment->delete();
|
||||
|
||||
return response()->json([], 200);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bulk actions on the list view
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
|
||||
$action = request()->input('action');
|
||||
|
||||
$ids = request()->input('ids');
|
||||
|
||||
$payments = Payment::withTrashed()->find($ids);
|
||||
|
||||
$payments->each(function ($payment, $key) use($action){
|
||||
|
||||
if(auth()->user()->can('edit', $payment))
|
||||
$this->payment_repo->{$action}($payment);
|
||||
|
||||
});
|
||||
|
||||
//todo need to return the updated dataset
|
||||
return $this->listResponse(Payment::withTrashed()->whereIn('id', $ids));
|
||||
|
||||
}
|
||||
|
||||
public function action(ActionPaymentRequest $request, Payment $payment, $action)
|
||||
{
|
||||
|
||||
switch ($action) {
|
||||
case 'clone_to_invoice':
|
||||
$payment = CloneInvoiceFactory::create($payment, auth()->user()->id);
|
||||
return $this->itemResponse($payment);
|
||||
break;
|
||||
case 'clone_to_quote':
|
||||
$quote = CloneInvoiceToQuoteFactory::create($payment, auth()->user()->id);
|
||||
// todo build the quote transformer and return response here
|
||||
break;
|
||||
case 'history':
|
||||
# code...
|
||||
break;
|
||||
case 'delivery_note':
|
||||
# code...
|
||||
break;
|
||||
case 'mark_paid':
|
||||
# code...
|
||||
break;
|
||||
case 'archive':
|
||||
# code...
|
||||
break;
|
||||
case 'delete':
|
||||
# code...
|
||||
break;
|
||||
case 'email':
|
||||
//dispatch email to queue
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,83 +2,235 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Factory\CloneRecurringInvoiceFactory;
|
||||
use App\Factory\CloneRecurringInvoiceToQuoteFactory;
|
||||
use App\Factory\RecurringInvoiceFactory;
|
||||
use App\Filters\RecurringInvoiceFilters;
|
||||
use App\Http\Requests\RecurringInvoice\ActionRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\CreateRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\DestroyRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\EditRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\ShowRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\StoreRecurringInvoiceRequest;
|
||||
use App\Http\Requests\RecurringInvoice\UpdateRecurringInvoiceRequest;
|
||||
use App\Jobs\Entity\ActionEntity;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Repositories\RecurringInvoiceRepository;
|
||||
use App\Transformers\RecurringInvoiceTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RecurringInvoiceController extends Controller
|
||||
/**
|
||||
* Class RecurringInvoiceController
|
||||
* @package App\Http\Controllers\RecurringInvoiceController
|
||||
*/
|
||||
|
||||
class RecurringInvoiceController extends BaseController
|
||||
{
|
||||
|
||||
use MakesHash;
|
||||
|
||||
protected $entity_type = RecurringInvoice::class;
|
||||
|
||||
protected $entity_transformer = RecurringInvoiceTransformer::class;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
* @var RecurringInvoiceRepository
|
||||
*/
|
||||
protected $recurring_invoice_repo;
|
||||
|
||||
protected $base_repo;
|
||||
|
||||
/**
|
||||
* RecurringInvoiceController constructor.
|
||||
*
|
||||
* @param \App\Repositories\RecurringInvoiceRepository $recurring_invoice_repo The RecurringInvoice repo
|
||||
*/
|
||||
public function __construct(RecurringInvoiceRepository $recurring_invoice_repo)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->recurring_invoice_repo = $recurring_invoice_repo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the list of recurring_invoices
|
||||
*
|
||||
* @param \App\Filters\RecurringInvoiceFilters $filters The filters
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
public function index(RecurringInvoiceFilters $filters)
|
||||
{
|
||||
//
|
||||
|
||||
$recurring_invoices = RecurringInvoice::filter($filters);
|
||||
|
||||
return $this->listResponse($recurring_invoices);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Http\Requests\RecurringInvoice\CreateRecurringInvoiceRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
public function create(CreateRecurringInvoiceRequest $request)
|
||||
{
|
||||
//
|
||||
|
||||
$recurring_invoice = RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Http\Requests\RecurringInvoice\StoreRecurringInvoiceRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(StoreRecurringInvoiceRequest $request)
|
||||
{
|
||||
//
|
||||
|
||||
$recurring_invoice = $this->recurring_invoice_repo->save($request, RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
return $this->itemResponse($recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @param \App\Http\Requests\RecurringInvoice\ShowRecurringInvoiceRequest $request The request
|
||||
* @param \App\Models\RecurringInvoice $recurring_invoice The RecurringInvoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show(ShowRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
//
|
||||
|
||||
return $this->itemResponse($recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @param \App\Http\Requests\RecurringInvoice\EditRecurringInvoiceRequest $request The request
|
||||
* @param \App\Models\RecurringInvoice $recurring_invoice The RecurringInvoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
public function edit(EditRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
return $this->itemResponse($recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @param \App\Http\Requests\RecurringInvoice\UpdateRecurringInvoiceRequest $request The request
|
||||
* @param \App\Models\RecurringInvoice $recurring_invoice The RecurringInvoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(UpdateRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
//
|
||||
|
||||
$recurring_invoice = $this->recurring_invoice_repo->save(request(), $recurring_invoice);
|
||||
|
||||
return $this->itemResponse($recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\RecurringInvoice\DestroyRecurringInvoiceRequest $request
|
||||
* @param \App\Models\RecurringInvoice $recurring_invoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy(DestroyRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
//
|
||||
|
||||
$recurring_invoice->delete();
|
||||
|
||||
return response()->json([], 200);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bulk actions on the list view
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
|
||||
$action = request()->input('action');
|
||||
|
||||
$ids = request()->input('ids');
|
||||
|
||||
$recurring_invoices = RecurringInvoice::withTrashed()->find($ids);
|
||||
|
||||
$recurring_invoices->each(function ($recurring_invoice, $key) use($action){
|
||||
|
||||
if(auth()->user()->can('edit', $recurring_invoice))
|
||||
$this->recurring_invoice_repo->{$action}($recurring_invoice);
|
||||
|
||||
});
|
||||
|
||||
//todo need to return the updated dataset
|
||||
return $this->listResponse(RecurringInvoice::withTrashed()->whereIn('id', $ids));
|
||||
|
||||
}
|
||||
|
||||
public function action(ActionRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice, $action)
|
||||
{
|
||||
|
||||
switch ($action) {
|
||||
case 'clone_to_RecurringInvoice':
|
||||
// $recurring_invoice = CloneRecurringInvoiceFactory::create($recurring_invoice, auth()->user()->id);
|
||||
// return $this->itemResponse($recurring_invoice);
|
||||
break;
|
||||
case 'clone_to_quote':
|
||||
// $quote = CloneRecurringInvoiceToQuoteFactory::create($recurring_invoice, auth()->user()->id);
|
||||
// todo build the quote transformer and return response here
|
||||
break;
|
||||
case 'history':
|
||||
# code...
|
||||
break;
|
||||
case 'delivery_note':
|
||||
# code...
|
||||
break;
|
||||
case 'mark_paid':
|
||||
# code...
|
||||
break;
|
||||
case 'archive':
|
||||
# code...
|
||||
break;
|
||||
case 'delete':
|
||||
# code...
|
||||
break;
|
||||
case 'email':
|
||||
//dispatch email to queue
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
21
app/Http/Requests/Payment/ActionPaymentRequest.php
Normal file
21
app/Http/Requests/Payment/ActionPaymentRequest.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class ActionPaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->payment);
|
||||
}
|
||||
|
||||
}
|
21
app/Http/Requests/Payment/CreatePaymentRequest.php
Normal file
21
app/Http/Requests/Payment/CreatePaymentRequest.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class CreatePaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', Payment::class);
|
||||
}
|
||||
|
||||
}
|
21
app/Http/Requests/Payment/DestroyPaymentRequest.php
Normal file
21
app/Http/Requests/Payment/DestroyPaymentRequest.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class DestroyPaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->payment);
|
||||
}
|
||||
|
||||
}
|
40
app/Http/Requests/Payment/EditPaymentRequest.php
Normal file
40
app/Http/Requests/Payment/EditPaymentRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class EditPaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->can('edit', $this->payment);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
//$input['id'] = $this->encodePrimaryKey($input['id']);
|
||||
|
||||
//$this->replace($input);
|
||||
|
||||
return $this->all();
|
||||
}
|
||||
|
||||
}
|
21
app/Http/Requests/Payment/ShowPaymentRequest.php
Normal file
21
app/Http/Requests/Payment/ShowPaymentRequest.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class ShowPaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('view', $this->payment);
|
||||
}
|
||||
|
||||
}
|
41
app/Http/Requests/Payment/StorePaymentRequest.php
Normal file
41
app/Http/Requests/Payment/StorePaymentRequest.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class StorePaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', Payment::class);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
//do post processing of Payment request here, ie. Payment_items
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
31
app/Http/Requests/Payment/UpdatePaymentRequest.php
Normal file
31
app/Http/Requests/Payment/UpdatePaymentRequest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdatePaymentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
|
||||
return auth()->user()->can('edit', $this->payment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class ActionRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->recurring_invoice);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class CreateRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', RecurringInvoice::class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class DestroyRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('edit', $this->recurring_invoice);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class EditRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->can('edit', $this->recurring_invoice);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
//$input['id'] = $this->encodePrimaryKey($input['id']);
|
||||
|
||||
//$this->replace($input);
|
||||
|
||||
return $this->all();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class ShowRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('view', $this->recurring_invoice);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class StoreRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->can('create', RecurringInvoice::class);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
//do post processing of RecurringInvoice request here, ie. RecurringInvoice_items
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\RecurringInvoice;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateRecurringInvoiceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
|
||||
return auth()->user()->can('edit', $this->recurring_invoice);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -2,27 +2,32 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Filterable;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Payment extends BaseModel
|
||||
{
|
||||
use MakesHash;
|
||||
use Filterable;
|
||||
|
||||
protected $guarded = [
|
||||
'id',
|
||||
];
|
||||
|
||||
protected $appends = ['payment_id'];
|
||||
|
||||
public function getRouteKeyName()
|
||||
public function client()
|
||||
{
|
||||
return 'payment_id';
|
||||
return $this->belongsTo(Client::class);
|
||||
}
|
||||
|
||||
public function getPaymentIdAttribute()
|
||||
public function company()
|
||||
{
|
||||
return $this->encodePrimaryKey($this->id);
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function documents()
|
||||
|
@ -7,12 +7,41 @@ use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class for Recurring Invoices.
|
||||
*/
|
||||
class RecurringInvoice extends BaseModel
|
||||
{
|
||||
use MakesHash;
|
||||
use SoftDeletes;
|
||||
use Filterable;
|
||||
|
||||
/**
|
||||
* Invoice Statuses
|
||||
*/
|
||||
const STATUS_DRAFT = 2;
|
||||
const STATUS_ACTIVE = 3;
|
||||
const STATUS_PENDING = -1;
|
||||
const STATUS_COMPLETED = -2;
|
||||
const STATUS_CANCELLED = -3;
|
||||
|
||||
|
||||
/**
|
||||
* Recurring intervals
|
||||
*/
|
||||
const FREQUENCY_WEEKLY = 1;
|
||||
const FREQUENCY_TWO_WEEKS = 2;
|
||||
const FREQUENCY_FOUR_WEEKS = 3;
|
||||
const FREQUENCY_MONTHLY = 4;
|
||||
const FREQUENCY_TWO_MONTHS = 5;
|
||||
const FREQUENCY_THREE_MONTHS = 6;
|
||||
const FREQUENCY_FOUR_MONTHS = 7;
|
||||
const FREQUENCY_SIX_MONTHS = 8;
|
||||
const FREQUENCY_ANNUALLY = 9;
|
||||
const FREQUENCY_TWO_YEARS = 10;
|
||||
|
||||
const RECURS_INDEFINITELY = 1;
|
||||
|
||||
protected $guarded = [
|
||||
'id',
|
||||
];
|
||||
@ -21,11 +50,21 @@ class RecurringInvoice extends BaseModel
|
||||
'settings' => 'object'
|
||||
];
|
||||
|
||||
protected $with = [
|
||||
// 'client',
|
||||
// 'company',
|
||||
];
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function client()
|
||||
{
|
||||
return $this->belongsTo(Client::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
25
app/Policies/PaymentPolicy.php
Normal file
25
app/Policies/PaymentPolicy.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Payment;
|
||||
use App\Models\User;
|
||||
|
||||
/**
|
||||
* Class PaymentPolicy
|
||||
* @package App\Policies
|
||||
*/
|
||||
class PaymentPolicy extends EntityPolicy
|
||||
{
|
||||
/**
|
||||
* Checks if the user has create permissions
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function create(User $user) : bool
|
||||
{
|
||||
return $user->isAdmin() || $user->hasPermission('create_payment');
|
||||
}
|
||||
|
||||
}
|
25
app/Policies/RecurringInvoicePolicy.php
Normal file
25
app/Policies/RecurringInvoicePolicy.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\User;
|
||||
|
||||
/**
|
||||
* Class RecurringInvoiceolicy
|
||||
* @package App\Policies
|
||||
*/
|
||||
class RecurringInvoicePolicy extends EntityPolicy
|
||||
{
|
||||
/**
|
||||
* Checks if the user has create permissions
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function create(User $user) : bool
|
||||
{
|
||||
return $user->isAdmin() || $user->hasPermission('create_recurring_invoice');
|
||||
}
|
||||
|
||||
}
|
@ -4,13 +4,17 @@ namespace App\Providers;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\User;
|
||||
use App\Policies\ClientPolicy;
|
||||
use App\Policies\InvoicePolicy;
|
||||
use App\Policies\PaymentPolicy;
|
||||
use App\Policies\ProductPolicy;
|
||||
use App\Policies\QuotePolicy;
|
||||
use App\Policies\RecurringInvoicePolicy;
|
||||
use Auth;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
@ -26,6 +30,8 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Client::class => ClientPolicy::class,
|
||||
Product::class => ProductPolicy::class,
|
||||
Invoice::class => InvoicePolicy::class,
|
||||
Payment::class => PaymentPolicy::class,
|
||||
RecurringInvoice::class => RecurringInvoicePolicy::class,
|
||||
Quote::class => QuotePolicy::class,
|
||||
User::class => UserPolicy::class,
|
||||
];
|
||||
|
@ -42,6 +42,10 @@ class RouteServiceProvider extends ServiceProvider
|
||||
return \App\Models\Invoice::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
});
|
||||
|
||||
Route::bind('recurring_invoice', function ($value) {
|
||||
return \App\Models\RecurringInvoice::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
});
|
||||
|
||||
Route::bind('quote', function ($value) {
|
||||
return \App\Models\Quote::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
});
|
||||
|
29
app/Repositories/PaymentRepository.php
Normal file
29
app/Repositories/PaymentRepository.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* PaymentRepository
|
||||
*/
|
||||
class PaymentRepository extends BaseRepository
|
||||
{
|
||||
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Payment::class;
|
||||
}
|
||||
|
||||
public function save(Request $request, Payment $payment) : ?Payment
|
||||
{
|
||||
$payment->fill($request->input());
|
||||
|
||||
$payment->save();
|
||||
|
||||
return $payment;
|
||||
}
|
||||
|
||||
}
|
38
app/Repositories/RecurringInvoiceRepository.php
Normal file
38
app/Repositories/RecurringInvoiceRepository.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Helpers\Invoice\InvoiceCalc;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* RecurringInvoiceRepository
|
||||
*/
|
||||
class RecurringInvoiceRepository extends BaseRepository
|
||||
{
|
||||
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return RecurringInvoice::class;
|
||||
}
|
||||
|
||||
public function save(Request $request, RecurringInvoice $invoice) : ?RecurringInvoice
|
||||
{
|
||||
$invoice->fill($request->input());
|
||||
|
||||
$invoice->save();
|
||||
|
||||
|
||||
$invoice_calc = new InvoiceCalc($invoice, $invoice->settings);
|
||||
|
||||
$invoice = $invoice_calc->build()->getInvoice();
|
||||
|
||||
//fire events here that cascading from the saving of an invoice
|
||||
//ie. client balance update...
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
}
|
162
app/Transformers/RecurringInvoiceTransformer.php
Normal file
162
app/Transformers/RecurringInvoiceTransformer.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
/**
|
||||
* @SWG\Definition(definition="Invoice", required={"invoice_number"}, @SWG\Xml(name="Invoice"))
|
||||
*/
|
||||
class RecurringInvoiceTransformer extends EntityTransformer
|
||||
{
|
||||
use MakesHash;
|
||||
/**
|
||||
* @SWG\Property(property="id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="amount", type="number", format="float", example=10, readOnly=true)
|
||||
* @SWG\Property(property="balance", type="number", format="float", example=10, readOnly=true)
|
||||
* @SWG\Property(property="updated_at", type="integer", example=1451160233, readOnly=true)
|
||||
* @SWG\Property(property="archived_at", type="integer", example=1451160233, readOnly=true)
|
||||
* @SWG\Property(property="is_deleted", type="boolean", example=false, readOnly=true)
|
||||
* @SWG\Property(property="client_id", type="integer", example=1)
|
||||
* @SWG\Property(property="status_id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="invoice_number", type="string", example="0001")
|
||||
* @SWG\Property(property="discount", type="number", format="float", example=10)
|
||||
* @SWG\Property(property="po_number", type="string", example="0001")
|
||||
* @SWG\Property(property="invoice_date", type="string", format="date", example="2018-01-01")
|
||||
* @SWG\Property(property="due_date", type="string", format="date", example="2018-01-01")
|
||||
* @SWG\Property(property="terms", type="string", example="sample")
|
||||
* @SWG\Property(property="private_notes", type="string", example="Notes")
|
||||
* @SWG\Property(property="public_notes", type="string", example="Notes")
|
||||
* @SWG\Property(property="invoice_type_id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="is_recurring", type="boolean", example=false)
|
||||
* @SWG\Property(property="frequency_id", type="integer", example=1)
|
||||
* @SWG\Property(property="start_date", type="string", format="date", example="2018-01-01")
|
||||
* @SWG\Property(property="end_date", type="string", format="date", example="2018-01-01")
|
||||
* @SWG\Property(property="last_sent_date", type="string", format="date", example="2018-01-01", readOnly=true)
|
||||
* @SWG\Property(property="recurring_invoice_id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="tax_name1", type="string", example="VAT")
|
||||
* @SWG\Property(property="tax_name2", type="string", example="Upkeep")
|
||||
* @SWG\Property(property="tax_rate1", type="number", format="float", example="17.5")
|
||||
* @SWG\Property(property="tax_rate2", type="number", format="float", example="30.0")
|
||||
* @SWG\Property(property="is_amount_discount", type="boolean", example=false)
|
||||
* @SWG\Property(property="invoice_footer", type="string", example="Footer")
|
||||
* @SWG\Property(property="partial", type="number",format="float", example=10)
|
||||
* @SWG\Property(property="partial_due_date", type="string", format="date", example="2018-01-01")
|
||||
* @SWG\Property(property="has_tasks", type="boolean", example=false, readOnly=true)
|
||||
* @SWG\Property(property="auto_bill", type="boolean", example=false)
|
||||
* @SWG\Property(property="custom_value1", type="number",format="float", example=10)
|
||||
* @SWG\Property(property="custom_value2", type="number",format="float", example=10)
|
||||
* @SWG\Property(property="custom_taxes1", type="boolean", example=false)
|
||||
* @SWG\Property(property="custom_taxes2", type="boolean", example=false)
|
||||
* @SWG\Property(property="has_expenses", type="boolean", example=false, readOnly=true)
|
||||
* @SWG\Property(property="quote_invoice_id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="custom_text_value1", type="string", example="Custom Text Value")
|
||||
* @SWG\Property(property="custom_text_value2", type="string", example="Custom Text Value")
|
||||
* @SWG\Property(property="is_quote", type="boolean", example=false, readOnly=true)
|
||||
* @SWG\Property(property="is_public", type="boolean", example=false)
|
||||
* @SWG\Property(property="filename", type="string", example="Filename", readOnly=true)
|
||||
*/
|
||||
protected $defaultIncludes = [
|
||||
// 'invoice_items',
|
||||
];
|
||||
|
||||
protected $availableIncludes = [
|
||||
// 'invitations',
|
||||
// 'payments',
|
||||
// 'client',
|
||||
// 'documents',
|
||||
];
|
||||
|
||||
/*
|
||||
public function includeInvoiceItems(Invoice $invoice)
|
||||
{
|
||||
$transformer = new InvoiceItemTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($invoice->invoice_items, $transformer, ENTITY_INVOICE_ITEM);
|
||||
}
|
||||
|
||||
public function includeInvitations(Invoice $invoice)
|
||||
{
|
||||
$transformer = new InvitationTransformer($this->account, $this->serializer);
|
||||
|
||||
return $this->includeCollection($invoice->invitations, $transformer, ENTITY_INVITATION);
|
||||
}
|
||||
|
||||
public function includePayments(Invoice $invoice)
|
||||
{
|
||||
$transformer = new PaymentTransformer($this->account, $this->serializer, $invoice);
|
||||
|
||||
return $this->includeCollection($invoice->payments, $transformer, ENTITY_PAYMENT);
|
||||
}
|
||||
|
||||
public function includeClient(Invoice $invoice)
|
||||
{
|
||||
$transformer = new ClientTransformer($this->account, $this->serializer);
|
||||
|
||||
return $this->includeItem($invoice->client, $transformer, ENTITY_CLIENT);
|
||||
}
|
||||
|
||||
public function includeExpenses(Invoice $invoice)
|
||||
{
|
||||
$transformer = new ExpenseTransformer($this->account, $this->serializer);
|
||||
|
||||
return $this->includeCollection($invoice->expenses, $transformer, ENTITY_EXPENSE);
|
||||
}
|
||||
|
||||
public function includeDocuments(Invoice $invoice)
|
||||
{
|
||||
$transformer = new DocumentTransformer($this->account, $this->serializer);
|
||||
|
||||
$invoice->documents->each(function ($document) use ($invoice) {
|
||||
$document->setRelation('invoice', $invoice);
|
||||
});
|
||||
|
||||
return $this->includeCollection($invoice->documents, $transformer, ENTITY_DOCUMENT);
|
||||
}
|
||||
*/
|
||||
public function transform(RecurringInvoice $invoice)
|
||||
{
|
||||
return [
|
||||
'id' => $this->encodePrimaryKey($invoice->id),
|
||||
'amount' => (float) $invoice->amount,
|
||||
'balance' => (float) $invoice->balance,
|
||||
'client_id' => (int) $invoice->client_id,
|
||||
'status_id' => (int) ($invoice->status_id ?: 1),
|
||||
'updated_at' => $invoice->updated_at,
|
||||
'archived_at' => $invoice->deleted_at,
|
||||
'discount' => (float) $invoice->discount,
|
||||
'po_number' => $invoice->po_number,
|
||||
'invoice_date' => $invoice->invoice_date ?: '',
|
||||
'due_date' => $invoice->due_date ?: '',
|
||||
'terms' => $invoice->terms ?: '',
|
||||
'public_notes' => $invoice->public_notes ?: '',
|
||||
'private_notes' => $invoice->private_notes ?: '',
|
||||
'is_deleted' => (bool) $invoice->is_deleted,
|
||||
'tax_name1' => $invoice->tax_name1 ? $invoice->tax_name1 : '',
|
||||
'tax_rate1' => (float) $invoice->tax_rate1,
|
||||
'tax_name2' => $invoice->tax_name2 ? $invoice->tax_name2 : '',
|
||||
'tax_rate2' => (float) $invoice->tax_rate2,
|
||||
'is_amount_discount' => (bool) ($invoice->is_amount_discount ?: false),
|
||||
'invoice_footer' => $invoice->invoice_footer ?: '',
|
||||
'partial' => (float) ($invoice->partial ?: 0.0),
|
||||
'partial_due_date' => $invoice->partial_due_date ?: '',
|
||||
'custom_value1' => (float) $invoice->custom_value1,
|
||||
'custom_value2' => (float) $invoice->custom_value2,
|
||||
'custom_taxes1' => (bool) $invoice->custom_taxes1,
|
||||
'custom_taxes2' => (bool) $invoice->custom_taxes2,
|
||||
'has_tasks' => (bool) $invoice->has_tasks,
|
||||
'has_expenses' => (bool) $invoice->has_expenses,
|
||||
'custom_text_value1' => $invoice->custom_text_value1 ?: '',
|
||||
'custom_text_value2' => $invoice->custom_text_value2 ?: '',
|
||||
'backup' => $invoice->backup ?: '',
|
||||
'settings' => $invoice->settings,
|
||||
'frequency_id' => (int) $invoice->frequency_id,
|
||||
'start_date' => $invoice->start_date,
|
||||
'last_sent_date' => $invoice->last_sent_date,
|
||||
'next_send_date' => $invoice->next_send_date,
|
||||
'remaining_cycles' => (int) $invoice->remaining_cycles,
|
||||
];
|
||||
}
|
||||
}
|
17
database/factories/PaymentFactory.php
Normal file
17
database/factories/PaymentFactory.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(App\Models\Payment::class, function (Faker $faker) {
|
||||
return [
|
||||
'is_deleted' => false,
|
||||
'amount' => $faker->numberBetween(1,10),
|
||||
'payment_date' => $faker->date(),
|
||||
'transaction_reference' => $faker->text(10),
|
||||
'invoice_id' => $faker->numberBetween(1,10)
|
||||
];
|
||||
});
|
||||
|
||||
|
32
database/factories/RecurringInvoiceFactory.php
Normal file
32
database/factories/RecurringInvoiceFactory.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(App\Models\RecurringInvoice::class, function (Faker $faker) {
|
||||
return [
|
||||
'status_id' => App\Models\RecurringInvoice::STATUS_PENDING,
|
||||
'discount' => $faker->numberBetween(1,10),
|
||||
'is_amount_discount' => $faker->boolean(),
|
||||
'tax_name1' => 'GST',
|
||||
'tax_rate1' => 10,
|
||||
'tax_name2' => 'VAT',
|
||||
'tax_rate2' => 17.5,
|
||||
'custom_value1' => $faker->numberBetween(1,4),
|
||||
'custom_value2' => $faker->numberBetween(1,4),
|
||||
'custom_value3' => $faker->numberBetween(1,4),
|
||||
'custom_value4' => $faker->numberBetween(1,4),
|
||||
'is_deleted' => false,
|
||||
'po_number' => $faker->text(10),
|
||||
'invoice_date' => $faker->date(),
|
||||
'due_date' => $faker->date(),
|
||||
'line_items' => false,
|
||||
'backup' => '',
|
||||
'frequency_id' => App\Models\RecurringInvoice::FREQUENCY_MONTHLY,
|
||||
'start_date' => $faker->date(),
|
||||
'last_sent_date' => $faker->date(),
|
||||
'next_send_date' => $faker->date(),
|
||||
'remaining_cycles' => $faker->numberBetween(1,10),
|
||||
];
|
||||
});
|
@ -418,7 +418,8 @@ class CreateUsersTable extends Migration
|
||||
$t->unsignedInteger('user_id');
|
||||
$t->unsignedInteger('company_id')->index();
|
||||
|
||||
$t->string('invoice_number');
|
||||
$t->unsignedInteger('status_id')->index();
|
||||
|
||||
$t->float('discount');
|
||||
$t->boolean('is_amount_discount');
|
||||
|
||||
@ -469,7 +470,6 @@ class CreateUsersTable extends Migration
|
||||
$t->timestamps();
|
||||
$t->softDeletes();
|
||||
|
||||
$t->unique(['company_id', 'invoice_number']);
|
||||
});
|
||||
|
||||
Schema::create('quotes', function ($t) {
|
||||
@ -624,7 +624,7 @@ class CreateUsersTable extends Migration
|
||||
$t->string('transaction_reference')->nullable();
|
||||
$t->string('payer_id')->nullable();
|
||||
|
||||
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
||||
//$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
||||
$t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||
$t->foreign('client_contact_id')->references('id')->on('client_contacts')->onDelete('cascade');
|
||||
|
@ -51,14 +51,16 @@ Route::group(['middleware' => ['db','api_secret_check','token_auth'], 'prefix' =
|
||||
Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk');
|
||||
|
||||
Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit
|
||||
|
||||
Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
|
||||
|
||||
/*
|
||||
Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
|
||||
|
||||
Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
|
||||
|
||||
Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
|
||||
|
||||
|
198
tests/Feature/PaymentTest.php
Normal file
198
tests/Feature/PaymentTest.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App\Http\Controllers\PaymentController
|
||||
*/
|
||||
|
||||
class PaymentTest extends TestCase
|
||||
{
|
||||
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
|
||||
parent::setUp();
|
||||
|
||||
Session::start();
|
||||
|
||||
$this->faker = \Faker\Factory::create();
|
||||
|
||||
Model::reguard();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testPaymentList()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data']['id']));
|
||||
|
||||
$company_token = $account->default_company->tokens()->first();
|
||||
$token = $company_token->token;
|
||||
$company = $company_token->company;
|
||||
|
||||
$user = $company_token->user;
|
||||
|
||||
$this->assertNotNull($company_token);
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($company);
|
||||
$this->assertNotNull($user->tokens->first()->company);
|
||||
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
]);
|
||||
|
||||
});
|
||||
$client = Client::all()->first();
|
||||
|
||||
factory(\App\Models\Payment::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/payments');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
public function testPaymentRESTEndPoints()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data']['id']));
|
||||
|
||||
$company_token = $account->default_company->tokens()->first();
|
||||
$token = $company_token->token;
|
||||
$company = $company_token->company;
|
||||
|
||||
$user = $company_token->user;
|
||||
|
||||
$this->assertNotNull($company_token);
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($company);
|
||||
$this->assertNotNull($user->tokens->first()->company);
|
||||
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
]);
|
||||
|
||||
});
|
||||
$client = Client::all()->first();
|
||||
|
||||
factory(\App\Models\Payment::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||
|
||||
$Payment = Payment::all()->first();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id).'/edit');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$Payment_update = [
|
||||
'amount' => 10
|
||||
];
|
||||
|
||||
$this->assertNotNull($Payment);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->put('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id), $Payment_update)
|
||||
->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->delete('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -160,7 +160,7 @@ class QuoteTest extends TestCase
|
||||
$quote = Quote::where('user_id',$user->id)->first();
|
||||
$quote->settings = $client->getMergedSettings();
|
||||
$quote->save();
|
||||
Log::error(print_r($quote,1));
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
|
203
tests/Feature/RecurringInvoiceTest.php
Normal file
203
tests/Feature/RecurringInvoiceTest.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App\Http\Controllers\RecurringInvoiceController
|
||||
*/
|
||||
|
||||
class RecurringInvoiceTest extends TestCase
|
||||
{
|
||||
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
|
||||
parent::setUp();
|
||||
|
||||
Session::start();
|
||||
|
||||
$this->faker = \Faker\Factory::create();
|
||||
|
||||
Model::reguard();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testRecurringInvoiceList()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data']['id']));
|
||||
|
||||
$company_token = $account->default_company->tokens()->first();
|
||||
$token = $company_token->token;
|
||||
$company = $company_token->company;
|
||||
|
||||
$user = $company_token->user;
|
||||
|
||||
$this->assertNotNull($company_token);
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($company);
|
||||
$this->assertNotNull($user->tokens->first()->company);
|
||||
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
]);
|
||||
|
||||
});
|
||||
$client = Client::all()->first();
|
||||
|
||||
factory(\App\Models\RecurringInvoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/recurring_invoices');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
public function testRecurringInvoiceRESTEndPoints()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data']['id']));
|
||||
|
||||
$company_token = $account->default_company->tokens()->first();
|
||||
$token = $company_token->token;
|
||||
$company = $company_token->company;
|
||||
|
||||
$user = $company_token->user;
|
||||
|
||||
$this->assertNotNull($company_token);
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($company);
|
||||
$this->assertNotNull($user->tokens->first()->company);
|
||||
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
]);
|
||||
|
||||
});
|
||||
$client = Client::all()->first();
|
||||
|
||||
factory(\App\Models\RecurringInvoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||
|
||||
$RecurringInvoice = RecurringInvoice::where('user_id',$user->id)->first();
|
||||
$RecurringInvoice->settings = $client->getMergedSettings();
|
||||
$RecurringInvoice->save();
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->get('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id).'/edit');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$RecurringInvoice_update = [
|
||||
'status_id' => RecurringInvoice::STATUS_DRAFT
|
||||
];
|
||||
|
||||
$this->assertNotNull($RecurringInvoice);
|
||||
$this->assertNotNull($RecurringInvoice->settings);
|
||||
|
||||
$this->assertTrue(property_exists($RecurringInvoice->settings, 'custom_taxes1'));
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->put('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id), $RecurringInvoice_update)
|
||||
->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
])->delete('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -85,7 +85,7 @@ class FactoryCreationTest extends TestCase
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App|Factory\CloneInvoiceFactory
|
||||
* @covers App\Factory\CloneInvoiceFactory
|
||||
*/
|
||||
public function testCloneInvoiceCreation()
|
||||
{
|
||||
@ -114,7 +114,7 @@ class FactoryCreationTest extends TestCase
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App|Factory\ClientFactory
|
||||
* @covers App\Factory\ClientFactory
|
||||
*/
|
||||
public function testClientCreate()
|
||||
{
|
||||
@ -129,7 +129,7 @@ class FactoryCreationTest extends TestCase
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App|Factory\ClientContactFactory
|
||||
* @covers App\Factory\ClientContactFactory
|
||||
*/
|
||||
public function testClientContactCreate()
|
||||
{
|
||||
@ -166,7 +166,7 @@ class FactoryCreationTest extends TestCase
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App|Factory\UserFactory
|
||||
* @covers App\Factory\UserFactory
|
||||
*/
|
||||
public function testUserCreate()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user