mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
abeac50aba
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@ -35,7 +35,6 @@ jobs:
|
|||||||
php artisan key:generate
|
php artisan key:generate
|
||||||
php artisan optimize
|
php artisan optimize
|
||||||
php artisan storage:link
|
php artisan storage:link
|
||||||
php artisan livewire:publish
|
|
||||||
sudo php artisan cache:clear
|
sudo php artisan cache:clear
|
||||||
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
||||||
sudo find ./ -type d -exec chmod 755 {} \;
|
sudo find ./ -type d -exec chmod 755 {} \;
|
||||||
|
@ -1 +1 @@
|
|||||||
5.3.79
|
5.3.80
|
@ -37,6 +37,15 @@ class ClientSettings extends BaseSettings
|
|||||||
'size_id' => 'string',
|
'size_id' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static $property_casts = [
|
||||||
|
'language_id' => 'string',
|
||||||
|
'currency_id' => 'string',
|
||||||
|
'payment_terms' => 'string',
|
||||||
|
'valid_until' => 'string',
|
||||||
|
'default_task_rate' => 'float',
|
||||||
|
'send_reminders' => 'bool',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast object values and return entire class
|
* Cast object values and return entire class
|
||||||
* prevents missing properties from not being returned
|
* prevents missing properties from not being returned
|
||||||
|
@ -503,6 +503,7 @@ class CompanySettings extends BaseSettings
|
|||||||
'language_id' => 'string',
|
'language_id' => 'string',
|
||||||
'show_currency_code' => 'bool',
|
'show_currency_code' => 'bool',
|
||||||
'website' => 'string',
|
'website' => 'string',
|
||||||
|
'default_task_rate' => 'float',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,11 @@ class CloneQuoteToInvoiceFactory
|
|||||||
unset($quote_array['invoice_id']);
|
unset($quote_array['invoice_id']);
|
||||||
unset($quote_array['id']);
|
unset($quote_array['id']);
|
||||||
unset($quote_array['invitations']);
|
unset($quote_array['invitations']);
|
||||||
unset($quote_array['terms']);
|
|
||||||
|
//preserve terms if they exist on Quotes
|
||||||
|
if(array_key_exists('terms', $quote_array) && strlen($quote_array['terms']) < 2)
|
||||||
|
unset($quote_array['terms']);
|
||||||
|
|
||||||
// unset($quote_array['public_notes']);
|
// unset($quote_array['public_notes']);
|
||||||
unset($quote_array['footer']);
|
unset($quote_array['footer']);
|
||||||
unset($quote_array['design_id']);
|
unset($quote_array['design_id']);
|
||||||
|
@ -24,7 +24,6 @@ class CompanyGatewayFactory
|
|||||||
$company_gateway->require_billing_address = false;
|
$company_gateway->require_billing_address = false;
|
||||||
$company_gateway->require_shipping_address = false;
|
$company_gateway->require_shipping_address = false;
|
||||||
$company_gateway->config = encrypt(json_encode(new \stdClass));
|
$company_gateway->config = encrypt(json_encode(new \stdClass));
|
||||||
// $company_gateway->fees_and_limits = new FeesAndLimits;
|
|
||||||
|
|
||||||
return $company_gateway;
|
return $company_gateway;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,16 @@ class RecurringInvoiceToInvoiceFactory
|
|||||||
$invoice->custom_value4 = $recurring_invoice->custom_value4;
|
$invoice->custom_value4 = $recurring_invoice->custom_value4;
|
||||||
$invoice->amount = $recurring_invoice->amount;
|
$invoice->amount = $recurring_invoice->amount;
|
||||||
$invoice->uses_inclusive_taxes = $recurring_invoice->uses_inclusive_taxes;
|
$invoice->uses_inclusive_taxes = $recurring_invoice->uses_inclusive_taxes;
|
||||||
|
|
||||||
|
$invoice->custom_surcharge1 = $recurring_invoice->custom_surcharge1;
|
||||||
|
$invoice->custom_surcharge2 = $recurring_invoice->custom_surcharge2;
|
||||||
|
$invoice->custom_surcharge3 = $recurring_invoice->custom_surcharge3;
|
||||||
|
$invoice->custom_surcharge4 = $recurring_invoice->custom_surcharge4;
|
||||||
|
$invoice->custom_surcharge_tax1 = $recurring_invoice->custom_surcharge_tax1;
|
||||||
|
$invoice->custom_surcharge_tax2 = $recurring_invoice->custom_surcharge_tax2;
|
||||||
|
$invoice->custom_surcharge_tax3 = $recurring_invoice->custom_surcharge_tax3;
|
||||||
|
$invoice->custom_surcharge_tax4 = $recurring_invoice->custom_surcharge_tax4;
|
||||||
|
|
||||||
// $invoice->balance = $recurring_invoice->balance;
|
// $invoice->balance = $recurring_invoice->balance;
|
||||||
$invoice->user_id = $recurring_invoice->user_id;
|
$invoice->user_id = $recurring_invoice->user_id;
|
||||||
$invoice->assigned_user_id = $recurring_invoice->assigned_user_id;
|
$invoice->assigned_user_id = $recurring_invoice->assigned_user_id;
|
||||||
|
@ -168,7 +168,7 @@ abstract class QueryFilters
|
|||||||
|
|
||||||
public function created_at($value)
|
public function created_at($value)
|
||||||
{
|
{
|
||||||
$created_at = $value ? $value : 0;
|
$created_at = $value ? (int)$value : 0;
|
||||||
|
|
||||||
$created_at = date('Y-m-d H:i:s', $value);
|
$created_at = date('Y-m-d H:i:s', $value);
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ class BaseController extends Controller
|
|||||||
$query->with(
|
$query->with(
|
||||||
[
|
[
|
||||||
'company' => function ($query) use ($updated_at, $user) {
|
'company' => function ($query) use ($updated_at, $user) {
|
||||||
$query->whereNotNull('updated_at')->with('documents')->with('users');
|
$query->whereNotNull('updated_at')->with('documents','users');
|
||||||
},
|
},
|
||||||
'company.clients' => function ($query) use ($updated_at, $user) {
|
'company.clients' => function ($query) use ($updated_at, $user) {
|
||||||
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts.company', 'gateway_tokens', 'documents');
|
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts.company', 'gateway_tokens', 'documents');
|
||||||
@ -392,7 +392,7 @@ class BaseController extends Controller
|
|||||||
$query->with(
|
$query->with(
|
||||||
[
|
[
|
||||||
'company' => function ($query) use ($created_at, $user) {
|
'company' => function ($query) use ($created_at, $user) {
|
||||||
$query->whereNotNull('created_at')->with('documents');
|
$query->whereNotNull('created_at')->with('documents','users');
|
||||||
},
|
},
|
||||||
'company.designs'=> function ($query) use ($created_at, $user) {
|
'company.designs'=> function ($query) use ($created_at, $user) {
|
||||||
$query->where('created_at', '>=', $created_at)->with('company');
|
$query->where('created_at', '>=', $created_at)->with('company');
|
||||||
@ -466,7 +466,7 @@ class BaseController extends Controller
|
|||||||
$query->with(
|
$query->with(
|
||||||
[
|
[
|
||||||
'company' => function ($query) use ($created_at, $user) {
|
'company' => function ($query) use ($created_at, $user) {
|
||||||
$query->whereNotNull('created_at')->with('documents');
|
$query->whereNotNull('created_at')->with('documents','users');
|
||||||
},
|
},
|
||||||
'company.clients' => function ($query) use ($created_at, $user) {
|
'company.clients' => function ($query) use ($created_at, $user) {
|
||||||
$query->where('clients.created_at', '>=', $created_at)->with('contacts.company', 'gateway_tokens', 'documents');
|
$query->where('clients.created_at', '>=', $created_at)->with('contacts.company', 'gateway_tokens', 'documents');
|
||||||
@ -500,9 +500,6 @@ class BaseController extends Controller
|
|||||||
},
|
},
|
||||||
'company.groups' => function ($query) use ($created_at, $user) {
|
'company.groups' => function ($query) use ($created_at, $user) {
|
||||||
$query->where('created_at', '>=', $created_at)->with('documents');
|
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||||
|
|
||||||
// if(!$user->isAdmin())
|
|
||||||
// $query->where('group_settings.user_id', $user->id);
|
|
||||||
},
|
},
|
||||||
'company.invoices'=> function ($query) use ($created_at, $user) {
|
'company.invoices'=> function ($query) use ($created_at, $user) {
|
||||||
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
||||||
@ -583,13 +580,30 @@ class BaseController extends Controller
|
|||||||
$query->where('activities.user_id', $user->id);
|
$query->where('activities.user_id', $user->id);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
'company.webhooks'=> function ($query) use($user) {
|
||||||
|
|
||||||
|
if(!$user->isAdmin())
|
||||||
|
$query->where('webhooks.user_id', $user->id);
|
||||||
|
|
||||||
|
},
|
||||||
|
'company.tokens'=> function ($query) use($user) {
|
||||||
|
$query->where('company_tokens.user_id', $user->id);
|
||||||
|
},
|
||||||
|
'company.system_logs',
|
||||||
'company.subscriptions'=> function ($query) use($created_at, $user) {
|
'company.subscriptions'=> function ($query) use($created_at, $user) {
|
||||||
$query->where('created_at', '>=', $created_at);
|
$query->where('created_at', '>=', $created_at);
|
||||||
|
|
||||||
if(!$user->isAdmin())
|
if(!$user->isAdmin())
|
||||||
$query->where('subscriptions.user_id', $user->id);
|
$query->where('subscriptions.user_id', $user->id);
|
||||||
|
|
||||||
}
|
},
|
||||||
|
'company.recurring_expenses'=> function ($query) use ($created_at, $user) {
|
||||||
|
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||||
|
|
||||||
|
if(!$user->hasPermission('view_recurring_expense'))
|
||||||
|
$query->where('recurring_expenses.user_id', $user->id)->orWhere('recurring_expenses.assigned_user_id', $user->id);
|
||||||
|
|
||||||
|
},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@ class SelfUpdateController extends BaseController
|
|||||||
{
|
{
|
||||||
use DispatchesJobs;
|
use DispatchesJobs;
|
||||||
|
|
||||||
|
private array $purge_file_list = [
|
||||||
|
'bootstrap/cache/compiled.php',
|
||||||
|
'bootstrap/cache/config.php',
|
||||||
|
'bootstrap/cache/packages.php',
|
||||||
|
'bootstrap/cache/services.php',
|
||||||
|
'bootstrap/cache/routes-v7.php',
|
||||||
|
'bootstrap/cache/livewire-components.php',
|
||||||
|
];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -117,10 +126,12 @@ class SelfUpdateController extends BaseController
|
|||||||
|
|
||||||
unlink($file);
|
unlink($file);
|
||||||
|
|
||||||
$cacheCompiled = base_path('bootstrap/cache/compiled.php');
|
foreach($this->purge_file_list as $purge_file_path)
|
||||||
if (file_exists($cacheCompiled)) { unlink ($cacheCompiled); }
|
{
|
||||||
$cacheServices = base_path('bootstrap/cache/services.php');
|
$purge_file = base_path($purge_file_path);
|
||||||
if (file_exists($cacheServices)) { unlink ($cacheServices); }
|
if (file_exists($purge_file)) { unlink ($purge_file); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Artisan::call('clear-compiled');
|
Artisan::call('clear-compiled');
|
||||||
Artisan::call('route:clear');
|
Artisan::call('route:clear');
|
||||||
|
@ -36,7 +36,7 @@ class StoreClientRequest extends Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{nlog($this->input);
|
||||||
if ($this->input('documents') && is_array($this->input('documents'))) {
|
if ($this->input('documents') && is_array($this->input('documents'))) {
|
||||||
$documents = count($this->input('documents'));
|
$documents = count($this->input('documents'));
|
||||||
|
|
||||||
@ -95,6 +95,10 @@ class StoreClientRequest extends Request
|
|||||||
|
|
||||||
if (array_key_exists('settings', $input) && ! empty($input['settings'])) {
|
if (array_key_exists('settings', $input) && ! empty($input['settings'])) {
|
||||||
foreach ($input['settings'] as $key => $value) {
|
foreach ($input['settings'] as $key => $value) {
|
||||||
|
|
||||||
|
if($key == 'default_task_rate')
|
||||||
|
$value = floatval($value);
|
||||||
|
|
||||||
$settings->{$key} = $value;
|
$settings->{$key} = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,10 @@ class UpdateClientRequest extends Request
|
|||||||
if (! array_key_exists($key, $saveable_casts)) {
|
if (! array_key_exists($key, $saveable_casts)) {
|
||||||
unset($settings->{$key});
|
unset($settings->{$key});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($key == 'default_task_rate'){
|
||||||
|
$settings->default_task_rate = floatval($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $settings;
|
return $settings;
|
||||||
|
@ -140,7 +140,7 @@ class CompanyImport implements ShouldQueue
|
|||||||
'expenses',
|
'expenses',
|
||||||
'tasks',
|
'tasks',
|
||||||
'payments',
|
'payments',
|
||||||
'activities',
|
// 'activities',
|
||||||
// 'backups',
|
// 'backups',
|
||||||
'company_ledger',
|
'company_ledger',
|
||||||
'designs',
|
'designs',
|
||||||
|
@ -84,7 +84,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
|
|
||||||
//check if this reminder needs to be emailed
|
//check if this reminder needs to be emailed
|
||||||
//15-01-2022 - insert addition if block if send_reminders is definitely set
|
//15-01-2022 - insert addition if block if send_reminders is definitely set
|
||||||
if(in_array($reminder_template, ['reminder1','reminder2','reminder3','reminder_endless']) && $invoice->client->getSetting("enable_".$reminder_template) && $invoice->client->getSetting("send_reminders"))
|
if(in_array($reminder_template, ['reminder1','reminder2','reminder3','reminder_endless']) && $invoice->client->getSetting("enable_".$reminder_template) && $invoice->client->getSetting("send_reminders") && $invoice->company->account->isPaidHostedClient())
|
||||||
{
|
{
|
||||||
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
||||||
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
||||||
|
@ -190,7 +190,7 @@ class BaseModel extends Model
|
|||||||
|
|
||||||
public function numberFormatter()
|
public function numberFormatter()
|
||||||
{
|
{
|
||||||
$number = strlen($this->number) >= 1 ? $this->number : class_basename($this) . "_" . Str::random(5); ;
|
$number = strlen($this->number) >= 1 ? $this->number : class_basename($this) . "_" . Str::random(5);
|
||||||
|
|
||||||
$formatted_number = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $number);
|
$formatted_number = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $number);
|
||||||
// Remove any runs of periods (thanks falstro!)
|
// Remove any runs of periods (thanks falstro!)
|
||||||
|
@ -52,6 +52,8 @@ class CompanyUser extends Pivot
|
|||||||
|
|
||||||
protected $touches = ['user'];
|
protected $touches = ['user'];
|
||||||
|
|
||||||
|
protected $with = ['user','account'];
|
||||||
|
|
||||||
public function getEntityType()
|
public function getEntityType()
|
||||||
{
|
{
|
||||||
return self::class;
|
return self::class;
|
||||||
|
@ -42,7 +42,10 @@ class Webhook extends BaseModel
|
|||||||
const EVENT_LATE_INVOICE = 22;
|
const EVENT_LATE_INVOICE = 22;
|
||||||
const EVENT_EXPIRED_QUOTE = 23;
|
const EVENT_EXPIRED_QUOTE = 23;
|
||||||
const EVENT_REMIND_INVOICE = 24;
|
const EVENT_REMIND_INVOICE = 24;
|
||||||
|
const EVENT_PROJECT_CREATE = 25;
|
||||||
|
const EVENT_PROJECT_UPDATE = 26;
|
||||||
|
|
||||||
|
|
||||||
public static $valid_events = [
|
public static $valid_events = [
|
||||||
self::EVENT_CREATE_CLIENT,
|
self::EVENT_CREATE_CLIENT,
|
||||||
self::EVENT_CREATE_INVOICE,
|
self::EVENT_CREATE_INVOICE,
|
||||||
@ -68,6 +71,8 @@ class Webhook extends BaseModel
|
|||||||
self::EVENT_LATE_INVOICE,
|
self::EVENT_LATE_INVOICE,
|
||||||
self::EVENT_EXPIRED_QUOTE,
|
self::EVENT_EXPIRED_QUOTE,
|
||||||
self::EVENT_REMIND_INVOICE,
|
self::EVENT_REMIND_INVOICE,
|
||||||
|
self::EVENT_PROJECT_CREATE,
|
||||||
|
self::EVENT_PROJECT_UPDATE
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
89
app/Observers/ProjectObserver.php
Normal file
89
app/Observers/ProjectObserver.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?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 App\Observers;
|
||||||
|
|
||||||
|
use App\Jobs\Util\WebhookHandler;
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\Webhook;
|
||||||
|
|
||||||
|
class ProjectObserver
|
||||||
|
{
|
||||||
|
public $afterCommit = true;
|
||||||
|
/**
|
||||||
|
* Handle the product "created" event.
|
||||||
|
*
|
||||||
|
* @param Project $project
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function created(Project $project)
|
||||||
|
{
|
||||||
|
$subscriptions = Webhook::where('company_id', $project->company_id)
|
||||||
|
->where('event_id', Webhook::EVENT_PROJECT_CREATE)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($subscriptions) {
|
||||||
|
|
||||||
|
WebhookHandler::dispatch(Webhook::EVENT_PROJECT_CREATE, $project, $project->company, 'client');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the product "updated" event.
|
||||||
|
*
|
||||||
|
* @param Project $project
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updated(Project $project)
|
||||||
|
{
|
||||||
|
$subscriptions = Webhook::where('company_id', $project->company_id)
|
||||||
|
->where('event_id', Webhook::EVENT_PROJECT_UPDATE)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($subscriptions) {
|
||||||
|
|
||||||
|
WebhookHandler::dispatch(Webhook::EVENT_PROJECT_UPDATE, $project, $project->company, 'client');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the product "deleted" event.
|
||||||
|
*
|
||||||
|
* @param Project $project
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleted(Project $project)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the product "restored" event.
|
||||||
|
*
|
||||||
|
* @param Project $project
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restored(Project $project)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the product "force deleted" event.
|
||||||
|
*
|
||||||
|
* @param Project $project
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceDeleted(Project $project)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -164,13 +164,13 @@ class AuthorizePaymentMethod
|
|||||||
if ($contact) {
|
if ($contact) {
|
||||||
// Create the Bill To info for new payment type
|
// Create the Bill To info for new payment type
|
||||||
$billto = new CustomerAddressType();
|
$billto = new CustomerAddressType();
|
||||||
$billto->setFirstName($contact->present()->first_name());
|
$billto->setFirstName(substr(0,50,$contact->present()->first_name()));
|
||||||
$billto->setLastName($contact->present()->last_name());
|
$billto->setLastName(substr(0,50,$contact->present()->last_name()));
|
||||||
$billto->setCompany($this->authorize->client->present()->name());
|
$billto->setCompany(substr(0,50,$this->authorize->client->present()->name()));
|
||||||
$billto->setAddress($this->authorize->client->address1);
|
$billto->setAddress(substr(0,60,$this->authorize->client->address1));
|
||||||
$billto->setCity($this->authorize->client->city);
|
$billto->setCity(substr(0,40,$this->authorize->client->city));
|
||||||
$billto->setState($this->authorize->client->state);
|
$billto->setState(substr(0,40,$this->authorize->client->state));
|
||||||
$billto->setZip($this->authorize->client->postal_code);
|
$billto->setZip(substr(0,20,$this->authorize->client->postal_code));
|
||||||
|
|
||||||
if ($this->authorize->client->country_id) {
|
if ($this->authorize->client->country_id) {
|
||||||
$billto->setCountry($this->authorize->client->country->name);
|
$billto->setCountry($this->authorize->client->country->name);
|
||||||
|
@ -170,16 +170,52 @@ class CreditCard
|
|||||||
|
|
||||||
$this->logResponse($response);
|
$this->logResponse($response);
|
||||||
|
|
||||||
$response_status = ErrorCode::getStatus($response->ResponseMessage);
|
// if(!$response || !property_exists($response, 'ResponseMessage'))
|
||||||
|
// throw new PaymentFailed('The gateway did not return a valid response. Please check your gateway credentials.', 400);
|
||||||
|
|
||||||
if(!$response_status['success']){
|
// $response_status = ErrorCode::getStatus($response->ResponseMessage);
|
||||||
|
|
||||||
$this->eway_driver->sendFailureMail($response_status['message']);
|
// if(!$response_status['success']){
|
||||||
|
|
||||||
throw new PaymentFailed($response_status['message'], 400);
|
// if($response->getErrors())
|
||||||
}
|
// {
|
||||||
|
// $message = false;
|
||||||
|
|
||||||
|
// foreach ($response->getErrors() as $error) {
|
||||||
|
// $message = \Eway\Rapid::getMessage($error);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $return_message = $message ?: $response_status['message'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $this->eway_driver->sendFailureMail($response_status['message']);
|
||||||
|
|
||||||
|
// throw new PaymentFailed($response_status['message'], 400);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if($response->TransactionStatus)
|
||||||
|
$payment = $this->storePayment($response);
|
||||||
|
else {
|
||||||
|
|
||||||
|
$message = 'Error processing payment.';
|
||||||
|
|
||||||
|
if(isset($response->ResponseMessage))
|
||||||
|
$message .= " Gateway Error Code = {$response->ResponseMessage}";
|
||||||
|
|
||||||
|
if($response->getErrors())
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach ($response->getErrors() as $error) {
|
||||||
|
$message = \Eway\Rapid::getMessage($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->eway_driver->sendFailureMail($message);
|
||||||
|
|
||||||
|
throw new PaymentFailed($message, 400);
|
||||||
|
}
|
||||||
|
|
||||||
$payment = $this->storePayment($response);
|
|
||||||
|
|
||||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||||
|
|
||||||
@ -257,20 +293,32 @@ class CreditCard
|
|||||||
|
|
||||||
$response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
|
$response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
|
||||||
|
|
||||||
$response_status = ErrorCode::getStatus($response->ResponseMessage);
|
if($response->TransactionStatus){
|
||||||
|
$this->logResponse($response, true);
|
||||||
|
$payment = $this->storePayment($response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
if(!$response_status['success']){
|
$message = 'Error processing payment.';
|
||||||
|
|
||||||
$this->logResponse($response, false);
|
if(isset($response->ResponseMessage))
|
||||||
|
$message .= " Gateway Error Code = {$response->ResponseMessage}";
|
||||||
|
|
||||||
$this->eway_driver->sendFailureMail($response_status['message']);
|
if($response->getErrors())
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach ($response->getErrors() as $error) {
|
||||||
|
$message = \Eway\Rapid::getMessage($error);
|
||||||
|
}
|
||||||
|
|
||||||
throw new PaymentFailed($response_status['message'], 400);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->logResponse($response, true);
|
$this->logResponse($response, false);
|
||||||
|
|
||||||
$payment = $this->storePayment($response);
|
$this->eway_driver->sendFailureMail($message);
|
||||||
|
|
||||||
|
throw new PaymentFailed($message, 400);
|
||||||
|
}
|
||||||
|
|
||||||
return $payment;
|
return $payment;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
private $omnipay_gateway;
|
private $omnipay_gateway;
|
||||||
|
|
||||||
|
private float $fee = 0;
|
||||||
|
|
||||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
||||||
|
|
||||||
public function gatewayTypes()
|
public function gatewayTypes()
|
||||||
@ -173,11 +175,17 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function generatePaymentDetails(array $data)
|
public function generatePaymentDetails(array $data)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||||
|
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||||
|
|
||||||
|
$this->fee = $this->feeCalc($invoice, $data['total']['amount_with_fee']);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'currency' => $this->client->getCurrencyCode(),
|
'currency' => $this->client->getCurrencyCode(),
|
||||||
'transactionType' => 'Purchase',
|
'transactionType' => 'Purchase',
|
||||||
'clientIp' => request()->getClientIp(),
|
'clientIp' => request()->getClientIp(),
|
||||||
'amount' => $data['total']['amount_with_fee'],
|
'amount' => $data['total']['amount_with_fee'] + $this->fee,
|
||||||
'returnUrl' => route('client.payments.response', [
|
'returnUrl' => route('client.payments.response', [
|
||||||
'company_gateway_id' => $this->company_gateway->id,
|
'company_gateway_id' => $this->company_gateway->id,
|
||||||
'payment_hash' => $this->payment_hash->hash,
|
'payment_hash' => $this->payment_hash->hash,
|
||||||
@ -200,8 +208,6 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
|||||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||||
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||||
|
|
||||||
$line_item = collect($invoice->line_items)->first();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
$items[] = new Item([
|
$items[] = new Item([
|
||||||
@ -211,8 +217,44 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
|||||||
'quantity' => 1,
|
'quantity' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
if($this->fee > 0.1){
|
||||||
|
|
||||||
|
$items[] = new Item([
|
||||||
|
'name' => " ",
|
||||||
|
'description' => ctrans('texts.gateway_fee_description'),
|
||||||
|
'price' => $this->fee,
|
||||||
|
'quantity' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function feeCalc($invoice, $invoice_total)
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice->service()->removeUnpaidGatewayFees();
|
||||||
|
$invoice = $invoice->fresh();
|
||||||
|
|
||||||
|
$balance = floatval($invoice->balance);
|
||||||
|
|
||||||
|
$_updated_invoice = $invoice->service()->addGatewayFee($this->company_gateway, GatewayType::PAYPAL, $invoice_total)->save();
|
||||||
|
|
||||||
|
if(floatval($_updated_invoice->balance) > $balance){
|
||||||
|
|
||||||
|
$fee = floatval($_updated_invoice->balance) - $balance;
|
||||||
|
|
||||||
|
$this->payment_hash->fee_total = $fee;
|
||||||
|
$this->payment_hash->save();
|
||||||
|
|
||||||
|
return $fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use Illuminate\Support\Facades\Queue;
|
|||||||
use Illuminate\Support\Facades\RateLimiter;
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Livewire\Livewire;
|
use Livewire\Livewire;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@ -69,6 +70,11 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
app()->instance(TruthSource::class, new TruthSource());
|
app()->instance(TruthSource::class, new TruthSource());
|
||||||
|
|
||||||
|
|
||||||
|
// Model::preventLazyLoading(
|
||||||
|
// !$this->app->isProduction()
|
||||||
|
// );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,6 +213,7 @@ use App\Models\Expense;
|
|||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Proposal;
|
use App\Models\Proposal;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Models\Subscription;
|
use App\Models\Subscription;
|
||||||
@ -228,6 +229,7 @@ use App\Observers\ExpenseObserver;
|
|||||||
use App\Observers\InvoiceObserver;
|
use App\Observers\InvoiceObserver;
|
||||||
use App\Observers\PaymentObserver;
|
use App\Observers\PaymentObserver;
|
||||||
use App\Observers\ProductObserver;
|
use App\Observers\ProductObserver;
|
||||||
|
use App\Observers\ProjectObserver;
|
||||||
use App\Observers\ProposalObserver;
|
use App\Observers\ProposalObserver;
|
||||||
use App\Observers\QuoteObserver;
|
use App\Observers\QuoteObserver;
|
||||||
use App\Observers\SubscriptionObserver;
|
use App\Observers\SubscriptionObserver;
|
||||||
@ -586,6 +588,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
Invoice::observe(InvoiceObserver::class);
|
Invoice::observe(InvoiceObserver::class);
|
||||||
Payment::observe(PaymentObserver::class);
|
Payment::observe(PaymentObserver::class);
|
||||||
Product::observe(ProductObserver::class);
|
Product::observe(ProductObserver::class);
|
||||||
|
Project::observe(ProjectObserver::class);
|
||||||
Proposal::observe(ProposalObserver::class);
|
Proposal::observe(ProposalObserver::class);
|
||||||
Quote::observe(QuoteObserver::class);
|
Quote::observe(QuoteObserver::class);
|
||||||
Task::observe(TaskObserver::class);
|
Task::observe(TaskObserver::class);
|
||||||
|
@ -19,20 +19,14 @@ use App\Models\Client;
|
|||||||
use App\Models\Design;
|
use App\Models\Design;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\Product;
|
|
||||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||||
use App\Services\PdfMaker\PdfMaker;
|
use App\Services\PdfMaker\PdfMaker;
|
||||||
use App\Utils\HostedPDF\NinjaPdf;
|
use App\Utils\HostedPDF\NinjaPdf;
|
||||||
use App\Utils\HtmlEngine;
|
use App\Utils\HtmlEngine;
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Number;
|
use App\Utils\Number;
|
||||||
use App\Utils\PhantomJS\Phantom;
|
use App\Utils\PhantomJS\Phantom;
|
||||||
use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
|
use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\LazyCollection;
|
|
||||||
|
|
||||||
class Statement
|
class Statement
|
||||||
{
|
{
|
||||||
@ -231,7 +225,7 @@ class Statement
|
|||||||
->where('client_id', $this->client->id)
|
->where('client_id', $this->client->id)
|
||||||
->whereIn('status_id', $this->invoiceStatuses())
|
->whereIn('status_id', $this->invoiceStatuses())
|
||||||
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
||||||
->orderBy('date', 'ASC')
|
->orderBy('due_date', 'ASC')
|
||||||
->cursor();
|
->cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class CompanyUserTransformer extends EntityTransformer
|
|||||||
|
|
||||||
public function includeToken(CompanyUser $company_user)
|
public function includeToken(CompanyUser $company_user)
|
||||||
{
|
{
|
||||||
$token = $company_user->tokens->where('company_id', $company_user->company_id)->where('user_id', $company_user->user_id)->first();
|
$token = $company_user->tokens()->where('company_id', $company_user->company_id)->where('user_id', $company_user->user_id)->first();
|
||||||
|
|
||||||
$transformer = new CompanyTokenTransformer($this->serializer);
|
$transformer = new CompanyTokenTransformer($this->serializer);
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class NinjaPdf
|
|||||||
$response = $client->post($this->url,[
|
$response = $client->post($this->url,[
|
||||||
RequestOptions::JSON => ['html' => $html]
|
RequestOptions::JSON => ['html' => $html]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $response->getBody();
|
return $response->getBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ class HtmlEngine
|
|||||||
$data['$invoice.date'] = &$data['$date'];
|
$data['$invoice.date'] = &$data['$date'];
|
||||||
$data['$invoiceDate'] = &$data['$date'];
|
$data['$invoiceDate'] = &$data['$date'];
|
||||||
$data['$due_date'] = ['value' => $this->translateDate($this->entity->due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
$data['$due_date'] = ['value' => $this->translateDate($this->entity->due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
||||||
|
|
||||||
|
$data['$partial_due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
||||||
|
|
||||||
$data['$dueDate'] = &$data['$due_date'];
|
$data['$dueDate'] = &$data['$due_date'];
|
||||||
|
|
||||||
$data['$payment_due'] = ['value' => $this->translateDate($this->entity->due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.payment_due')];
|
$data['$payment_due'] = ['value' => $this->translateDate($this->entity->due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.payment_due')];
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Utils\Traits;
|
namespace App\Utils\Traits;
|
||||||
|
|
||||||
|
use App\DataMapper\ClientSettings;
|
||||||
use App\DataMapper\CompanySettings;
|
use App\DataMapper\CompanySettings;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
@ -63,15 +64,6 @@ trait ClientGroupSettingsSaver
|
|||||||
$entity_settings->{$key} = $value;
|
$entity_settings->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this pass will handle any null values that are in the translations
|
|
||||||
// foreach ($settings->translations as $key => $value) {
|
|
||||||
// if (is_null($settings->translations[$key])) {
|
|
||||||
// $settings->translations[$key] = '';
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// $entity_settings->translations = $settings->translations;
|
|
||||||
|
|
||||||
$entity->settings = $entity_settings;
|
$entity->settings = $entity_settings;
|
||||||
$entity->save();
|
$entity->save();
|
||||||
|
|
||||||
@ -121,8 +113,12 @@ trait ClientGroupSettingsSaver
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
||||||
elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') {
|
elseif (substr($key, -3) == '_id' ||
|
||||||
$value = 'integer';
|
substr($key, -14) == 'number_counter' ||
|
||||||
|
($key == 'payment_terms' && property_exists($settings, 'payment_terms') && strlen($settings->{$key}) >= 1) ||
|
||||||
|
($key == 'valid_until' && property_exists($settings, 'valid_until') && strlen($settings->{$key}) >= 1)) {
|
||||||
|
|
||||||
|
$value = 'integer';
|
||||||
|
|
||||||
if (! property_exists($settings, $key)) {
|
if (! property_exists($settings, $key)) {
|
||||||
continue;
|
continue;
|
||||||
@ -170,7 +166,11 @@ trait ClientGroupSettingsSaver
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
||||||
if (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') {
|
if (substr($key, -3) == '_id' ||
|
||||||
|
substr($key, -14) == 'number_counter' ||
|
||||||
|
($key == 'payment_terms' && property_exists($settings, 'payment_terms') && strlen($settings->{$key}) >= 1) ||
|
||||||
|
($key == 'valid_until' && property_exists($settings, 'valid_until') && strlen($settings->{$key}) >= 1)) {
|
||||||
|
|
||||||
$value = 'integer';
|
$value = 'integer';
|
||||||
|
|
||||||
if (! property_exists($settings, $key)) {
|
if (! property_exists($settings, $key)) {
|
||||||
@ -219,8 +219,7 @@ trait ClientGroupSettingsSaver
|
|||||||
switch ($key) {
|
switch ($key) {
|
||||||
case 'int':
|
case 'int':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
// return ctype_digit(strval(abs($value)));
|
return is_numeric($value) && ctype_digit(strval(abs($value)));
|
||||||
return ctype_digit(strval($value));
|
|
||||||
case 'real':
|
case 'real':
|
||||||
case 'float':
|
case 'float':
|
||||||
case 'double':
|
case 'double':
|
||||||
|
@ -32,7 +32,7 @@ trait UserNotifies
|
|||||||
$notifiable_methods = [];
|
$notifiable_methods = [];
|
||||||
$notifications = $company_user->notifications;
|
$notifications = $company_user->notifications;
|
||||||
|
|
||||||
if ($company_user->company->is_disabled && is_array($notifications->email) || $company_user->trashed() || $company_user->user->trashed()) {
|
if ($invitation->company->is_disabled && is_array($notifications->email) || $company_user->trashed() || $company_user->user->trashed()) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ trait UserNotifies
|
|||||||
$notifiable_methods = [];
|
$notifiable_methods = [];
|
||||||
$notifications = $company_user->notifications;
|
$notifications = $company_user->notifications;
|
||||||
|
|
||||||
if ($company_user->company->is_disabled || ! $notifications || $company_user->trashed() || $company_user->user->trashed()) {
|
if ($entity->company->is_disabled || ! $notifications || $company_user->trashed() || $company_user->user->trashed()) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ trait SettingsSaver
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
/*Separate loop if it is a _id field which is an integer cast as a string*/
|
||||||
elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') {
|
elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter' || ($key == 'payment_terms' && strlen($settings->{$key}) >= 1) || ($key == 'valid_until' && strlen($settings->{$key}) >= 1)) {
|
||||||
$value = 'integer';
|
$value = 'integer';
|
||||||
|
|
||||||
if($key == 'gmail_sending_user_id')
|
if($key == 'gmail_sending_user_id')
|
||||||
@ -94,12 +94,11 @@ trait SettingsSaver
|
|||||||
switch ($key) {
|
switch ($key) {
|
||||||
case 'int':
|
case 'int':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
return ctype_digit(strval(abs($value)));
|
return is_numeric($value) && ctype_digit(strval(abs($value)));
|
||||||
case 'real':
|
case 'real':
|
||||||
case 'float':
|
case 'float':
|
||||||
case 'double':
|
case 'double':
|
||||||
return !is_string($value) && (is_float($value) || is_numeric(strval($value)));
|
return !is_string($value) && (is_float($value) || is_numeric(strval($value)));
|
||||||
// return is_float($value) || is_numeric(strval($value));
|
|
||||||
case 'string':
|
case 'string':
|
||||||
return !is_int($value) || ( is_string( $value ) && method_exists($value, '__toString') ) || is_null($value) || is_string($value);
|
return !is_int($value) || ( is_string( $value ) && method_exists($value, '__toString') ) || is_null($value) || is_string($value);
|
||||||
case 'bool':
|
case 'bool':
|
||||||
|
@ -54,7 +54,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'asset_url' => null,
|
'asset_url' => env('ASSET_URL', null),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -14,8 +14,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' => '5.3.79',
|
'app_version' => '5.3.80',
|
||||||
'app_tag' => '5.3.79',
|
'app_tag' => '5.3.80',
|
||||||
'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', ''),
|
||||||
|
@ -50,8 +50,6 @@ class CompanySettingsTest extends TestCase
|
|||||||
|
|
||||||
$this->company->saveSettings($settings, $this->company);
|
$this->company->saveSettings($settings, $this->company);
|
||||||
|
|
||||||
//$this->withoutExceptionHandling();
|
|
||||||
|
|
||||||
$response = false;
|
$response = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -36,7 +36,7 @@ class UpdateCompanyUserTest extends TestCase
|
|||||||
|
|
||||||
public function testUpdatingCompanyUserAsAdmin()
|
public function testUpdatingCompanyUserAsAdmin()
|
||||||
{
|
{
|
||||||
User::unguard();
|
// User::unguard();
|
||||||
|
|
||||||
$settings = new \stdClass;
|
$settings = new \stdClass;
|
||||||
$settings->invoice = 'ninja';
|
$settings->invoice = 'ninja';
|
||||||
@ -59,7 +59,7 @@ class UpdateCompanyUserTest extends TestCase
|
|||||||
$message = json_decode($e->validator->getMessageBag(), 1);
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
$this->assertNotNull($message);
|
$this->assertNotNull($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
|
|
||||||
$arr = $response->json();
|
$arr = $response->json();
|
||||||
|
337
tests/Unit/ClientSettingsTest.php
Normal file
337
tests/Unit/ClientSettingsTest.php
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
namespace Tests\Unit;
|
||||||
|
|
||||||
|
use App\DataMapper\ClientSettings;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
class ClientSettingsTest extends TestCase
|
||||||
|
{
|
||||||
|
use MockAccountData;
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
public function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->makeTestData();
|
||||||
|
|
||||||
|
$this->faker = \Faker\Factory::create();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testClientBaseline()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals("1", $arr['data']['settings']['currency_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testClientValidSettings()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => 10,
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals("1", $arr['data']['settings']['currency_id']);
|
||||||
|
$this->assertEquals("1", $arr['data']['settings']['language_id']);
|
||||||
|
$this->assertEquals("1", $arr['data']['settings']['payment_terms']);
|
||||||
|
$this->assertEquals(10, $arr['data']['settings']['default_task_rate']);
|
||||||
|
$this->assertEquals(true, $arr['data']['settings']['send_reminders']);
|
||||||
|
$this->assertEquals("1", $arr['data']['settings']['valid_until']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientIllegalCurrency()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => 'a',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => 10,
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(302);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientIllegalLanguage()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => 'a',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => 10,
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(302);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientIllegalPaymenTerms()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => 'a',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => 10,
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(302);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testClientIllegalValidUntil()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => 'a',
|
||||||
|
'default_task_rate' => 10,
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(302);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientIllegalDefaultTaskRate()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => "a",
|
||||||
|
'send_reminders' => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertFalse(array_key_exists('default_task_rate', $arr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientIllegalSendReminderBool()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => "a",
|
||||||
|
'send_reminders' => "faaalse"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(302);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClientSettingBools()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => $this->faker->firstName,
|
||||||
|
'id_number' => 'Coolio',
|
||||||
|
'settings' => [
|
||||||
|
'currency_id' => '1',
|
||||||
|
'language_id' => '1',
|
||||||
|
'payment_terms' => '1',
|
||||||
|
'valid_until' => '1',
|
||||||
|
'default_task_rate' => "a",
|
||||||
|
'send_reminders' => "true"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients/', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
nlog($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user