mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
commit
fe34ab41d7
@ -1 +1 @@
|
||||
5.7.59
|
||||
5.7.60
|
@ -12,7 +12,8 @@
|
||||
|
||||
namespace App\DataProviders;
|
||||
|
||||
class Domains {
|
||||
class Domains
|
||||
{
|
||||
|
||||
private static array $verify_domains = [
|
||||
'0-00.usa.cc',
|
||||
|
@ -146,16 +146,26 @@ class InvoiceFilters extends QueryFilters
|
||||
*/
|
||||
public function upcoming(): Builder
|
||||
{
|
||||
return $this->builder->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
|
||||
->whereNull('due_date')
|
||||
|
||||
return $this->builder->where(function ($query) {
|
||||
$query->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
|
||||
->where('is_deleted', 0)
|
||||
->where('balance', '>', 0)
|
||||
->where(function ($query) {
|
||||
|
||||
$query->whereNull('due_date')
|
||||
->orWhere(function ($q) {
|
||||
$q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0);
|
||||
})
|
||||
->orWhere(function ($q) {
|
||||
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0);
|
||||
})
|
||||
->orderByRaw('ISNULL(due_date), due_date '. 'desc')
|
||||
->orderByRaw('ISNULL(partial_due_date), partial_due_date '. 'desc');
|
||||
->orWhere(function ($q) {
|
||||
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0);
|
||||
});
|
||||
|
||||
})
|
||||
->orderByRaw('ISNULL(due_date), due_date ' . 'desc')
|
||||
->orderByRaw('ISNULL(partial_due_date), partial_due_date ' . 'desc');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,13 +175,18 @@ class InvoiceFilters extends QueryFilters
|
||||
*/
|
||||
public function overdue(): Builder
|
||||
{
|
||||
return $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
return $this->builder->where(function ($query) {
|
||||
|
||||
$query->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_deleted', 0)
|
||||
->where('balance', '>', 0)
|
||||
->where(function ($query) {
|
||||
$query->where('due_date', '<', now())
|
||||
->orWhere('partial_due_date', '<', now());
|
||||
})
|
||||
->orderBy('due_date', 'ASC');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,6 +155,7 @@ class PaymentController extends BaseController
|
||||
$user = auth()->user();
|
||||
|
||||
$payment = PaymentFactory::create($user->company()->id, $user->id);
|
||||
$payment->date = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d');
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
@ -30,6 +30,12 @@ class SubdomainController extends BaseController
|
||||
return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401);
|
||||
}
|
||||
|
||||
|
||||
if (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', request()->input('subdomain'))) {
|
||||
return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401);
|
||||
}
|
||||
|
||||
|
||||
return response()->json(['message' => 'Domain available'], 200);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ use Twilio\Rest\Client;
|
||||
|
||||
class TwilioController extends BaseController
|
||||
{
|
||||
|
||||
private array $invalid_codes = [
|
||||
'+21',
|
||||
'+17152567760',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -38,6 +44,10 @@ class TwilioController extends BaseController
|
||||
|
||||
$account = $user->company()->account;
|
||||
|
||||
if(!$this->checkPhoneValidity($request->phone)) {
|
||||
return response()->json(['message' => 'This phone number is not supported'], 400);
|
||||
}
|
||||
|
||||
if (MultiDB::hasPhoneNumber($request->phone)) {
|
||||
return response()->json(['message' => 'This phone number has already been verified with another account'], 400);
|
||||
}
|
||||
@ -65,6 +75,19 @@ class TwilioController extends BaseController
|
||||
return response()->json(['message' => 'Code sent.'], 200);
|
||||
}
|
||||
|
||||
private function checkPhoneValidity($phone)
|
||||
{
|
||||
foreach($this->invalid_codes as $code){
|
||||
|
||||
if(stripos($phone, $code) !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
|
@ -60,7 +60,7 @@ class UpdateCreditRequest extends Request
|
||||
$rules['file'] = $this->file_validation;
|
||||
}
|
||||
|
||||
$rules['number'] = ['bail', 'sometimes', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)];
|
||||
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)];
|
||||
|
||||
$rules['client_id'] = ['bail', 'sometimes',Rule::in([$this->credit->client_id])];
|
||||
|
||||
|
@ -37,7 +37,7 @@ class ImportRequest extends Request
|
||||
'column_map' => 'required_with:hash|array',
|
||||
'skip_header' => 'required_with:hash|boolean',
|
||||
'files.*' => 'file|mimes:csv,txt',
|
||||
'bank_integration_id' => 'bail|required_if:column_map,bank_transaction|min:2'
|
||||
'bank_integration_id' => 'bail|required_with:column_map.bank_transaction|min:2'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -59,9 +59,8 @@ class UpdateInvoiceRequest extends Request
|
||||
|
||||
$rules['id'] = new LockedInvoiceRule($this->invoice);
|
||||
|
||||
$rules['number'] = ['bail', 'sometimes', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)];
|
||||
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)];
|
||||
|
||||
|
||||
$rules['is_amount_discount'] = ['boolean'];
|
||||
$rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->invoice->client_id])];
|
||||
$rules['line_items'] = 'array';
|
||||
|
@ -48,7 +48,7 @@ class UpdatePurchaseOrderRequest extends Request
|
||||
|
||||
$rules = [];
|
||||
|
||||
$rules['number'] = ['bail', 'sometimes', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)];
|
||||
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)];
|
||||
$rules['vendor_id'] = ['bail', 'sometimes', Rule::in([$this->purchase_order->vendor_id])];
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
|
@ -55,7 +55,7 @@ class UpdateQuoteRequest extends Request
|
||||
}
|
||||
|
||||
|
||||
$rules['number'] = ['bail', 'sometimes', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)];
|
||||
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)];
|
||||
|
||||
$rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->quote->client_id])];
|
||||
|
||||
@ -73,6 +73,8 @@ class UpdateQuoteRequest extends Request
|
||||
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$input['id'] = $this->quote->id;
|
||||
|
||||
if (isset($input['line_items'])) {
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
}
|
||||
@ -85,7 +87,6 @@ class UpdateQuoteRequest extends Request
|
||||
$input['exchange_rate'] = 1;
|
||||
}
|
||||
|
||||
$input['id'] = $this->quote->id;
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ class StoreSchedulerRequest extends Request
|
||||
'template' => 'bail|required|string',
|
||||
'parameters' => 'bail|array',
|
||||
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
|
||||
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom',
|
||||
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
|
||||
'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
|
||||
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
|
||||
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
|
||||
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
|
||||
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
|
||||
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,client,contact,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'],
|
||||
'parameters.date_key' => ['bail','sometimes', 'string'],
|
||||
'parameters.status' => ['bail','sometimes', 'string', 'in:all,draft,paid,unpaid,overdue'],
|
||||
];
|
||||
@ -67,6 +67,10 @@ class StoreSchedulerRequest extends Request
|
||||
$input['frequency_id'] = 0;
|
||||
}
|
||||
|
||||
if(isset($input['parameters']) && isset($input['parameters']['clients'])) {
|
||||
$input['parameters']['clients'] = [];
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,12 @@ class UpdateSchedulerRequest extends Request
|
||||
'template' => 'bail|required|string',
|
||||
'parameters' => 'bail|array',
|
||||
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
|
||||
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom',
|
||||
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
|
||||
'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
|
||||
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
|
||||
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
|
||||
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
|
||||
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
|
||||
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'],
|
||||
'parameters.date_key' => ['bail','sometimes', 'string'],
|
||||
];
|
||||
|
||||
@ -63,6 +63,10 @@ class UpdateSchedulerRequest extends Request
|
||||
$input['frequency_id'] = 0;
|
||||
}
|
||||
|
||||
if(isset($input['parameters']) && isset($input['parameters']['clients'])) {
|
||||
$input['parameters']['clients'] = [];
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
|
||||
|
||||
|
@ -387,19 +387,19 @@ class CompanyExport implements ShouldQueue
|
||||
})->all();
|
||||
|
||||
|
||||
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) {
|
||||
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) {
|
||||
$bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']);
|
||||
|
||||
return $bank_integration->makeVisible(['id','user_id','company_id','account_id']);
|
||||
return $bank_integration->makeVisible(['id','user_id','company_id','account_id','hashed_id']);
|
||||
})->all();
|
||||
|
||||
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) {
|
||||
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','category_id','ninja_category_id','vendor_id']);
|
||||
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) {
|
||||
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','ninja_category_id','vendor_id']);
|
||||
|
||||
return $bank_transaction->makeVisible(['id','user_id','company_id']);
|
||||
})->all();
|
||||
|
||||
$this->export_data['schedulers'] = $this->company->schedulers()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) {
|
||||
$this->export_data['schedulers'] = $this->company->schedulers()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) {
|
||||
$scheduler = $this->transformArrayOfKeys($scheduler, ['company_id', 'user_id']);
|
||||
|
||||
return $scheduler->makeVisible(['id','user_id','company_id']);
|
||||
|
@ -63,14 +63,12 @@ use App\Utils\Ninja;
|
||||
use App\Utils\TempFile;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use function GuzzleHttp\json_encode;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
@ -142,7 +140,6 @@ class CompanyImport implements ShouldQueue
|
||||
'recurring_expenses',
|
||||
'expenses',
|
||||
'tasks',
|
||||
'payments',
|
||||
'company_ledger',
|
||||
'designs',
|
||||
'documents',
|
||||
@ -569,7 +566,7 @@ class CompanyImport implements ShouldQueue
|
||||
['expenses' => 'expense_id'],
|
||||
['vendors' => 'vendor_id'],
|
||||
['expense_categories' => 'ninja_category_id'],
|
||||
['expense_categories' => 'category_id'],
|
||||
// ['expense_categories' => 'category_id'],
|
||||
['bank_integrations' => 'bank_integration_id']
|
||||
],
|
||||
'bank_transactions',
|
||||
@ -1143,7 +1140,34 @@ class CompanyImport implements ShouldQueue
|
||||
continue;
|
||||
}
|
||||
|
||||
$storage_url = (object)$this->getObject('storage_url', true);
|
||||
|
||||
if (!Storage::exists($document->url) && is_string($storage_url)) {
|
||||
$url = $storage_url . $document->url;
|
||||
|
||||
$file = @file_get_contents($url);
|
||||
|
||||
|
||||
if ($file) {
|
||||
try {
|
||||
Storage::disk(config('filesystems.default'))->put($document->url, $file);
|
||||
|
||||
|
||||
} catch(\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
nlog("I could not upload {$document->url}");
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
$new_document = new Document();
|
||||
$new_document->disk = config('filesystems.default');
|
||||
$new_document->user_id = $this->transformId('users', $document->user_id);
|
||||
$new_document->assigned_user_id = $this->transformId('users', $document->assigned_user_id);
|
||||
$new_document->company_id = $this->company->id;
|
||||
@ -1169,26 +1193,6 @@ class CompanyImport implements ShouldQueue
|
||||
|
||||
$new_document->save(['timestamps' => false]);
|
||||
|
||||
$storage_url = (object)$this->getObject('storage_url', true);
|
||||
|
||||
if (!Storage::exists($new_document->url) && is_string($storage_url)) {
|
||||
$url = $storage_url . $new_document->url;
|
||||
|
||||
$file = @file_get_contents($url);
|
||||
|
||||
if ($file) {
|
||||
try {
|
||||
Storage::disk(config('filesystems.default'))->put($new_document->url, $file);
|
||||
|
||||
$new_document->disk = config('filesystems.default');
|
||||
$new_document->save();
|
||||
} catch(\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
nlog("I could not upload {$new_document->url}");
|
||||
$new_document->forceDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -1727,7 +1731,9 @@ class CompanyImport implements ShouldQueue
|
||||
*/
|
||||
private function transformId(string $resource, ?string $old): ?int
|
||||
{
|
||||
if (empty($old)) {
|
||||
|
||||
// WjnegYbwZ1 == 0 return null;
|
||||
if (empty($old) || $old == 'WjnegYbwZ1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1736,6 +1742,7 @@ class CompanyImport implements ShouldQueue
|
||||
}
|
||||
|
||||
if (! array_key_exists($resource, $this->ids)) {
|
||||
|
||||
$this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available.");
|
||||
|
||||
throw new \Exception("Resource {$resource} not available.");
|
||||
@ -1744,16 +1751,12 @@ class CompanyImport implements ShouldQueue
|
||||
if (! array_key_exists("{$old}", $this->ids[$resource])) {
|
||||
// nlog($this->ids[$resource]);
|
||||
nlog("searching for {$old} in {$resource}");
|
||||
|
||||
nlog("If we are missing a user - default to the company owner");
|
||||
|
||||
if ($resource == 'users') {
|
||||
return $this->company_owner->id;
|
||||
}
|
||||
|
||||
$this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available.");
|
||||
|
||||
nlog($this->ids[$resource]);
|
||||
$this->sendImportMail("The Import failed due to missing data in the import file. Key {$old} not found in {$resource}.");
|
||||
|
||||
throw new \Exception("Missing {$resource} key: {$old}");
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
});
|
||||
|
||||
//add client payment failures here.
|
||||
//
|
||||
|
||||
if ($this->client->contacts()->whereNotNull('email')->exists() && $this->payment_hash) {
|
||||
$contact = $this->client->contacts()->whereNotNull('email')->first();
|
||||
|
||||
|
@ -305,14 +305,20 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
|
||||
if($sl) {
|
||||
$this->updateSystemLog($sl, $data);
|
||||
|
||||
if (config('ninja.notification.slack')) {
|
||||
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
(new SystemLogger($data, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company))->handle();
|
||||
|
||||
if (config('ninja.notification.slack')) {
|
||||
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
|
||||
}
|
||||
if (config('ninja.notification.slack')) {
|
||||
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function discoverInvitation($message_id)
|
||||
|
@ -307,8 +307,6 @@ class ReminderJob implements ShouldQueue
|
||||
/**Refresh Invoice values*/
|
||||
$invoice = $invoice->calc()->getInvoice();
|
||||
|
||||
// nlog('adjusting client balance and invoice balance by #'.$invoice->number.' '.($invoice->balance - $temp_invoice_balance));
|
||||
// $invoice->client->service()->updateBalance($invoice->balance - $temp_invoice_balance);
|
||||
$invoice->ledger()->updateInvoiceBalance($invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$invoice->number}");
|
||||
$invoice->client->service()->calculateBalance();
|
||||
|
||||
|
@ -113,6 +113,10 @@ class InstantBankPay implements MethodInterface
|
||||
return $this->processSuccessfulPayment($payment);
|
||||
}
|
||||
|
||||
if ($billing_request->status === 'submitted') {
|
||||
return $this->processPendingPayment($payment);
|
||||
}
|
||||
|
||||
return $this->processUnsuccessfulPayment($payment);
|
||||
} catch (\Exception $exception) {
|
||||
throw new PaymentFailed(
|
||||
@ -125,7 +129,40 @@ class InstantBankPay implements MethodInterface
|
||||
/**
|
||||
* Handle pending payments for Instant Bank Transfer.
|
||||
*
|
||||
* @param ResourcesPayment $payment
|
||||
* @param \GoCardlessPro\Resources\Payment $payment
|
||||
* @param array $data
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = [])
|
||||
{
|
||||
$data = [
|
||||
'payment_method' => $payment->links->mandate,
|
||||
'payment_type' => PaymentType::INSTANT_BANK_PAY,
|
||||
'amount' => $this->go_cardless->payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $payment->id,
|
||||
'gateway_type_id' => GatewayType::INSTANT_BANK_PAY,
|
||||
];
|
||||
|
||||
$payment = $this->go_cardless->createPayment($data, Payment::STATUS_PENDING);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => $payment, 'data' => $data],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_GOCARDLESS,
|
||||
$this->go_cardless->client,
|
||||
$this->go_cardless->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->go_cardless->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handle pending payments for Instant Bank Transfer.
|
||||
*
|
||||
* @param \GoCardlessPro\Resources\Payment $payment
|
||||
* @param array $data
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
@ -163,12 +200,12 @@ class InstantBankPay implements MethodInterface
|
||||
{
|
||||
PaymentFailureMailer::dispatch($this->go_cardless->client, $payment->status, $this->go_cardless->client->company, $this->go_cardless->payment_hash->data->amount_with_fee);
|
||||
|
||||
PaymentFailureMailer::dispatch(
|
||||
$this->go_cardless->client,
|
||||
$payment,
|
||||
$this->go_cardless->client->company,
|
||||
$payment->amount
|
||||
);
|
||||
// PaymentFailureMailer::dispatch(
|
||||
// $this->go_cardless->client,
|
||||
// $payment,
|
||||
// $this->go_cardless->client->company,
|
||||
// $payment->amount
|
||||
// );
|
||||
|
||||
$message = [
|
||||
'server_response' => $payment,
|
||||
|
@ -165,7 +165,7 @@ class GoCardlessPaymentDriver extends BaseDriver
|
||||
],
|
||||
]);
|
||||
|
||||
if ($payment->status === 'pending_submission') {
|
||||
if (in_array($payment->status, ['submitted', 'pending_submission'])) {
|
||||
$this->confirmGatewayFee();
|
||||
|
||||
$data = [
|
||||
|
@ -70,7 +70,7 @@ class EmailReport
|
||||
'report_keys' => []
|
||||
];
|
||||
|
||||
if (count($this->scheduler->parameters['clients']) >= 1) {
|
||||
if (isset($this->scheduler->parameters['clients']) && count($this->scheduler->parameters['clients']) >= 1) {
|
||||
$data['clients'] = $this->transformKeys($this->scheduler->parameters['clients']);
|
||||
}
|
||||
|
||||
@ -84,20 +84,20 @@ class EmailReport
|
||||
'client_balance' => $export = (new ClientBalanceReport($this->scheduler->company, $data)),
|
||||
'client_sales' => $export = (new ClientSalesReport($this->scheduler->company, $data)),
|
||||
'user_sales' => $export = (new UserSalesReport($this->scheduler->company, $data)),
|
||||
'clients' => $export = (new ClientExport($this->scheduler->company, $data)),
|
||||
'client_contacts' => $export = (new ContactExport($this->scheduler->company, $data)),
|
||||
'credits' => $export = (new CreditExport($this->scheduler->company, $data)),
|
||||
'documents' => $export = (new DocumentExport($this->scheduler->company, $data)),
|
||||
'expenses' => $export = (new ExpenseExport($this->scheduler->company, $data)),
|
||||
'invoices' => $export = (new InvoiceExport($this->scheduler->company, $data)),
|
||||
'invoice_items' => $export = (new InvoiceItemExport($this->scheduler->company, $data)),
|
||||
'quotes' => $export = (new QuoteExport($this->scheduler->company, $data)),
|
||||
'quote_items' => $export = (new QuoteItemExport($this->scheduler->company, $data)),
|
||||
'recurring_invoices' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)),
|
||||
'payments' => $export = (new PaymentExport($this->scheduler->company, $data)),
|
||||
'products' => $export = (new ProductExport($this->scheduler->company, $data)),
|
||||
'tasks' => $export = (new TaskExport($this->scheduler->company, $data)),
|
||||
'profitloss' => $export = (new ProfitLoss($this->scheduler->company, $data)),
|
||||
'client' => $export = (new ClientExport($this->scheduler->company, $data)),
|
||||
'client_contact' => $export = (new ContactExport($this->scheduler->company, $data)),
|
||||
'credit' => $export = (new CreditExport($this->scheduler->company, $data)),
|
||||
'document' => $export = (new DocumentExport($this->scheduler->company, $data)),
|
||||
'expense' => $export = (new ExpenseExport($this->scheduler->company, $data)),
|
||||
'invoice' => $export = (new InvoiceExport($this->scheduler->company, $data)),
|
||||
'invoice_item' => $export = (new InvoiceItemExport($this->scheduler->company, $data)),
|
||||
'quote' => $export = (new QuoteExport($this->scheduler->company, $data)),
|
||||
'quote_item' => $export = (new QuoteItemExport($this->scheduler->company, $data)),
|
||||
'recurring_invoice' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)),
|
||||
'payment' => $export = (new PaymentExport($this->scheduler->company, $data)),
|
||||
'product' => $export = (new ProductExport($this->scheduler->company, $data)),
|
||||
'task' => $export = (new TaskExport($this->scheduler->company, $data)),
|
||||
default => $export = false,
|
||||
};
|
||||
|
||||
|
86
composer.lock
generated
86
composer.lock
generated
@ -485,16 +485,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.293.5",
|
||||
"version": "3.293.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "f2002e52b382b45231da3f9552033f769acfebd8"
|
||||
"reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f2002e52b382b45231da3f9552033f769acfebd8",
|
||||
"reference": "f2002e52b382b45231da3f9552033f769acfebd8",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3bf86ba8b9bbea2b298f89e6f5edc58de276690b",
|
||||
"reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -574,9 +574,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.293.5"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.293.7"
|
||||
},
|
||||
"time": "2023-12-06T19:09:15+00:00"
|
||||
"time": "2023-12-08T19:11:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -6576,16 +6576,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.72.0",
|
||||
"version": "2.72.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b"
|
||||
"reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
|
||||
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
|
||||
"reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6679,7 +6679,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-28T10:13:25+00:00"
|
||||
"time": "2023-12-08T23:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@ -6831,16 +6831,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.17.1",
|
||||
"version": "v4.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
|
||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6881,9 +6881,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
|
||||
},
|
||||
"time": "2023-08-13T19:53:39+00:00"
|
||||
"time": "2023-12-10T21:03:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/termwind",
|
||||
@ -13841,23 +13841,23 @@
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
"version": "2.2.6",
|
||||
"version": "v2.2.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
|
||||
"reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c"
|
||||
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c",
|
||||
"reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c",
|
||||
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb",
|
||||
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
|
||||
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
|
||||
@ -13888,9 +13888,9 @@
|
||||
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
|
||||
"support": {
|
||||
"issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
|
||||
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6"
|
||||
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7"
|
||||
},
|
||||
"time": "2023-01-03T09:29:04+00:00"
|
||||
"time": "2023-12-08T13:03:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "turbo124/beacon",
|
||||
@ -15263,16 +15263,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.40.2",
|
||||
"version": "v3.41.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8"
|
||||
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4344562a516b76afe8f2d64b2e52214c30d64ed8",
|
||||
"reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
|
||||
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -15302,8 +15302,6 @@
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
|
||||
"phpspec/prophecy": "^1.17",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"symfony/phpunit-bridge": "^6.3.8 || ^7.0",
|
||||
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
|
||||
@ -15344,7 +15342,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.2"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -15352,7 +15350,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-03T09:21:33+00:00"
|
||||
"time": "2023-12-10T19:59:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
@ -15633,16 +15631,16 @@
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.6.6",
|
||||
"version": "1.6.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mockery/mockery.git",
|
||||
"reference": "b8e0bb7d8c604046539c1115994632c74dcb361e"
|
||||
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/b8e0bb7d8c604046539c1115994632c74dcb361e",
|
||||
"reference": "b8e0bb7d8c604046539c1115994632c74dcb361e",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
|
||||
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -15655,9 +15653,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5 || ^9.6.10",
|
||||
"psalm/plugin-phpunit": "^0.18.4",
|
||||
"symplify/easy-coding-standard": "^11.5.0",
|
||||
"vimeo/psalm": "^4.30"
|
||||
"symplify/easy-coding-standard": "^12.0.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -15714,7 +15710,7 @@
|
||||
"security": "https://github.com/mockery/mockery/security/advisories",
|
||||
"source": "https://github.com/mockery/mockery"
|
||||
},
|
||||
"time": "2023-08-09T00:03:52+00:00"
|
||||
"time": "2023-12-10T02:24:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
@ -16071,16 +16067,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.47",
|
||||
"version": "1.10.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39"
|
||||
"reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/84dbb33b520ea28b6cf5676a3941f4bae1c1ff39",
|
||||
"reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6",
|
||||
"reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -16129,7 +16125,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-01T15:19:17+00:00"
|
||||
"time": "2023-12-08T14:34:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
@ -17,8 +17,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => env('APP_VERSION', '5.7.59'),
|
||||
'app_tag' => env('APP_TAG', '5.7.59'),
|
||||
'app_version' => env('APP_VERSION', '5.7.60'),
|
||||
'app_tag' => env('APP_TAG', '5.7.60'),
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', false),
|
||||
|
@ -28,8 +28,20 @@ class DomainCheckTest extends TestCase
|
||||
public function testDomainCheck()
|
||||
{
|
||||
|
||||
$this->assertTrue(in_array('yopmail.com', Domains::getDomains()));
|
||||
$this->assertFalse(in_array('invoiceninja.com', Domains::getDomains()));
|
||||
$this->assertTrue(in_array('yopmail.com', \App\DataProviders\Domains::getDomains()));
|
||||
$this->assertFalse(in_array('invoiceninja.com', \App\DataProviders\Domains::getDomains()));
|
||||
|
||||
}
|
||||
|
||||
public function testSubdomainValidation()
|
||||
{
|
||||
$this->assertFalse($this->checker('invoiceninja'));
|
||||
$this->assertFalse($this->checker('hello'));
|
||||
$this->assertTrue($this->checker('nasty.pasty'));
|
||||
}
|
||||
|
||||
public function checker($subdomain)
|
||||
{
|
||||
return (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', $subdomain));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user