mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge branch 'v5-develop' into v5-develop
This commit is contained in:
commit
2a1667605d
@ -1 +1 @@
|
|||||||
5.6.28
|
5.6.30
|
@ -812,14 +812,14 @@ class CompanySettings extends BaseSettings
|
|||||||
* need to provide a fallback catch on old settings objects which will
|
* need to provide a fallback catch on old settings objects which will
|
||||||
* set new properties to the object prior to being returned.
|
* set new properties to the object prior to being returned.
|
||||||
*
|
*
|
||||||
* @param $settings
|
* @param \stdClass $settings
|
||||||
*
|
*
|
||||||
* @return stdClass
|
* @return stdClass
|
||||||
*/
|
*/
|
||||||
public static function setProperties($settings): stdClass
|
public static function setProperties($settings): stdClass
|
||||||
{
|
{
|
||||||
$company_settings = (object) get_class_vars(self::class);
|
$company_settings = (object) get_class_vars(self::class);
|
||||||
|
|
||||||
foreach ($company_settings as $key => $value) {
|
foreach ($company_settings as $key => $value) {
|
||||||
if (! property_exists($settings, $key)) {
|
if (! property_exists($settings, $key)) {
|
||||||
$settings->{$key} = self::castAttribute($key, $company_settings->{$key});
|
$settings->{$key} = self::castAttribute($key, $company_settings->{$key});
|
||||||
|
45
app/Events/Vendor/VendorContactLoggedIn.php
vendored
Normal file
45
app/Events/Vendor/VendorContactLoggedIn.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Events\Vendor;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorContactLoggedIn.
|
||||||
|
*/
|
||||||
|
class VendorContactLoggedIn
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct(public VendorContact $contact, public Company $company, public array $event_vars)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channels the event should broadcast on.
|
||||||
|
*
|
||||||
|
* @return Channel|array
|
||||||
|
*/
|
||||||
|
public function broadcastOn()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Filters;
|
namespace App\Filters;
|
||||||
|
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,6 +118,8 @@ class PaymentFilters extends QueryFilters
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of payments that can be matched to bank transactions
|
* Returns a list of payments that can be matched to bank transactions
|
||||||
|
* @param ?string $value
|
||||||
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public function match_transactions($value = 'true'): Builder
|
public function match_transactions($value = 'true'): Builder
|
||||||
{
|
{
|
||||||
@ -124,7 +127,7 @@ class PaymentFilters extends QueryFilters
|
|||||||
if ($value == 'true') {
|
if ($value == 'true') {
|
||||||
return $this->builder
|
return $this->builder
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->where(function ($query) {
|
->where(function (Builder $query) {
|
||||||
$query->whereNull('transaction_id')
|
$query->whereNull('transaction_id')
|
||||||
->orWhere("transaction_id", "")
|
->orWhere("transaction_id", "")
|
||||||
->company();
|
->company();
|
||||||
|
@ -127,8 +127,7 @@ class UserFilters extends QueryFilters
|
|||||||
$user_array = $this->transformKeys(explode(',', $user_id));
|
$user_array = $this->transformKeys(explode(',', $user_id));
|
||||||
|
|
||||||
return $this->builder->where(function ($query) use ($user_array) {
|
return $this->builder->where(function ($query) use ($user_array) {
|
||||||
$query->whereNotIn('id', $user_array)
|
$query->whereNotIn('id', $user_array);
|
||||||
->where('account_id', auth()->user()->account_id);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
111
app/Helpers/Bank/Yodlee/DTO/AccountSummary.php
Normal file
111
app/Helpers/Bank/Yodlee/DTO/AccountSummary.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Helpers\Bank\Yodlee\DTO;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
|
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [
|
||||||
|
"account": [
|
||||||
|
[
|
||||||
|
"CONTAINER": "bank",
|
||||||
|
"providerAccountId": 1005,
|
||||||
|
"accountName": "Business Acct",
|
||||||
|
"accountStatus": "ACTIVE",
|
||||||
|
"accountNumber": "1011",
|
||||||
|
"aggregationSource": "USER",
|
||||||
|
"isAsset": true,
|
||||||
|
"balance": [
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 304.98,
|
||||||
|
],
|
||||||
|
"id": 10139315,
|
||||||
|
"includeInNetWorth": true,
|
||||||
|
"providerId": "3857",
|
||||||
|
"providerName": "Bank",
|
||||||
|
"isManual": false,
|
||||||
|
"availableBalance": {#2966
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 304.98,
|
||||||
|
],
|
||||||
|
"currentBalance": [
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 3044.98,
|
||||||
|
],
|
||||||
|
"accountType": "CHECKING",
|
||||||
|
"displayedName": "after David",
|
||||||
|
"createdDate": "2023-01-10T08:29:07Z",
|
||||||
|
"classification": "SMALL_BUSINESS",
|
||||||
|
"lastUpdated": "2023-08-01T23:50:13Z",
|
||||||
|
"nickname": "Business ",
|
||||||
|
"bankTransferCode": [
|
||||||
|
[
|
||||||
|
"id": "062",
|
||||||
|
"type": "BSB",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"dataset": [
|
||||||
|
[
|
||||||
|
"name": "BASIC_AGG_DATA",
|
||||||
|
"additionalStatus": "AVAILABLE_DATA_RETRIEVED",
|
||||||
|
"updateEligibility": "ALLOW_UPDATE",
|
||||||
|
"lastUpdated": "2023-08-01T23:49:53Z",
|
||||||
|
"lastUpdateAttempt": "2023-08-01T23:49:53Z",
|
||||||
|
"nextUpdateScheduled": "2023-08-03T14:45:14Z",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
class AccountSummary extends Data
|
||||||
|
{
|
||||||
|
public ?int $id;
|
||||||
|
|
||||||
|
#[MapInputName('CONTAINER')]
|
||||||
|
public ?string $account_type = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountName')]
|
||||||
|
public ?string $account_name = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountStatus')]
|
||||||
|
public ?string $account_status = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountNumber')]
|
||||||
|
public ?string $account_number = '';
|
||||||
|
|
||||||
|
#[MapInputName('providerAccountId')]
|
||||||
|
public int $provider_account_id;
|
||||||
|
|
||||||
|
#[MapInputName('providerId')]
|
||||||
|
public ?string $provider_id = '';
|
||||||
|
|
||||||
|
#[MapInputName('providerName')]
|
||||||
|
public ?string $provider_name = '';
|
||||||
|
|
||||||
|
public ?string $nickname = '';
|
||||||
|
|
||||||
|
public ?float $current_balance = 0;
|
||||||
|
public ?string $account_currency = '';
|
||||||
|
|
||||||
|
public static function prepareForPipeline(Collection $properties) : Collection
|
||||||
|
{
|
||||||
|
|
||||||
|
$properties->put('current_balance', $properties['currentBalance']['amount'] ?? 0);
|
||||||
|
$properties->put('account_currency', $properties['currentBalance']['currency'] ?? 0);
|
||||||
|
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
}
|
@ -64,6 +64,7 @@ use App\Helpers\Bank\AccountTransformerInterface;
|
|||||||
|
|
||||||
class AccountTransformer implements AccountTransformerInterface
|
class AccountTransformer implements AccountTransformerInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
public function transform($yodlee_account)
|
public function transform($yodlee_account)
|
||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
@ -93,13 +94,54 @@ class AccountTransformer implements AccountTransformerInterface
|
|||||||
$account_currency = $account->balance->currency ?? '';
|
$account_currency = $account->balance->currency ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$account_status = $account->accountStatus;
|
||||||
|
|
||||||
|
if(property_exists($account, 'dataset')){
|
||||||
|
$dataset = $account->dataset[0];
|
||||||
|
$status = false;
|
||||||
|
$update = false;
|
||||||
|
|
||||||
|
match($dataset->additionalStatus ?? ''){
|
||||||
|
'LOGIN_IN_PROGRESS' => $status = 'Data retrieval in progress.',
|
||||||
|
'USER_INPUT_REQUIRED' => $status = 'Please reconnect your account, authentication required.',
|
||||||
|
'LOGIN_SUCCESS' => $status = 'Data retrieval in progress',
|
||||||
|
'ACCOUNT_SUMMARY_RETRIEVED' => $status = 'Account summary retrieval in progress.',
|
||||||
|
'NEVER_INITIATED' => $status = 'Upstream working on connecting to your account.',
|
||||||
|
'LOGIN_FAILED' => $status = 'Authentication failed, please try reauthenticating.',
|
||||||
|
'REQUEST_TIME_OUT' => $status = 'Timeout encountered retrieving data.',
|
||||||
|
'DATA_RETRIEVAL_FAILED' => $status = 'Login successful, but data retrieval failed.',
|
||||||
|
'PARTIAL_DATA_RETRIEVED' => $status = 'Partial data update failed.',
|
||||||
|
'PARTIAL_DATA_RETRIEVED_REM_SCHED' => $status = 'Partial data update failed.',
|
||||||
|
'SUCCESS' => $status = 'All accounts added or updated successfully.',
|
||||||
|
default => $status = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if($status){
|
||||||
|
$account_status = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
match($dataset->updateEligibility ?? ''){
|
||||||
|
'ALLOW_UPDATE' => $update = 'Account connection stable.',
|
||||||
|
'ALLOW_UPDATE_WITH_CREDENTIALS' => $update = 'Please reconnect your account with updated credentials.',
|
||||||
|
'DISALLOW_UPDATE' => $update = 'Update not available due to technical issues.',
|
||||||
|
default => $update = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if($status && $update){
|
||||||
|
$account_status = $status . ' - ' . $update;
|
||||||
|
}
|
||||||
|
elseif($update){
|
||||||
|
$account_status = $update;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $account->id,
|
'id' => $account->id,
|
||||||
'account_type' => $account->CONTAINER,
|
'account_type' => $account->CONTAINER,
|
||||||
// 'account_name' => $account->accountName,
|
// 'account_name' => $account->accountName,
|
||||||
'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
|
'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
|
||||||
'account_status' => $account->accountStatus,
|
'account_status' => $account_status,
|
||||||
'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
|
'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
|
||||||
'provider_account_id' => $account->providerAccountId,
|
'provider_account_id' => $account->providerAccountId,
|
||||||
'provider_id' => $account->providerId,
|
'provider_id' => $account->providerId,
|
||||||
|
@ -297,4 +297,71 @@ class Yodlee
|
|||||||
'secret' => $this->client_secret,
|
'secret' => $this->client_secret,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updateEligibility
|
||||||
|
*
|
||||||
|
* ALLOW_UPDATE
|
||||||
|
* ALLOW_UPDATE_WITH_CREDENTIALS
|
||||||
|
* DISALLOW_UPDATE
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* additionalStatus
|
||||||
|
*
|
||||||
|
* LOGIN_IN_PROGRESS
|
||||||
|
* DATA_RETRIEVAL_IN_PROGRESS
|
||||||
|
* ACCT_SUMMARY_RECEIVED
|
||||||
|
* AVAILABLE_DATA_RETRIEVED
|
||||||
|
* PARTIAL_DATA_RETRIEVED
|
||||||
|
* DATA_RETRIEVAL_FAILED
|
||||||
|
* DATA_NOT_AVAILABLE
|
||||||
|
* ACCOUNT_LOCKED
|
||||||
|
* ADDL_AUTHENTICATION_REQUIRED
|
||||||
|
* BETA_SITE_DEV_IN_PROGRESS
|
||||||
|
* CREDENTIALS_UPDATE_NEEDED
|
||||||
|
* INCORRECT_CREDENTIALS
|
||||||
|
* PROPERTY_VALUE_NOT_AVAILABLE
|
||||||
|
* INVALID_ADDL_INFO_PROVIDED
|
||||||
|
* REQUEST_TIME_OUT
|
||||||
|
* SITE_BLOCKING_ERROR
|
||||||
|
* UNEXPECTED_SITE_ERROR
|
||||||
|
* SITE_NOT_SUPPORTED
|
||||||
|
* SITE_UNAVAILABLE
|
||||||
|
* TECH_ERROR
|
||||||
|
* USER_ACTION_NEEDED_AT_SITE
|
||||||
|
* SITE_SESSION_INVALIDATED
|
||||||
|
* NEW_AUTHENTICATION_REQUIRED
|
||||||
|
* DATASET_NOT_SUPPORTED
|
||||||
|
* ENROLLMENT_REQUIRED_FOR_DATASET
|
||||||
|
* CONSENT_REQUIRED
|
||||||
|
* CONSENT_EXPIRED
|
||||||
|
* CONSENT_REVOKED
|
||||||
|
* INCORRECT_OAUTH_TOKEN
|
||||||
|
* MIGRATION_IN_PROGRESS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IN_PROGRESS LOGIN_IN_PROGRESS Provider login is in progress.
|
||||||
|
* IN_PROGRESS USER_INPUT_REQUIRED Provider site requires MFA-based authentication and needs user input for login.
|
||||||
|
* IN_PROGRESS LOGIN_SUCCESS Provider login is successful.
|
||||||
|
* IN_PROGRESS ACCOUNT_SUMMARY_RETRIEVED Account summary info may not have the complete info of accounts that are available in the provider site. This depends on the sites behaviour. Account summary info may not be available at all times.
|
||||||
|
* FAILED NEVER_INITIATED The add or update provider account was not triggered due to techincal reasons. This is a rare occurrence and usually resolves quickly.
|
||||||
|
* FAILED LOGIN_FAILED Provider login failed.
|
||||||
|
* FAILED REQUEST_TIME_OUT The process timed out.
|
||||||
|
* FAILED DATA_RETRIEVAL_FAILED All accounts under the provider account failed with same or different errors, though login was successful.
|
||||||
|
* FAILED No additional status or information will be provided when there are errors other than the ones listed above.
|
||||||
|
* PARTIAL_SUCCESS PARTIAL_DATA_RETRIEVED DATA_RETRIEVAL_FAILED_PARTIALLY One/few accounts data gathered and one/few accounts failed.
|
||||||
|
* PARTIAL_SUCCESS PARTIAL_DATA_RETRIEVED_REM_SCHED DATA_RETRIEVAL_FAILED_PARTIALLY One/few accounts data gathered One/few accounts failed
|
||||||
|
* SUCCESS All accounts under the provider was added or updated successfully.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updateEligibility
|
||||||
|
*
|
||||||
|
* ALLOW_UPDATE The status indicates that the account is eligible for the next update and applies to both MFA and non-MFA accounts. For MFA-based accounts, the user may have to provide the MFA details during account refresh.
|
||||||
|
* ALLOW_UPDATE_WITH_CREDENTIALS The status indicates updating or refreshing the account by directing the user to edit the provided credentials.
|
||||||
|
* DISALLOW_UPDATE The status indicates the account is not eligible for the update or refresh process due to a site issue or a technical error.
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Bank;
|
namespace App\Http\Controllers\Bank;
|
||||||
|
|
||||||
|
use App\Helpers\Bank\Yodlee\DTO\AccountSummary;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\BankIntegration;
|
||||||
use App\Helpers\Bank\Yodlee\Yodlee;
|
use App\Helpers\Bank\Yodlee\Yodlee;
|
||||||
use App\Http\Controllers\BaseController;
|
use App\Http\Controllers\BaseController;
|
||||||
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
|
||||||
use App\Jobs\Bank\ProcessBankTransactions;
|
use App\Jobs\Bank\ProcessBankTransactions;
|
||||||
use App\Models\BankIntegration;
|
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
||||||
use Illuminate\Http\Request;
|
use App\Http\Requests\Yodlee\YodleeAdminRequest;
|
||||||
|
|
||||||
class YodleeController extends BaseController
|
class YodleeController extends BaseController
|
||||||
{
|
{
|
||||||
@ -277,4 +279,27 @@ class YodleeController extends BaseController
|
|||||||
|
|
||||||
// return response()->json(['message' => 'Unauthorized'], 403);
|
// return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function accountStatus(YodleeAdminRequest $request, $account_number)
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$bank_integration = BankIntegration::query()
|
||||||
|
->withTrashed()
|
||||||
|
->where('company_id', $user->company()->id)
|
||||||
|
->where('account_id', $account_number)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if(!$bank_integration)
|
||||||
|
return response()->json(['message' => 'Account does not exist.'], 400);
|
||||||
|
|
||||||
|
$yodlee = new Yodlee($user->account->bank_integration_account_id);
|
||||||
|
|
||||||
|
$summary = $yodlee->getAccountSummary($account_number);
|
||||||
|
|
||||||
|
$transformed_summary = AccountSummary::from($summary[0]);
|
||||||
|
|
||||||
|
return response()->json($transformed_summary, 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,30 +11,31 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Client\ClientWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Client\ClientWasUpdated;
|
use App\Models\Client;
|
||||||
|
use App\Models\Account;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use App\Factory\ClientFactory;
|
use App\Factory\ClientFactory;
|
||||||
use App\Filters\ClientFilters;
|
use App\Filters\ClientFilters;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Jobs\Client\UpdateTaxData;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Repositories\ClientRepository;
|
||||||
|
use App\Events\Client\ClientWasCreated;
|
||||||
|
use App\Events\Client\ClientWasUpdated;
|
||||||
|
use App\Transformers\ClientTransformer;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use App\Http\Requests\Client\BulkClientRequest;
|
use App\Http\Requests\Client\BulkClientRequest;
|
||||||
use App\Http\Requests\Client\CreateClientRequest;
|
|
||||||
use App\Http\Requests\Client\DestroyClientRequest;
|
|
||||||
use App\Http\Requests\Client\EditClientRequest;
|
use App\Http\Requests\Client\EditClientRequest;
|
||||||
use App\Http\Requests\Client\PurgeClientRequest;
|
|
||||||
use App\Http\Requests\Client\ShowClientRequest;
|
use App\Http\Requests\Client\ShowClientRequest;
|
||||||
|
use App\Http\Requests\Client\PurgeClientRequest;
|
||||||
use App\Http\Requests\Client\StoreClientRequest;
|
use App\Http\Requests\Client\StoreClientRequest;
|
||||||
|
use App\Http\Requests\Client\CreateClientRequest;
|
||||||
use App\Http\Requests\Client\UpdateClientRequest;
|
use App\Http\Requests\Client\UpdateClientRequest;
|
||||||
use App\Http\Requests\Client\UploadClientRequest;
|
use App\Http\Requests\Client\UploadClientRequest;
|
||||||
use App\Models\Account;
|
use App\Http\Requests\Client\DestroyClientRequest;
|
||||||
use App\Models\Client;
|
|
||||||
use App\Repositories\ClientRepository;
|
|
||||||
use App\Transformers\ClientTransformer;
|
|
||||||
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\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ClientController.
|
* Class ClientController.
|
||||||
@ -285,4 +286,18 @@ class ClientController extends BaseController
|
|||||||
|
|
||||||
return $this->itemResponse($merged_client);
|
return $this->itemResponse($merged_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the client's tax data
|
||||||
|
*
|
||||||
|
* @param PurgeClientRequest $request
|
||||||
|
* @param Client $client
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function updateTaxData(PurgeClientRequest $request, Client $client)
|
||||||
|
{
|
||||||
|
(new UpdateTaxData($client, $client->company))->handle();
|
||||||
|
|
||||||
|
return $this->itemResponse($client->fresh());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,26 +11,27 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Events\Credit\CreditWasViewed;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Invoice\InvoiceWasViewed;
|
use App\Models\Client;
|
||||||
use App\Events\Misc\InvitationWasViewed;
|
use App\Models\Payment;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\QuoteInvitation;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Models\CreditInvitation;
|
||||||
|
use App\Utils\Traits\MakesDates;
|
||||||
|
use App\Jobs\Entity\CreateRawPdf;
|
||||||
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Events\Quote\QuoteWasViewed;
|
use App\Events\Quote\QuoteWasViewed;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Jobs\Entity\CreateRawPdf;
|
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\ClientContact;
|
|
||||||
use App\Models\CreditInvitation;
|
|
||||||
use App\Models\InvoiceInvitation;
|
|
||||||
use App\Models\Payment;
|
|
||||||
use App\Models\PurchaseOrderInvitation;
|
|
||||||
use App\Models\QuoteInvitation;
|
|
||||||
use App\Services\ClientPortal\InstantPayment;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesDates;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Str;
|
use App\Events\Credit\CreditWasViewed;
|
||||||
|
use App\Events\Contact\ContactLoggedIn;
|
||||||
|
use App\Models\PurchaseOrderInvitation;
|
||||||
|
use App\Events\Invoice\InvoiceWasViewed;
|
||||||
|
use App\Events\Misc\InvitationWasViewed;
|
||||||
|
use App\Services\ClientPortal\InstantPayment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvitationController.
|
* Class InvitationController.
|
||||||
@ -94,6 +95,7 @@ class InvitationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$client_contact = $invitation->contact;
|
$client_contact = $invitation->contact;
|
||||||
|
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars()));
|
||||||
|
|
||||||
if (empty($client_contact->email)) {
|
if (empty($client_contact->email)) {
|
||||||
$client_contact->email = Str::random(15) . "@example.com";
|
$client_contact->email = Str::random(15) . "@example.com";
|
||||||
|
@ -11,38 +11,39 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\DataMapper\Analytics\AccountDeleted;
|
use Str;
|
||||||
use App\DataMapper\CompanySettings;
|
use App\Utils\Ninja;
|
||||||
use App\Http\Requests\Company\CreateCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\DefaultCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\DestroyCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\EditCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\ShowCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\StoreCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\UploadCompanyRequest;
|
|
||||||
use App\Jobs\Company\CreateCompany;
|
|
||||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
|
||||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
|
||||||
use App\Jobs\Company\CreateCompanyToken;
|
|
||||||
use App\Jobs\Mail\NinjaMailerJob;
|
|
||||||
use App\Jobs\Mail\NinjaMailerObject;
|
|
||||||
use App\Mail\Company\CompanyDeleted;
|
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyUser;
|
use App\Models\CompanyUser;
|
||||||
use App\Repositories\CompanyRepository;
|
|
||||||
use App\Transformers\CompanyTransformer;
|
|
||||||
use App\Transformers\CompanyUserTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use App\Utils\Traits\Uploadable;
|
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Str;
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Jobs\Company\CreateCompany;
|
||||||
|
use App\Jobs\Company\CompanyTaxRate;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Mail\Company\CompanyDeleted;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
use App\Repositories\CompanyRepository;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
|
use App\Transformers\CompanyTransformer;
|
||||||
|
use App\DataMapper\Analytics\AccountDeleted;
|
||||||
|
use App\Transformers\CompanyUserTransformer;
|
||||||
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||||
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
|
use App\Http\Requests\Company\EditCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\ShowCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\StoreCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\CreateCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\UploadCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\DefaultCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\DestroyCompanyRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CompanyController.
|
* Class CompanyController.
|
||||||
@ -679,4 +680,21 @@ class CompanyController extends BaseController
|
|||||||
|
|
||||||
return $this->itemResponse($company->fresh());
|
return $this->itemResponse($company->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateOriginTaxData(DefaultCompanyRequest $request, Company $company)
|
||||||
|
{
|
||||||
|
|
||||||
|
if($company->settings->country_id == "840" && !$company?->account->isFreeHostedClient())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
(new CompanyTaxRate($company))->handle();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return response()->json(['message' => 'There was a problem updating the tax rates. Please try again.'], 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return response()->json(['message' => 'Tax configuration not available due to settings / plan restriction.'], 400);
|
||||||
|
|
||||||
|
return $this->itemResponse($company->fresh());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ class MigrationController extends BaseController
|
|||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$company_count = $user->account->companies()->count();
|
$company_count = $user->account->companies()->count();
|
||||||
|
$fresh_company = false;
|
||||||
|
|
||||||
// Look for possible existing company (based on company keys).
|
// Look for possible existing company (based on company keys).
|
||||||
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first();
|
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first();
|
||||||
|
@ -74,6 +74,7 @@ class OneTimeTokenController extends BaseController
|
|||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_key'=> $user->company()->company_key,
|
'company_key'=> $user->company()->company_key,
|
||||||
'context' => $request->input('context'),
|
'context' => $request->input('context'),
|
||||||
|
'is_react' => $request->has('react') && $request->query('react') == 'true' ? true : false,
|
||||||
];
|
];
|
||||||
|
|
||||||
Cache::put($hash, $data, 3600);
|
Cache::put($hash, $data, 3600);
|
||||||
|
@ -181,8 +181,8 @@ class PreviewPurchaseOrderController extends BaseController
|
|||||||
DB::connection(config('database.default'))->beginTransaction();
|
DB::connection(config('database.default'))->beginTransaction();
|
||||||
|
|
||||||
if ($request->has('entity_id')) {
|
if ($request->has('entity_id')) {
|
||||||
/** @var \App\Models\PurchaseOrder|\Illuminate\Database\Eloquent\Builder $entity_obj **/
|
/** @var \App\Models\PurchaseOrder|\Illuminate\Contracts\Database\Eloquent\Builder $entity_obj **/
|
||||||
$entity_obj = $class::on(config('database.default'))
|
$entity_obj = \App\Models\PurchaseOrder::on(config('database.default'))
|
||||||
->with('vendor.company')
|
->with('vendor.company')
|
||||||
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
|
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
|
||||||
->where('company_id', $company->id)
|
->where('company_id', $company->id)
|
||||||
|
@ -32,7 +32,6 @@ class StripeConnectController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function initialize(InitializeStripeConnectRequest $request, string $token)
|
public function initialize(InitializeStripeConnectRequest $request, string $token)
|
||||||
{
|
{
|
||||||
// Should we check if company has set country in the ap? Otherwise this will fail.
|
|
||||||
|
|
||||||
if (! is_array($request->getTokenContent())) {
|
if (! is_array($request->getTokenContent())) {
|
||||||
abort(400, 'Invalid token');
|
abort(400, 'Invalid token');
|
||||||
@ -40,8 +39,6 @@ class StripeConnectController extends BaseController
|
|||||||
|
|
||||||
MultiDB::findAndSetDbByCompanyKey($request->getTokenContent()['company_key']);
|
MultiDB::findAndSetDbByCompanyKey($request->getTokenContent()['company_key']);
|
||||||
|
|
||||||
$company = Company::where('company_key', $request->getTokenContent()['company_key'])->first();
|
|
||||||
|
|
||||||
$company_gateway = CompanyGateway::query()
|
$company_gateway = CompanyGateway::query()
|
||||||
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
||||||
->where('company_id', $request->getCompany()->id)
|
->where('company_id', $request->getCompany()->id)
|
||||||
@ -71,6 +68,20 @@ class StripeConnectController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
/** @class \stdClass $response
|
||||||
|
* @property string $scope
|
||||||
|
* @property string $stripe_user_id
|
||||||
|
* @property string $stripe_publishable_key
|
||||||
|
* @property string $refresh_token
|
||||||
|
* @property string $livemode
|
||||||
|
* @property string $access_token
|
||||||
|
* @property string $token_type
|
||||||
|
* @property string $stripe_user
|
||||||
|
* @property string $stripe_account
|
||||||
|
* @property string $error
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @var \stdClass $response */
|
||||||
$response = \Stripe\OAuth::token([
|
$response = \Stripe\OAuth::token([
|
||||||
'grant_type' => 'authorization_code',
|
'grant_type' => 'authorization_code',
|
||||||
'code' => $request->input('code'),
|
'code' => $request->input('code'),
|
||||||
@ -81,8 +92,7 @@ class StripeConnectController extends BaseController
|
|||||||
|
|
||||||
MultiDB::findAndSetDbByCompanyKey($request->getTokenContent()['company_key']);
|
MultiDB::findAndSetDbByCompanyKey($request->getTokenContent()['company_key']);
|
||||||
|
|
||||||
/** @var \App\Models\Company $company */
|
$company = Company::query()->where('company_key', $request->getTokenContent()['company_key'])->first();
|
||||||
$company = Company::where('company_key', $request->getTokenContent()['company_key'])->first();
|
|
||||||
|
|
||||||
$company_gateway = CompanyGateway::query()
|
$company_gateway = CompanyGateway::query()
|
||||||
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
||||||
@ -97,7 +107,6 @@ class StripeConnectController extends BaseController
|
|||||||
$company_gateway->fees_and_limits = $fees_and_limits;
|
$company_gateway->fees_and_limits = $fees_and_limits;
|
||||||
$company_gateway->setConfig([]);
|
$company_gateway->setConfig([]);
|
||||||
$company_gateway->token_billing = 'always';
|
$company_gateway->token_billing = 'always';
|
||||||
// $company_gateway->save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
@ -116,39 +125,14 @@ class StripeConnectController extends BaseController
|
|||||||
$company_gateway->save();
|
$company_gateway->save();
|
||||||
|
|
||||||
// StripeWebhook::dispatch($company->company_key, $company_gateway->id);
|
// StripeWebhook::dispatch($company->company_key, $company_gateway->id);
|
||||||
|
if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
|
||||||
//response here
|
$redirect_uri = 'https://app.invoicing.co/#/settings/online_payments';
|
||||||
return view('auth.connect.completed');
|
} else {
|
||||||
}
|
$redirect_uri = 'https://invoicing.co/stripe/completed';
|
||||||
|
|
||||||
private function checkAccountAlreadyLinkToEmail($company_gateway, $email)
|
|
||||||
{
|
|
||||||
$client = Client::first() ? Client::first() : new Client;
|
|
||||||
|
|
||||||
//Pull the list of Stripe Accounts and see if we match
|
|
||||||
$accounts = $company_gateway->driver($client)->getAllConnectedAccounts()->data;
|
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
if ($account['email'] == $email) {
|
|
||||||
return $account['id'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
//response here
|
||||||
|
return view('auth.connect.completed', ['url' => $redirect_uri]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* Stripe OAuth
|
|
||||||
*/
|
|
||||||
|
|
||||||
// public function initialize(InitializeStripeConnectRequest $request, string $token)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// $stripe_key = config('ninja.ninja_stripe_key');
|
|
||||||
|
|
||||||
// $endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_key}&scope=read_write";
|
|
||||||
|
|
||||||
// return redirect($endpoint);
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,10 @@ class TwilioController extends BaseController
|
|||||||
return response()->json(['message' => 'Unable to retrieve user.'], 400);
|
return response()->json(['message' => 'Unable to retrieve user.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$user->phone || $user->phone == '') {
|
||||||
|
return response()->json(['message' => 'User found, but no valid phone number on file, please contact support.'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
$sid = config('ninja.twilio_account_sid');
|
$sid = config('ninja.twilio_account_sid');
|
||||||
$token = config('ninja.twilio_auth_token');
|
$token = config('ninja.twilio_auth_token');
|
||||||
|
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Vendor;
|
|
||||||
use App\Models\VendorContact;
|
|
||||||
use Auth;
|
use Auth;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use App\Models\Vendor;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use App\Libraries\MultiDB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class VendorContactKeyLogin
|
class VendorContactKeyLogin
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ class VendorContactKeyLogin
|
|||||||
$vendor_contact->save();
|
$vendor_contact->save();
|
||||||
|
|
||||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||||
|
|
||||||
if ($request->query('redirect') && ! empty($request->query('redirect'))) {
|
if ($request->query('redirect') && ! empty($request->query('redirect'))) {
|
||||||
return redirect()->to($request->query('redirect'));
|
return redirect()->to($request->query('redirect'));
|
||||||
}
|
}
|
||||||
@ -72,7 +72,6 @@ class VendorContactKeyLogin
|
|||||||
$vendor_contact->save();
|
$vendor_contact->save();
|
||||||
|
|
||||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||||
|
|
||||||
if ($request->query('next')) {
|
if ($request->query('next')) {
|
||||||
return redirect()->to($request->query('next'));
|
return redirect()->to($request->query('next'));
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class VendorLocale
|
|||||||
$locale = $request->input('lang');
|
$locale = $request->input('lang');
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} elseif (auth()->guard('vendor')->user()) {
|
} elseif (auth()->guard('vendor')->user()) {
|
||||||
App::setLocale(auth()->guard('vendor')->user()->company->locale());
|
App::setLocale(auth()->guard('vendor')->user()->vendor->locale());
|
||||||
} elseif (auth()->user()) {
|
} elseif (auth()->user()) {
|
||||||
try {
|
try {
|
||||||
App::setLocale(auth()->user()->company()->getLocale());
|
App::setLocale(auth()->user()->company()->getLocale());
|
||||||
|
@ -22,7 +22,10 @@ class DefaultCompanyRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
|
@ -85,8 +85,6 @@ class StorePaymentRequest extends Request
|
|||||||
$input['amount'] = $invoices_total - $credits_total;
|
$input['amount'] = $invoices_total - $credits_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $input['is_manual'] = true;
|
|
||||||
|
|
||||||
if (! isset($input['date'])) {
|
if (! isset($input['date'])) {
|
||||||
$input['date'] = now()->addSeconds(auth()->user()->company()->timezone()->utc_offset)->format('Y-m-d');
|
$input['date'] = now()->addSeconds(auth()->user()->company()->timezone()->utc_offset)->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,11 @@ class GenericReportRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin() || $user->hasPermission('view_reports');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
|
17
app/Http/Requests/Vendor/StoreVendorRequest.php
vendored
17
app/Http/Requests/Vendor/StoreVendorRequest.php
vendored
@ -26,17 +26,23 @@ class StoreVendorRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->can('create', Vendor::class);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->can('create', Vendor::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
$rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email';
|
$rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email';
|
||||||
|
|
||||||
if (isset($this->number)) {
|
if (isset($this->number)) {
|
||||||
$rules['number'] = Rule::unique('vendors')->where('company_id', auth()->user()->company()->id);
|
$rules['number'] = Rule::unique('vendors')->where('company_id', $user->company()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['currency_id'] = 'bail|required|exists:currencies,id';
|
$rules['currency_id'] = 'bail|required|exists:currencies,id';
|
||||||
@ -53,15 +59,20 @@ class StoreVendorRequest extends Request
|
|||||||
$rules['file'] = $this->file_validation;
|
$rules['file'] = $this->file_validation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
if (!array_key_exists('currency_id', $input) || empty($input['currency_id'])) {
|
if (!array_key_exists('currency_id', $input) || empty($input['currency_id'])) {
|
||||||
$input['currency_id'] = auth()->user()->company()->settings->currency_id;
|
$input['currency_id'] = $user->company()->settings->currency_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$input = $this->decodePrimaryKeys($input);
|
$input = $this->decodePrimaryKeys($input);
|
||||||
|
14
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
14
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
@ -28,17 +28,21 @@ class UpdateVendorRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->can('edit', $this->vendor);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->can('edit', $this->vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
/* Ensure we have a client name, and that all emails are unique*/
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$rules['country_id'] = 'integer';
|
$rules['country_id'] = 'integer';
|
||||||
|
|
||||||
if ($this->number) {
|
if ($this->number) {
|
||||||
$rules['number'] = Rule::unique('vendors')->where('company_id', auth()->user()->company()->id)->ignore($this->vendor->id);
|
$rules['number'] = Rule::unique('vendors')->where('company_id', $user->company()->id)->ignore($this->vendor->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['contacts.*.email'] = 'nullable|distinct';
|
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||||
@ -56,6 +60,8 @@ class UpdateVendorRequest extends Request
|
|||||||
$rules['file'] = $this->file_validation;
|
$rules['file'] = $this->file_validation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,11 @@ use App\Models\Company;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class \App\Http\Requests\Yodlee\YodleeAuthRequest
|
||||||
|
* @property string $token
|
||||||
|
* @property string $state
|
||||||
|
*/
|
||||||
class YodleeAuthRequest extends Request
|
class YodleeAuthRequest extends Request
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,6 @@ class ValidCreditsRules implements Rule
|
|||||||
foreach ($this->input['credits'] as $credit) {
|
foreach ($this->input['credits'] as $credit) {
|
||||||
$unique_array[] = $credit['credit_id'];
|
$unique_array[] = $credit['credit_id'];
|
||||||
|
|
||||||
// $cred = Credit::find($this->decodePrimaryKey($credit['credit_id']));
|
|
||||||
$cred = $cred_collection->firstWhere('id', $credit['credit_id']);
|
$cred = $cred_collection->firstWhere('id', $credit['credit_id']);
|
||||||
|
|
||||||
if (! $cred) {
|
if (! $cred) {
|
||||||
@ -77,6 +76,11 @@ class ValidCreditsRules implements Rule
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($cred->status_id == Credit::STATUS_DRAFT){
|
||||||
|
$cred->service()->markSent()->save();
|
||||||
|
$cred = $cred->fresh();
|
||||||
|
}
|
||||||
|
|
||||||
if($cred->balance < $credit['amount']) {
|
if($cred->balance < $credit['amount']) {
|
||||||
$this->error_msg = ctrans('texts.insufficient_credit_balance');
|
$this->error_msg = ctrans('texts.insufficient_credit_balance');
|
||||||
return false;
|
return false;
|
||||||
|
@ -109,8 +109,8 @@ class ProcessBankTransactions implements ShouldQueue
|
|||||||
$account = $at->transform($account_summary);
|
$account = $at->transform($account_summary);
|
||||||
|
|
||||||
if($account[0]['current_balance']) {
|
if($account[0]['current_balance']) {
|
||||||
$this->bank_integration->balance = $account['current_balance'];
|
$this->bank_integration->balance = $account[0]['current_balance'];
|
||||||
$this->bank_integration->currency = $account['account_currency'];
|
$this->bank_integration->currency = $account[0]['account_currency'];
|
||||||
$this->bank_integration->save();
|
$this->bank_integration->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,6 @@ class ZipDocuments implements ShouldQueue
|
|||||||
* Execute the job.
|
* Execute the job.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ZipStream\Exception\FileNotFoundException
|
|
||||||
* @throws \ZipStream\Exception\FileNotReadableException
|
|
||||||
* @throws \ZipStream\Exception\OverflowException
|
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
@ -62,9 +62,6 @@ class ZipPurchaseOrders implements ShouldQueue
|
|||||||
* Execute the job.
|
* Execute the job.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ZipStream\Exception\FileNotFoundException
|
|
||||||
* @throws \ZipStream\Exception\FileNotReadableException
|
|
||||||
* @throws \ZipStream\Exception\OverflowException
|
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
@ -62,9 +62,6 @@ class ZipQuotes implements ShouldQueue
|
|||||||
* Execute the job.
|
* Execute the job.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ZipStream\Exception\FileNotFoundException
|
|
||||||
* @throws \ZipStream\Exception\FileNotReadableException
|
|
||||||
* @throws \ZipStream\Exception\OverflowException
|
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
2
app/Jobs/Vendor/CreatePurchaseOrderPdf.php
vendored
2
app/Jobs/Vendor/CreatePurchaseOrderPdf.php
vendored
@ -102,7 +102,7 @@ class CreatePurchaseOrderPdf implements ShouldQueue
|
|||||||
/* Init a new copy of the translator*/
|
/* Init a new copy of the translator*/
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
/* Set the locale*/
|
/* Set the locale*/
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->vendor->locale());
|
||||||
|
|
||||||
/* Set customized translations _NOW_ */
|
/* Set customized translations _NOW_ */
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
45
app/Listeners/Vendor/UpdateVendorContactLastLogin.php
vendored
Normal file
45
app/Listeners/Vendor/UpdateVendorContactLastLogin.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Listeners\Vendor;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
|
||||||
|
class UpdateVendorContactLastLogin
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param object $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle($event)
|
||||||
|
{
|
||||||
|
MultiDB::setDb($event->company->db);
|
||||||
|
|
||||||
|
$contact = $event->contact;
|
||||||
|
|
||||||
|
$contact->last_login = now();
|
||||||
|
$contact->vendor->last_login = now();
|
||||||
|
|
||||||
|
$contact->push();
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,6 @@ use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundExceptio
|
|||||||
* @property int $assigned_user_id
|
* @property int $assigned_user_id
|
||||||
* @method BaseModel service()
|
* @method BaseModel service()
|
||||||
* @property \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property \App\Models\Vendor $vendor
|
|
||||||
* @method static BaseModel find($value)
|
* @method static BaseModel find($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel<static> company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel<static> company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|Illuminate\Database\Eloquent\Relations\BelongsTo|\Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo|\App\Models\Company company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|Illuminate\Database\Eloquent\Relations\BelongsTo|\Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo|\App\Models\Company company()
|
||||||
@ -63,11 +62,15 @@ use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundExceptio
|
|||||||
* @method int companyId()
|
* @method int companyId()
|
||||||
* @method createInvitations()
|
* @method createInvitations()
|
||||||
* @method Builder scopeCompany(Builder $builder)
|
* @method Builder scopeCompany(Builder $builder)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static> company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder withTrashed(bool $withTrashed = true)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder withTrashed(bool $withTrashed = true)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder onlyTrashed()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder onlyTrashed()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder withoutTrashed()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|\Illuminate\Database\Query\Builder withoutTrashed()
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
* @mixin \Illuminate\Database\Eloquent\Builder
|
* @mixin \Illuminate\Database\Eloquent\Builder
|
||||||
|
*
|
||||||
|
* @property \Illuminate\Support\Collection $tax_map
|
||||||
|
* @property array $total_tax_map
|
||||||
*/
|
*/
|
||||||
class BaseModel extends Model
|
class BaseModel extends Model
|
||||||
{
|
{
|
||||||
@ -119,7 +122,10 @@ class BaseModel extends Model
|
|||||||
return parent::__call($method, $params);
|
return parent::__call($method, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
public function scopeCompany($query): \Illuminate\Database\Eloquent\Builder
|
public function scopeCompany($query): \Illuminate\Database\Eloquent\Builder
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
|
@ -58,7 +58,7 @@ use Illuminate\Contracts\Translation\HasLocalePreference;
|
|||||||
* @property string|null $city
|
* @property string|null $city
|
||||||
* @property string|null $state
|
* @property string|null $state
|
||||||
* @property string|null $postal_code
|
* @property string|null $postal_code
|
||||||
* @property string|null $country_id
|
* @property int|null $country_id
|
||||||
* @property string|null $custom_value1
|
* @property string|null $custom_value1
|
||||||
* @property string|null $custom_value2
|
* @property string|null $custom_value2
|
||||||
* @property string|null $custom_value3
|
* @property string|null $custom_value3
|
||||||
@ -238,7 +238,10 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
return $this->hasMany(CompanyLedger::class)->orderBy('id', 'desc');
|
return $this->hasMany(CompanyLedger::class)->orderBy('id', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function company_ledger()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<CompanyLedger>
|
||||||
|
*/
|
||||||
|
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
||||||
}
|
}
|
||||||
@ -516,7 +519,10 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
throw new \Exception('Could not find a settings object', 1);
|
throw new \Exception('Could not find a settings object', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function documents() :MorphMany
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
|
public function documents() :\Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
* @property string|null $portal_domain
|
* @property string|null $portal_domain
|
||||||
* @property int $enable_modules
|
* @property int $enable_modules
|
||||||
* @property object $custom_fields
|
* @property object $custom_fields
|
||||||
* @property object $settings
|
* @property \App\DataMapper\CompanySettings $settings
|
||||||
* @property string $slack_webhook_url
|
* @property string $slack_webhook_url
|
||||||
* @property string $google_analytics_key
|
* @property string $google_analytics_key
|
||||||
* @property int|null $created_at
|
* @property int|null $created_at
|
||||||
@ -395,6 +395,9 @@ class Company extends BaseModel
|
|||||||
return $this->calculate_taxes && in_array($this->getSetting('country_id'), $this->tax_coverage_countries);
|
return $this->calculate_taxes && in_array($this->getSetting('country_id'), $this->tax_coverage_countries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
public function documents()
|
public function documents()
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
|
@ -13,6 +13,8 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||||
|
use Awobaz\Compoships\Exceptions\InvalidUsageException;
|
||||||
|
use Awobaz\Compoships\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\CompanyUser
|
* App\Models\CompanyUser
|
||||||
@ -129,50 +131,62 @@ class CompanyUser extends Pivot
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
*/
|
*/
|
||||||
public function user_pivot()
|
public function user_pivot(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(User::class)->withPivot('permissions', 'settings', 'react_settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
|
return $this->hasOne(User::class)->withPivot('permissions', 'settings', 'react_settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
*/
|
*/
|
||||||
public function company_pivot()
|
public function company_pivot(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(Company::class)->withPivot('permissions', 'settings', 'react_settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
|
return $this->hasOne(Company::class)->withPivot('permissions', 'settings', 'react_settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class)->withTrashed();
|
return $this->belongsTo(User::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function company()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Company::class);
|
return $this->belongsTo(Company::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function users(): \Illuminate\Database\Eloquent\Relations\HasMany
|
/**
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function users()
|
||||||
{
|
{
|
||||||
return $this->hasMany(User::class)->withTrashed();
|
return $this->hasMany(User::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*todo monitor this function - may fail under certain conditions*/
|
/**
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
public function token()
|
public function token()
|
||||||
{
|
{
|
||||||
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
|
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tokens(): \Illuminate\Database\Eloquent\Relations\HasMany
|
/**
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function tokens()
|
||||||
{
|
{
|
||||||
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
|
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeAuthCompany($query)
|
public function scopeAuthCompany($query): \Illuminate\Database\Eloquent\Builder
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
@ -187,7 +201,7 @@ class CompanyUser extends Pivot
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function portalType():bool
|
public function portalType(): bool
|
||||||
{
|
{
|
||||||
return isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link;
|
return isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link;
|
||||||
}
|
}
|
||||||
|
@ -93,29 +93,30 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
|
|||||||
* @property string|null $reminder_last_sent
|
* @property string|null $reminder_last_sent
|
||||||
* @property float $paid_to_date
|
* @property float $paid_to_date
|
||||||
* @property int|null $subscription_id
|
* @property int|null $subscription_id
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
* @property-read int|null $activities_count
|
* @property int|null $activities_count
|
||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property \App\Models\User|null $assigned_user
|
||||||
* @property-read \App\Models\Client $client
|
* @property \App\Models\Client $client
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
* @property \App\Models\CreditInvitation $invitation
|
||||||
* @property-read int|null $company_ledger_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property int|null $company_ledger_count
|
||||||
* @property-read int|null $documents_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read mixed $hashed_id
|
* @property int|null $documents_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
* @property mixed $hashed_id
|
||||||
* @property-read int|null $history_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $invitations
|
* @property int|null $history_count
|
||||||
* @property-read int|null $invitations_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\CreditInvitation> $invitations
|
||||||
* @property-read \App\Models\Invoice|null $invoice
|
* @property int|null $invitations_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @property \App\Models\Invoice|null $invoice
|
||||||
* @property-read int|null $invoices_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
* @property int|null $invoices_count
|
||||||
* @property-read int|null $payments_count
|
* @property \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
||||||
* @property-read \App\Models\Project|null $project
|
* @property int|null $payments_count
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\Project|null $project
|
||||||
* @property-read \App\Models\Client $client
|
* @property \App\Models\User $user
|
||||||
* @property-read \App\Models\Vendor|null $vendor
|
* @property \App\Models\Client $client
|
||||||
|
* @property \App\Models\Vendor|null $vendor
|
||||||
* @property-read mixed $pivot
|
* @property-read mixed $pivot
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||||
@ -269,6 +270,9 @@ class Credit extends BaseModel
|
|||||||
return $this->belongsTo(Invoice::class);
|
return $this->belongsTo(Invoice::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<CompanyLedger>
|
||||||
|
*/
|
||||||
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
||||||
@ -288,11 +292,17 @@ class Credit extends BaseModel
|
|||||||
return $this->belongsToMany(Invoice::class)->using(Paymentable::class);
|
return $this->belongsToMany(Invoice::class)->using(Paymentable::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Payment>
|
||||||
|
*/
|
||||||
public function payments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
public function payments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphToMany(Payment::class, 'paymentable');
|
return $this->morphToMany(Payment::class, 'paymentable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
|
@ -41,11 +41,11 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property int|null $deleted_at
|
* @property int|null $deleted_at
|
||||||
* @property string|null $signature_ip
|
* @property string|null $signature_ip
|
||||||
* @property string|null $email_status
|
* @property string|null $email_status
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \App\Models\ClientContact $contact
|
* @property \App\Models\ClientContact $contact
|
||||||
* @property-read \App\Models\Credit $credit
|
* @property \App\Models\Credit $credit
|
||||||
* @property-read mixed $hashed_id
|
* @property mixed $hashed_id
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Database\Factories\CreditInvitationFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\CreditInvitationFactory factory($count = null, $state = [])
|
||||||
|
@ -150,7 +150,10 @@ class Expense extends BaseModel
|
|||||||
return self::class;
|
return self::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function documents()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,10 @@ class GroupSetting extends StaticModel
|
|||||||
return $this->hasMany(Client::class, 'id', 'group_settings_id');
|
return $this->hasMany(Client::class, 'id', 'group_settings_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function documents()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ use App\Helpers\Invoice\InvoiceSumInclusive;
|
|||||||
use App\Utils\Traits\Invoice\ActionsInvoice;
|
use App\Utils\Traits\Invoice\ActionsInvoice;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use App\Events\Invoice\InvoiceReminderWasEmailed;
|
use App\Events\Invoice\InvoiceReminderWasEmailed;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\Invoice
|
* App\Models\Invoice
|
||||||
@ -99,12 +100,13 @@ use App\Events\Invoice\InvoiceReminderWasEmailed;
|
|||||||
* @property int $auto_bill_tries
|
* @property int $auto_bill_tries
|
||||||
* @property bool $is_proforma
|
* @property bool $is_proforma
|
||||||
* @property-read int|null $activities_count
|
* @property-read int|null $activities_count
|
||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property \App\Models\User|null $assigned_user
|
||||||
* @property \App\Models\Client $client
|
* @property \App\Models\Client $client
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\InvoiceInvitation $invitation
|
||||||
|
* @property \App\Models\Company $company
|
||||||
* @property-read int|null $company_ledger_count
|
* @property-read int|null $company_ledger_count
|
||||||
* @property-read int|null $credits_count
|
* @property-read int|null $credits_count
|
||||||
* @property-read \App\Models\Design|null $design
|
* @property \App\Models\Design|null $design
|
||||||
* @property-read int|null $documents_count
|
* @property-read int|null $documents_count
|
||||||
* @property-read \App\Models\Expense|null $expense
|
* @property-read \App\Models\Expense|null $expense
|
||||||
* @property-read int|null $expenses_count
|
* @property-read int|null $expenses_count
|
||||||
@ -301,16 +303,25 @@ class Invoice extends BaseModel
|
|||||||
return $this->belongsTo(Subscription::class)->withTrashed();
|
return $this->belongsTo(Subscription::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Payment>
|
||||||
|
*/
|
||||||
public function payments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
public function payments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphToMany(Payment::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
return $this->morphToMany(Payment::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<CompanyLedger>
|
||||||
|
*/
|
||||||
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
||||||
@ -321,32 +332,41 @@ class Invoice extends BaseModel
|
|||||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(50);
|
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function history()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough<Backup>
|
||||||
|
*/
|
||||||
|
public function history(): \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||||
{
|
{
|
||||||
return $this->hasManyThrough(Backup::class, Activity::class);
|
return $this->hasManyThrough(Backup::class, Activity::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function credits()
|
public function credits(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Credit::class);
|
return $this->hasMany(Credit::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tasks()
|
public function tasks(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Task::class);
|
return $this->hasMany(Task::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function task()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne<Task>
|
||||||
|
*/
|
||||||
|
public function task(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(Task::class);
|
return $this->hasOne(Task::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function expenses()
|
public function expenses(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Expense::class);
|
return $this->hasMany(Expense::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function expense()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne<Expense>
|
||||||
|
*/
|
||||||
|
public function expense(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(Expense::class);
|
return $this->hasOne(Expense::class);
|
||||||
}
|
}
|
||||||
@ -745,4 +765,55 @@ class Invoice extends BaseModel
|
|||||||
return $type;
|
return $type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reminderSchedule(): string
|
||||||
|
{
|
||||||
|
$reminder_schedule = '';
|
||||||
|
$settings = $this->client->getMergedSettings();
|
||||||
|
|
||||||
|
$send_email_enabled = ctrans('texts.send_email') . " " .ctrans('texts.enabled');
|
||||||
|
$send_email_disabled = ctrans('texts.send_email') . " " .ctrans('texts.disabled');
|
||||||
|
|
||||||
|
$sends_email_1 = $settings->enable_reminder2 ? $send_email_enabled : $send_email_disabled;
|
||||||
|
$days_1 = $settings->num_days_reminder1 . " " . ctrans('texts.days');
|
||||||
|
$schedule_1 = ctrans("texts.{$settings->schedule_reminder1}"); //after due date etc or disabled
|
||||||
|
$label_1 = ctrans('texts.reminder1');
|
||||||
|
|
||||||
|
$sends_email_2 = $settings->enable_reminder2 ? $send_email_enabled : $send_email_disabled;
|
||||||
|
$days_2 = $settings->num_days_reminder2 . " " . ctrans('texts.days');
|
||||||
|
$schedule_2 = ctrans("texts.{$settings->schedule_reminder2}"); //after due date etc or disabled
|
||||||
|
$label_2 = ctrans('texts.reminder2');
|
||||||
|
|
||||||
|
$sends_email_3 = $settings->enable_reminder2 ? $send_email_enabled : $send_email_disabled;
|
||||||
|
$days_3 = $settings->num_days_reminder3 . " " . ctrans('texts.days');
|
||||||
|
$schedule_3 = ctrans("texts.{$settings->schedule_reminder3}"); //after due date etc or disabled
|
||||||
|
$label_3 = ctrans('texts.reminder3');
|
||||||
|
|
||||||
|
$sends_email_endless = $settings->enable_reminder_endless ? $send_email_enabled : $send_email_disabled;
|
||||||
|
$days_endless = \App\Models\RecurringInvoice::frequencyForKey($settings->endless_reminder_frequency_id);
|
||||||
|
$label_endless = ctrans('texts.reminder_endless');
|
||||||
|
|
||||||
|
if($schedule_1 == ctrans('texts.disabled') || $settings->schedule_reminder1 == 'disabled' || $settings->schedule_reminder1 == '')
|
||||||
|
$reminder_schedule .= "{$label_1}: " . ctrans('texts.disabled') ."<br>";
|
||||||
|
else
|
||||||
|
$reminder_schedule .= "{$label_1}: {$days_1} {$schedule_1} [{$sends_email_1}]<br>";
|
||||||
|
|
||||||
|
if($schedule_2 == ctrans('texts.disabled') || $settings->schedule_reminder2 == 'disabled' || $settings->schedule_reminder2 == '')
|
||||||
|
$reminder_schedule .= "{$label_2}: " . ctrans('texts.disabled') ."<br>";
|
||||||
|
else
|
||||||
|
$reminder_schedule .= "{$label_2}: {$days_2} {$schedule_2} [{$sends_email_2}]<br>";
|
||||||
|
|
||||||
|
if($schedule_3 == ctrans('texts.disabled') || $settings->schedule_reminder3 == 'disabled' || $settings->schedule_reminder3 == '')
|
||||||
|
$reminder_schedule .= "{$label_3}: " . ctrans('texts.disabled') ."<br>";
|
||||||
|
else
|
||||||
|
$reminder_schedule .= "{$label_3}: {$days_3} {$schedule_3} [{$sends_email_3}]<br>";
|
||||||
|
|
||||||
|
if($sends_email_endless == ctrans('texts.disabled') || $settings->endless_reminder_frequency_id == '0' || $settings->endless_reminder_frequency_id == '')
|
||||||
|
$reminder_schedule .= "{$label_endless}: " . ctrans('texts.disabled') ."<br>";
|
||||||
|
else
|
||||||
|
$reminder_schedule .= "{$label_endless}: {$days_endless} [{$sends_email_endless}]<br>";
|
||||||
|
|
||||||
|
|
||||||
|
return $reminder_schedule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,11 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property int|null $deleted_at
|
* @property int|null $deleted_at
|
||||||
* @property string|null $signature_ip
|
* @property string|null $signature_ip
|
||||||
* @property string|null $email_status
|
* @property string|null $email_status
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \App\Models\ClientContact $contact
|
* @property \App\Models\ClientContact $contact
|
||||||
* @property-read mixed $hashed_id
|
* @property mixed $hashed_id
|
||||||
* @property-read \App\Models\Invoice $invoice
|
* @property \App\Models\Invoice $invoice
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Database\Factories\InvoiceInvitationFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\InvoiceInvitationFactory factory($count = null, $state = [])
|
||||||
|
@ -216,21 +216,24 @@ class Payment extends BaseModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MorphedByMany
|
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Paymentable>
|
||||||
*/
|
*/
|
||||||
public function invoices()
|
public function invoices(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphedByMany(Invoice::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
return $this->morphedByMany(Invoice::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MorphedByMany
|
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Paymentable>
|
||||||
*/
|
*/
|
||||||
public function credits()
|
public function credits(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphedByMany(Credit::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
return $this->morphedByMany(Credit::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded')->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<CompanyLedger>
|
||||||
|
*/
|
||||||
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function company_ledger(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
|
||||||
@ -266,7 +269,7 @@ class Payment extends BaseModel
|
|||||||
return $this->belongsTo(Project::class);
|
return $this->belongsTo(Project::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function translatedType()
|
public function translatedType(): string
|
||||||
{
|
{
|
||||||
if (! $this->type_id) {
|
if (! $this->type_id) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -87,17 +87,17 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property int|null $expense_id
|
* @property int|null $expense_id
|
||||||
* @property int|null $currency_id
|
* @property int|null $currency_id
|
||||||
* @property-read int|null $activities_count
|
* @property-read int|null $activities_count
|
||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property \App\Models\User|null $assigned_user
|
||||||
* @property-read \App\Models\Client|null $client
|
* @property \App\Models\Client|null $client
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read int|null $documents_count
|
* @property-read int|null $documents_count
|
||||||
* @property-read \App\Models\Expense|null $expense
|
* @property \App\Models\Expense|null $expense
|
||||||
* @property-read mixed $hashed_id
|
* @property string $hashed_id
|
||||||
* @property-read \App\Models\Invoice|null $invoice
|
* @property \App\Models\Invoice|null $invoice
|
||||||
* @property-read \App\Models\Project|null $project
|
* @property \App\Models\Project|null $project
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @property \App\Models\Vendor|null $vendor
|
* @property \App\Models\Vendor $vendor
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder company()
|
* @property \App\Models\PurchaseOrderInvitation $invitation
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder exclude($columns)
|
||||||
* @method static \Database\Factories\PurchaseOrderFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\PurchaseOrderFactory factory($count = null, $state = [])
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder filter(\App\Filters\QueryFilters $filters)
|
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder filter(\App\Filters\QueryFilters $filters)
|
||||||
@ -110,10 +110,8 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $invitations
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PurchaseOrderInvitation> $invitations
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Invoice> $invoices
|
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder withTrashed()
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Payment> $payments
|
* @method static \Illuminate\Database\Eloquent\Builder|PurchaseOrder withoutTrashed()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Task withTrashed()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Task withoutTrashed()
|
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class PurchaseOrder extends BaseModel
|
class PurchaseOrder extends BaseModel
|
||||||
@ -236,6 +234,9 @@ class PurchaseOrder extends BaseModel
|
|||||||
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
public function vendor(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
public function vendor(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Vendor::class)->withTrashed();
|
return $this->belongsTo(Vendor::class)->withTrashed();
|
||||||
|
@ -40,11 +40,11 @@ use Illuminate\Support\Str;
|
|||||||
* @property int|null $updated_at
|
* @property int|null $updated_at
|
||||||
* @property int|null $deleted_at
|
* @property int|null $deleted_at
|
||||||
* @property string|null $email_status
|
* @property string|null $email_status
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \App\Models\VendorContact $contact
|
* @property \App\Models\VendorContact $contact
|
||||||
* @property-read mixed $hashed_id
|
* @property string $hashed_id
|
||||||
* @property-read \App\Models\PurchaseOrder $purchase_order
|
* @property \App\Models\PurchaseOrder $purchase_order
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Database\Factories\PurchaseOrderInvitationFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\PurchaseOrderInvitationFactory factory($count = null, $state = [])
|
||||||
|
@ -91,9 +91,10 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property string|null $reminder_last_sent
|
* @property string|null $reminder_last_sent
|
||||||
* @property string $paid_to_date
|
* @property string $paid_to_date
|
||||||
* @property int|null $subscription_id
|
* @property int|null $subscription_id
|
||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property \App\Models\User|null $assigned_user
|
||||||
* @property-read \App\Models\Client $client
|
* @property \App\Models\Client $client
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
|
* @property \App\Models\QuoteInvitation $invitation
|
||||||
* @property-read mixed $balance_due
|
* @property-read mixed $balance_due
|
||||||
* @property-read mixed $hashed_id
|
* @property-read mixed $hashed_id
|
||||||
* @property-read mixed $total
|
* @property-read mixed $total
|
||||||
@ -226,6 +227,9 @@ class Quote extends BaseModel
|
|||||||
return $this->belongsTo(Vendor::class);
|
return $this->belongsTo(Vendor::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough<Backup>
|
||||||
|
*/
|
||||||
public function history(): \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
public function history(): \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||||
{
|
{
|
||||||
return $this->hasManyThrough(Backup::class, Activity::class);
|
return $this->hasManyThrough(Backup::class, Activity::class);
|
||||||
@ -266,6 +270,9 @@ class Quote extends BaseModel
|
|||||||
return $this->hasMany(QuoteInvitation::class);
|
return $this->hasMany(QuoteInvitation::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<Document>
|
||||||
|
*/
|
||||||
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
|
@ -41,11 +41,11 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
* @property int|null $deleted_at
|
* @property int|null $deleted_at
|
||||||
* @property string|null $signature_ip
|
* @property string|null $signature_ip
|
||||||
* @property string|null $email_status
|
* @property string|null $email_status
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \App\Models\ClientContact $contact
|
* @property \App\Models\ClientContact $contact
|
||||||
* @property-read mixed $hashed_id
|
* @property mixed $hashed_id
|
||||||
* @property-read \App\Models\Quote $quote
|
* @property \App\Models\Quote $quote
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Database\Factories\QuoteInvitationFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\QuoteInvitationFactory factory($count = null, $state = [])
|
||||||
|
@ -91,6 +91,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property-read \App\Models\User|null $assigned_user
|
||||||
* @property-read \App\Models\Client $client
|
* @property-read \App\Models\Client $client
|
||||||
* @property-read \App\Models\Company $company
|
* @property-read \App\Models\Company $company
|
||||||
|
* @property \App\Models\RecurringInvoiceInvitation $invitation
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||||
* @property-read int|null $documents_count
|
* @property-read int|null $documents_count
|
||||||
* @property-read mixed $hashed_id
|
* @property-read mixed $hashed_id
|
||||||
|
@ -37,11 +37,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property string|null $viewed_date
|
* @property string|null $viewed_date
|
||||||
* @property string|null $opened_date
|
* @property string|null $opened_date
|
||||||
* @property string|null $email_status
|
* @property string|null $email_status
|
||||||
* @property-read \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @property-read \App\Models\ClientContact $contact
|
* @property \App\Models\ClientContact $contact
|
||||||
* @property-read mixed $hashed_id
|
* @property string $hashed_id
|
||||||
* @property-read \App\Models\RecurringInvoice $recurring_invoice
|
* @property \App\Models\RecurringInvoice $recurring_invoice
|
||||||
* @property-read \App\Models\User $user
|
* @property \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|RecurringInvoiceInvitation newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|RecurringInvoiceInvitation newModelQuery()
|
||||||
|
@ -95,6 +95,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyUser> $company_users
|
||||||
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyToken> $tokens
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Company> $companies
|
||||||
* @method bool hasPermissionTo(string $permission)
|
* @method bool hasPermissionTo(string $permission)
|
||||||
* @method \App\Models\Company getCompany()
|
* @method \App\Models\Company getCompany()
|
||||||
* @method \App\Models\Company company()
|
* @method \App\Models\Company company()
|
||||||
|
@ -51,6 +51,8 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property string|null $vendor_hash
|
* @property string|null $vendor_hash
|
||||||
* @property string|null $public_notes
|
* @property string|null $public_notes
|
||||||
* @property string|null $id_number
|
* @property string|null $id_number
|
||||||
|
* @property string|null $language_id
|
||||||
|
* @property int|null $last_login
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
* @property-read int|null $activities_count
|
* @property-read int|null $activities_count
|
||||||
* @property-read \App\Models\User|null $assigned_user
|
* @property-read \App\Models\User|null $assigned_user
|
||||||
@ -64,7 +66,6 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $primary_contact
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\VendorContact> $primary_contact
|
||||||
* @property-read int|null $primary_contact_count
|
* @property-read int|null $primary_contact_count
|
||||||
* @property-read \App\Models\User $user
|
* @property-read \App\Models\User $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
* @method static \Database\Factories\VendorFactory factory($count = null, $state = [])
|
* @method static \Database\Factories\VendorFactory factory($count = null, $state = [])
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor filter(\App\Filters\QueryFilters $filters)
|
* @method static \Illuminate\Database\Eloquent\Builder|Vendor filter(\App\Filters\QueryFilters $filters)
|
||||||
@ -73,35 +74,6 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor onlyTrashed()
|
* @method static \Illuminate\Database\Eloquent\Builder|Vendor onlyTrashed()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor query()
|
* @method static \Illuminate\Database\Eloquent\Builder|Vendor query()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel scope()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel scope()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereAddress1($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereAddress2($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereAssignedUserId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCity($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCompanyId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCountryId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCurrencyId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCustomValue1($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCustomValue2($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCustomValue3($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereCustomValue4($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereDeletedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereIdNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereIsDeleted($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor wherePhone($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor wherePostalCode($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor wherePrivateNotes($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor wherePublicNotes($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereState($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereTransactionName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereUserId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereVatNumber($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereVendorHash($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor whereWebsite($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor withTrashed()
|
* @method static \Illuminate\Database\Eloquent\Builder|Vendor withTrashed()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Vendor withoutTrashed()
|
* @method static \Illuminate\Database\Eloquent\Builder|Vendor withoutTrashed()
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||||
@ -140,6 +112,7 @@ class Vendor extends BaseModel
|
|||||||
'custom_value3',
|
'custom_value3',
|
||||||
'custom_value4',
|
'custom_value4',
|
||||||
'number',
|
'number',
|
||||||
|
'language_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
@ -149,6 +122,7 @@ class Vendor extends BaseModel
|
|||||||
'updated_at' => 'timestamp',
|
'updated_at' => 'timestamp',
|
||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
|
'last_login' => 'timestamp',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $touches = [];
|
protected $touches = [];
|
||||||
@ -169,12 +143,12 @@ class Vendor extends BaseModel
|
|||||||
return $this->hasMany(VendorContact::class)->where('is_primary', true);
|
return $this->hasMany(VendorContact::class)->where('is_primary', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function documents()
|
public function documents(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Document::class, 'documentable');
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function assigned_user()
|
public function assigned_user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
||||||
}
|
}
|
||||||
@ -211,17 +185,20 @@ class Vendor extends BaseModel
|
|||||||
return $this->company->timezone();
|
return $this->company->timezone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function company()
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Company::class);
|
return $this->belongsTo(Company::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user()
|
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class)->withTrashed();
|
return $this->belongsTo(User::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function translate_entity()
|
public function translate_entity(): string
|
||||||
{
|
{
|
||||||
return ctrans('texts.vendor');
|
return ctrans('texts.vendor');
|
||||||
}
|
}
|
||||||
@ -249,7 +226,13 @@ class Vendor extends BaseModel
|
|||||||
return $defaults;
|
return $defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSetting($setting)
|
/**
|
||||||
|
* Returns a vendor settings proxying company setting
|
||||||
|
*
|
||||||
|
* @param string $setting
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSetting($setting): string
|
||||||
{
|
{
|
||||||
if ((property_exists($this->company->settings, $setting) != false) && (isset($this->company->settings->{$setting}) !== false)) {
|
if ((property_exists($this->company->settings, $setting) != false) && (isset($this->company->settings->{$setting}) !== false)) {
|
||||||
return $this->company->settings->{$setting};
|
return $this->company->settings->{$setting};
|
||||||
@ -265,24 +248,29 @@ class Vendor extends BaseModel
|
|||||||
return $this->company->settings;
|
return $this->company->settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function purchase_order_filepath($invitation)
|
public function purchase_order_filepath($invitation): string
|
||||||
{
|
{
|
||||||
$contact_key = $invitation->contact->contact_key;
|
$contact_key = $invitation->contact->contact_key;
|
||||||
|
|
||||||
return $this->company->company_key.'/'.$this->vendor_hash.'/'.$contact_key.'/purchase_orders/';
|
return $this->company->company_key.'/'.$this->vendor_hash.'/'.$contact_key.'/purchase_orders/';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function locale()
|
public function locale(): string
|
||||||
{
|
{
|
||||||
return $this->company->locale();
|
return $this->language ? $this->language->locale : $this->company->locale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function country()
|
public function language(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Language::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function country(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Country::class);
|
return $this->belongsTo(Country::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function date_format()
|
public function date_format(): string
|
||||||
{
|
{
|
||||||
return $this->company->date_format();
|
return $this->company->date_format();
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,7 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
|||||||
'updated_at' => 'timestamp',
|
'updated_at' => 'timestamp',
|
||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
|
'last_login' => 'timestamp',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -80,7 +80,7 @@ class ImportCustomers
|
|||||||
{
|
{
|
||||||
$account = $this->stripe->company_gateway->company->account;
|
$account = $this->stripe->company_gateway->company->account;
|
||||||
|
|
||||||
if (Ninja::isHosted() && ! $account->isPaidHostedClient() && Client::where('company_id', $this->stripe->company_gateway->company_id)->count() > config('ninja.quotas.free.clients')) {
|
if (Ninja::isHosted() && ! $account->isPaidHostedClient() && Client::query()->where('company_id', $this->stripe->company_gateway->company_id)->count() > config('ninja.quotas.free.clients')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ class ImportCustomers
|
|||||||
$client->phone = $customer->address->phone ? $customer->phone : '';
|
$client->phone = $customer->address->phone ? $customer->phone : '';
|
||||||
|
|
||||||
if ($customer->address->country) {
|
if ($customer->address->country) {
|
||||||
$country = Country::where('iso_3166_2', $customer->address->country)->first();
|
$country = Country::query()->where('iso_3166_2', $customer->address->country)->first();
|
||||||
|
|
||||||
if ($country) {
|
if ($country) {
|
||||||
$client->country_id = $country->id;
|
$client->country_id = $country->id;
|
||||||
@ -124,7 +124,7 @@ class ImportCustomers
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($customer->currency) {
|
if ($customer->currency) {
|
||||||
$currency = Currency::where('code', $customer->currency)->first();
|
$currency = Currency::query()->where('code', $customer->currency)->first();
|
||||||
|
|
||||||
if ($currency) {
|
if ($currency) {
|
||||||
$settings = $client->settings;
|
$settings = $client->settings;
|
||||||
@ -209,7 +209,7 @@ class ImportCustomers
|
|||||||
// nlog(count($searchResults));
|
// nlog(count($searchResults));
|
||||||
|
|
||||||
if (count($searchResults) == 1) {
|
if (count($searchResults) == 1) {
|
||||||
$cgt = ClientGatewayToken::where('gateway_customer_reference', $searchResults->data[0]->id)->where('company_id', $this->stripe->company_gateway->company->id)->exists();
|
$cgt = ClientGatewayToken::query()->where('gateway_customer_reference', $searchResults->data[0]->id)->where('company_id', $this->stripe->company_gateway->company->id)->exists();
|
||||||
|
|
||||||
if (! $cgt) {
|
if (! $cgt) {
|
||||||
nlog('customer '.$searchResults->data[0]->id.' does not exist.');
|
nlog('customer '.$searchResults->data[0]->id.' does not exist.');
|
||||||
|
@ -50,7 +50,7 @@ class PaymentIntentFailureWebhook implements ShouldQueue
|
|||||||
{
|
{
|
||||||
MultiDB::findAndSetDbByCompanyKey($this->company_key);
|
MultiDB::findAndSetDbByCompanyKey($this->company_key);
|
||||||
|
|
||||||
$company = Company::where('company_key', $this->company_key)->first();
|
$company = Company::query()->where('company_key', $this->company_key)->first();
|
||||||
|
|
||||||
foreach ($this->stripe_request as $transaction) {
|
foreach ($this->stripe_request as $transaction) {
|
||||||
if (array_key_exists('payment_intent', $transaction)) {
|
if (array_key_exists('payment_intent', $transaction)) {
|
||||||
@ -78,7 +78,7 @@ class PaymentIntentFailureWebhook implements ShouldQueue
|
|||||||
$payment->status_id = Payment::STATUS_FAILED;
|
$payment->status_id = Payment::STATUS_FAILED;
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
|
||||||
$payment_hash = PaymentHash::where('payment_id', $payment->id)->first();
|
$payment_hash = PaymentHash::query()->where('payment_id', $payment->id)->first();
|
||||||
|
|
||||||
if ($payment_hash) {
|
if ($payment_hash) {
|
||||||
$error = ctrans('texts.client_payment_failure_body', [
|
$error = ctrans('texts.client_payment_failure_body', [
|
||||||
|
@ -208,17 +208,24 @@ class UpdatePaymentMethods
|
|||||||
switch ($type_id) {
|
switch ($type_id) {
|
||||||
case GatewayType::CREDIT_CARD:
|
case GatewayType::CREDIT_CARD:
|
||||||
|
|
||||||
$payment_meta = new \stdClass;
|
/**
|
||||||
$payment_meta->exp_month = (string) $method->card->exp_month;
|
* @class \Stripe\PaymentMethod $method
|
||||||
$payment_meta->exp_year = (string) $method->card->exp_year;
|
* @property \Stripe\StripeObject $card
|
||||||
$payment_meta->brand = (string) $method->card->brand;
|
* @class \Stripe\StripeObject $card
|
||||||
$payment_meta->last4 = (string) $method->card->last4;
|
* @property string $exp_year
|
||||||
$payment_meta->type = GatewayType::CREDIT_CARD;
|
* @property string $exp_month
|
||||||
|
* @property string $brand
|
||||||
return $payment_meta;
|
* @property string $last4
|
||||||
|
*/
|
||||||
break;
|
|
||||||
|
$payment_meta = new \stdClass;
|
||||||
|
$payment_meta->exp_month = (string) $method->card->exp_month;
|
||||||
|
$payment_meta->exp_year = (string) $method->card->exp_year;
|
||||||
|
$payment_meta->brand = (string) $method->card->brand;
|
||||||
|
$payment_meta->last4 = (string) $method->card->last4;
|
||||||
|
$payment_meta->type = GatewayType::CREDIT_CARD;
|
||||||
|
|
||||||
|
return $payment_meta;
|
||||||
case GatewayType::ALIPAY:
|
case GatewayType::ALIPAY:
|
||||||
case GatewayType::SOFORT:
|
case GatewayType::SOFORT:
|
||||||
|
|
||||||
|
@ -70,13 +70,13 @@ use App\Events\Quote\QuoteWasRestored;
|
|||||||
use App\Events\Client\ClientWasCreated;
|
use App\Events\Client\ClientWasCreated;
|
||||||
use App\Events\Client\ClientWasDeleted;
|
use App\Events\Client\ClientWasDeleted;
|
||||||
use App\Events\Client\ClientWasUpdated;
|
use App\Events\Client\ClientWasUpdated;
|
||||||
use App\Events\Design\DesignWasDeleted;
|
|
||||||
use App\Events\Design\DesignWasUpdated;
|
|
||||||
use App\Events\Contact\ContactLoggedIn;
|
use App\Events\Contact\ContactLoggedIn;
|
||||||
use App\Events\Credit\CreditWasCreated;
|
use App\Events\Credit\CreditWasCreated;
|
||||||
use App\Events\Credit\CreditWasDeleted;
|
use App\Events\Credit\CreditWasDeleted;
|
||||||
use App\Events\Credit\CreditWasEmailed;
|
use App\Events\Credit\CreditWasEmailed;
|
||||||
use App\Events\Credit\CreditWasUpdated;
|
use App\Events\Credit\CreditWasUpdated;
|
||||||
|
use App\Events\Design\DesignWasDeleted;
|
||||||
|
use App\Events\Design\DesignWasUpdated;
|
||||||
use App\Events\Vendor\VendorWasCreated;
|
use App\Events\Vendor\VendorWasCreated;
|
||||||
use App\Events\Vendor\VendorWasDeleted;
|
use App\Events\Vendor\VendorWasDeleted;
|
||||||
use App\Events\Vendor\VendorWasUpdated;
|
use App\Events\Vendor\VendorWasUpdated;
|
||||||
@ -85,10 +85,10 @@ use App\Observers\SubscriptionObserver;
|
|||||||
use Illuminate\Mail\Events\MessageSent;
|
use Illuminate\Mail\Events\MessageSent;
|
||||||
use App\Events\Client\ClientWasArchived;
|
use App\Events\Client\ClientWasArchived;
|
||||||
use App\Events\Client\ClientWasRestored;
|
use App\Events\Client\ClientWasRestored;
|
||||||
use App\Events\Design\DesignWasRestored;
|
|
||||||
use App\Events\Credit\CreditWasArchived;
|
use App\Events\Credit\CreditWasArchived;
|
||||||
use App\Events\Credit\CreditWasRestored;
|
use App\Events\Credit\CreditWasRestored;
|
||||||
use App\Events\Design\DesignWasArchived;
|
use App\Events\Design\DesignWasArchived;
|
||||||
|
use App\Events\Design\DesignWasRestored;
|
||||||
use App\Events\Invoice\InvoiceWasViewed;
|
use App\Events\Invoice\InvoiceWasViewed;
|
||||||
use App\Events\Misc\InvitationWasViewed;
|
use App\Events\Misc\InvitationWasViewed;
|
||||||
use App\Events\Payment\PaymentWasVoided;
|
use App\Events\Payment\PaymentWasVoided;
|
||||||
@ -133,6 +133,7 @@ use App\Listeners\User\UpdateUserLastLogin;
|
|||||||
use App\Events\Document\DocumentWasArchived;
|
use App\Events\Document\DocumentWasArchived;
|
||||||
use App\Events\Document\DocumentWasRestored;
|
use App\Events\Document\DocumentWasRestored;
|
||||||
use App\Events\Invoice\InvoiceWasMarkedSent;
|
use App\Events\Invoice\InvoiceWasMarkedSent;
|
||||||
|
use App\Events\Vendor\VendorContactLoggedIn;
|
||||||
use App\Listeners\Quote\QuoteViewedActivity;
|
use App\Listeners\Quote\QuoteViewedActivity;
|
||||||
use App\Listeners\User\ArchivedUserActivity;
|
use App\Listeners\User\ArchivedUserActivity;
|
||||||
use App\Listeners\User\RestoredUserActivity;
|
use App\Listeners\User\RestoredUserActivity;
|
||||||
@ -220,6 +221,7 @@ use App\Listeners\Invoice\InvoiceEmailFailedActivity;
|
|||||||
use App\Events\PurchaseOrder\PurchaseOrderWasAccepted;
|
use App\Events\PurchaseOrder\PurchaseOrderWasAccepted;
|
||||||
use App\Events\PurchaseOrder\PurchaseOrderWasArchived;
|
use App\Events\PurchaseOrder\PurchaseOrderWasArchived;
|
||||||
use App\Events\PurchaseOrder\PurchaseOrderWasRestored;
|
use App\Events\PurchaseOrder\PurchaseOrderWasRestored;
|
||||||
|
use App\Listeners\Vendor\UpdateVendorContactLastLogin;
|
||||||
use App\Events\RecurringQuote\RecurringQuoteWasCreated;
|
use App\Events\RecurringQuote\RecurringQuoteWasCreated;
|
||||||
use App\Events\RecurringQuote\RecurringQuoteWasDeleted;
|
use App\Events\RecurringQuote\RecurringQuoteWasDeleted;
|
||||||
use App\Events\RecurringQuote\RecurringQuoteWasUpdated;
|
use App\Events\RecurringQuote\RecurringQuoteWasUpdated;
|
||||||
@ -615,6 +617,9 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
VendorWasUpdated::class => [
|
VendorWasUpdated::class => [
|
||||||
VendorUpdatedActivity::class,
|
VendorUpdatedActivity::class,
|
||||||
],
|
],
|
||||||
|
VendorContactLoggedIn::class => [
|
||||||
|
UpdateVendorContactLastLogin::class,
|
||||||
|
],
|
||||||
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
|
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
|
||||||
// ... Manager won't register drivers that are not added to this listener.
|
// ... Manager won't register drivers that are not added to this listener.
|
||||||
\SocialiteProviders\Apple\AppleExtendSocialite::class.'@handle',
|
\SocialiteProviders\Apple\AppleExtendSocialite::class.'@handle',
|
||||||
|
@ -155,7 +155,8 @@ class ClientService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->emailStatement($pdf, $statement->options);
|
$this->emailStatement($pdf, $statement->options);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $pdf;
|
return $pdf;
|
||||||
|
@ -218,8 +218,10 @@ class FacturaEInvoice extends AbstractService
|
|||||||
private function setPoNumber(): self
|
private function setPoNumber(): self
|
||||||
{
|
{
|
||||||
$po = $this->invoice->po_number ?? '';
|
$po = $this->invoice->po_number ?? '';
|
||||||
|
$transaction_reference = (isset($this->invoice->custom_value1) && strlen($this->invoice->custom_value1) > 2) ? substr($this->invoice->custom_value1, 0, 20) : null;
|
||||||
|
$contract_reference = (isset($this->invoice->custom_value2) && strlen($this->invoice->custom_value2) > 2) ? $this->invoice->custom_value2: null;
|
||||||
|
|
||||||
$this->fac->setReferences($po, substr($this->invoice->custom_value1, 0, 20), $this->invoice->custom_value2);
|
$this->fac->setReferences($po, $transaction_reference, $contract_reference);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -242,6 +244,9 @@ class FacturaEInvoice extends AbstractService
|
|||||||
|
|
||||||
private function setBillingPeriod(): self
|
private function setBillingPeriod(): self
|
||||||
{
|
{
|
||||||
|
if(!$this->invoice->custom_value3)
|
||||||
|
return $this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (\Carbon\Carbon::createFromFormat('Y-m-d', $this->invoice->custom_value3)->format('Y-m-d') === $this->invoice->custom_value3 &&
|
if (\Carbon\Carbon::createFromFormat('Y-m-d', $this->invoice->custom_value3)->format('Y-m-d') === $this->invoice->custom_value3 &&
|
||||||
\Carbon\Carbon::createFromFormat('Y-m-d', $this->invoice->custom_value4)->format('Y-m-d') === $this->invoice->custom_value4
|
\Carbon\Carbon::createFromFormat('Y-m-d', $this->invoice->custom_value4)->format('Y-m-d') === $this->invoice->custom_value4
|
||||||
|
@ -133,7 +133,7 @@ class PdfMock
|
|||||||
$entity->vendor = Vendor::factory()->make();
|
$entity->vendor = Vendor::factory()->make();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
# code...
|
$entity = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +152,12 @@ class PdfMock
|
|||||||
*/
|
*/
|
||||||
public function getMergedSettings() :object
|
public function getMergedSettings() :object
|
||||||
{
|
{
|
||||||
|
$settings = $this->company->settings;
|
||||||
|
|
||||||
match ($this->request['settings_type']) {
|
match ($this->request['settings_type']) {
|
||||||
'group' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']),
|
'group' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']),
|
||||||
'client' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']),
|
'client' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']),
|
||||||
'company' => $settings = (object)$this->request['settings'],
|
'company' => $settings = (object)$this->request['settings']
|
||||||
default => $settings = $this->company->settings,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$settings = CompanySettings::setProperties($settings);
|
$settings = CompanySettings::setProperties($settings);
|
||||||
@ -168,9 +169,9 @@ class PdfMock
|
|||||||
/**
|
/**
|
||||||
* getTaxMap
|
* getTaxMap
|
||||||
*
|
*
|
||||||
* @return void
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
private function getTaxMap()
|
private function getTaxMap(): \Illuminate\Support\Collection
|
||||||
{
|
{
|
||||||
return collect([['name' => 'GST', 'total' => 10]]);
|
return collect([['name' => 'GST', 'total' => 10]]);
|
||||||
}
|
}
|
||||||
@ -178,9 +179,9 @@ class PdfMock
|
|||||||
/**
|
/**
|
||||||
* getTotalTaxMap
|
* getTotalTaxMap
|
||||||
*
|
*
|
||||||
* @return void
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function getTotalTaxMap()
|
private function getTotalTaxMap(): array
|
||||||
{
|
{
|
||||||
return [['name' => 'GST', 'total' => 10]];
|
return [['name' => 'GST', 'total' => 10]];
|
||||||
}
|
}
|
||||||
@ -188,8 +189,9 @@ class PdfMock
|
|||||||
/**
|
/**
|
||||||
* getStubVariables
|
* getStubVariables
|
||||||
*
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getStubVariables()
|
public function getStubVariables(): array
|
||||||
{
|
{
|
||||||
return ['values' =>
|
return ['values' =>
|
||||||
[
|
[
|
||||||
|
@ -227,10 +227,13 @@ class StubBuilder
|
|||||||
|
|
||||||
private function createClient(): self
|
private function createClient(): self
|
||||||
{
|
{
|
||||||
$this->recipient = Client::factory()->create([
|
/** @var \App\Models\Client $client */
|
||||||
|
$client = Client::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->recipient = $client;
|
||||||
|
|
||||||
$this->contact = ClientContact::factory()->create([
|
$this->contact = ClientContact::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
@ -245,10 +248,13 @@ class StubBuilder
|
|||||||
|
|
||||||
private function createVendor(): self
|
private function createVendor(): self
|
||||||
{
|
{
|
||||||
$this->recipient = Vendor::factory()->create([
|
/** @var \App\Models\Vendor $vendor */
|
||||||
|
$vendor = Vendor::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'company_id' => $this->user->company()->id,
|
'company_id' => $this->user->company()->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->recipient = $vendor;
|
||||||
|
|
||||||
$this->contact = VendorContact::factory()->create([
|
$this->contact = VendorContact::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
@ -276,7 +282,8 @@ class StubBuilder
|
|||||||
|
|
||||||
private function createInvoice()
|
private function createInvoice()
|
||||||
{
|
{
|
||||||
$this->entity = Invoice::factory()->create([
|
/** @var \App\Models\Invoice $invoice */
|
||||||
|
$invoice = Invoice::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'client_id' => $this->recipient->id,
|
'client_id' => $this->recipient->id,
|
||||||
@ -285,6 +292,8 @@ class StubBuilder
|
|||||||
'status_id' => Invoice::STATUS_PAID,
|
'status_id' => Invoice::STATUS_PAID,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->entity = $invoice;
|
||||||
|
|
||||||
$this->invitation = InvoiceInvitation::factory()->create([
|
$this->invitation = InvoiceInvitation::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Transformers;
|
namespace App\Transformers;
|
||||||
|
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\BankIntegration;
|
use App\Models\BankIntegration;
|
||||||
use App\Models\BankTransaction;
|
use App\Models\BankTransaction;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
@ -11,11 +11,12 @@
|
|||||||
|
|
||||||
namespace App\Transformers;
|
namespace App\Transformers;
|
||||||
|
|
||||||
use App\Models\CompanyGateway;
|
use stdClass;
|
||||||
|
use App\Models\Gateway;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
|
use App\Models\CompanyGateway;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use stdClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CompanyGatewayTransformer.
|
* Class CompanyGatewayTransformer.
|
||||||
|
@ -87,7 +87,7 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
|
|
||||||
public function transform(Invoice $invoice)
|
public function transform(Invoice $invoice)
|
||||||
{
|
{
|
||||||
return [
|
$data = [
|
||||||
'id' => $this->encodePrimaryKey($invoice->id),
|
'id' => $this->encodePrimaryKey($invoice->id),
|
||||||
'user_id' => $this->encodePrimaryKey($invoice->user_id),
|
'user_id' => $this->encodePrimaryKey($invoice->user_id),
|
||||||
'project_id' => $this->encodePrimaryKey($invoice->project_id),
|
'project_id' => $this->encodePrimaryKey($invoice->project_id),
|
||||||
@ -151,5 +151,12 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
'auto_bill_enabled' => (bool) $invoice->auto_bill_enabled,
|
'auto_bill_enabled' => (bool) $invoice->auto_bill_enabled,
|
||||||
'tax_info' => $invoice->tax_data ?: new \stdClass,
|
'tax_info' => $invoice->tax_data ?: new \stdClass,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (request()->has('reminder_schedule') && request()->query('reminder_schedule') == 'true') {
|
||||||
|
$data['reminder_schedule'] = (string) $invoice->reminderSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ class VendorContactTransformer extends EntityTransformer
|
|||||||
'custom_value3' => $vendor->custom_value3 ?: '',
|
'custom_value3' => $vendor->custom_value3 ?: '',
|
||||||
'custom_value4' => $vendor->custom_value4 ?: '',
|
'custom_value4' => $vendor->custom_value4 ?: '',
|
||||||
'link' => $vendor->getLoginLink(),
|
'link' => $vendor->getLoginLink(),
|
||||||
|
'last_login' => (int)$vendor->last_login,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ class VendorTransformer extends EntityTransformer
|
|||||||
'archived_at' => (int) $vendor->deleted_at,
|
'archived_at' => (int) $vendor->deleted_at,
|
||||||
'created_at' => (int) $vendor->created_at,
|
'created_at' => (int) $vendor->created_at,
|
||||||
'number' => (string) $vendor->number ?: '',
|
'number' => (string) $vendor->number ?: '',
|
||||||
|
'language_id' => (string) $vendor->language_id ?: '',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,22 @@ class HtmlEngine
|
|||||||
use MakesHash;
|
use MakesHash;
|
||||||
use DesignCalculator;
|
use DesignCalculator;
|
||||||
|
|
||||||
|
/** @var \App\Models\Invoice | \App\Models\Credit | \App\Models\RecurringInvoice | \App\Models\Quote $entity **/
|
||||||
public $entity;
|
public $entity;
|
||||||
|
|
||||||
|
/** @var \App\Models\CreditInvitation | CreditInvitation | \App\Models\RecurringInvoiceInvitation | \App\Models\QuoteInvitation $invitation **/
|
||||||
public $invitation;
|
public $invitation;
|
||||||
|
|
||||||
|
/** @var \App\Models\Client $client */
|
||||||
public $client;
|
public $client;
|
||||||
|
|
||||||
|
/** @var \App\Models\ClientContact $contact */
|
||||||
public $contact;
|
public $contact;
|
||||||
|
|
||||||
|
/** @var \App\Models\Company $company */
|
||||||
public $company;
|
public $company;
|
||||||
|
|
||||||
|
/** @var \App\DataMapper\CompanySettings $settings **/
|
||||||
public $settings;
|
public $settings;
|
||||||
|
|
||||||
public $entity_calc;
|
public $entity_calc;
|
||||||
@ -53,6 +59,13 @@ class HtmlEngine
|
|||||||
|
|
||||||
private $helpers;
|
private $helpers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __construct
|
||||||
|
*
|
||||||
|
* @param InvoiceInvitation | CreditInvitation | RecurringInvoiceInvitation | QuoteInvitation $invitation
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function __construct($invitation)
|
public function __construct($invitation)
|
||||||
{
|
{
|
||||||
$this->invitation = $invitation;
|
$this->invitation = $invitation;
|
||||||
@ -150,7 +163,9 @@ class HtmlEngine
|
|||||||
$data['$payment_link'] = ['value' => $this->invitation->getPaymentLink(), 'label' => ctrans('texts.pay_now')];
|
$data['$payment_link'] = ['value' => $this->invitation->getPaymentLink(), 'label' => ctrans('texts.pay_now')];
|
||||||
$data['$payment_qrcode'] = ['value' => $this->invitation->getPaymentQrCode(), 'label' => ctrans('texts.pay_now')];
|
$data['$payment_qrcode'] = ['value' => $this->invitation->getPaymentQrCode(), 'label' => ctrans('texts.pay_now')];
|
||||||
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
|
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
|
||||||
|
$data['$triangular_tax'] = ['value' => ctrans('texts.triangular_tax'), 'label' => ''];
|
||||||
|
$data['$tax_info'] = ['value' => $this->taxLabel(), 'label' => ''];
|
||||||
|
|
||||||
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
|
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
|
||||||
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
|
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
|
||||||
$data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')];
|
$data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')];
|
||||||
@ -676,6 +691,26 @@ class HtmlEngine
|
|||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a localized string for tax compliance purposes
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function taxLabel(): string
|
||||||
|
{
|
||||||
|
$tax_label = '';
|
||||||
|
|
||||||
|
if (collect($this->entity->line_items)->contains('tax_id', \App\Models\Product::PRODUCT_TYPE_REVERSE_TAX)) {
|
||||||
|
$tax_label .= ctrans('texts.reverse_tax_info') . "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if((int)$this->client->country_id !== (int)$this->company->settings->country_id){
|
||||||
|
$tax_label .= ctrans('texts.intracommunity_tax_info') . "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tax_label;
|
||||||
|
}
|
||||||
|
|
||||||
private function getBalance()
|
private function getBalance()
|
||||||
{
|
{
|
||||||
|
@ -52,8 +52,8 @@ class TemplateEngine
|
|||||||
|
|
||||||
public $template;
|
public $template;
|
||||||
|
|
||||||
/** @var Invoice | Quote | Credit | PurchaseOrder | RecurringInvoice | null $entity_obj **/
|
/** @var \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\RecurringInvoice $entity_obj **/
|
||||||
private $entity_obj;
|
private \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\RecurringInvoice $entity_obj;
|
||||||
|
|
||||||
/** @var \App\Models\Company | \App\Models\Client | null $settings_entity **/
|
/** @var \App\Models\Company | \App\Models\Client | null $settings_entity **/
|
||||||
private $settings_entity;
|
private $settings_entity;
|
||||||
@ -81,7 +81,7 @@ class TemplateEngine
|
|||||||
|
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
|
|
||||||
$this->entity_obj = null;
|
// $this->entity_obj = null;
|
||||||
|
|
||||||
$this->settings_entity = null;
|
$this->settings_entity = null;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ class TemplateEngine
|
|||||||
{
|
{
|
||||||
if (strlen($this->entity) > 1 && strlen($this->entity_id) > 1) {
|
if (strlen($this->entity) > 1 && strlen($this->entity_id) > 1) {
|
||||||
$class = 'App\Models\\' . ucfirst(Str::camel($this->entity));
|
$class = 'App\Models\\' . ucfirst(Str::camel($this->entity));
|
||||||
$this->entity_obj = $class::withTrashed()->where('id', $this->decodePrimaryKey($this->entity_id))->company()->first();
|
$this->entity_obj = $class::query()->withTrashed()->where('id', $this->decodePrimaryKey($this->entity_id))->company()->first();
|
||||||
} elseif (stripos($this->template, 'quote') !== false && $quote = Quote::query()->whereHas('invitations')->withTrashed()->company()->first()) {
|
} elseif (stripos($this->template, 'quote') !== false && $quote = Quote::query()->whereHas('invitations')->withTrashed()->company()->first()) {
|
||||||
$this->entity = 'quote';
|
$this->entity = 'quote';
|
||||||
$this->entity_obj = $quote;
|
$this->entity_obj = $quote;
|
||||||
@ -111,6 +111,7 @@ class TemplateEngine
|
|||||||
$this->entity_obj = $payment;
|
$this->entity_obj = $payment;
|
||||||
}
|
}
|
||||||
elseif ($invoice = Invoice::query()->whereHas('invitations')->withTrashed()->company()->first()) {
|
elseif ($invoice = Invoice::query()->whereHas('invitations')->withTrashed()->company()->first()) {
|
||||||
|
/** @var \App\Models\Invoice $invoice */
|
||||||
$this->entity_obj = $invoice;
|
$this->entity_obj = $invoice;
|
||||||
} else {
|
} else {
|
||||||
$this->mockEntity();
|
$this->mockEntity();
|
||||||
@ -286,6 +287,8 @@ class TemplateEngine
|
|||||||
|
|
||||||
private function mockEntity()
|
private function mockEntity()
|
||||||
{
|
{
|
||||||
|
$invitation = false;
|
||||||
|
|
||||||
if (!$this->entity && $this->template && str_contains($this->template, 'purchase_order')) {
|
if (!$this->entity && $this->template && str_contains($this->template, 'purchase_order')) {
|
||||||
$this->entity = 'purchaseOrder';
|
$this->entity = 'purchaseOrder';
|
||||||
} elseif (str_contains($this->template, 'payment')) {
|
} elseif (str_contains($this->template, 'payment')) {
|
||||||
@ -304,7 +307,6 @@ class TemplateEngine
|
|||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
/** @var \App\Models\ClientContact $contact */
|
/** @var \App\Models\ClientContact $contact */
|
||||||
$contact = ClientContact::factory()->create([
|
$contact = ClientContact::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
@ -315,7 +317,8 @@ class TemplateEngine
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->entity == 'payment') {
|
if ($this->entity == 'payment') {
|
||||||
$this->entity_obj = Payment::factory()->create([
|
/** @var \App\Models\Payment $payment */
|
||||||
|
$payment = Payment::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
@ -324,6 +327,8 @@ class TemplateEngine
|
|||||||
'refunded' => 5,
|
'refunded' => 5,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->entity_obj = $payment;
|
||||||
|
|
||||||
/** @var \App\Models\Invoice $invoice */
|
/** @var \App\Models\Invoice $invoice */
|
||||||
$invoice = Invoice::factory()->create([
|
$invoice = Invoice::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
@ -349,7 +354,8 @@ class TemplateEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->entity || $this->entity == 'invoice') {
|
if (!$this->entity || $this->entity == 'invoice') {
|
||||||
$this->entity_obj = Invoice::factory()->create([
|
/** @var \App\Models\Invoice $invoice */
|
||||||
|
$invoice = Invoice::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
@ -357,6 +363,8 @@ class TemplateEngine
|
|||||||
'balance' => '10',
|
'balance' => '10',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->entity_obj = $invoice;
|
||||||
|
|
||||||
$invitation = InvoiceInvitation::factory()->create([
|
$invitation = InvoiceInvitation::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
@ -366,11 +374,14 @@ class TemplateEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->entity == 'quote') {
|
if ($this->entity == 'quote') {
|
||||||
$this->entity_obj = Quote::factory()->create([
|
/** @var \App\Models\Quote $quote */
|
||||||
|
$quote = Quote::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->entity_obj = $quote;
|
||||||
|
|
||||||
$invitation = QuoteInvitation::factory()->create([
|
$invitation = QuoteInvitation::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
@ -395,12 +406,15 @@ class TemplateEngine
|
|||||||
'is_primary' => 1,
|
'is_primary' => 1,
|
||||||
'send_email' => true,
|
'send_email' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->entity_obj = PurchaseOrder::factory()->create([
|
/** @var \App\Models\PurchaseOrder $purchase_order **/
|
||||||
|
$purchase_order = PurchaseOrder::factory()->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_id' => $user->company()->id,
|
'company_id' => $user->company()->id,
|
||||||
'vendor_id' => $vendor->id,
|
'vendor_id' => $vendor->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->entity_obj = $purchase_order;
|
||||||
|
|
||||||
/** @var \App\Models\PurchaseOrderInvitation $invitation **/
|
/** @var \App\Models\PurchaseOrderInvitation $invitation **/
|
||||||
$invitation = PurchaseOrderInvitation::factory()->create([
|
$invitation = PurchaseOrderInvitation::factory()->create([
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace App\Utils;
|
namespace App\Utils;
|
||||||
|
|
||||||
use App\Models\PaymentTerm;
|
use App\Models\PaymentTerm;
|
||||||
use Cache;
|
use \Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class TranslationHelper
|
class TranslationHelper
|
||||||
|
@ -112,7 +112,7 @@ class VendorHtmlEngine
|
|||||||
|
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->vendor->locale());
|
||||||
$t->replace(Ninja::transformTranslations($this->settings));
|
$t->replace(Ninja::transformTranslations($this->settings));
|
||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
@ -126,16 +126,16 @@ class VendorHtmlEngine
|
|||||||
$data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')];
|
$data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')];
|
||||||
$data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')];
|
$data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')];
|
||||||
$data['$line_tax_values'] = ['value' => $this->lineTaxValues(), 'label' => ctrans('texts.taxes')];
|
$data['$line_tax_values'] = ['value' => $this->lineTaxValues(), 'label' => ctrans('texts.taxes')];
|
||||||
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.date')];
|
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.date')];
|
||||||
|
|
||||||
$data['$due_date'] = ['value' => $this->translateDate($this->entity->due_date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.due_date')];
|
$data['$due_date'] = ['value' => $this->translateDate($this->entity->due_date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.due_date')];
|
||||||
|
|
||||||
$data['$partial_due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
$data['$partial_due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
||||||
|
|
||||||
$data['$dueDate'] = &$data['$due_date'];
|
$data['$dueDate'] = &$data['$due_date'];
|
||||||
$data['$purchase_order.due_date'] = &$data['$due_date'];
|
$data['$purchase_order.due_date'] = &$data['$due_date'];
|
||||||
|
|
||||||
$data['$payment_due'] = ['value' => $this->translateDate($this->entity->due_date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.payment_due')];
|
$data['$payment_due'] = ['value' => $this->translateDate($this->entity->due_date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.payment_due')];
|
||||||
$data['$purchase_order.po_number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.po_number')];
|
$data['$purchase_order.po_number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.po_number')];
|
||||||
|
|
||||||
$data['$poNumber'] = &$data['$purchase_order.po_number'];
|
$data['$poNumber'] = &$data['$purchase_order.po_number'];
|
||||||
@ -153,7 +153,7 @@ class VendorHtmlEngine
|
|||||||
$data['$viewButton'] = &$data['$view_link'];
|
$data['$viewButton'] = &$data['$view_link'];
|
||||||
$data['$view_button'] = &$data['$view_link'];
|
$data['$view_button'] = &$data['$view_link'];
|
||||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_invoice')];
|
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_invoice')];
|
||||||
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.date')];
|
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.date')];
|
||||||
|
|
||||||
$data['$purchase_order.number'] = &$data['$number'];
|
$data['$purchase_order.number'] = &$data['$number'];
|
||||||
$data['$purchase_order.date'] = &$data['$date'];
|
$data['$purchase_order.date'] = &$data['$date'];
|
||||||
@ -177,7 +177,7 @@ class VendorHtmlEngine
|
|||||||
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->partial, $this->vendor) ?: ' ', 'label' => ctrans('texts.partial_due')];
|
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->partial, $this->vendor) ?: ' ', 'label' => ctrans('texts.partial_due')];
|
||||||
$data['$balance_due_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
$data['$balance_due_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
||||||
$data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
$data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
||||||
$data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
$data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->company->date_format(), $this->vendor->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
||||||
} else {
|
} else {
|
||||||
if ($this->entity->status_id == 1) {
|
if ($this->entity->status_id == 1) {
|
||||||
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->vendor) ?: ' ', 'label' => ctrans('texts.balance_due')];
|
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->vendor) ?: ' ', 'label' => ctrans('texts.balance_due')];
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
"phpstan/phpstan": "^1.9",
|
"phpstan/phpstan": "^1.9",
|
||||||
"phpunit/phpunit": "^9.5.10",
|
"phpunit/phpunit": "^9.5.10",
|
||||||
"spatie/laravel-ignition": "^1.0",
|
"spatie/laravel-ignition": "^1.0",
|
||||||
|
"spaze/phpstan-stripe": "^3.0",
|
||||||
"vimeo/psalm": "^4.24"
|
"vimeo/psalm": "^4.24"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
64
composer.lock
generated
64
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "be16996524279f340c44e2f6c9a0ba53",
|
"content-hash": "9d7348352c913eb82fcca2e67670e1f8",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adrienrn/php-mimetyper",
|
"name": "adrienrn/php-mimetyper",
|
||||||
@ -17898,6 +17898,68 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-01-03T19:28:04+00:00"
|
"time": "2023-01-03T19:28:04+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spaze/phpstan-stripe",
|
||||||
|
"version": "v3.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spaze/phpstan-stripe.git",
|
||||||
|
"reference": "6e5debe4f65b15192a28bd01f01670ced8250443"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spaze/phpstan-stripe/zipball/6e5debe4f65b15192a28bd01f01670ced8250443",
|
||||||
|
"reference": "6e5debe4f65b15192a28bd01f01670ced8250443",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.0",
|
||||||
|
"phpstan/phpstan": "^1.7"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"nikic/php-parser": "^4.13",
|
||||||
|
"php-parallel-lint/php-console-highlighter": "^1.0",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||||
|
"spaze/coding-standard": "^1.1",
|
||||||
|
"stripe/stripe-php": "^8.7|^9.9|^10.8"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"phpstan/extension-installer": "Allows automatic requirement of extension.neon"
|
||||||
|
},
|
||||||
|
"type": "phpstan-extension",
|
||||||
|
"extra": {
|
||||||
|
"phpstan": {
|
||||||
|
"includes": [
|
||||||
|
"extension.neon"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Spaze\\PHPStan\\Stripe\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michal Špaček",
|
||||||
|
"email": "mail@michalspacek.cz",
|
||||||
|
"homepage": "https://www.michalspacek.cz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Stripe SDK extension for PHPStan",
|
||||||
|
"keywords": [
|
||||||
|
"static analysis"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/spaze/phpstan-stripe/issues",
|
||||||
|
"source": "https://github.com/spaze/phpstan-stripe/tree/v3.0.0"
|
||||||
|
},
|
||||||
|
"time": "2023-03-06T00:39:29+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php81",
|
"name": "symfony/polyfill-php81",
|
||||||
"version": "v1.27.0",
|
"version": "v1.27.0",
|
||||||
|
@ -15,8 +15,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => env('APP_VERSION','5.6.28'),
|
'app_version' => env('APP_VERSION','5.6.30'),
|
||||||
'app_tag' => env('APP_TAG','5.6.28'),
|
'app_tag' => env('APP_TAG','5.6.30'),
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', ''),
|
'api_secret' => env('API_SECRET', ''),
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$cur = \App\Models\Currency::find(118);
|
||||||
|
|
||||||
|
if(!$cur) {
|
||||||
|
$cur = new \App\Models\Currency();
|
||||||
|
$cur->id = 118;
|
||||||
|
$cur->code = 'NIO';
|
||||||
|
$cur->name = 'Nicaraguan Córdoba';
|
||||||
|
$cur->symbol = 'C$';
|
||||||
|
$cur->thousand_separator = ',';
|
||||||
|
$cur->decimal_separator = '.';
|
||||||
|
$cur->precision = 2;
|
||||||
|
$cur->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema::table('vendors', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('language_id')->nullable();
|
||||||
|
$table->timestamp('last_login')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
@ -140,6 +140,7 @@ class CurrenciesSeeder extends Seeder
|
|||||||
['id' => 115, 'name' => 'Libyan Dinar', 'code' => 'LYD', 'symbol' => 'LD', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
['id' => 115, 'name' => 'Libyan Dinar', 'code' => 'LYD', 'symbol' => 'LD', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||||
['id' => 116, 'name' => 'Silver Troy Ounce', 'code' => 'XAG', 'symbol' => 'XAG', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
['id' => 116, 'name' => 'Silver Troy Ounce', 'code' => 'XAG', 'symbol' => 'XAG', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||||
['id' => 117, 'name' => 'Gold Troy Ounce', 'code' => 'XAU', 'symbol' => 'XAU', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
['id' => 117, 'name' => 'Gold Troy Ounce', 'code' => 'XAU', 'symbol' => 'XAU', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||||
|
['id' => 118, 'name' => 'Nicaraguan Córdoba', 'code' => 'NIO', 'symbol' => 'C$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
|
@ -5144,6 +5144,19 @@ $LANG = array(
|
|||||||
'drop_files_here' => 'Drop files here',
|
'drop_files_here' => 'Drop files here',
|
||||||
'upload_files' => 'Upload Files',
|
'upload_files' => 'Upload Files',
|
||||||
'download_e_invoice' => 'Download E-Invoice',
|
'download_e_invoice' => 'Download E-Invoice',
|
||||||
|
'triangular_tax_info' => 'Intra-community triangular transaction',
|
||||||
|
'intracommunity_tax_info' => 'Tax-free intra-community delivery',
|
||||||
|
'reverse_tax_info' => 'Please note that this supply is subject to reverse charge',
|
||||||
|
'currency_nicaraguan_cordoba' => 'Nicaraguan Córdoba',
|
||||||
|
'public' => 'Public',
|
||||||
|
'private' => 'Private',
|
||||||
|
'image' => 'Image',
|
||||||
|
'other' => 'Other',
|
||||||
|
'linked_to' => 'Linked To',
|
||||||
|
'file_saved_in_path' => 'The file has been saved in :path',
|
||||||
|
'unlinked_transactions' => 'Successfully unlinked :count transactions',
|
||||||
|
'unlinked_transaction' => 'Successfully unlinked transaction',
|
||||||
|
'view_dashboard_permission' => 'Allow user to access the dashboard, data is limited to available permissions',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -2189,7 +2189,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'credit_total' => 'Total du crédit',
|
'credit_total' => 'Total du crédit',
|
||||||
'mark_billable' => 'Marquer comme facturable',
|
'mark_billable' => 'Marquer comme facturable',
|
||||||
'billed' => 'Facturé',
|
'billed' => 'Facturé',
|
||||||
'company_variables' => 'Variables de la compagnie',
|
'company_variables' => 'Variables de l\'entreprise',
|
||||||
'client_variables' => 'Variables du client',
|
'client_variables' => 'Variables du client',
|
||||||
'invoice_variables' => 'Variables de facture',
|
'invoice_variables' => 'Variables de facture',
|
||||||
'navigation_variables' => 'Variables de navigation',
|
'navigation_variables' => 'Variables de navigation',
|
||||||
@ -2396,6 +2396,9 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
|
|
||||||
'currency_cuban_peso' => 'Cuban Peso',
|
'currency_cuban_peso' => 'Cuban Peso',
|
||||||
'currency_bz_dollar' => 'Dollar bélizien',
|
'currency_bz_dollar' => 'Dollar bélizien',
|
||||||
|
'currency_libyan_dinar' => 'Dinar libyen',
|
||||||
|
'currency_silver_troy_ounce' => 'Once troy d\'argent',
|
||||||
|
'currency_gold_troy_ounce' => 'Once troy d\'or',
|
||||||
|
|
||||||
'review_app_help' => 'Nous espérons que votre utilisation de cette application vous est agréable.<br/>Un commentaire de votre part serait grandement apprécié!',
|
'review_app_help' => 'Nous espérons que votre utilisation de cette application vous est agréable.<br/>Un commentaire de votre part serait grandement apprécié!',
|
||||||
'writing_a_review' => 'rédiger un commentaire',
|
'writing_a_review' => 'rédiger un commentaire',
|
||||||
@ -3264,8 +3267,8 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'contact_custom_value4' => 'Valeur personnalisée du contact 4',
|
'contact_custom_value4' => 'Valeur personnalisée du contact 4',
|
||||||
'assigned_to_id' => 'Assigné à ID',
|
'assigned_to_id' => 'Assigné à ID',
|
||||||
'created_by_id' => 'Créé par ID',
|
'created_by_id' => 'Créé par ID',
|
||||||
'add_column' => 'Ajouter colonne',
|
'add_column' => 'Ajouter une colonne',
|
||||||
'edit_columns' => 'Éditer colonne',
|
'edit_columns' => 'Éditer les colonnes',
|
||||||
'to_learn_about_gogle_fonts' => 'en savoir plus sur Google Fonts',
|
'to_learn_about_gogle_fonts' => 'en savoir plus sur Google Fonts',
|
||||||
'refund_date' => 'Date de remboursement',
|
'refund_date' => 'Date de remboursement',
|
||||||
'multiselect' => 'Sélection multiple',
|
'multiselect' => 'Sélection multiple',
|
||||||
@ -3320,7 +3323,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'item_tax_rates' => 'Taux de taxe par article',
|
'item_tax_rates' => 'Taux de taxe par article',
|
||||||
'configure_rates' => 'Configuration des taux',
|
'configure_rates' => 'Configuration des taux',
|
||||||
'tax_settings_rates' => 'Taux de taxe',
|
'tax_settings_rates' => 'Taux de taxe',
|
||||||
'accent_color' => 'Couleur de mise en évidence',
|
'accent_color' => 'Couleur d\'accent',
|
||||||
'comma_sparated_list' => 'Liste séparée par virgule',
|
'comma_sparated_list' => 'Liste séparée par virgule',
|
||||||
'single_line_text' => 'Ligne de texte simple',
|
'single_line_text' => 'Ligne de texte simple',
|
||||||
'multi_line_text' => 'Zone de texte multilignes',
|
'multi_line_text' => 'Zone de texte multilignes',
|
||||||
@ -3415,7 +3418,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'quote_details' => 'Informations de la soumission',
|
'quote_details' => 'Informations de la soumission',
|
||||||
'credit_details' => 'Informations de crédit',
|
'credit_details' => 'Informations de crédit',
|
||||||
'product_columns' => 'Colonnes produit',
|
'product_columns' => 'Colonnes produit',
|
||||||
'task_columns' => 'Colonnes tâches',
|
'task_columns' => 'Colonnes tâche',
|
||||||
'add_field' => 'Ajouter un champ',
|
'add_field' => 'Ajouter un champ',
|
||||||
'all_events' => 'Ajouter un événement',
|
'all_events' => 'Ajouter un événement',
|
||||||
'owned' => 'Propriétaire',
|
'owned' => 'Propriétaire',
|
||||||
@ -4209,7 +4212,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'copyright' => 'Droits d\'auteur',
|
'copyright' => 'Droits d\'auteur',
|
||||||
'user_created_user' => ':user a créé :created_user à :time',
|
'user_created_user' => ':user a créé :created_user à :time',
|
||||||
'company_deleted' => 'Entreprise supprimée',
|
'company_deleted' => 'Entreprise supprimée',
|
||||||
'company_deleted_body' => 'La compagnie [:company] a été supprimé par :user',
|
'company_deleted_body' => 'L\'entreprise [:company] a été supprimé par :user',
|
||||||
'back_to' => 'Retour à :url',
|
'back_to' => 'Retour à :url',
|
||||||
'stripe_connect_migration_title' => 'Connectez votre compte Stripe',
|
'stripe_connect_migration_title' => 'Connectez votre compte Stripe',
|
||||||
'stripe_connect_migration_desc' => 'Invoice Ninja v5 utilise Stripe Connect pour lier votre compte Stripe à Invoice Ninja. Cela fournit une couche de sécurité supplémentaire pour votre compte. Maintenant que vos données ont migré, vous devez autoriser Stripe à accepter les paiements dans la v5.<br><br>Pour ce faire, accédez à Paramètres > Paiements en ligne > Configurer les passerelles. Cliquez sur Stripe Connect, puis sous Paramètres, cliquez sur Configurer la passerelle. Cela vous amènera à Stripe pour autoriser Invoice Ninja et à votre retour, votre compte sera lié !',
|
'stripe_connect_migration_desc' => 'Invoice Ninja v5 utilise Stripe Connect pour lier votre compte Stripe à Invoice Ninja. Cela fournit une couche de sécurité supplémentaire pour votre compte. Maintenant que vos données ont migré, vous devez autoriser Stripe à accepter les paiements dans la v5.<br><br>Pour ce faire, accédez à Paramètres > Paiements en ligne > Configurer les passerelles. Cliquez sur Stripe Connect, puis sous Paramètres, cliquez sur Configurer la passerelle. Cela vous amènera à Stripe pour autoriser Invoice Ninja et à votre retour, votre compte sera lié !',
|
||||||
@ -4478,7 +4481,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'id' => 'Id',
|
'id' => 'Id',
|
||||||
'convert_to' => 'Convertir en',
|
'convert_to' => 'Convertir en',
|
||||||
'client_currency' => 'Devise du client',
|
'client_currency' => 'Devise du client',
|
||||||
'company_currency' => 'Devise de la compagnie',
|
'company_currency' => 'Devise de l\'entreprise',
|
||||||
'custom_emails_disabled_help' => 'Il est nécessaire de souscrire à un compte payant pour personnaliser les paramètres anti-pourriels',
|
'custom_emails_disabled_help' => 'Il est nécessaire de souscrire à un compte payant pour personnaliser les paramètres anti-pourriels',
|
||||||
'upgrade_to_add_company' => 'Augmenter votre plan pour ajouter des entreprises',
|
'upgrade_to_add_company' => 'Augmenter votre plan pour ajouter des entreprises',
|
||||||
'file_saved_in_downloads_folder' => 'Le fichier a été sauvegardé dans le dossier Téléchargements',
|
'file_saved_in_downloads_folder' => 'Le fichier a été sauvegardé dans le dossier Téléchargements',
|
||||||
@ -4944,7 +4947,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'sync_from' => 'Sync de',
|
'sync_from' => 'Sync de',
|
||||||
'gateway_payment_text' => 'Factures: :invoices pour :amount pour :client',
|
'gateway_payment_text' => 'Factures: :invoices pour :amount pour :client',
|
||||||
'gateway_payment_text_no_invoice' => 'Paiement sans facture d\'un montant de :amount pour le client :client',
|
'gateway_payment_text_no_invoice' => 'Paiement sans facture d\'un montant de :amount pour le client :client',
|
||||||
'click_to_variables' => 'Cliquez ici pour voir toutes les variables',
|
'click_to_variables' => 'Cliquez ici pour voir toutes les variables.',
|
||||||
'ship_to' => 'Livrer à',
|
'ship_to' => 'Livrer à',
|
||||||
'stripe_direct_debit_details' => 'Veuillez transférer dans le compte bancaire indiqué ci-dessus.',
|
'stripe_direct_debit_details' => 'Veuillez transférer dans le compte bancaire indiqué ci-dessus.',
|
||||||
'branch_name' => 'Nom de succursale',
|
'branch_name' => 'Nom de succursale',
|
||||||
@ -5127,9 +5130,13 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'activity_10_online' => ':contact a saisi un paiement :payment pour la facture :invoice pour :client',
|
'activity_10_online' => ':contact a saisi un paiement :payment pour la facture :invoice pour :client',
|
||||||
'activity_10_manual' => ':user a saisi un paiement :payment pour la facture :invoice pour :client',
|
'activity_10_manual' => ':user a saisi un paiement :payment pour la facture :invoice pour :client',
|
||||||
'default_payment_type' => 'Type de paiement par défaut',
|
'default_payment_type' => 'Type de paiement par défaut',
|
||||||
|
'number_precision' => 'Précision du nombre',
|
||||||
|
'number_precision_help' => 'Contrôle le nombre de décimales supportées dans l\'interface',
|
||||||
|
'is_tax_exempt' => 'Exonéré de taxe',
|
||||||
|
'drop_files_here' => 'Déposez les fichiers ici',
|
||||||
|
'upload_files' => 'Téléverser les fichiers',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
includes:
|
includes:
|
||||||
- ./vendor/nunomaduro/larastan/extension.neon
|
- ./vendor/nunomaduro/larastan/extension.neon
|
||||||
|
- ./vendor/spaze/phpstan-stripe/extension.neon
|
||||||
parameters:
|
parameters:
|
||||||
level: 2
|
level: 2
|
||||||
paths:
|
paths:
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Connecting your account using Stripe has been successfully completed.</p>
|
<p>Connecting your account using Stripe has been successfully completed.</p>
|
||||||
<span>Click <a class="font-semibold hover:underline" href="{{ url('/#/settings/company_gateways') }}">here</a> to continue.</span>
|
<span>Click <a class="font-semibold hover:underline" href="{{ $url ?? url('/#/settings/company_gateways') }}">here</a> to continue.</span>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.8rem;
|
padding-bottom: 0.8rem;
|
||||||
padding-left: 0.7rem;
|
padding-left: 0.7rem;
|
||||||
page-break-inside:auto;
|
/*page-break-inside:auto; this may cause weird breaking*/
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
|
|||||||
Route::resource('clients', ClientController::class); // name = (clients. index / create / show / update / destroy / edit
|
Route::resource('clients', ClientController::class); // name = (clients. index / create / show / update / destroy / edit
|
||||||
Route::put('clients/{client}/upload', [ClientController::class, 'upload'])->name('clients.upload');
|
Route::put('clients/{client}/upload', [ClientController::class, 'upload'])->name('clients.upload');
|
||||||
Route::post('clients/{client}/purge', [ClientController::class, 'purge'])->name('clients.purge')->middleware('password_protected');
|
Route::post('clients/{client}/purge', [ClientController::class, 'purge'])->name('clients.purge')->middleware('password_protected');
|
||||||
|
Route::post('clients/{client}/updateTaxData', [ClientController::class, 'updateTaxData'])->name('clients.update_tax_data')->middleware('throttle:3,1');
|
||||||
Route::post('clients/{client}/{mergeable_client}/merge', [ClientController::class, 'merge'])->name('clients.merge')->middleware('password_protected');
|
Route::post('clients/{client}/{mergeable_client}/merge', [ClientController::class, 'merge'])->name('clients.merge')->middleware('password_protected');
|
||||||
Route::post('clients/bulk', [ClientController::class, 'bulk'])->name('clients.bulk');
|
Route::post('clients/bulk', [ClientController::class, 'bulk'])->name('clients.bulk');
|
||||||
|
|
||||||
@ -171,11 +172,11 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
|
|||||||
|
|
||||||
Route::post('companies/purge/{company}', [MigrationController::class, 'purgeCompany'])->middleware('password_protected');
|
Route::post('companies/purge/{company}', [MigrationController::class, 'purgeCompany'])->middleware('password_protected');
|
||||||
Route::post('companies/purge_save_settings/{company}', [MigrationController::class, 'purgeCompanySaveSettings'])->middleware('password_protected');
|
Route::post('companies/purge_save_settings/{company}', [MigrationController::class, 'purgeCompanySaveSettings'])->middleware('password_protected');
|
||||||
|
|
||||||
Route::resource('companies', CompanyController::class); // name = (companies. index / create / show / update / destroy / edit
|
Route::resource('companies', CompanyController::class); // name = (companies. index / create / show / update / destroy / edit
|
||||||
|
|
||||||
Route::put('companies/{company}/upload', [CompanyController::class, 'upload']);
|
Route::put('companies/{company}/upload', [CompanyController::class, 'upload']);
|
||||||
Route::post('companies/{company}/default', [CompanyController::class, 'default']);
|
Route::post('companies/{company}/default', [CompanyController::class, 'default']);
|
||||||
|
Route::post('companies/updateOriginTaxData/{company}', [CompanyController::class, 'updateOriginTaxData'])->middleware('throttle:3,1');
|
||||||
|
|
||||||
Route::get('company_ledger', [CompanyLedgerController::class, 'index'])->name('company_ledger.index');
|
Route::get('company_ledger', [CompanyLedgerController::class, 'index'])->name('company_ledger.index');
|
||||||
|
|
||||||
@ -382,6 +383,8 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
|
|||||||
Route::post('subscriptions/bulk', [SubscriptionController::class, 'bulk'])->name('subscriptions.bulk');
|
Route::post('subscriptions/bulk', [SubscriptionController::class, 'bulk'])->name('subscriptions.bulk');
|
||||||
Route::get('statics', StaticController::class);
|
Route::get('statics', StaticController::class);
|
||||||
// Route::post('apple_pay/upload_file','ApplyPayController::class, 'upload');
|
// Route::post('apple_pay/upload_file','ApplyPayController::class, 'upload');
|
||||||
|
|
||||||
|
Route::post('api/v1/yodlee/status/{account_number}', [YodleeController::class, 'accountStatus']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::post('api/v1/sms_reset', [TwilioController::class, 'generate2faResetCode'])->name('sms_reset.generate')->middleware('throttle:10,1');
|
Route::post('api/v1/sms_reset', [TwilioController::class, 'generate2faResetCode'])->name('sms_reset.generate')->middleware('throttle:10,1');
|
||||||
|
@ -41,6 +41,8 @@ class ClientTest extends TestCase
|
|||||||
use DatabaseTransactions;
|
use DatabaseTransactions;
|
||||||
use MockAccountData;
|
use MockAccountData;
|
||||||
|
|
||||||
|
public $faker;
|
||||||
|
|
||||||
protected function setUp() :void
|
protected function setUp() :void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -63,7 +65,6 @@ class ClientTest extends TestCase
|
|||||||
$this->makeTestData();
|
$this->makeTestData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testClientMergeContactDrop()
|
public function testClientMergeContactDrop()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ class CreditTest extends TestCase
|
|||||||
use DatabaseTransactions;
|
use DatabaseTransactions;
|
||||||
use MockAccountData;
|
use MockAccountData;
|
||||||
|
|
||||||
|
public $faker;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -58,6 +58,78 @@ class PaymentV2Test extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUsingDraftCreditsForPayments()
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice = Invoice::factory()->create([
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'status_id' => Invoice::STATUS_SENT,
|
||||||
|
'uses_inclusive_taxes' => false,
|
||||||
|
'amount' => 20,
|
||||||
|
'balance' => 20,
|
||||||
|
'discount' => 0,
|
||||||
|
'number' => uniqid("st", true),
|
||||||
|
'line_items' => []
|
||||||
|
]);
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::generateCredit();
|
||||||
|
$item['cost'] = 20;
|
||||||
|
$item['quantity'] = 1;
|
||||||
|
|
||||||
|
$credit = Credit::factory()->create([
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'status_id' => Credit::STATUS_DRAFT,
|
||||||
|
'uses_inclusive_taxes' => false,
|
||||||
|
'amount' => 20,
|
||||||
|
'balance' => 0,
|
||||||
|
'discount' => 0,
|
||||||
|
'number' => uniqid("st", true),
|
||||||
|
'line_items' => [
|
||||||
|
$item
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'client_id' => $this->client->hashed_id,
|
||||||
|
'invoices' => [
|
||||||
|
[
|
||||||
|
'invoice_id' => $invoice->hashed_id,
|
||||||
|
'amount' => 20,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'credits' => [
|
||||||
|
[
|
||||||
|
'credit_id' => $credit->hashed_id,
|
||||||
|
'amount' => 20,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'date' => '2020/12/12',
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = null;
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/payments?include=invoices', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$payment_id = $arr['data']['id'];
|
||||||
|
$this->assertEquals(Credit::STATUS_APPLIED, $credit->fresh()->status_id);
|
||||||
|
$this->assertEquals(Invoice::STATUS_PAID, $invoice->fresh()->status_id);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $credit->fresh()->balance);
|
||||||
|
$this->assertEquals(0, $invoice->fresh()->balance);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testStorePaymentWithCreditsThenDeletingInvoices()
|
public function testStorePaymentWithCreditsThenDeletingInvoices()
|
||||||
{
|
{
|
||||||
$client = Client::factory()->create(['company_id' =>$this->company->id, 'user_id' => $this->user->id, 'balance' => 20, 'paid_to_date' => 0]);
|
$client = Client::factory()->create(['company_id' =>$this->company->id, 'user_id' => $this->user->id, 'balance' => 20, 'paid_to_date' => 0]);
|
||||||
|
@ -38,6 +38,8 @@ class UserTest extends TestCase
|
|||||||
|
|
||||||
private $default_email = 'attach@gmail.com';
|
private $default_email = 'attach@gmail.com';
|
||||||
|
|
||||||
|
public $faker;
|
||||||
|
|
||||||
protected function setUp() :void
|
protected function setUp() :void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -50,7 +52,7 @@ class UserTest extends TestCase
|
|||||||
|
|
||||||
Model::reguard();
|
Model::reguard();
|
||||||
|
|
||||||
$this->withoutExceptionHandling();
|
// $this->withoutExceptionHandling();
|
||||||
|
|
||||||
$this->withoutMiddleware(
|
$this->withoutMiddleware(
|
||||||
ThrottleRequests::class,
|
ThrottleRequests::class,
|
||||||
@ -58,10 +60,9 @@ class UserTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUserAttemptingtToDeleteThemselves()
|
private function mockAccount()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
$account = Account::factory()->create([
|
$account = Account::factory()->create([
|
||||||
'hosted_client_count' => 1000,
|
'hosted_client_count' => 1000,
|
||||||
'hosted_company_count' => 1000,
|
'hosted_company_count' => 1000,
|
||||||
@ -74,6 +75,7 @@ class UserTest extends TestCase
|
|||||||
'account_id' => $this->account->id,
|
'account_id' => $this->account->id,
|
||||||
'confirmation_code' => 'xyz123',
|
'confirmation_code' => 'xyz123',
|
||||||
'email' => $this->faker->unique()->safeEmail(),
|
'email' => $this->faker->unique()->safeEmail(),
|
||||||
|
'password' => \Illuminate\Support\Facades\Hash::make('ALongAndBriliantPassword'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$settings = CompanySettings::defaults();
|
$settings = CompanySettings::defaults();
|
||||||
@ -101,18 +103,164 @@ class UserTest extends TestCase
|
|||||||
$company_token->name = 'test token';
|
$company_token->name = 'test token';
|
||||||
$company_token->token = $token;
|
$company_token->token = $token;
|
||||||
$company_token->is_system = true;
|
$company_token->is_system = true;
|
||||||
|
$company_token->save();
|
||||||
|
|
||||||
|
return $company_token;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUserResponse()
|
||||||
|
{
|
||||||
|
$company_token = $this->mockAccount();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'first_name' => 'hey',
|
||||||
|
'last_name' => 'you',
|
||||||
|
'email' => 'normal_user@gmail.com',
|
||||||
|
'company_user' => [
|
||||||
|
'is_admin' => true,
|
||||||
|
'is_owner' => false,
|
||||||
|
'permissions' => 'create_client,create_invoice',
|
||||||
|
],
|
||||||
|
'phone' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->post('/api/v1/users?include=company_user', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$user = $response->json();
|
||||||
|
$user_id = $user['data']['id'];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->get('/api/v1/users', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertCount(2, $arr['data']);
|
||||||
|
|
||||||
|
//archive the user we just created:
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'action' => 'archive',
|
||||||
|
'ids' => [$user_id],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->postJson('/api/v1/users/bulk', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$this->assertCount(1, $response->json()['data']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->get("/api/v1/users?without={$company_token->user->hashed_id}");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$this->assertCount(1, $response->json()['data']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->get("/api/v1/users?without={$company_token->user->hashed_id}&status=active");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$this->assertCount(0, $response->json()['data']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->get("/api/v1/users?without={$company_token->user->hashed_id}&status=archived");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$this->assertCount(1, $response->json()['data']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $company_token->token,
|
||||||
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
|
])->get("/api/v1/users?without={$company_token->user->hashed_id}&status=deleted");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$this->assertCount(0, $response->json()['data']);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUserAttemptingtToDeleteThemselves()
|
||||||
|
{
|
||||||
|
|
||||||
|
$account = Account::factory()->create([
|
||||||
|
'hosted_client_count' => 1000,
|
||||||
|
'hosted_company_count' => 1000,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$account->num_users = 3;
|
||||||
|
$account->save();
|
||||||
|
|
||||||
|
$user = User::factory()->create([
|
||||||
|
'account_id' => $this->account->id,
|
||||||
|
'confirmation_code' => 'xyz123',
|
||||||
|
'email' => $this->faker->unique()->safeEmail(),
|
||||||
|
'password' => \Illuminate\Support\Facades\Hash::make('ALongAndBriliantPassword'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$settings = CompanySettings::defaults();
|
||||||
|
$settings->client_online_payment_notification = false;
|
||||||
|
$settings->client_manual_payment_notification = false;
|
||||||
|
|
||||||
|
$company = Company::factory()->create([
|
||||||
|
'account_id' => $account->id,
|
||||||
|
'settings' => $settings,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$cu = CompanyUserFactory::create($user->id, $company->id, $account->id);
|
||||||
|
$cu->is_owner = true;
|
||||||
|
$cu->is_admin = true;
|
||||||
|
$cu->is_locked = false;
|
||||||
|
$cu->save();
|
||||||
|
|
||||||
|
$token = \Illuminate\Support\Str::random(64);
|
||||||
|
|
||||||
|
$company_token = new CompanyToken();
|
||||||
|
$company_token->user_id = $user->id;
|
||||||
|
$company_token->company_id = $company->id;
|
||||||
|
$company_token->account_id = $account->id;
|
||||||
|
$company_token->name = 'test token';
|
||||||
|
$company_token->token = $token;
|
||||||
|
$company_token->is_system = true;
|
||||||
|
$company_token->save();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'ids' => [$user->hashed_id],
|
'ids' => [$user->hashed_id],
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
'X-API-SECRET' => config('ninja.api_secret'),
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
'X-API-TOKEN' => $token,
|
'X-API-TOKEN' => $token,
|
||||||
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||||
])->postJson('/api/v1/users/bulk?action=dete', $data)
|
])->postJson('/api/v1/users/bulk?action=delete', $data);
|
||||||
->assertStatus(403);
|
|
||||||
|
|
||||||
|
nlog($response);
|
||||||
|
|
||||||
|
$response->assertStatus(401);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,13 +11,15 @@
|
|||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use Tests\MockAccountData;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use App\Events\Vendor\VendorContactLoggedIn;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Tests\MockAccountData;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Tests\TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
@ -29,6 +31,8 @@ class VendorApiTest extends TestCase
|
|||||||
use DatabaseTransactions;
|
use DatabaseTransactions;
|
||||||
use MockAccountData;
|
use MockAccountData;
|
||||||
|
|
||||||
|
public $faker;
|
||||||
|
|
||||||
protected function setUp() :void
|
protected function setUp() :void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -42,6 +46,73 @@ class VendorApiTest extends TestCase
|
|||||||
Model::reguard();
|
Model::reguard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testVendorLoggedInEvents()
|
||||||
|
{
|
||||||
|
$v = \App\Models\Vendor::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vc = \App\Models\VendorContact::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'vendor_id' => $v->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertNull($v->last_login);
|
||||||
|
$this->assertNull($vc->last_login);
|
||||||
|
|
||||||
|
event(new VendorContactLoggedIn($vc, $this->company, Ninja::eventVars()));
|
||||||
|
|
||||||
|
$this->expectsEvents([VendorContactLoggedIn::class]);
|
||||||
|
|
||||||
|
// $vc->fresh();
|
||||||
|
// $v->fresh();
|
||||||
|
|
||||||
|
// $this->assertNotNull($vc->fresh()->last_login);
|
||||||
|
// $this->assertNotNull($v->fresh()->last_login);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testVendorLocale()
|
||||||
|
{
|
||||||
|
$v = \App\Models\Vendor::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertNotNull($v->locale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testVendorLocaleEn()
|
||||||
|
{
|
||||||
|
$v = \App\Models\Vendor::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'language_id' => '1'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals('en', $v->locale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testVendorLocaleEnCompanyFallback()
|
||||||
|
{
|
||||||
|
$settings = $this->company->settings;
|
||||||
|
$settings->language_id = '2';
|
||||||
|
|
||||||
|
$c = \App\Models\Company::factory()->create([
|
||||||
|
'account_id' => $this->account->id,
|
||||||
|
'settings' => $settings,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = \App\Models\Vendor::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $c->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals('it', $v->locale());
|
||||||
|
}
|
||||||
|
|
||||||
public function testVendorGetFilter()
|
public function testVendorGetFilter()
|
||||||
{
|
{
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
@ -52,10 +123,79 @@ class VendorApiTest extends TestCase
|
|||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testAddVendorLanguage200()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName(),
|
||||||
|
'language_id' => 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/vendors', $data)->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$this->assertEquals('2', $arr['data']['language_id']);
|
||||||
|
|
||||||
|
$id = $arr['data']['id'];
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'language_id' => 3,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/vendors/{$id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$this->assertEquals('3', $arr['data']['language_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddVendorLanguage422()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName(),
|
||||||
|
'language_id' => '4431',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/vendors', $data)->assertStatus(422);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testAddVendorLanguage()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName(),
|
||||||
|
'language_id' => '1',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/vendors', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals('1', $arr['data']['language_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testAddVendorToInvoice()
|
public function testAddVendorToInvoice()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'name' => $this->faker->firstName(),
|
'name' => $this->faker->firstName(),
|
||||||
|
'language_id' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
|
144
tests/Integration/DTO/AccountSummaryTest.php
Normal file
144
tests/Integration/DTO/AccountSummaryTest.php
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<?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=>//www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tests\Integration\DTO;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
class AccountSummaryTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
private $data = [
|
||||||
|
[
|
||||||
|
"CONTAINER"=> "bank",
|
||||||
|
"providerAccountId"=> 330,
|
||||||
|
"accountName"=> "Business Acct",
|
||||||
|
"accountStatus"=> "ACTIVE",
|
||||||
|
"accountNumber"=> "1012",
|
||||||
|
"aggregationSource"=> "USER",
|
||||||
|
"isAsset"=> true,
|
||||||
|
"balance"=> [
|
||||||
|
"currency"=> "AUD",
|
||||||
|
"amount"=> 44.98,
|
||||||
|
],
|
||||||
|
"id"=> 19315,
|
||||||
|
"includeInNetWorth"=> true,
|
||||||
|
"providerId"=> "3857",
|
||||||
|
"providerName"=> "Bank",
|
||||||
|
"isManual"=> false,
|
||||||
|
"availableBalance"=> [
|
||||||
|
"currency"=> "AUD",
|
||||||
|
"amount"=> 34.98,
|
||||||
|
],
|
||||||
|
"currentBalance"=> [
|
||||||
|
"currency"=> "AUD",
|
||||||
|
"amount"=> 344.98,
|
||||||
|
],
|
||||||
|
"accountType"=> "CHECKING",
|
||||||
|
"displayedName"=> "after David",
|
||||||
|
"createdDate"=> "2023-01-10T08=>29=>07Z",
|
||||||
|
"classification"=> "",
|
||||||
|
"lastUpdated"=> "2023-08-01T23=>50=>13Z",
|
||||||
|
"nickname"=> "Busines Acct",
|
||||||
|
"bankTransferCode"=> [
|
||||||
|
[
|
||||||
|
"id"=> "062",
|
||||||
|
"type"=> "BSB",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"dataset"=> [
|
||||||
|
[
|
||||||
|
"name"=> "BASIC_AGG_DATA",
|
||||||
|
"additionalStatus"=> "AVAILABLE_DATA_RETRIEVED",
|
||||||
|
"updateEligibility"=> "ALLOW_UPDATE",
|
||||||
|
"lastUpdated"=> "2023-08-01T23=>49=>53Z",
|
||||||
|
"lastUpdateAttempt"=> "2023-08-01T23=>49=>53Z",
|
||||||
|
"nextUpdateScheduled"=> "2023-08-03T14=>45=>14Z",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
private $bad_data = [
|
||||||
|
[
|
||||||
|
"CONTAINER"=> "bank",
|
||||||
|
"providerAccountId"=> 10090,
|
||||||
|
"accountName"=> "Business Trans Acct",
|
||||||
|
// "accountStatus"=> "ACTIVE",
|
||||||
|
"accountNumber"=> "4402",
|
||||||
|
"aggregationSource"=> "USER",
|
||||||
|
"isAsset"=> true,
|
||||||
|
"balance"=> [
|
||||||
|
"currency"=> "AUD",
|
||||||
|
"amount"=> 34.98,
|
||||||
|
],
|
||||||
|
"id"=> 19315,
|
||||||
|
"includeInNetWorth"=> true,
|
||||||
|
"providerId"=> "37",
|
||||||
|
"providerName"=> "Bank",
|
||||||
|
"isManual"=> false,
|
||||||
|
// "availableBalance"=> [
|
||||||
|
// "currency"=> "AUD",
|
||||||
|
// "amount"=> 7.98,
|
||||||
|
// ],
|
||||||
|
"currentBalance"=> [
|
||||||
|
"currency"=> "AUD",
|
||||||
|
"amount"=> 344.98,
|
||||||
|
],
|
||||||
|
"accountType"=> "CHECKING",
|
||||||
|
"displayedName"=> "after David",
|
||||||
|
"createdDate"=> "2023-01-10T08=>29=>07Z",
|
||||||
|
"classification"=> "SMALL_BUSINESS",
|
||||||
|
"lastUpdated"=> "2023-08-01T23=>50=>13Z",
|
||||||
|
"nickname"=> "Busines Acct",
|
||||||
|
"bankTransferCode"=> [
|
||||||
|
[
|
||||||
|
"id"=> "060",
|
||||||
|
"type"=> "BSB",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"dataset"=> [
|
||||||
|
[
|
||||||
|
"name"=> "BASIC_AGG_DATA",
|
||||||
|
"additionalStatus"=> "AVAILABLE_DATA_RETRIEVED",
|
||||||
|
"updateEligibility"=> "ALLOW_UPDATE",
|
||||||
|
"lastUpdated"=> "2023-08-01T23=>49=>53Z",
|
||||||
|
"lastUpdateAttempt"=> "2023-08-01T23=>49=>53Z",
|
||||||
|
"nextUpdateScheduled"=> "2023-08-03T14=>45=>14Z",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithBadDataTransformations()
|
||||||
|
{
|
||||||
|
$dtox = \App\Helpers\Bank\Yodlee\DTO\AccountSummary::from($this->bad_data[0]);
|
||||||
|
$this->assertEquals(19315, $dtox->id);
|
||||||
|
$this->assertEquals('', $dtox->account_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTransform()
|
||||||
|
{
|
||||||
|
$dto = \App\Helpers\Bank\Yodlee\DTO\AccountSummary::from($this->data[0]);
|
||||||
|
$this->assertEquals($dto->id, 19315);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user