1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-29 20:57:11 +02:00

Merge branch 'v5-develop' into v5-stable

This commit is contained in:
David Bomba 2021-04-21 07:42:04 +10:00
commit 5b6d15e828
34 changed files with 2328 additions and 1340 deletions

View File

@ -48,11 +48,12 @@ jobs:
run: |
sudo rm -rf bootstrap/cache/*
sudo rm -rf node_modules
- name: Prune Git History
run: |
sudo git gc
sudo git gc --aggressive
sudo git prune
sudo rm -rf .git
# - name: Prune Git History
# run: |
# sudo git gc
# sudo git gc --aggressive
# sudo git prune
- name: Build project # This would actually build your project, using zip for an example artifact
run: |
zip -r ./invoiceninja.zip .* -x "../*"

View File

@ -1 +1 @@
5.1.48
5.1.49

View File

@ -0,0 +1,31 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Factory;
use App\Models\ClientGatewayToken;
use Illuminate\Support\Str;
class ClientGatewayTokenFactory
{
public static function create(int $company_id) :ClientGatewayToken
{
$client_gateway_token = new ClientGatewayToken;
$client_gateway_token->company_id = $company_id;
$client_gateway_token->is_default = false;
$client_gateway_token->meta = '';
$client_gateway_token->is_deleted = false;
$client_gateway_token->token = '';
$client_gateway_token->routing_number = '';
return $client_gateway_token;
}
}

View File

@ -0,0 +1,437 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers;
use App\Events\ClientGatewayToken\ClientGatewayTokenWasCreated;
use App\Events\ClientGatewayToken\ClientGatewayTokenWasUpdated;
use App\Factory\ClientGatewayTokenFactory;
use App\Filters\ClientGatewayTokenFilters;
use App\Http\Requests\ClientGatewayToken\CreateClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\DestroyClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\EditClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\ShowClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\StoreClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\UpdateClientGatewayTokenRequest;
use App\Http\Requests\ClientGatewayToken\UploadClientGatewayTokenRequest;
use App\Jobs\ClientGatewayToken\StoreClientGatewayToken;
use App\Jobs\ClientGatewayToken\UpdateClientGatewayToken;
use App\Models\Account;
use App\Models\ClientGatewayToken;
use App\Repositories\ClientGatewayTokenRepository;
use App\Transformers\ClientGatewayTokenTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SavesDocuments;
use App\Utils\Traits\Uploadable;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* Class ClientGatewayTokenController.
* @covers App\Http\Controllers\ClientGatewayTokenController
*/
class ClientGatewayTokenController extends BaseController
{
use MakesHash;
use Uploadable;
use BulkOptions;
use SavesDocuments;
protected $entity_type = ClientGatewayToken::class;
protected $entity_transformer = ClientGatewayTokenTransformer::class;
/**
* @var ClientGatewayTokenRepository
*/
protected $client_gateway_token_gateway_token_repo;
/**
* ClientGatewayTokenController constructor.
* @param ClientGatewayTokenRepository $client_gateway_token_gateway_token_repo
*/
public function __construct(ClientGatewayTokenRepository $client_gateway_token_gateway_token_repo)
{
parent::__construct();
$this->client_gateway_token_repo = $client_gateway_token_gateway_token_repo;
}
/**
* @OA\Get(
* path="/api/v1/client_gateway_tokens",
* operationId="getClientGatewayTokens",
* tags={"client_gateway_tokens"},
* summary="Gets a list of client_gateway_tokens",
* description="Lists client_gateway_tokens, search and filters allow fine grained lists to be generated.
Query parameters can be added to performed more fine grained filtering of the client_gateway_tokens, these are handled by the ClientGatewayTokenFilters class which defines the methods available",
* @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 client_gateway_tokens",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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"),
* ),
* )
* @param ClientGatewayTokenFilters $filters
* @return Response|mixed
*/
public function index(Request $request)
{
$client_gateway_token_gateway_tokens = ClientGatewayToken::scope();
return $this->listResponse($client_gateway_token_gateway_tokens);
}
/**
* Display the specified resource.
*
* @param ShowClientGatewayTokenRequest $request
* @param ClientGatewayToken $client_gateway_token
* @return Response
*
*
* @OA\Get(
* path="/api/v1/client_gateway_tokens/{id}",
* operationId="showClientGatewayToken",
* tags={"client_gateway_tokens"},
* summary="Shows a client",
* description="Displays a client by id",
* @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(
* name="id",
* in="path",
* description="The ClientGatewayToken Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the cl.ient object",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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 show(ShowClientGatewayTokenRequest $request, ClientGatewayToken $client_gateway_token)
{
return $this->itemResponse($client_gateway_token);
}
/**
* Show the form for editing the specified resource.
*
* @param EditClientGatewayTokenRequest $request
* @param ClientGatewayToken $client_gateway_token
* @return Response
*
*
* @OA\Get(
* path="/api/v1/client_gateway_tokens/{id}/edit",
* operationId="editClientGatewayToken",
* tags={"client_gateway_tokens"},
* summary="Shows a client for editting",
* description="Displays a client by id",
* @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(
* name="id",
* in="path",
* description="The ClientGatewayToken Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the client object",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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 edit(EditClientGatewayTokenRequest $request, ClientGatewayToken $client_gateway_token)
{
return $this->itemResponse($client_gateway_token);
}
/**
* Update the specified resource in storage.
*
* @param UpdateClientGatewayTokenRequest $request
* @param ClientGatewayToken $client_gateway_token
* @return Response
*
*
*
* @OA\Put(
* path="/api/v1/client_gateway_tokens/{id}",
* operationId="updateClientGatewayToken",
* tags={"client_gateway_tokens"},
* summary="Updates a client",
* description="Handles the updating of a client by id",
* @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(
* name="id",
* in="path",
* description="The ClientGatewayToken Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the client object",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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 update(UpdateClientGatewayTokenRequest $request, ClientGatewayToken $client_gateway_token)
{
$client_gateway_token = $this->client_gateway_token_repo->save($request->all(), $client_gateway_token);
return $this->itemResponse($client_gateway_token->fresh());
}
/**
* Show the form for creating a new resource.
*
* @param CreateClientGatewayTokenRequest $request
* @return Response
*
*
*
* @OA\Get(
* path="/api/v1/client_gateway_tokens/create",
* operationId="getClientGatewayTokensCreate",
* tags={"client_gateway_tokens"},
* summary="Gets a new blank client object",
* description="Returns a blank object with default values",
* @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\Response(
* response=200,
* description="A blank client object",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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 create(CreateClientGatewayTokenRequest $request)
{
$client_gateway_token = ClientGatewayTokenFactory::create(auth()->user()->company()->id);
$client_gateway_token = $this->client_gateway_token_repo->save($request->all(), $client_gateway_token);
return $this->itemResponse($client_gateway_token);
}
/**
* Store a newly created resource in storage.
*
* @param StoreClientGatewayTokenRequest $request
* @return Response
*
*
*
* @OA\Post(
* path="/api/v1/client_gateway_tokens",
* operationId="storeClientGatewayToken",
* tags={"client_gateway_tokens"},
* summary="Adds a client",
* description="Adds an client to a company",
* @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\Response(
* response=200,
* description="Returns the saved client object",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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/ClientGatewayToken"),
* ),
* @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 store(StoreClientGatewayTokenRequest $request)
{
$client_gateway_token = ClientGatewayTokenFactory::create(auth()->user()->company()->id);
$client_gateway_token = $this->client_gateway_token_repo->save($request->all(), $client_gateway_token);
return $this->itemResponse($client_gateway_token);
}
/**
* Remove the specified resource from storage.
*
* @param DestroyClientGatewayTokenRequest $request
* @param ClientGatewayToken $client_gateway_token
* @return Response
*
*
* @throws \Exception
* @OA\Delete(
* path="/api/v1/client_gateway_tokens/{id}",
* operationId="deleteClientGatewayToken",
* tags={"client_gateway_tokens"},
* summary="Deletes a client",
* description="Handles the deletion of a client by id",
* @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(
* name="id",
* in="path",
* description="The ClientGatewayToken Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns a HTTP status",
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-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\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 destroy(DestroyClientGatewayTokenRequest $request, ClientGatewayToken $client_gateway_token)
{
$this->client_gateway_token_repo->delete($client_gateway_token);
return $this->itemResponse($client_gateway_token->fresh());
}
}

View File

@ -81,6 +81,7 @@ class LicenseController extends BaseController
*/
public function index()
{
$this->checkLicense();
/* Catch claim license requests */
if (config('ninja.environment') == 'selfhost' && request()->has('license_key')) {
@ -140,4 +141,15 @@ class LicenseController extends BaseController
return response()->json($error, 400);
}
private function checkLicense()
{
$account = auth()->user()->company()->account;
if($account->plan == 'white_label' && $account->plan_expires->lt(now())){
$account->plan = null;
$account->plan_expires = null;
$account->save();
}
}
}

View File

@ -165,6 +165,10 @@ class MigrationController extends BaseController
{
$company->clients()->forceDelete();
$company->products()->forceDelete();
$company->projects()->forceDelete();
$company->tasks()->forceDelete();
$company->vendors()->forceDelete();
$company->expenses()->forceDelete();
$company->save();

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\Http\Requests\Request;
use App\Models\ClientGatewayToken;
class CreateClientGatewayTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\Http\Requests\Request;
class DestroyClientGatewayTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\Http\Requests\Request;
class EditClientGatewayTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\Http\Requests\Request;
class ShowClientGatewayTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\DataMapper\ClientSettings;
use App\Http\Requests\Request;
use App\Http\ValidationRules\Ninja\CanStoreClientsRule;
use App\Http\ValidationRules\ValidClientGroupSettingsRule;
use App\Models\Client;
use App\Models\GroupSetting;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\Rule;
class StoreClientGatewayTokenRequest extends Request
{
use MakesHash;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
public function rules()
{
$rules = [
'client_id' => 'required',
'company_gateway_id' => 'required',
'gateway_type_id' => 'required|integer',
'meta' => 'required',
];
return $this->globalRules($rules);
}
protected function prepareForValidation()
{
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
$this->replace($input);
}
public function messages()
{
return [
];
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientGatewayToken;
use App\DataMapper\CompanySettings;
use App\Http\Requests\Request;
use App\Http\ValidationRules\ValidClientGroupSettingsRule;
use App\Utils\Traits\ChecksEntityStatus;
use App\Utils\Traits\MakesHash;
use Illuminate\Validation\Rule;
class UpdateClientGatewayTokenRequest extends Request
{
use MakesHash;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
public function rules()
{
/* Ensure we have a client name, and that all emails are unique*/
$rules = [];
return $rules;
}
public function messages()
{
return [
];
}
protected function prepareForValidation()
{
$input = $this->all();
$this->replace($input);
}
}

View File

@ -106,6 +106,10 @@ class Request extends FormRequest
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
}
if (array_key_exists('company_gateway_id', $input) && is_string($input['company_gateway_id'])) {
$input['company_gateway_id'] = $this->decodePrimaryKey($input['company_gateway_id']);
}
if (isset($input['client_contacts'])) {
foreach ($input['client_contacts'] as $key => $contact) {
if (! array_key_exists('send_email', $contact) || ! array_key_exists('id', $contact)) {

View File

@ -12,6 +12,7 @@
namespace App\Jobs\Util;
use App\Models\Account;
use App\Utils\Ninja;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@ -40,5 +41,16 @@ class VersionCheck implements ShouldQueue
if ($version_file) {
Account::whereNotNull('id')->update(['latest_version' => $version_file]);
}
if(Ninja::isSelfHost())
{
$account = Account::first();
if($account->plan == 'white_label' && $account->plan_expires->lt(now())){
$account->plan = null;
$account->plan_expires = null;
$account->save();
}
}
}
}

View File

@ -29,6 +29,14 @@ class ClientGatewayToken extends BaseModel
'hashed_id',
];
protected $fillable = [
'token',
'routing_number',
'gateway_customer_reference',
'gateway_type_id',
'meta',
];
public function getEntityType()
{
return self::class;

View File

@ -397,7 +397,7 @@ class Invoice extends BaseModel
$storage_path = Storage::$type($this->client->invoice_filepath().$this->numberFormatter().'.pdf');
if (! Storage::exists($this->client->invoice_filepath().$this->numberFormatter().'.pdf')) {
event(new InvoiceWasUpdated($this, $this->company, Ninja::eventVars(auth()->user()->id)));
event(new InvoiceWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
CreateEntityPdf::dispatchNow($invitation);
}

View File

@ -143,7 +143,7 @@ class InvoiceInvitation extends BaseModel
$storage_path = Storage::url($this->invoice->client->invoice_filepath().$this->invoice->numberFormatter().'.pdf');
if (! Storage::exists($this->invoice->client->invoice_filepath().$this->invoice->numberFormatter().'.pdf')) {
event(new InvoiceWasUpdated($this->invoice, $this->company, Ninja::eventVars(auth()->user()->id)));
event(new InvoiceWasUpdated($this->invoice, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
CreateEntityPdf::dispatchNow($this);
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Repositories;
use App\Models\ClientGatewayToken;
/**
* Class for ClientGatewayTokenRepository .
*/
class ClientGatewayTokenRepository extends BaseRepository
{
public function save(array $data, ClientGatewayToken $client_gateway_token) :ClientGatewayToken
{
$client_gateway_token->fill($data);
$client_gateway_token->save();
return $client_gateway_token->fresh();
}
}

View File

@ -144,11 +144,11 @@ class ApplyPayment
->ledger()
->updateCreditBalance(($this->amount_applied * -1), "Credit payment applied to Invoice {$this->invoice->number}");
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user()->id)));
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
if ((int)$this->invoice->balance == 0) {
$this->invoice->service()->deletePdf();
event(new InvoiceWasPaid($this->invoice, $this->payment, $this->payment->company, Ninja::eventVars(auth()->user()->id)));
event(new InvoiceWasPaid($this->invoice, $this->payment, $this->payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
}
}
}

View File

@ -87,7 +87,7 @@ class UpdateInvoicePayment
InvoiceWorkflowSettings::dispatchNow($invoice);
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars()));
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
});
$this->payment->save();

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', ''),
'app_version' => '5.1.48',
'app_tag' => '5.1.48-release',
'app_version' => '5.1.49',
'app_tag' => '5.1.49-release',
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because it is too large Load Diff

View File

@ -37,6 +37,8 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
Route::put('clients/{client}/upload', 'ClientController@upload')->name('clients.upload');
Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
Route::resource('client_gateway_tokens', 'ClientGatewayTokenController');
Route::post('connected_account', 'ConnectedAccountController@index');
Route::post('connected_account/gmail', 'ConnectedAccountController@handleGmailOauth');

View File

@ -0,0 +1,181 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace Tests\Feature;
use App\Models\CompanyGateway;
use App\Models\GatewayType;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
* @covers App\Http\Controllers\ClientGatewayTokenController
*/
class ClientGatewayTokenApiTest extends TestCase
{
use MakesHash;
use DatabaseTransactions;
use MockAccountData;
public function setUp() :void
{
parent::setUp();
$this->withoutMiddleware(
ThrottleRequests::class
);
if (! config('ninja.testvars.stripe')) {
$this->markTestSkipped('Skip test no company gateways installed');
}
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->makeTestData();
$this->withoutExceptionHandling();
CompanyGateway::whereNotNull('id')->delete();
$data = [];
$data[1]['min_limit'] = -1;
$data[1]['max_limit'] = -1;
$data[1]['fee_amount'] = 0.00;
$data[1]['fee_percent'] = 2;
$data[1]['fee_tax_name1'] = 'GST';
$data[1]['fee_tax_rate1'] = 10;
$data[1]['fee_tax_name2'] = 'GST';
$data[1]['fee_tax_rate2'] = 10;
$data[1]['fee_tax_name3'] = 'GST';
$data[1]['fee_tax_rate3'] = 10;
$data[1]['adjust_fee_percent'] = true;
$data[1]['fee_cap'] = 0;
$data[1]['is_enabled'] = true;
$data[2]['min_limit'] = -1;
$data[2]['max_limit'] = -1;
$data[2]['fee_amount'] = 0.00;
$data[2]['fee_percent'] = 1;
$data[2]['fee_tax_name1'] = 'GST';
$data[2]['fee_tax_rate1'] = 10;
$data[2]['fee_tax_name2'] = 'GST';
$data[2]['fee_tax_rate2'] = 10;
$data[2]['fee_tax_name3'] = 'GST';
$data[2]['fee_tax_rate3'] = 10;
$data[2]['adjust_fee_percent'] = true;
$data[2]['fee_cap'] = 0;
$data[2]['is_enabled'] = true;
//disable ach here
$json_config = json_decode(config('ninja.testvars.stripe'));
$this->cg = new CompanyGateway;
$this->cg->company_id = $this->company->id;
$this->cg->user_id = $this->user->id;
$this->cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23';
$this->cg->require_cvv = true;
$this->cg->require_billing_address = true;
$this->cg->require_shipping_address = true;
$this->cg->update_details = true;
$this->cg->config = encrypt(json_encode($json_config));
$this->cg->fees_and_limits = $data;
$this->cg->save();
}
public function testClientGatewayPostPost()
{
$data = [
'client_id' => $this->client->hashed_id,
'company_gateway_id' => $this->cg->hashed_id,
'gateway_type_id' => GatewayType::CREDIT_CARD,
'meta' => '{}',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/client_gateway_tokens', $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertNotNull($arr['data']['token']);
}
public function testClientPut()
{
$data = [
'client_id' => $this->client->hashed_id,
'company_gateway_id' => $this->cg->hashed_id,
'gateway_type_id' => GatewayType::CREDIT_CARD,
'meta' => '{}',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/client_gateway_tokens', $data);
$arr = $response->json();
$response->assertStatus(200);
$data = [
'token' => 'a_testy_token',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/client_gateway_tokens/'.$arr['data']['id'], $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals('a_testy_token', $arr['data']['token']);
}
public function testClientGet()
{
$data = [
'client_id' => $this->client->hashed_id,
'company_gateway_id' => $this->cg->hashed_id,
'gateway_type_id' => GatewayType::CREDIT_CARD,
'meta' => '{}',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/client_gateway_tokens', $data);
$arr = $response->json();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/client_gateway_tokens/'.$arr['data']['id']);
$response->assertStatus(200);
}
}