mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-05 18:52:44 +01:00
Payment refunds, Projects, Expenses and Vendors. (#3228)
* OpenAPI Documentation for Vendors and Expenses * Rules for refunds * Rules for Payment Refunds * Fixes for quote invitation link * Project
This commit is contained in:
parent
0e9d098049
commit
a70b024d94
@ -22,6 +22,7 @@ use App\Models\PaymentType;
|
||||
use App\Models\User;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Carbon\Carbon;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@ -232,6 +233,17 @@ class CreateTestData extends Command
|
||||
|
||||
$this->createClient($company, $user);
|
||||
}
|
||||
|
||||
foreach($company->clients as $client) {
|
||||
|
||||
|
||||
$this->createInvoice($client);
|
||||
$this->createQuote($client);
|
||||
$this->createExpense($client);
|
||||
$this->createVendor($client);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function createClient($company, $user)
|
||||
@ -254,16 +266,8 @@ class CreateTestData extends Command
|
||||
'company_id' => $company->id
|
||||
]);
|
||||
|
||||
$y = $this->count * rand(1, 5);
|
||||
|
||||
$this->info("Creating {$y} invoices & quotes");
|
||||
|
||||
for ($x=0; $x<$y; $x++) {
|
||||
$this->createInvoice($client);
|
||||
$this->createQuote($client);
|
||||
$this->createExpense($client);
|
||||
$this->createVendor($client);
|
||||
}
|
||||
}
|
||||
|
||||
private function createExpense($client)
|
||||
@ -308,7 +312,8 @@ class CreateTestData extends Command
|
||||
|
||||
$invoice = InvoiceFactory::create($client->company->id, $client->user->id);//stub the company and user_id
|
||||
$invoice->client_id = $client->id;
|
||||
$invoice->date = $faker->date();
|
||||
// $invoice->date = $faker->date();
|
||||
$invoice->date = Carbon::now()->subDays(rand(0,90));
|
||||
|
||||
$invoice->line_items = $this->buildLineItems();
|
||||
$invoice->uses_inclusive_taxes = false;
|
||||
|
43
app/Http/Controllers/OpenAPI/ExpenseSchema.php
Normal file
43
app/Http/Controllers/OpenAPI/ExpenseSchema.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="Expense",
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"),
|
||||
* @OA\Property(property="user_id", type="string", example="", description="__________"),
|
||||
* @OA\Property(property="assigned_user_id", type="string", example="", description="__________"),
|
||||
* @OA\Property(property="company_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="client_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="invoice_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="bank_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="invoice_currency_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="expense_currency_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="invoice_category_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="payment_type_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="recurring_expense_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="private_notes", type="string", example="", description="________"),
|
||||
* @OA\Property(property="public_notes", type="string", example="", description="________"),
|
||||
* @OA\Property(property="transaction_reference", type="string", example="", description="________"),
|
||||
* @OA\Property(property="transcation_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value1", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value2", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value3", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
|
||||
* @OA\Property(property="tax_name1", type="string", example="", description="________"),
|
||||
* @OA\Property(property="tax_name2", type="string", example="", description="________"),
|
||||
* @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"),
|
||||
* @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"),
|
||||
* @OA\Property(property="tax_name3", type="string", example="", description="________"),
|
||||
* @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"),
|
||||
* @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"),
|
||||
* @OA\Property(property="foreign_amount", type="number", format="float", example="10.00", description="_________"),
|
||||
* @OA\Property(property="exchange_rate", type="number", format="float", example="0.80", description="_________"),
|
||||
* @OA\Property(property="expense_date", type="string", example="", description="________"),
|
||||
* @OA\Property(property="payment_date", type="string", example="", description="________"),
|
||||
* @OA\Property(property="should_be_invoiced", type="boolean", example=true, description="_________"),
|
||||
* @OA\Property(property="is_deleted", type="boolean", example=true, description="_________"),
|
||||
* @OA\Property(property="invoice_documents", type="boolean", example=true, description=""),
|
||||
* @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"),
|
||||
* @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"),
|
||||
* )
|
||||
*/
|
23
app/Http/Controllers/OpenAPI/VendorContact.php
Normal file
23
app/Http/Controllers/OpenAPI/VendorContact.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="VendorContact",
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"),
|
||||
* @OA\Property(property="user_id", type="string", example="", description="__________"),
|
||||
* @OA\Property(property="company_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="vendor_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="first_name", type="string", example="", description="________"),
|
||||
* @OA\Property(property="last_name", type="string", example="", description="________"),
|
||||
* @OA\Property(property="phone", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value1", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value2", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value3", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
|
||||
* @OA\Property(property="email", type="string", example="", description="________"),
|
||||
* @OA\Property(property="is_primary", type="boolean", example=true, description="________"),
|
||||
* @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="deleted_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* )
|
||||
*/
|
44
app/Http/Controllers/OpenAPI/VendorSchema.php
Normal file
44
app/Http/Controllers/OpenAPI/VendorSchema.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="Vendor",
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"),
|
||||
* @OA\Property(property="user_id", type="string", example="", description="__________"),
|
||||
* @OA\Property(property="assigned_user_id", type="string", example="", description="__________"),
|
||||
* @OA\Property(property="company_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="client_id", type="string", example="", description="________"),
|
||||
* @OA\Property(
|
||||
* property="contacts",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
*
|
||||
* ref="#/components/schemas/VendorContact",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(property="name", type="string", example="", description="________"),
|
||||
* @OA\Property(property="website", type="string", example="", description="________"),
|
||||
* @OA\Property(property="private_notes", type="string", example="", description="________"),
|
||||
* @OA\Property(property="industry_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="size_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="address1", type="string", example="", description="________"),
|
||||
* @OA\Property(property="address2", type="string", example="", description="________"),
|
||||
* @OA\Property(property="city", type="string", example="", description="________"),
|
||||
* @OA\Property(property="state", type="string", example="", description="________"),
|
||||
* @OA\Property(property="postal_code", type="string", example="", description="________"),
|
||||
* @OA\Property(property="work_phone", type="string", example="555-3434-3434", description="The client phone number"),
|
||||
* @OA\Property(property="country_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="currency_id", type="string", example="4", description="________"),
|
||||
* @OA\Property(property="custom_value1", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value2", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value3", type="string", example="", description="________"),
|
||||
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
|
||||
* @OA\Property(property="vat_number", type="string", example="", description="________"),
|
||||
* @OA\Property(property="id_number", type="string", example="", description="________"),
|
||||
* @OA\Property(property="is_deleted", type="boolean", example=true, description="________"),
|
||||
* @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"),
|
||||
* )
|
||||
*/
|
@ -17,6 +17,7 @@ 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\RefundPaymentRequest;
|
||||
use App\Http\Requests\Payment\ShowPaymentRequest;
|
||||
use App\Http\Requests\Payment\StorePaymentRequest;
|
||||
use App\Http\Requests\Payment\UpdatePaymentRequest;
|
||||
@ -624,4 +625,60 @@ class PaymentController extends BaseController
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created refund.
|
||||
*
|
||||
* @param \App\Http\Requests\Payment\RefundPaymentRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/payments/refund",
|
||||
* operationId="storeRefund",
|
||||
* tags={"payments"},
|
||||
* summary="Adds a Refund",
|
||||
* description="Adds an Refund to the system",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\RequestBody(
|
||||
* description="The refund request",
|
||||
* required=true,
|
||||
* @OA\JsonContent(ref="#/components/schemas/Payment"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the saved Payment object",
|
||||
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/Payment"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*/
|
||||
public function refund(RefundPaymentRequest $request)
|
||||
{
|
||||
\Log::error("Payment id = ".$request->input('id'));
|
||||
|
||||
$payment = Payment::whereId($request->input('id'))->first();
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
}
|
||||
|
59
app/Http/Requests/Payment/RefundPaymentRequest.php
Normal file
59
app/Http/Requests/Payment/RefundPaymentRequest.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\ValidRefundableInvoices;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class RefundPaymentRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(!isset($input['gateway_refund']))
|
||||
$input['gateway_refund'] = false;
|
||||
|
||||
if(isset($input['id']))
|
||||
$input['id'] = $this->decodePrimaryKey($input['id']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'id' => 'required',
|
||||
'refunded' => 'numeric',
|
||||
'date' => 'required',
|
||||
'invoices.*.invoice_id' => 'required',
|
||||
'invoices.*.refunded' => 'required',
|
||||
'invoices' => new ValidRefundableInvoices(),
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
83
app/Http/ValidationRules/ValidRefundableInvoices.php
Normal file
83
app/Http/ValidationRules/ValidRefundableInvoices.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\ValidationRules;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class ValidRefundableInvoices
|
||||
* @package App\Http\ValidationRules
|
||||
*/
|
||||
class ValidRefundableInvoices implements Rule
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
private $error_msg;
|
||||
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$payment = Payment::whereId($this->decodePrimaryKey(request()->input('id')))->first();
|
||||
|
||||
if($request->has('refunded') && ($request->input('refunded') > $payment->amount)){
|
||||
$this->error_msg = "Attempting to refunded more than payment amount, enter a value equal to or lower than the payment amount of ". $payment->amount;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*If no invoices has been sent, then we apply the payment to the client account*/
|
||||
$invoices = [];
|
||||
|
||||
if (is_array($value)) {
|
||||
$invoices = Invoice::whereIn('id', array_column($value, 'invoice_id'))->company()->get();
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
if (! $invoice->isRefundable()) {
|
||||
$this->error_msg = "One or more of these invoices have been paid";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
foreach ($value as $val) {
|
||||
if ($val['invoice_id'] == $invoice->id) {
|
||||
|
||||
if($val['refunded'] > ($invoice->amount - $invoice->balance))
|
||||
$this->error_msg = "Attempting to refund more than is possible for an invoice";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return $this->error_msg;
|
||||
}
|
||||
}
|
@ -231,6 +231,17 @@ class Invoice extends BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
public function isRefundable() : bool
|
||||
{
|
||||
if($this->is_deleted){
|
||||
return false;
|
||||
} elseif ($this->balance <= 0)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function badgeForStatus(int $status)
|
||||
{
|
||||
switch ($status) {
|
||||
|
62
app/Models/Project.php
Normal file
62
app/Models/Project.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
|
||||
/**
|
||||
* Class Project.
|
||||
*/
|
||||
class Project extends BaseModel
|
||||
{
|
||||
// Expense Categories
|
||||
use SoftDeletes;
|
||||
use PresentableTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'task_rate',
|
||||
'private_notes',
|
||||
'due_date',
|
||||
'budgeted_hours',
|
||||
'custom_value1',
|
||||
'custom_value2',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function client()
|
||||
{
|
||||
return $this->belongsTo(Client::class)->withTrashed();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
// */
|
||||
// public function tasks()
|
||||
// {
|
||||
// return $this->hasMany('App\Models\Task');
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,12 +12,14 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Traits\Inviteable;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class QuoteInvitation extends BaseModel
|
||||
{
|
||||
use MakesDates;
|
||||
use Inviteable;
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
|
@ -74,6 +74,8 @@ Route::group(['middleware' => ['api_db','api_secret_check','token_auth','locale'
|
||||
|
||||
Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
|
||||
|
||||
Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund');
|
||||
|
||||
Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
|
||||
|
||||
// Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
|
||||
|
@ -116,7 +116,7 @@ class ClientApiTest extends TestCase
|
||||
])->post('/api/v1/clients/bulk?action=archive', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
\Log::error($arr);
|
||||
|
||||
$this->assertNotNull($arr['data'][0]['archived_at']);
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertNotNull($payment);
|
||||
$this->assertNotNull($payment->invoices());
|
||||
@ -405,7 +405,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertNotNull($payment);
|
||||
$this->assertNotNull($payment->invoices());
|
||||
@ -466,7 +466,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertNotNull($payment);
|
||||
$this->assertNotNull($payment->invoices());
|
||||
@ -786,7 +786,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertEquals($payment->amount, 15);
|
||||
$this->assertEquals($payment->applied, 10);
|
||||
@ -890,7 +890,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertEquals($payment->amount, 20);
|
||||
$this->assertEquals($payment->applied, 10);
|
||||
@ -1005,7 +1005,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
$this->assertEquals($this->invoice->amount, $arr['data']['amount']);
|
||||
|
||||
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertNotNull($payment);
|
||||
$this->assertNotNull($payment->invoices());
|
||||
@ -1066,4 +1066,81 @@ class PaymentTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testBasicRefundValidation()
|
||||
{
|
||||
$client = ClientFactory::create($this->company->id, $this->user->id);
|
||||
$client->save();
|
||||
|
||||
$this->invoice = InvoiceFactory::create($this->company->id,$this->user->id);//stub the company and user_id
|
||||
$this->invoice->client_id = $client->id;
|
||||
$this->invoice->status_id = Invoice::STATUS_SENT;
|
||||
|
||||
$this->invoice->line_items = $this->buildLineItems();
|
||||
$this->invoice->uses_inclusive_Taxes = false;
|
||||
|
||||
$this->invoice->save();
|
||||
|
||||
$this->invoice_calc = new InvoiceSum($this->invoice);
|
||||
$this->invoice_calc->build();
|
||||
|
||||
$this->invoice = $this->invoice_calc->getInvoice();
|
||||
$this->invoice->save();
|
||||
|
||||
$data = [
|
||||
'amount' => 50,
|
||||
'client_id' => $client->hashed_id,
|
||||
// 'invoices' => [
|
||||
// [
|
||||
// 'invoice_id' => $this->invoice->hashed_id,
|
||||
// 'amount' => $this->invoice->amount
|
||||
// ],
|
||||
// ],
|
||||
'date' => '2020/12/12',
|
||||
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments', $data);
|
||||
|
||||
|
||||
$arr = $response->json();
|
||||
$response->assertStatus(200);
|
||||
|
||||
$payment_id = $arr['data']['id'];
|
||||
|
||||
$this->assertEquals(50, $arr['data']['amount']);
|
||||
|
||||
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
|
||||
|
||||
$this->assertNotNull($payment);
|
||||
// $this->assertNotNull($payment->invoices());
|
||||
// $this->assertEquals(1, $payment->invoices()->count());
|
||||
|
||||
|
||||
$data = [
|
||||
'id' => $this->encodePrimaryKey($payment->id),
|
||||
'refunded' => 50,
|
||||
// 'invoices' => [
|
||||
// [
|
||||
// 'invoice_id' => $this->invoice->hashed_id,
|
||||
// 'amount' => $this->invoice->amount
|
||||
// ],
|
||||
// ],
|
||||
'date' => '2020/12/12',
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments/refund', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user