mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Activity API fixes + Payments API (#3076)
* Fixes for Store Payment Validation * Tests for Payments * Use custom validator to ensure payments are made ONLY to payable invoices * Working on custom payment validators * Update Client balance * fixes for client balance * Fixes for activity API
This commit is contained in:
parent
81c481c071
commit
fe5a97e174
@ -29,9 +29,38 @@ class ActivityController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
* @OA\Get(
|
||||
* path="/api/v1/actvities",
|
||||
* operationId="getActivities",
|
||||
* tags={"actvities"},
|
||||
* summary="Gets a list of actvities",
|
||||
* description="Lists all activities",
|
||||
* @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\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A list of actvities",
|
||||
* @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/Activity"),
|
||||
* ),
|
||||
* @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"),
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -185,6 +185,40 @@ class PaymentController extends BaseController
|
||||
* @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 payment request",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="amount",
|
||||
* description="The payment amount",
|
||||
* type="number",
|
||||
* format="float",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="payment_date",
|
||||
* example="2019/12/1",
|
||||
* description="The payment date",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="transation_reference",
|
||||
* example="sdfasdfs98776d6kbkfd",
|
||||
* description="The transaction reference for the payment",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="invoices",
|
||||
* example="j7s76d,s8765afk,D8fj3Sfdj",
|
||||
* description="A comma separated list of invoice hashed ids that this payment relates to",
|
||||
* type="string",
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the saved Payment object",
|
||||
@ -449,6 +483,7 @@ class PaymentController extends BaseController
|
||||
public function destroy(DestroyPaymentRequest $request, Payment $payment)
|
||||
{
|
||||
|
||||
$payment->is_deleted = true;
|
||||
$payment->delete();
|
||||
|
||||
return response()->json([], 200);
|
||||
|
@ -12,12 +12,14 @@
|
||||
namespace App\Http\Requests\Payment;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\ValidPayableInvoicesRule;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class StorePaymentRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
@ -26,41 +28,47 @@ class StorePaymentRequest extends Request
|
||||
|
||||
public function authorize() : bool
|
||||
{
|
||||
|
||||
return auth()->user()->can('create', Payment::class);
|
||||
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$this->sanitize();
|
||||
|
||||
return [
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
'client_id' => 'integer|nullable',
|
||||
'payment_type_id' => 'integer|nullable',
|
||||
'amount' => 'numeric',
|
||||
$rules = [
|
||||
'amount' => 'numeric|required',
|
||||
'payment_date' => 'required',
|
||||
'client_id' => 'required',
|
||||
'invoices' => 'required',
|
||||
'invoices' => new ValidPayableInvoicesRule(),
|
||||
];
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
|
||||
$input = $this->all();
|
||||
|
||||
if(isset($input['client_id']))
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
|
||||
if(isset($input['invoices']))
|
||||
$input['invoices'] = $this->transformKeys(array_column($input['invoices']), 'id');
|
||||
$input['invoices'] = $this->transformKeys(explode(",", $input['invoices']));
|
||||
|
||||
if(is_array($input['invoices']) === false)
|
||||
$input['invoices'] = null;
|
||||
|
||||
|
||||
$this->replace($input);
|
||||
|
||||
return $this->all();
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
56
app/Http/ValidationRules/ValidPayableInvoicesRule.php
Normal file
56
app/Http/ValidationRules/ValidPayableInvoicesRule.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\ValidationRules;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class ValidPayableInvoicesRule
|
||||
* @package App\Http\ValidationRules
|
||||
*/
|
||||
class ValidPayableInvoicesRule implements Rule
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(explode(",",$value)))->get();
|
||||
|
||||
if(!$invoices || $invoices->count() == 0)
|
||||
return false;
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
|
||||
if(! $invoice->isPayable())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return "One or more of these invoices have been paid";
|
||||
}
|
||||
|
||||
}
|
51
app/Jobs/Client/UpdateClientBalance.php
Normal file
51
app/Jobs/Client/UpdateClientBalance.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Client;
|
||||
|
||||
|
||||
use App\Models\Client;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class UpdateClientBalance
|
||||
{
|
||||
use Dispatchable;
|
||||
|
||||
protected $amount;
|
||||
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct(Client $client, $amount)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$this->client->balance += $this->amount;
|
||||
$this->client->paid_to_date += $this->amount;
|
||||
$this->client->save();
|
||||
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Jobs\Invoice;
|
||||
|
||||
use App\Jobs\Client\UpdateClientBalance;
|
||||
use App\Jobs\Company\UpdateCompanyLedgerWithInvoice;
|
||||
use App\Jobs\Company\UpdateCompanyLedgerWithPayment;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
@ -51,7 +52,7 @@ class UpdateInvoicePayment implements ShouldQueue
|
||||
|
||||
$invoices_total = $invoices->sum('balance');
|
||||
|
||||
/* Simplest scenario*/
|
||||
/* Simplest scenario - All invoices are paid in full*/
|
||||
if(strval($invoices_total) === strval($this->payment->amount))
|
||||
{
|
||||
$invoices->each(function ($invoice){
|
||||
@ -60,14 +61,17 @@ class UpdateInvoicePayment implements ShouldQueue
|
||||
$invoice->clearPartial();
|
||||
$invoice->updateBalance($invoice->balance*-1);
|
||||
|
||||
UpdateClientBalance::dispatchNow($this->payment->client, $invoice->balance*-1);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
/*Combination of partials and full invoices are being paid*/
|
||||
else {
|
||||
|
||||
$total = 0;
|
||||
|
||||
|
||||
/* Calculate the grand total of the invoices*/
|
||||
foreach($invoices as $invoice)
|
||||
{
|
||||
|
||||
@ -78,7 +82,7 @@ class UpdateInvoicePayment implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
/* test if there is a batch of partial invoices that have been paid */
|
||||
/*Test if there is a batch of partial invoices that have been paid */
|
||||
if($this->payment->amount == $total)
|
||||
{
|
||||
|
||||
@ -92,12 +96,17 @@ class UpdateInvoicePayment implements ShouldQueue
|
||||
$invoice->setDueDate();
|
||||
$invoice->setStatus(Invoice::STATUS_PARTIAL);
|
||||
|
||||
UpdateClientBalance::dispatchNow($this->payment->client, $invoice->partial*-1);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($invoice->balance*-1));
|
||||
$invoice->clearPartial();
|
||||
$invoice->updateBalance($invoice->balance*-1);
|
||||
|
||||
UpdateClientBalance::dispatchNow($this->payment->client, $invoice->balance*-1);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -120,18 +120,18 @@ class Activity extends StaticModel
|
||||
return $this->belongsTo(Payment::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return $this->belongsTo(Task::class)->withTrashed();
|
||||
}
|
||||
// public function task()
|
||||
// {
|
||||
// return $this->belongsTo(Task::class)->withTrashed();
|
||||
// }
|
||||
|
||||
public function expense()
|
||||
{
|
||||
return $this->belongsTo(Expense::class)->withTrashed();
|
||||
}
|
||||
// public function expense()
|
||||
// {
|
||||
// return $this->belongsTo(Expense::class)->withTrashed();
|
||||
// }
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class)->withTrashed();
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class GatewayType extends StaticModel
|
||||
const CREDIT_CARD = 1;
|
||||
const BANK_TRANSFER = 2;
|
||||
const PAYPAL = 3;
|
||||
const BITCOIN = 4;
|
||||
const CRYPTO = 4;
|
||||
const DWOLLA = 5;
|
||||
const CUSTOM1 = 6;
|
||||
const ALIPAY = 7;
|
||||
|
@ -18,12 +18,14 @@ use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Payment extends BaseModel
|
||||
{
|
||||
use MakesHash;
|
||||
use Filterable;
|
||||
use MakesDates;
|
||||
use SoftDeletes;
|
||||
|
||||
const STATUS_PENDING = 1;
|
||||
const STATUS_VOIDED = 2;
|
||||
@ -147,6 +149,7 @@ class Payment extends BaseModel
|
||||
public function resolveRouteBinding($value)
|
||||
{
|
||||
return $this
|
||||
->withTrashed()
|
||||
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Jobs\Company\UpdateCompanyLedgerWithPayment;
|
||||
use App\Jobs\Invoice\UpdateInvoicePayment;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@ -20,7 +24,6 @@ use Illuminate\Http\Request;
|
||||
class PaymentRepository extends BaseRepository
|
||||
{
|
||||
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Payment::class;
|
||||
@ -31,19 +34,23 @@ class PaymentRepository extends BaseRepository
|
||||
|
||||
$payment->fill($request->input());
|
||||
|
||||
$payment->save();
|
||||
|
||||
if($request->input('invoices'))
|
||||
{
|
||||
|
||||
$invoices = Invoice::whereIn('id', $request->input('invoices'))->get();
|
||||
|
||||
$payment->invoices()->saveMany($invoices);
|
||||
|
||||
}
|
||||
|
||||
//parse invoices[] and attach to paymentables
|
||||
//parse invoices[] and apply payments and subfunctions
|
||||
event(new PaymentWasCreated($payment));
|
||||
|
||||
$payment->save();
|
||||
UpdateInvoicePayment::dispatchNow($payment);
|
||||
|
||||
return $payment;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -27,17 +27,17 @@ class ActivityTransformer extends EntityTransformer
|
||||
return [
|
||||
'id' => (string) $this->encodePrimaryKey($activity->id),
|
||||
'activity_type_id' => (string) $activity->activity_type_id,
|
||||
'client_id' => $activity->client ? (string) $activity->client->id : '',
|
||||
'company_id' => $activity->company ? (string) $activity->company->id : '',
|
||||
'client_id' => $activity->client ? (string) $this->encodePrimaryKey($activity->client->id) : '',
|
||||
'company_id' => $activity->company ? (string) $this->encodePrimaryKey($activity->company->id) : '',
|
||||
'user_id' => (string) $activity->user_id,
|
||||
'invoice_id' => $activity->invoice ? (string) $activity->invoice->id : '',
|
||||
'payment_id' => $activity->payment ? (string) $activity->payment->id : '',
|
||||
'credit_id' => $activity->credit ? (string) $activity->credit->id : '',
|
||||
'invoice_id' => $activity->invoice ? (string) $this->encodePrimaryKey($activity->invoice->id) : '',
|
||||
'payment_id' => $activity->payment ? (string) $this->encodePrimaryKey($activity->payment->id) : '',
|
||||
'credit_id' => $activity->credit ? (string) $this->encodePrimaryKey($activity->credit->id) : '',
|
||||
'updated_at' => $activity->updated_at,
|
||||
'expense_id' => $activity->expense_id ? (string) $activity->expense->id : '',
|
||||
'expense_id' => $activity->expense_id ? (string) $this->encodePrimaryKey($activity->expense->id) : '',
|
||||
'is_system' => (bool) $activity->is_system,
|
||||
'contact_id' => $activity->contact_id ? (string) $activity->contact->id : '',
|
||||
'task_id' => $activity->task_id ? (string) $activity->task->id : '',
|
||||
'contact_id' => $activity->contact_id ? (string) $this->encodePrimaryKey($activity->contact->id) : '',
|
||||
'task_id' => $activity->task_id ? (string) $this->encodePrimaryKey($activity->task->id) : '',
|
||||
'notes' => $activity->notes ? (string) $activity->notes : '',
|
||||
'ip' => (string) $activity->ip,
|
||||
|
||||
|
@ -27,7 +27,7 @@ class PaymentTransformer extends EntityTransformer
|
||||
|
||||
protected $availableIncludes = [
|
||||
'client',
|
||||
'invoice',
|
||||
'invoices',
|
||||
];
|
||||
|
||||
public function __construct($serializer = null)
|
||||
@ -37,11 +37,11 @@ class PaymentTransformer extends EntityTransformer
|
||||
|
||||
}
|
||||
|
||||
public function includeInvoice(Payment $payment)
|
||||
public function includeInvoices(Payment $payment)
|
||||
{
|
||||
$transformer = new InvoiceTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($payment->invoice, $transformer, Invoice::class);
|
||||
return $this->includeCollection($payment->invoices, $transformer, Invoice::class);
|
||||
}
|
||||
|
||||
public function includeClient(Payment $payment)
|
||||
@ -65,6 +65,7 @@ class PaymentTransformer extends EntityTransformer
|
||||
'is_deleted' => (bool) $payment->is_deleted,
|
||||
'payment_type_id' => (string) $payment->payment_type_id ?: '',
|
||||
'invitation_id' => (string) $payment->invitation_id ?: '',
|
||||
'client_id' => (string) $this->encodePrimaryKey($payment->client_id),
|
||||
/*
|
||||
'private_notes' => $payment->private_notes ?: '',
|
||||
'exchange_rate' => (float) $payment->exchange_rate,
|
||||
|
@ -6,6 +6,7 @@ use App\Models\Payment;
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(App\Models\Payment::class, function (Faker $faker) {
|
||||
|
||||
return [
|
||||
'is_deleted' => false,
|
||||
'amount' => $faker->numberBetween(1,10),
|
||||
@ -14,6 +15,7 @@ $factory->define(App\Models\Payment::class, function (Faker $faker) {
|
||||
'payment_type_id' => Payment::TYPE_CREDIT_CARD,
|
||||
'status_id' => Payment::STATUS_COMPLETED
|
||||
];
|
||||
|
||||
});
|
||||
|
||||
|
@ -4,8 +4,13 @@ namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -15,6 +20,8 @@ use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -27,7 +34,7 @@ class PaymentTest extends TestCase
|
||||
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
|
||||
use MockAccountData;
|
||||
public function setUp() :void
|
||||
{
|
||||
|
||||
@ -39,67 +46,40 @@ class PaymentTest extends TestCase
|
||||
|
||||
Model::reguard();
|
||||
|
||||
$this->makeTestData();
|
||||
$this->withoutExceptionHandling();
|
||||
|
||||
}
|
||||
|
||||
public function testPaymentList()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'name' => $this->faker->company,
|
||||
'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?include=account', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['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->token->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\Client::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'company_id' => $this->company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class,1)->create([
|
||||
'user_id' => $user->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
'company_id' => $this->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]);
|
||||
factory(\App\Models\Payment::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $client->id]);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/payments');
|
||||
|
||||
$response->assertStatus(200);
|
||||
@ -108,95 +88,164 @@ class PaymentTest extends TestCase
|
||||
|
||||
public function testPaymentRESTEndPoints()
|
||||
{
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'name' => $this->faker->company,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
factory(\App\Models\Payment::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]);
|
||||
|
||||
$Payment = Payment::all()->last();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup?include=account', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['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->token->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,
|
||||
'X-API-TOKEN' => $this->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,
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id).'/edit');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$Payment_update = [
|
||||
'amount' => 10,
|
||||
'payment_date' => Carbon::now()
|
||||
];
|
||||
|
||||
$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);
|
||||
|
||||
}
|
||||
|
||||
public function testStorePaymentWithoutClientId()
|
||||
{
|
||||
$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->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();
|
||||
|
||||
$data = [
|
||||
'amount' => $this->invoice->amount,
|
||||
'invoices' => $this->invoice->hashed_id,
|
||||
'payment_date' => '2020/12/11',
|
||||
|
||||
];
|
||||
|
||||
try {
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments/', $data);
|
||||
}
|
||||
catch(ValidationException $e) {
|
||||
|
||||
$message = json_decode($e->validator->getMessageBag(),1);
|
||||
|
||||
$this->assertTrue(array_key_exists('client_id', $message));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testStorePaymentWithClientId()
|
||||
{
|
||||
$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' => $this->invoice->amount,
|
||||
'client_id' => $client->hashed_id,
|
||||
'invoices' => $this->invoice->hashed_id,
|
||||
'payment_date' => '2020/12/12',
|
||||
|
||||
];
|
||||
|
||||
|
||||
try {
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments?include=invoices', $data);
|
||||
|
||||
}
|
||||
catch(ValidationException $e) {
|
||||
\Log::error('in the validator');
|
||||
$message = json_decode($e->validator->getMessageBag(),1);
|
||||
\Log::error($message);
|
||||
$this->assertNotNull($message);
|
||||
|
||||
}
|
||||
|
||||
$arr = $response->json();
|
||||
\Log::error($arr);
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testStorePaymentWithNoInvoiecs()
|
||||
{
|
||||
$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' => $this->invoice->amount,
|
||||
'client_id' => $client->hashed_id,
|
||||
'invoices' => '',
|
||||
'payment_date' => '2020/12/12',
|
||||
|
||||
];
|
||||
|
||||
|
||||
try {
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments?include=invoices', $data);
|
||||
|
||||
}
|
||||
catch(ValidationException $e) {
|
||||
\Log::error('in the validator');
|
||||
$message = json_decode($e->validator->getMessageBag(),1);
|
||||
\Log::error($message);
|
||||
$this->assertNotNull($message);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user