Merge branch 'v5-develop' into gocardless-direct-debit

This commit is contained in:
Benjamin Beganović 2021-10-19 16:29:50 +02:00 committed by GitHub
commit a9ac839fc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 177287 additions and 177833 deletions

View File

@ -1 +1 @@
5.3.23 5.3.25

View File

@ -486,7 +486,7 @@ class DemoMode extends Command
if (rand(0, 1)) { if (rand(0, 1)) {
$invoice->assigned_user_id = $assigned_user_id; $invoice->assigned_user_id = $assigned_user_id;
} }
$invoice->number = $this->getNextRecurringInvoiceNumber($client); $invoice->number = $this->getNextRecurringInvoiceNumber($client, $invoice);
$invoice->save(); $invoice->save();
} }

View File

@ -70,10 +70,15 @@ class Kernel extends ConsoleKernel
$schedule->job(new SchedulerCheck)->daily()->withoutOverlapping(); $schedule->job(new SchedulerCheck)->daily()->withoutOverlapping();
if(Ninja::isSelfHost())
{
$schedule->call(function () { $schedule->call(function () {
Account::whereNotNull('id')->update(['is_scheduler_running' => true]); Account::whereNotNull('id')->update(['is_scheduler_running' => true]);
})->everyFiveMinutes(); })->everyFiveMinutes();
}
/* Run hosted specific jobs */ /* Run hosted specific jobs */
if (Ninja::isHosted()) { if (Ninja::isHosted()) {

View File

@ -24,6 +24,7 @@ class ClientContactFactory
$client_contact->company_id = $company_id; $client_contact->company_id = $company_id;
$client_contact->contact_key = Str::random(40); $client_contact->contact_key = Str::random(40);
$client_contact->id = 0; $client_contact->id = 0;
$client_contact->send_email = true;
return $client_contact; return $client_contact;
} }

View File

@ -32,6 +32,8 @@ class CloneQuoteToInvoiceFactory
// 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']);
unset($quote_array['user']);
foreach ($quote_array as $key => $value) { foreach ($quote_array as $key => $value) {
$invoice->{$key} = $value; $invoice->{$key} = $value;

View File

@ -38,7 +38,7 @@ class RecurringExpenseToExpenseFactory
$expense->date = now()->format('Y-m-d'); $expense->date = now()->format('Y-m-d');
$expense->payment_date = $recurring_expense->payment_date; $expense->payment_date = $recurring_expense->payment_date;
$expense->amount = $recurring_expense->amount; $expense->amount = $recurring_expense->amount;
$expense->foreign_amount = $recurring_expense->foreign_amount; $expense->foreign_amount = $recurring_expense->foreign_amount ?: 0;
$expense->private_notes = $recurring_expense->private_notes; $expense->private_notes = $recurring_expense->private_notes;
$expense->public_notes = $recurring_expense->public_notes; $expense->public_notes = $recurring_expense->public_notes;
$expense->transaction_reference = $recurring_expense->transaction_reference; $expense->transaction_reference = $recurring_expense->transaction_reference;

View File

@ -175,6 +175,8 @@ abstract class QueryFilters
public function is_deleted($value) public function is_deleted($value)
{ {
if($value == 'true')
return $this->builder->where('is_deleted', $value)->withTrashed();
return $this->builder->where('is_deleted', $value); return $this->builder->where('is_deleted', $value);
@ -207,4 +209,17 @@ abstract class QueryFilters
return $this->builder; return $this->builder;
} }
public function with_trashed($value)
{
if($value == 'true'){
$this->builder->withTrashed();
}
return $this->builder;
}
} }

View File

@ -782,6 +782,8 @@ class BaseController extends Controller
return 'main.next.dart.js'; return 'main.next.dart.js';
case 'profile': case 'profile':
return 'main.profile.dart.js'; return 'main.profile.dart.js';
case 'html':
return 'main.html.dart.js';
default: default:
return 'main.foss.dart.js'; return 'main.foss.dart.js';

View File

@ -114,7 +114,7 @@ class PaymentController extends Controller
} else { } else {
$payment = PaymentFactory::create($payment_hash->fee_invoice->company_id, $payment_hash->fee_invoice->user_id); $payment = PaymentFactory::create($payment_hash->fee_invoice->company_id, $payment_hash->fee_invoice->user_id);
$payment->client_id = $payment_hash->fee_invoice->client_id; $payment->client_id = $payment_hash->fee_invoice->client_id;
$payment->save(); $payment->saveQuietly();
$payment_hash->payment_id = $payment->id; $payment_hash->payment_id = $payment->id;
$payment_hash->save(); $payment_hash->save();
@ -122,6 +122,8 @@ class PaymentController extends Controller
$payment = $payment->service()->applyCredits($payment_hash)->save(); $payment = $payment->service()->applyCredits($payment_hash)->save();
event('eloquent.created: App\Models\Payment', $payment);
if (property_exists($payment_hash->data, 'billing_context')) { if (property_exists($payment_hash->data, 'billing_context')) {
$billing_subscription = \App\Models\Subscription::find($payment_hash->data->billing_context->subscription_id); $billing_subscription = \App\Models\Subscription::find($payment_hash->data->billing_context->subscription_id);

View File

@ -499,7 +499,7 @@ class CompanyController extends BaseController
$account->delete(); $account->delete();
if(Ninja::isHosted()) if(Ninja::isHosted() && $request->has('cancellation_message') && strlen($request->input('cancellation_message')) > 1)
\Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all()); \Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all());
LightLogs::create(new AccountDeleted()) LightLogs::create(new AccountDeleted())

View File

@ -185,6 +185,10 @@ class InvoiceController extends BaseController
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"), * @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"), * @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"), * @OA\Parameter(ref="#/components/parameters/include"),
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/FillableInvoice")
* ),
* @OA\Response( * @OA\Response(
* response=200, * response=200,
* description="Returns the saved invoice object", * description="Returns the saved invoice object",

View File

@ -0,0 +1,37 @@
<?php
/**
* @OA\Schema(
* schema="FillableInvoice",
* type="object",
* @OA\Property(property="assigned_user_id", type="string", example="", description="__________"),
* @OA\Property(property="client_id", type="string", example="", description="________"),
* @OA\Property(property="number", type="string", example="INV_101", description="The invoice number - is a unique alpha numeric number per invoice per company"),
* @OA\Property(property="po_number", type="string", example="", description="________"),
* @OA\Property(property="terms", type="string", example="", description="________"),
* @OA\Property(property="public_notes", type="string", example="", description="________"),
* @OA\Property(property="private_notes", type="string", example="", description="________"),
* @OA\Property(property="footer", type="string", example="", description="________"),
* @OA\Property(property="custom_value1", type="string", example="", description="________"),
* @OA\Property(property="custom_value2", type="string", example="", description="________"),
* @OA\Property(property="custom_value3", type="string", example="", description="________"),
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
* @OA\Property(property="tax_name1", type="string", example="", description="________"),
* @OA\Property(property="tax_name2", type="string", example="", description="________"),
* @OA\Property(property="tax_rate1", type="number", example="10.00", description="_________"),
* @OA\Property(property="tax_rate2", type="number", example="10.00", description="_________"),
* @OA\Property(property="tax_name3", type="string", example="", description="________"),
* @OA\Property(property="tax_rate3", type="number", example="10.00", description="_________"),
* @OA\Property(property="line_items", type="object", example="", description="_________"),
* @OA\Property(property="discount", type="number", example="10.00", description="_________"),
* @OA\Property(property="partial", type="number", example="10.00", description="_________"),
* @OA\Property(property="is_amount_discount", type="boolean", example="1", description="_________"),
* @OA\Property(property="uses_inclusive_taxes", type="boolean", example="1", description="Defines the type of taxes used as either inclusive or exclusive"),
* @OA\Property(property="date", type="string", example="1994-07-30", description="The Invoice Date"),
* @OA\Property(property="partial_due_date", type="string", example="1994-07-30", description="_________"),
* @OA\Property(property="due_date", type="string", example="1994-07-30", description="_________"),
* @OA\Property(property="custom_surcharge1", type="number", example="10.00", description="First Custom Surcharge"),
* @OA\Property(property="custom_surcharge2", type="number", example="10.00", description="Second Custom Surcharge"),
* @OA\Property(property="custom_surcharge3", type="number", example="10.00", description="Third Custom Surcharge"),
* @OA\Property(property="custom_surcharge4", type="number", example="10.00", description="Fourth Custom Surcharge")
* )
*/

View File

@ -16,6 +16,7 @@ use App\Http\ValidationRules\Credit\UniqueCreditNumberRule;
use App\Models\Credit; use App\Models\Credit;
use App\Utils\Traits\CleanLineItems; use App\Utils\Traits\CleanLineItems;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Illuminate\Validation\Rule;
class StoreCreditRequest extends Request class StoreCreditRequest extends Request
{ {
@ -53,7 +54,11 @@ class StoreCreditRequest extends Request
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id; $rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
$rules['number'] = new UniqueCreditNumberRule($this->all()); // $rules['number'] = new UniqueCreditNumberRule($this->all());
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
$rules['line_items'] = 'array'; $rules['line_items'] = 'array';
return $rules; return $rules;

View File

@ -63,6 +63,10 @@ class StoreRecurringExpenseRequest extends Request
if(array_key_exists('color', $input) && is_null($input['color'])) if(array_key_exists('color', $input) && is_null($input['color']))
$input['color'] = ''; $input['color'] = '';
if(array_key_exists('foreign_amount', $input) && is_null($input['foreign_amount']))
$input['foreign_amount'] = 0;
$this->replace($input); $this->replace($input);
} }

View File

@ -0,0 +1,109 @@
<?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\Jobs\Mail;
use App\Jobs\Mail\NinjaMailer;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Libraries\MultiDB;
use App\Mail\Admin\EntityNotificationMailer;
use App\Mail\Admin\PaymentFailureObject;
use App\Models\Client;
use App\Models\Company;
use App\Models\PaymentHash;
use App\Models\User;
use App\Utils\Traits\Notifications\UserNotifies;
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\Mail;
/*Multi Mailer implemented*/
class PaymentFailedMailer implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies;
public PaymentHash $payment_hash;
public string $error;
public Company $company;
public Client $client;
/**
* Create a new job instance.
*
* @param $client
* @param $message
* @param $company
* @param $amount
*/
public function __construct(?PaymentHash $payment_hash, Company $company, Client $client, string $error)
{
$this->payment_hash = $payment_hash;
$this->client = $client;
$this->error = $error;
$this->company = $company;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//Set DB
MultiDB::setDb($this->company->db);
$settings = $this->client->getMergedSettings();
$amount = 0;
if($this->payment_hash)
$amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
//iterate through company_users
$this->company->company_users->each(function ($company_user) use($amount, $settings){
//determine if this user has the right permissions
$methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure','all_notifications']);
//if mail is a method type -fire mail!!
if (($key = array_search('mail', $methods)) !== false) {
unset($methods[$key]);
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $amount, $this->payment_hash))->build();
$nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer($mail_obj);
$nmo->company = $this->company;
$nmo->to_user = $company_user->user;
$nmo->settings = $settings;
NinjaMailerJob::dispatch($nmo);
}
});
//add client payment failures here.
}
}

View File

@ -86,7 +86,7 @@ class PaymentFailureMailer implements ShouldQueue
if (($key = array_search('mail', $methods)) !== false) { if (($key = array_search('mail', $methods)) !== false) {
unset($methods[$key]); unset($methods[$key]);
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->amount))->build(); $mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->amount, null))->build();
$nmo = new NinjaMailerObject; $nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer($mail_obj); $nmo->mailable = new NinjaMailer($mail_obj);
@ -98,5 +98,7 @@ class PaymentFailureMailer implements ShouldQueue
} }
}); });
//add client payment failures here.
} }
} }

View File

@ -65,11 +65,11 @@ class ApplyQuoteNumber implements ShouldQueue
switch ($this->settings->quote_number_applied) { switch ($this->settings->quote_number_applied) {
case 'when_saved': case 'when_saved':
$this->quote->number = $this->getNextQuoteNumber($this->quote->client); $this->quote->number = $this->getNextQuoteNumber($this->quote->client, $this->quote);
break; break;
case 'when_sent': case 'when_sent':
if ($this->quote->status_id == Quote::STATUS_SENT) { if ($this->quote->status_id == Quote::STATUS_SENT) {
$this->quote->number = $this->getNextQuoteNumber($this->quote->client); $this->quote->number = $this->getNextQuoteNumber($this->quote->client, $this->quote);
} }
break; break;

View File

@ -13,12 +13,14 @@ namespace App\Jobs\RecurringInvoice;
use App\DataMapper\Analytics\SendRecurringFailure; use App\DataMapper\Analytics\SendRecurringFailure;
use App\Events\Invoice\InvoiceWasEmailed; use App\Events\Invoice\InvoiceWasEmailed;
use App\Factory\InvoiceInvitationFactory;
use App\Factory\RecurringInvoiceToInvoiceFactory; use App\Factory\RecurringInvoiceToInvoiceFactory;
use App\Jobs\Entity\EmailEntity; use App\Jobs\Entity\EmailEntity;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Traits\GeneratesCounter; use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceValues; use App\Utils\Traits\MakesInvoiceValues;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
@ -32,6 +34,7 @@ class SendRecurring implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
use GeneratesCounter; use GeneratesCounter;
use MakesHash;
public $recurring_invoice; public $recurring_invoice;
@ -58,16 +61,6 @@ class SendRecurring implements ShouldQueue
*/ */
public function handle() : void public function handle() : void
{ {
//reset all contacts here
// $this->recurring_invoice->client->contacts()->update(['send_email' => false]);
// $this->recurring_invoice->invitations->each(function ($invitation){
// $contact = $invitation->contact;
// $contact->send_email = true;
// $contact->save();
// });
// Generate Standard Invoice // Generate Standard Invoice
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client); $invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
@ -86,10 +79,12 @@ class SendRecurring implements ShouldQueue
$invoice = $invoice->service() $invoice = $invoice->service()
->markSent() ->markSent()
->applyNumber() ->applyNumber()
->createInvitations() //need to only link invitations to those in the recurring invoice // ->createInvitations() //need to only link invitations to those in the recurring invoice
->fillDefaults() ->fillDefaults()
->save(); ->save();
$invoice = $this->createRecurringInvitations($invoice);
} }
else{ else{
@ -126,7 +121,7 @@ class SendRecurring implements ShouldQueue
if ($invitation->contact && !$invitation->contact->trashed() && strlen($invitation->contact->email) >=1 && $invoice->client->getSetting('auto_email_invoice')) { if ($invitation->contact && !$invitation->contact->trashed() && strlen($invitation->contact->email) >=1 && $invoice->client->getSetting('auto_email_invoice')) {
try{ try{
EmailEntity::dispatch($invitation, $invoice->company); EmailEntity::dispatch($invitation, $invoice->company)->delay(now()->addSeconds(1));
} }
catch(\Exception $e) { catch(\Exception $e) {
nlog($e->getMessage()); nlog($e->getMessage());
@ -152,9 +147,28 @@ class SendRecurring implements ShouldQueue
} }
//important catch all here - we should never leave contacts send_email to false incase they are permanently set to false in the future. }
// $this->recurring_invoice->client->contacts()->update(['send_email' => true]);
/**
* Only create the invitations that are defined on the recurring invoice.
* @param Invoice $invoice
* @return Invoice $invoice
*/
private function createRecurringInvitations($invoice) :Invoice
{
$this->recurring_invoice->invitations->each(function ($recurring_invitation) use($invoice){
$ii = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->invoice_id = $invoice->id;
$ii->client_contact_id = $recurring_invitation->client_contact_id;
$ii->save();
});
return $invoice->fresh();
} }
public function failed($exception = null) public function failed($exception = null)

View File

@ -11,25 +11,29 @@
namespace App\Mail\Admin; namespace App\Mail\Admin;
use App\Models\Client;
use App\Models\Company;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\PaymentHash;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Number; use App\Utils\Number;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use stdClass;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use stdClass;
class PaymentFailureObject class PaymentFailureObject
{ {
use MakesHash; use MakesHash;
public $client; public Client $client;
public $error; public string $error;
public $company; public Company $company;
public $amount; public $amount;
public PaymentHash $payment_hash;
// private $invoices; // private $invoices;
/** /**
@ -40,7 +44,7 @@ class PaymentFailureObject
* @param $company * @param $company
* @param $amount * @param $amount
*/ */
public function __construct($client, $error, $company, $amount) public function __construct(Client $client, string $error, Company $company, $amount, ?PaymentHash $payment_hash)
{ {
$this->client = $client; $this->client = $client;
@ -52,6 +56,8 @@ class PaymentFailureObject
$this->company = $company; $this->company = $company;
$this->payment_hash = $payment_hash;
} }
public function build() public function build()
@ -65,8 +71,6 @@ class PaymentFailureObject
/* Set customized translations _NOW_ */ /* Set customized translations _NOW_ */
$t->replace(Ninja::transformTranslations($this->company->settings)); $t->replace(Ninja::transformTranslations($this->company->settings));
// $this->invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
$mail_obj = new stdClass; $mail_obj = new stdClass;
$mail_obj->amount = $this->getAmount(); $mail_obj->amount = $this->getAmount();
$mail_obj->subject = $this->getSubject(); $mail_obj->subject = $this->getSubject();
@ -106,32 +110,33 @@ class PaymentFailureObject
'client' => $this->client->present()->name() 'client' => $this->client->present()->name()
] ]
), ),
'message' => $this->error, 'content' => ctrans(
'texts.notification_invoice_payment_failed',
[
'client' => $this->client->present()->name(),
'invoice' => $this->getDescription(),
'amount' => Number::formatMoney($this->amount, $this->client)
]),
'signature' => $signature, 'signature' => $signature,
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'settings' => $this->client->getMergedSettings(), 'settings' => $this->client->getMergedSettings(),
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'url' => config('ninja.app_url'), 'url' => config('ninja.app_url'),
'button' => ctrans('texts.login'), 'button' => ctrans('texts.login'),
'additional_info' => $this->buildFailedInvoices() 'additional_info' => $this->error
]; ];
return $data; return $data;
} }
private function buildFailedInvoices()
public function getDescription(bool $abbreviated = false)
{ {
if(!$this->payment_hash)
return "";
$text = ''; return \implode(', ', collect($this->payment_hash->invoices())->pluck('invoice_number')->toArray());
// foreach($this->invoices as $invoice)
// {
// $text .= ctrans('texts.notification_invoice_payment_failed_subject', ['invoice' => $invoice->number]) . "\n";
// }
return $text;
} }
} }

View File

@ -69,7 +69,7 @@ class SupportMessageSent extends Mailable
if(Ninja::isHosted()) if(Ninja::isHosted())
$subject = "{$priority}Hosted-{$db}-{$is_large}{$platform}{$migrated} :: {$plan} :: ".date('M jS, g:ia'); $subject = "{$priority}Hosted-{$db}-{$is_large}{$platform}{$migrated} :: {$plan} :: ".date('M jS, g:ia');
else else
$subject = "{$priority}Self Hosted :: {$plan} :: {$platform} :: ".date('M jS, g:ia'); $subject = "{$priority}Self Hosted :: {$plan} :: {$is_large}{$platform}{$migrated} :: ".date('M jS, g:ia');
return $this->from(config('mail.from.address'), $user->present()->name()) return $this->from(config('mail.from.address'), $user->present()->name())
->replyTo($user->email, $user->present()->name()) ->replyTo($user->email, $user->present()->name())

View File

@ -531,31 +531,7 @@ class Client extends BaseModel implements HasLocalePreference
} }
return null; return null;
// $company_gateways = $this->getSetting('company_gateway_ids');
// if (strlen($company_gateways) >= 1) {
// $transformed_ids = $this->transformKeys(explode(',', $company_gateways));
// $gateways = $this->company
// ->company_gateways
// ->whereIn('id', $transformed_ids)
// ->sortby(function ($model) use ($transformed_ids) {
// return array_search($model->id, $transformed_ids);
// });
// } else {
// $gateways = $this->company->company_gateways;
// }
// foreach ($gateways as $gateway) {
// if ($this->currency()->code == 'USD' && in_array(GatewayType::BANK_TRANSFER, $gateway->driver($this)->gatewayTypeEnabled(GatewayType::BANK_TRANSFER))) {
// return $gateway;
// }
// if ($this->currency()->code == 'EUR' && in_array(GatewayType::SEPA, $gateway->driver($this)->gatewayTypeEnabled(GatewayType::SEPA))) {
// return $gateway;
// }
// }
// return null;
} }
public function getBankTransferMethodType() public function getBankTransferMethodType()

View File

@ -12,7 +12,6 @@
namespace App\Models; namespace App\Models;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\PaymentDrivers\BasePaymentDriver;
use App\Utils\Number; use App\Utils\Number;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use stdClass; use stdClass;
@ -134,11 +133,10 @@ class CompanyGateway extends BaseModel
$class = 'App\\PaymentDrivers\\'.$this->gateway->provider.'PaymentDriver'; $class = 'App\\PaymentDrivers\\'.$this->gateway->provider.'PaymentDriver';
$class = str_replace('_', '', $class); $class = str_replace('_', '', $class);
if (class_exists($class)) { if (class_exists($class))
return $class; return $class;
} else {
return BasePaymentDriver::class; throw new \Exception("Payment Driver does not exist");
}
} }
/** /**

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Authorize; namespace App\PaymentDrivers\Authorize;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -134,7 +133,15 @@ class AuthorizeCreditCard
'data' => $this->formatGatewayResponse($data, $vars), 'data' => $this->formatGatewayResponse($data, $vars),
]; ];
PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransId(), $this->authorize->client->company, $amount); $code = "Error";
$description = "There was an error processing the payment";
if ($response->getErrors() != null) {
$code = $response->getErrors()[0]->getErrorCode();
$description = $response->getErrors()[0]->getErrorText();
}
$this->authorize->sendFailureMail($description);
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company); SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
@ -212,9 +219,9 @@ class AuthorizeCreditCard
$description = $response->getErrors()[0]->getErrorText(); $description = $response->getErrors()[0]->getErrorText();
} }
PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransId(), $this->authorize->client->company, $amount); $this->authorize->sendFailureMail($description);
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->input('payment_hash')])->firstOrFail(); $payment_hash = PaymentHash::where('hash', $request->input('payment_hash'))->firstOrFail();
$vars = [ $vars = [
'invoices' => $payment_hash->invoices(), 'invoices' => $payment_hash->invoices(),

View File

@ -19,7 +19,7 @@ use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\NinjaMailer; use App\Jobs\Mail\NinjaMailer;
use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject; use App\Jobs\Mail\NinjaMailerObject;
use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Mail\PaymentFailedMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Mail\Admin\ClientPaymentFailureObject; use App\Mail\Admin\ClientPaymentFailureObject;
use App\Models\Client; use App\Models\Client;
@ -236,7 +236,7 @@ class BaseDriver extends AbstractPaymentDriver
$payment->type_id = $data['payment_type']; $payment->type_id = $data['payment_type'];
$payment->transaction_reference = $data['transaction_reference']; $payment->transaction_reference = $data['transaction_reference'];
$payment->client_contact_id = $client_contact_id; $payment->client_contact_id = $client_contact_id;
$payment->save(); $payment->saveQuietly();
$this->payment_hash->payment_id = $payment->id; $this->payment_hash->payment_id = $payment->id;
$this->payment_hash->save(); $this->payment_hash->save();
@ -248,6 +248,8 @@ class BaseDriver extends AbstractPaymentDriver
$payment->service()->updateInvoicePayment($this->payment_hash); $payment->service()->updateInvoicePayment($this->payment_hash);
event('eloquent.created: App\Models\Payment', $payment);
if ($this->client->getSetting('client_online_payment_notification')) if ($this->client->getSetting('client_online_payment_notification'))
$payment->service()->sendEmail(); $payment->service()->sendEmail();
@ -306,7 +308,7 @@ class BaseDriver extends AbstractPaymentDriver
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->get(); $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->get();
$invoices->each(function ($invoice) { $invoices->each(function ($invoice) {
$invoice->service()->removeUnpaidGatewayFees(); $invoice->service()->removeUnpaidGatewayFees()->save();
}); });
} }
@ -371,12 +373,9 @@ class BaseDriver extends AbstractPaymentDriver
} else } else
$error = $e->getMessage(); $error = $e->getMessage();
PaymentFailureMailer::dispatch( $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
$gateway->client,
$error, $this->sendFailureMail($error);
$gateway->client->company,
$this->payment_hash
);
SystemLogger::dispatch( SystemLogger::dispatch(
$gateway->payment_hash, $gateway->payment_hash,
@ -390,13 +389,23 @@ class BaseDriver extends AbstractPaymentDriver
throw new PaymentFailed($error, $e->getCode()); throw new PaymentFailed($error, $e->getCode());
} }
public function sendFailureMail(string $error)
{
PaymentFailedMailer::dispatch(
$this->payment_hash,
$this->client->company,
$this->client,
$error
);
}
public function clientPaymentFailureMailer($error) public function clientPaymentFailureMailer($error)
{ {
nlog("outside");
if ($this->payment_hash && is_array($this->payment_hash->invoices())) { if ($this->payment_hash && is_array($this->payment_hash->invoices())) {
nlog("inside");
$nmo = new NinjaMailerObject; $nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer((new ClientPaymentFailureObject($this->client, $error, $this->client->company, $this->payment_hash))->build()); $nmo->mailable = new NinjaMailer((new ClientPaymentFailureObject($this->client, $error, $this->client->company, $this->payment_hash))->build());
@ -448,7 +457,7 @@ nlog("inside");
$this->unWindGatewayFees($this->payment_hash); $this->unWindGatewayFees($this->payment_hash);
PaymentFailureMailer::dispatch($this->client, $error, $this->client->company, $this->payment_hash->data->amount_with_fee); $this->sendFailureMail($error);
$nmo = new NinjaMailerObject; $nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer( (new ClientPaymentFailureObject($this->client, $error, $this->client->company, $this->payment_hash))->build() ); $nmo->mailable = new NinjaMailer( (new ClientPaymentFailureObject($this->client, $error, $this->client->company, $this->payment_hash))->build() );
@ -465,7 +474,7 @@ nlog("inside");
$invoices->first()->invitations->each(function ($invitation) use ($nmo){ $invoices->first()->invitations->each(function ($invitation) use ($nmo){
if (!$invitation->contact->trashed() && $invitation->contact->email) { if (!$invitation->contact->trashed()) {
$nmo->to_user = $invitation->contact; $nmo->to_user = $invitation->contact;
NinjaMailerJob::dispatch($nmo); NinjaMailerJob::dispatch($nmo);

View File

@ -1,313 +0,0 @@
<?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\PaymentDrivers;
use App\Factory\PaymentFactory;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\CompanyGateway;
use App\Models\GatewayType;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SystemLogTrait;
use Illuminate\Support\Carbon;
use Omnipay\Omnipay;
/**
* Class BasePaymentDriver.
'amount' => $invoice->getRequestedAmount(),
'currency' => $invoice->getCurrencyCode(),
'returnUrl' => $completeUrl,
'cancelUrl' => $this->invitation->getLink(),
'description' => trans('texts.' . $invoice->getEntityType()) . " {$invoice->number}",
'transactionId' => $invoice->number,
'transactionType' => 'Purchase',
'clientIp' => Request::getClientIp(),
];
*/
class BasePaymentDriver
{
use SystemLogTrait;
use MakesHash;
/* The company gateway instance*/
public $company_gateway;
/* The Omnipay payment driver instance*/
protected $gateway;
/* The Invitation */
protected $invitation;
/* Gateway capabilities */
protected $refundable = false;
/* Token billing */
public $token_billing = false;
/* Authorise payment methods */
protected $can_authorise_credit_card = false;
public function __construct(CompanyGateway $company_gateway, Client $client, $invitation = false)
{
$this->company_gateway = $company_gateway;
$this->invitation = $invitation;
$this->client = $client;
}
/**
* Returns the Omnipay driver.
* @return stdClass Omnipay initialized object
*/
protected function gateway()
{
$this->gateway = Omnipay::create($this->company_gateway->gateway->provider);
$this->gateway->initialize((array) $this->company_gateway->getConfig());
return $this;
}
/**
* Return the configuration fields for the
* Gatway.
* @return array The configuration fields
*/
public function getFields()
{
return $this->gateway->getDefaultParameters();
}
/**
* Returns the default gateway type.
*/
public function gatewayTypes()
{
return [
GatewayType::CREDIT_CARD,
];
}
public function getCompanyGatewayId(): int
{
return $this->company_gateway->id;
}
/**
* Returns whether refunds are possible with the gateway.
* @return bool TRUE|FALSE
*/
public function getRefundable(): bool
{
return $this->refundable;
}
/**
* Returns whether token billing is possible with the gateway.
* @return bool TRUE|FALSE
*/
public function getTokenBilling(): bool
{
return $this->token_billing;
}
/**
* Returns whether gateway can
* authorise and credit card.
* @return bool [type] [description]
*/
public function canAuthoriseCreditCard(): bool
{
return $this->can_authorise_credit_card;
}
/**
* Refunds a given payment.
* @param $payment
* @param int $amount
* @return false
*/
public function refundPayment($payment, $amount = 0)
{
if ($amount) {
$amount = min($amount, $payment->getCompletedAmount());
} else {
$amount = $payment->getCompletedAmount();
}
if ($payment->is_deleted || ! $amount) {
return false;
}
if ($payment->type_id == Payment::TYPE_CREDIT_CARD) {
return $payment->recordRefund($amount);
}
$details = $this->refundDetails($payment, $amount);
$response = $this->gateway()->refund($details)->send();
if ($response->isSuccessful()) {
return $payment->recordRefund($amount);
} elseif ($this->attemptVoidPayment($response, $payment, $amount)) {
$details = ['transactionReference' => $payment->transaction_reference];
$response = $this->gateway->void($details)->send();
if ($response->isSuccessful()) {
return $payment->markVoided();
}
}
return false;
}
protected function attemptVoidPayment($response, $payment, $amount)
{
// Partial refund not allowed for unsettled transactions
return $amount == $payment->amount;
}
public function authorizeCreditCardView(array $data)
{
}
public function authorizeCreditCardResponse($request)
{
}
public function processPaymentView(array $data)
{
}
public function processPaymentResponse($request)
{
}
/**
* Return the contact if possible.
*
* @return ClientContact The ClientContact object
*/
public function getContact()
{
if ($this->invitation) {
return ClientContact::find($this->invitation->client_contact_id);
} elseif (auth()->guard('contact')->user()) {
return auth()->user();
} else {
return false;
}
}
/************************************* Omnipay ******************************************
* authorize($options) - authorize an amount on the customer's card
* completeAuthorize($options) - handle return from off-site gateways after authorization
* capture($options) - capture an amount you have previously authorized
* purchase($options) - authorize and immediately capture an amount on the customer's card
* completePurchase($options) - handle return from off-site gateways after purchase
* refund($options) - refund an already processed transaction
* void($options) - generally can only be called up to 24 hours after submitting a transaction
* acceptNotification() - convert an incoming request from an off-site gateway to a generic notification object for further processing
* @param $input
* @return array
*/
protected function paymentDetails($input): array
{
$data = [
'currency' => $this->client->getCurrencyCode(),
'transactionType' => 'Purchase',
'clientIp' => request()->getClientIp(),
];
return $data;
}
public function purchase($data, $items)
{
$this->gateway();
$response = $this->gateway
->purchase($data)
->setItems($items)
->send();
return $response;
}
public function completePurchase($data)
{
$this->gateway();
return $this->gateway
->completePurchase($data)
->send();
}
public function createPayment($data, $status = Payment::STATUS_COMPLETED): Payment
{
$payment = PaymentFactory::create($this->client->company->id, $this->client->user->id);
$payment->client_id = $this->client->id;
$payment->company_gateway_id = $this->company_gateway->id;
$payment->status_id = $status;
$payment->currency_id = $this->client->getSetting('currency_id');
$payment->date = Carbon::now();
return $payment->service()->applyNumber()->save();
}
public function attachInvoices(Payment $payment, PaymentHash $payment_hash): Payment
{
$paid_invoices = $payment_hash->invoices();
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($paid_invoices, 'invoice_id')))->withTrashed()->get();
$payment->invoices()->sync($invoices);
$payment->save();
return $payment;
}
/**
* When a successful payment is made, we need to append the gateway fee
* to an invoice.
*
* @param PaymentResponseRequest $request The incoming payment request
* @return void Success/Failure
*/
public function confirmGatewayFee(PaymentResponseRequest $request) :void
{
/*Payment meta data*/
$payment_hash = $request->getPaymentHash();
/*Payment invoices*/
$payment_invoices = $payment_hash->invoices();
// /*Fee charged at gateway*/
$fee_total = $payment_hash->fee_total;
// Sum of invoice amounts
// $invoice_totals = array_sum(array_column($payment_invoices,'amount'));
/*Hydrate invoices*/
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_invoices, 'invoice_id')))->withTrashed()->get();
$invoices->each(function ($invoice) use ($fee_total) {
if (collect($invoice->line_items)->contains('type_id', '3')) {
$invoice->service()->toggleFeesPaid()->save();
$invoice->client->service()->updateBalance($fee_total)->save();
$invoice->ledger()->updateInvoiceBalance($fee_total, "Gateway fee adjustment for Invoice {$invoice->number}");
}
});
}
}

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers\Braintree;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -158,14 +157,7 @@ class ACH implements MethodInterface
private function processUnsuccessfulPayment($response) private function processUnsuccessfulPayment($response)
{ {
PaymentFailureMailer::dispatch($this->braintree->client, $response->transaction->additionalProcessorResponse, $this->braintree->client->company, $this->braintree->payment_hash->data->amount_with_fee); $this->braintree->sendFailureMail($response->transaction->additionalProcessorResponse);
PaymentFailureMailer::dispatch(
$this->braintree->client,
$response,
$this->braintree->client->company,
$this->braintree->payment_hash->data->amount_with_fee,
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,

View File

@ -16,7 +16,6 @@ namespace App\PaymentDrivers\Braintree;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -113,9 +112,14 @@ class CreditCard
$result = $this->braintree->gateway->transaction()->sale($data); $result = $this->braintree->gateway->transaction()->sale($data);
} catch(\Exception $e) { } catch(\Exception $e) {
if ($e instanceof \Braintree\Exception\Authorization) { if ($e instanceof \Braintree\Exception\Authorization) {
$this->braintree->sendFailureMail(ctrans('texts.generic_gateway_error'));
throw new PaymentFailed(ctrans('texts.generic_gateway_error'), $e->getCode()); throw new PaymentFailed(ctrans('texts.generic_gateway_error'), $e->getCode());
} }
$this->braintree->sendFailureMail($e->getMessage());
throw new PaymentFailed($e->getMessage(), $e->getCode()); throw new PaymentFailed($e->getMessage(), $e->getCode());
} }
@ -162,6 +166,8 @@ class CreditCard
return $response->paymentMethod->token; return $response->paymentMethod->token;
} }
$this->braintree->sendFailureMail($response->message);
throw new PaymentFailed($response->message); throw new PaymentFailed($response->message);
} }
@ -195,14 +201,8 @@ class CreditCard
*/ */
private function processUnsuccessfulPayment($response) private function processUnsuccessfulPayment($response)
{ {
PaymentFailureMailer::dispatch($this->braintree->client, $response->transaction->additionalProcessorResponse, $this->braintree->client->company, $this->braintree->payment_hash->data->amount_with_fee);
PaymentFailureMailer::dispatch( $this->braintree->sendFailureMail($response->transaction->additionalProcessorResponse);
$this->braintree->client,
$response,
$this->braintree->client->company,
$this->braintree->payment_hash->data->amount_with_fee,
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,

View File

@ -6,7 +6,6 @@ namespace App\PaymentDrivers\Braintree;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -149,14 +148,7 @@ class PayPal
private function processUnsuccessfulPayment($response) private function processUnsuccessfulPayment($response)
{ {
PaymentFailureMailer::dispatch($this->braintree->client, $response->message, $this->braintree->client->company, $this->braintree->payment_hash->data->amount_with_fee); $this->braintree->sendFailureMail($response->message);
PaymentFailureMailer::dispatch(
$this->braintree->client,
$response,
$this->braintree->client->company,
$this->braintree->payment_hash->data->amount_with_fee,
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -240,7 +239,7 @@ class BraintreePaymentDriver extends BaseDriver
if (!$result->success) { if (!$result->success) {
$this->unWindGatewayFees($payment_hash); $this->unWindGatewayFees($payment_hash);
PaymentFailureMailer::dispatch($this->client, $result->transaction->additionalProcessorResponse, $this->client->company, $this->payment_hash->data->amount_with_fee); $this->sendFailureMail($result->transaction->additionalProcessorResponse);
$message = [ $message = [
'server_response' => $result, 'server_response' => $result,

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\CheckoutCom;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\PaymentDrivers\CheckoutComPaymentDriver; use App\PaymentDrivers\CheckoutComPaymentDriver;
@ -210,8 +209,9 @@ class CreditCard implements MethodInterface
if ($response->status == 'Declined') { if ($response->status == 'Declined') {
$this->checkout->unWindGatewayFees($this->checkout->payment_hash); $this->checkout->unWindGatewayFees($this->checkout->payment_hash);
PaymentFailureMailer::dispatch($this->checkout->client, $response->response_summary, $this->checkout->client->company, $this->checkout->payment_hash->data->value); $this->checkout->sendFailureMail($response->response_summary);
//@todo - this will double up the checkout . com failed mails
$this->checkout->clientPaymentFailureMailer($response->status); $this->checkout->clientPaymentFailureMailer($response->status);
return $this->processUnsuccessfulPayment($response); return $this->processUnsuccessfulPayment($response);

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\CheckoutCom; namespace App\PaymentDrivers\CheckoutCom;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\PaymentType; use App\Models\PaymentType;
@ -85,12 +84,8 @@ trait Utilities
public function processUnsuccessfulPayment(Payment $_payment, $throw_exception = true) public function processUnsuccessfulPayment(Payment $_payment, $throw_exception = true)
{ {
PaymentFailureMailer::dispatch(
$this->getParent()->client, $this->getParent()->sendFailureMail($_payment->status . " " . $_payment->response_summary);
$_payment,
$this->getParent()->client->company,
$this->getParent()->payment_hash->data->value
);
$message = [ $message = [
'server_response' => $_payment, 'server_response' => $_payment,
@ -107,7 +102,7 @@ trait Utilities
); );
if ($throw_exception) { if ($throw_exception) {
throw new PaymentFailed($_payment->status, $_payment->http_code); throw new PaymentFailed($_payment->status . " " . $_payment->response_summary, $_payment->http_code);
} }
} }

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Gateways\Checkout3ds\Checkout3dsRequest; use App\Http\Requests\Gateways\Checkout3ds\Checkout3dsRequest;
use App\Http\Requests\Payments\PaymentWebhookRequest; use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\Company; use App\Models\Company;
@ -284,11 +283,7 @@ class CheckoutComPaymentDriver extends BaseDriver
if ($response->status == 'Declined') { if ($response->status == 'Declined') {
$this->unWindGatewayFees($payment_hash); $this->unWindGatewayFees($payment_hash);
PaymentFailureMailer::dispatch( $this->sendFailureMail($response->status . " " . $response->response_summary);
$this->client, $response->response_summary,
$this->client->company,
$amount
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,
@ -319,7 +314,16 @@ class CheckoutComPaymentDriver extends BaseDriver
'message' => $message, 'message' => $message,
]; ];
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client, $this->client->company); $this->sendFailureMail($message);
SystemLogger::dispatch(
$data,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_CHECKOUT,
$this->client,
$this->client->company
);
} }
} }

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Eway; namespace App\PaymentDrivers\Eway;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -84,8 +83,12 @@ class CreditCard
$response_status = ErrorCode::getStatus($response->ResponseMessage); $response_status = ErrorCode::getStatus($response->ResponseMessage);
if(!$response_status['success']) if(!$response_status['success']){
$this->eway_driver->sendFailureMail($response_status['message']);
throw new PaymentFailed($response_status['message'], 400); throw new PaymentFailed($response_status['message'], 400);
}
//success //success
$cgt = []; $cgt = [];
@ -159,6 +162,8 @@ class CreditCard
$this->logResponse($response, false); $this->logResponse($response, false);
$this->eway_driver->sendFailureMail($response_status['message']);
throw new PaymentFailed($response_status['message'], 400); throw new PaymentFailed($response_status['message'], 400);
} }
@ -238,6 +243,8 @@ class CreditCard
$this->logResponse($response, false); $this->logResponse($response, false);
$this->eway_driver->sendFailureMail($response_status['message']);
throw new PaymentFailed($response_status['message'], 400); throw new PaymentFailed($response_status['message'], 400);
} }

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Eway; namespace App\PaymentDrivers\Eway;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -73,8 +72,8 @@ class Token
$amount = array_sum(array_column($this->eway_driver->payment_hash->invoices(), 'amount')) + $this->eway_driver->payment_hash->fee_total; $amount = array_sum(array_column($this->eway_driver->payment_hash->invoices(), 'amount')) + $this->eway_driver->payment_hash->fee_total;
$data = [ $data = [
'gateway_type_id' => $cgt->gateway_type_id, 'gateway_type_id' => GatewayType::CREDIT_CARD,
'payment_type' => GatewayType::CREDIT_CARD_OTHER, 'payment_type' => PaymentType::CREDIT_CARD_OTHER,
'transaction_reference' => $response->Customer->Reference, 'transaction_reference' => $response->Customer->Reference,
'amount' => $amount, 'amount' => $amount,
]; ];
@ -83,8 +82,8 @@ class Token
$payment->meta = $cgt->meta; $payment->meta = $cgt->meta;
$payment->save(); $payment->save();
$payment_hash->payment_id = $payment->id; $this->eway_driver->payment_hash->payment_id = $payment->id;
$payment_hash->save(); $this->eway_driver->payment_hash->save();
return $payment; return $payment;

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\GoCardless;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -229,14 +228,7 @@ class ACH implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\GoCardlessPro\Resources\Payment $payment) public function processUnsuccessfulPayment(\GoCardlessPro\Resources\Payment $payment)
{ {
PaymentFailureMailer::dispatch($this->go_cardless->client, $payment->status, $this->go_cardless->client->company, $this->go_cardless->payment_hash->data->amount_with_fee); $this->go_cardless->sendFailureMail($payment->status);
PaymentFailureMailer::dispatch(
$this->go_cardless->client,
$payment,
$this->go_cardless->client->company,
$payment->amount
);
$message = [ $message = [
'server_response' => $payment, 'server_response' => $payment,

View File

@ -12,7 +12,6 @@
namespace App\PaymentDrivers; namespace App\PaymentDrivers;
use App\Http\Requests\Payments\PaymentWebhookRequest; use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -157,12 +156,7 @@ class GoCardlessPaymentDriver extends BaseDriver
return $payment; return $payment;
} }
PaymentFailureMailer::dispatch( $this->sendFailureMail($payment->status);
$this->client,
$payment->status,
$this->client->company,
$amount
);
$message = [ $message = [
'server_response' => $payment, 'server_response' => $payment,

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\Mollie;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -109,12 +108,8 @@ class Bancontact implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\Exception $exception): void public function processUnsuccessfulPayment(\Exception $exception): void
{ {
PaymentFailureMailer::dispatch(
$this->mollie->client, $this->mollie->sendFailureMail($exception->getMessage());
$exception->getMessage(),
$this->mollie->client->company,
$this->mollie->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$exception->getMessage(), $exception->getMessage(),

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\Mollie;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -112,12 +111,8 @@ class BankTransfer implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\Exception $e): void public function processUnsuccessfulPayment(\Exception $e): void
{ {
PaymentFailureMailer::dispatch(
$this->mollie->client, $this->mollie->sendFailureMail($e->getMessage());
$e->getMessage(),
$this->mollie->client->company,
$this->mollie->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$e->getMessage(), $e->getMessage(),

View File

@ -4,7 +4,6 @@ namespace App\PaymentDrivers\Mollie;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -88,6 +87,8 @@ class CreditCard
return redirect($payment->getCheckoutUrl()); return redirect($payment->getCheckoutUrl());
} }
} catch (\Exception $e) { } catch (\Exception $e) {
return $this->processUnsuccessfulPayment($e); return $this->processUnsuccessfulPayment($e);
} }
} }
@ -142,6 +143,7 @@ class CreditCard
return redirect($payment->getCheckoutUrl()); return redirect($payment->getCheckoutUrl());
} }
} catch (\Exception $e) { } catch (\Exception $e) {
$this->processUnsuccessfulPayment($e); $this->processUnsuccessfulPayment($e);
throw new PaymentFailed($e->getMessage(), $e->getCode()); throw new PaymentFailed($e->getMessage(), $e->getCode());
@ -196,12 +198,8 @@ class CreditCard
public function processUnsuccessfulPayment(\Exception $e) public function processUnsuccessfulPayment(\Exception $e)
{ {
PaymentFailureMailer::dispatch(
$this->mollie->client, $this->mollie->sendFailureMail($e->getMessage());
$e->getMessage(),
$this->mollie->client->company,
$this->mollie->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$e->getMessage(), $e->getMessage(),

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\Mollie;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -109,12 +108,8 @@ class IDEAL implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\Exception $exception): void public function processUnsuccessfulPayment(\Exception $exception): void
{ {
PaymentFailureMailer::dispatch(
$this->mollie->client, $this->mollie->sendFailureMail($exception->getMessage());
$exception->getMessage(),
$this->mollie->client->company,
$this->mollie->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$exception->getMessage(), $exception->getMessage(),

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers\Mollie;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -109,12 +108,8 @@ class KBC implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\Exception $exception): void public function processUnsuccessfulPayment(\Exception $exception): void
{ {
PaymentFailureMailer::dispatch(
$this->mollie->client, $this->mollie->sendFailureMail($exception->getMessage());
$exception->getMessage(),
$this->mollie->client->company,
$this->mollie->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$exception->getMessage(), $exception->getMessage(),

View File

@ -15,7 +15,6 @@ namespace App\PaymentDrivers;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Gateways\Mollie\Mollie3dsRequest; use App\Http\Requests\Gateways\Mollie\Mollie3dsRequest;
use App\Http\Requests\Payments\PaymentWebhookRequest; use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -247,12 +246,7 @@ class MolliePaymentDriver extends BaseDriver
$this->unWindGatewayFees($payment_hash); $this->unWindGatewayFees($payment_hash);
PaymentFailureMailer::dispatch( $this->sendFailureMail($payment->details);
$this->client,
$payment->details,
$this->client->company,
$amount
);
$message = [ $message = [
'server_response' => $payment, 'server_response' => $payment,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\PayFast; namespace App\PaymentDrivers\PayFast;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -253,14 +252,7 @@ class CreditCard
private function processUnsuccessfulPayment($server_response) private function processUnsuccessfulPayment($server_response)
{ {
PaymentFailureMailer::dispatch($this->payfast->client, $server_response->cancellation_reason, $this->payfast->client->company, $server_response->amount); $this->payfast->sendFailureMail($server_response->cancellation_reason);
PaymentFailureMailer::dispatch(
$this->payfast->client,
$server_response,
$this->payfast->client->company,
$server_response['amount_gross']
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\PayFast; namespace App\PaymentDrivers\PayFast;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -32,45 +31,11 @@ class Token
public $payfast; public $payfast;
//https://api.payfast.co.za/subscriptions/dc0521d3-55fe-269b-fa00-b647310d760f/adhoc
public function __construct(PayFastPaymentDriver $payfast) public function __construct(PayFastPaymentDriver $payfast)
{ {
$this->payfast = $payfast; $this->payfast = $payfast;
} }
// Attributes
// merchant-id
// integer, 8 char | REQUIRED
// Header, the Merchant ID as given by the PayFast system.
// version
// string | REQUIRED
// Header, the PayFast API version (i.e. v1).
// timestamp
// ISO-8601 date and time | REQUIRED
// Header, the current timestamp (YYYY-MM-DDTHH:MM:SS[+HH:MM]).
// signature
// string | REQUIRED
// Header, MD5 hash of the alphabetised submitted header and body variables, as well as the passphrase. Characters must be in lower case.
// amount
// integer | REQUIRED
// Body, the amount which the buyer must pay, in cents (ZAR), no decimals.
// item_name
// string, 100 char | REQUIRED
// Body, the name of the item being charged for.
// item_description
// string, 255 char | OPTIONAL
// Body, the description of the item being charged for.
// itn
// boolean | OPTIONAL
// Body, specify whether an ITN must be sent for the tokenization payment (true by default).
// m_payment_id
// string, 100 char | OPTIONAL
// Body, unique payment ID on the merchants system.
// cc_cvv
// numeric | OPTIONAL
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{ {
@ -90,73 +55,12 @@ class Token
'm_payment_id' => $payment_hash->hash, 'm_payment_id' => $payment_hash->hash,
]; ];
nlog(array_merge($body, $header));
// $header['signature'] = md5( $this->generate_parameter_string(array_merge($header, $body), false) );
$header['signature'] = $this->payfast->generateTokenSignature(array_merge($body, $header)); $header['signature'] = $this->payfast->generateTokenSignature(array_merge($body, $header));
nlog($header['signature']); nlog($header['signature']);
$result = $this->send($header, $body, $cgt->token); $result = $this->send($header, $body, $cgt->token);
nlog($result);
// $api = new \PayFast\PayFastApi(
// [
// 'merchantId' => $this->payfast->company_gateway->getConfigField('merchantId'),
// 'passPhrase' => $this->payfast->company_gateway->getConfigField('passPhrase'),
// 'testMode' => $this->payfast->company_gateway->getConfigField('testMode')
// ]
// );
// $adhocArray = $api
// ->subscriptions
// ->adhoc($cgt->token, ['amount' => $amount, 'item_name' => 'purchase']);
// nlog($adhocArray);
// /*Refactor and push to BaseDriver*/
// if ($data['response'] != null && $data['response']->getMessages()->getResultCode() == 'Ok') {
// $response = $data['response'];
// $this->storePayment($payment_hash, $data);
// $vars = [
// 'invoices' => $payment_hash->invoices(),
// 'amount' => $amount,
// ];
// $logger_message = [
// 'server_response' => $response->getTransactionResponse()->getTransId(),
// 'data' => $this->formatGatewayResponse($data, $vars),
// ];
// SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
// return true;
// } else {
// $vars = [
// 'invoices' => $payment_hash->invoices(),
// 'amount' => $amount,
// ];
// $logger_message = [
// 'server_response' => $response->getTransactionResponse()->getTransId(),
// 'data' => $this->formatGatewayResponse($data, $vars),
// ];
// PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransactionResponse()->getTransId(), $this->authorize->client->company, $amount);
// SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
// return false;
// }
} }
protected function generate_parameter_string( $api_data, $sort_data_before_merge = true, $skip_empty_values = true ) { protected function generate_parameter_string( $api_data, $sort_data_before_merge = true, $skip_empty_values = true ) {

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers; namespace App\PaymentDrivers;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Invoice; use App\Models\Invoice;
@ -94,7 +93,7 @@ class PayPalExpressPaymentDriver extends BaseDriver
return $response->redirect(); return $response->redirect();
} }
PaymentFailureMailer::dispatch($this->client, $response->getData(), $this->client->company, $data['total']['amount_with_fee']); $this->sendFailureMail($response->getData());
$message = [ $message = [
'server_response' => $response->getMessage(), 'server_response' => $response->getMessage(),
@ -152,7 +151,7 @@ class PayPalExpressPaymentDriver extends BaseDriver
$data = $response->getData(); $data = $response->getData();
PaymentFailureMailer::dispatch($this->client, $response->getMessage(), $this->client->company, $this->payment_hash->data->amount); $this->sendFailureMail($response->getMessage());
$message = [ $message = [
'server_response' => $data['L_LONGMESSAGE0'], 'server_response' => $data['L_LONGMESSAGE0'],

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\PayTrace; namespace App\PaymentDrivers\PayTrace;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;

View File

@ -16,7 +16,6 @@ namespace App\PaymentDrivers\Razorpay;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -106,6 +105,9 @@ class Hosted implements MethodInterface
]); ]);
if (! property_exists($this->razorpay->payment_hash->data, 'order_id')) { if (! property_exists($this->razorpay->payment_hash->data, 'order_id')) {
$this->razorpay->sendFailureMail("Missing [order_id] property. ");
throw new PaymentFailed('Missing [order_id] property. Please contact the administrator. Reference: ' . $this->razorpay->payment_hash->hash); throw new PaymentFailed('Missing [order_id] property. Please contact the administrator. Reference: ' . $this->razorpay->payment_hash->hash);
} }
@ -163,12 +165,8 @@ class Hosted implements MethodInterface
*/ */
public function processUnsuccessfulPayment(\Exception $exception): void public function processUnsuccessfulPayment(\Exception $exception): void
{ {
PaymentFailureMailer::dispatch(
$this->razorpay->client, $this->razorpay->sendFailureMail($exception->getMessage());
$exception->getMessage(),
$this->razorpay->client->company,
$this->razorpay->payment_hash->data->amount_with_fee
);
SystemLogger::dispatch( SystemLogger::dispatch(
$exception->getMessage(), $exception->getMessage(),
@ -180,5 +178,6 @@ class Hosted implements MethodInterface
); );
throw new PaymentFailed($exception->getMessage(), $exception->getCode()); throw new PaymentFailed($exception->getMessage(), $exception->getCode());
} }
} }

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Sample; namespace App\PaymentDrivers\Sample;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;

View File

@ -12,7 +12,6 @@
namespace App\PaymentDrivers; namespace App\PaymentDrivers;
use App\Http\Requests\Payments\PaymentWebhookRequest; use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
@ -167,12 +166,7 @@ class SquarePaymentDriver extends BaseDriver
$this->unWindGatewayFees($payment_hash); $this->unWindGatewayFees($payment_hash);
PaymentFailureMailer::dispatch( $this->sendFailureMail($body->errors[0]->detail);
$this->client,
$body->errors[0]->detail,
$this->client->company,
$amount
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,

View File

@ -17,7 +17,6 @@ use App\Http\Requests\ClientPortal\PaymentMethod\VerifyPaymentMethodRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject; use App\Jobs\Mail\NinjaMailerObject;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Mail\Gateways\ACHVerificationNotification; use App\Mail\Gateways\ACHVerificationNotification;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
@ -194,7 +193,7 @@ class ACH
return $this->processUnsuccessfulPayment($state); return $this->processUnsuccessfulPayment($state);
} catch (Exception $e) { } catch (Exception $e) {
if ($e instanceof CardException) { if ($e instanceof CardException) {
return redirect()->route('client.payment_methods.verification', ['payment_method' => $source->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); return redirect()->route('client.payment_methods.verification', ['payment_method' => $cgt->hashed_id, 'method' => GatewayType::BANK_TRANSFER]);
} }
throw new PaymentFailed($e->getMessage(), $e->getCode()); throw new PaymentFailed($e->getMessage(), $e->getCode());
@ -290,13 +289,7 @@ class ACH
public function processUnsuccessfulPayment($state) public function processUnsuccessfulPayment($state)
{ {
$this->stripe->sendFailureMail($state['charge']);
PaymentFailureMailer::dispatch(
$this->stripe->client,
$state['charge'],
$this->stripe->client->company,
$state['amount']
);
$message = [ $message = [
'server_response' => $state['charge'], 'server_response' => $state['charge'],

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -98,14 +97,7 @@ class Alipay
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch($this->stripe->client, $server_response->redirect_status, $this->stripe->client->company, $server_response->amount); $this->stripe->sendFailureMail($server_response->redirect_status);
PaymentFailureMailer::dispatch(
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -119,12 +118,7 @@ class Bancontact
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -81,12 +81,7 @@ class Charge
'description' => $description, 'description' => $description,
]; ];
nlog("Stripe tokenBilling payload");
nlog($data);
$response = $this->stripe->createPaymentIntent($data, $this->stripe->stripe_connect_auth); $response = $this->stripe->createPaymentIntent($data, $this->stripe->stripe_connect_auth);
// $response = $local_stripe->paymentIntents->create($data);
SystemLogger::dispatch($response, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client, $this->stripe->client->company); SystemLogger::dispatch($response, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client, $this->stripe->client->company);
} catch (\Exception $e) { } catch (\Exception $e) {
@ -136,7 +131,6 @@ class Charge
} }
$payment_method_type = $response->charges->data[0]->payment_method_details->card->brand; $payment_method_type = $response->charges->data[0]->payment_method_details->card->brand;
//nlog($payment_method_type);
$data = [ $data = [
'gateway_type_id' => $cgt->gateway_type_id, 'gateway_type_id' => $cgt->gateway_type_id,
@ -184,302 +178,3 @@ class Charge
} }
} }
} }
// const CREDIT = 1;
// const ACH = 4;
// const VISA = 5;
// const MASTERCARD = 6;
// const AMERICAN_EXPRESS = 7;
// const DISCOVER = 8;
// const DINERS = 9;
// const EUROCARD = 10;
// const NOVA = 11;
// const CREDIT_CARD_OTHER = 12;
// const PAYPAL = 13;
// const CARTE_BLANCHE = 16;
// const UNIONPAY = 17;
// const JCB = 18;
// const LASER = 19;
// const MAESTRO = 20;
// const SOLO = 21;
// const SWITCH = 22;
// const ALIPAY = 27;
// const SOFORT = 28;
// const SEPA = 29;
// const GOCARDLESS = 30;
// const CRYPTO = 31;
// {
// "id": "ch_1H4lp42eZvKYlo2Ch5igaUwg",
// "object": "charge",
// "amount": 2000,
// "amount_refunded": 0,
// "application": null,
// "application_fee": null,
// "application_fee_amount": null,
// "balance_transaction": "txn_19XJJ02eZvKYlo2ClwuJ1rbA",
// "billing_details": {
// "address": {
// "city": null,
// "country": null,
// "line1": null,
// "line2": null,
// "postal_code": "45465",
// "state": null
// },
// "email": null,
// "name": null,
// "phone": null
// },
// "calculated_statement_descriptor": null,
// "captured": false,
// "created": 1594724238,
// "currency": "usd",
// "customer": null,
// "description": "My First Test Charge (created for API docs)",
// "disputed": false,
// "failure_code": null,
// "failure_message": null,
// "fraud_details": {},
// "invoice": null,
// "livemode": false,
// "metadata": {},
// "on_behalf_of": null,
// "order": null,
// "outcome": null,
// "paid": true,
// "payment_intent": null,
// "payment_method": "card_1F8MLI2eZvKYlo2CvsyCzps2",
// "payment_method_details": {
// "card": {
// "brand": "visa",
// "checks": {
// "address_line1_check": null,
// "address_postal_code_check": "pass",
// "cvc_check": null
// },
// "country": "US",
// "exp_month": 12,
// "exp_year": 2023,
// "fingerprint": "Xt5EWLLDS7FJjR1c",
// "funding": "credit",
// "installments": null,
// "last4": "4242",
// "network": "visa",
// "three_d_secure": null,
// "wallet": null
// },
// "type": "card"
// },
// "receipt_email": null,
// "receipt_number": null,
// "receipt_url": "https://pay.stripe.com/receipts/acct_1032D82eZvKYlo2C/ch_1H4lp42eZvKYlo2Ch5igaUwg/rcpt_He3wuRQtzvT2Oi4OAYQSpajtmteo55J",
// "refunded": false,
// "refunds": {
// "object": "list",
// "data": [],
// "has_more": false,
// "url": "/v1/charges/ch_1H4lp42eZvKYlo2Ch5igaUwg/refunds"
// },
// "review": null,
// "shipping": null,
// "source_transfer": null,
// "statement_descriptor": null,
// "statement_descriptor_suffix": null,
// "status": "succeeded",
// "transfer_data": null,
// "transfer_group": null,
// "source": "tok_visa"
// }
//
//
// [2020-07-14 23:06:47] local.INFO: Stripe\PaymentIntent Object
// (
// [id] => pi_1H4xD0Kmol8YQE9DKhrvV6Nc
// [object] => payment_intent
// [allowed_source_types] => Array
// (
// [0] => card
// )
// [amount] => 1000
// [amount_capturable] => 0
// [amount_received] => 1000
// [application] =>
// [application_fee_amount] =>
// [canceled_at] =>
// [cancellation_reason] =>
// [capture_method] => automatic
// [charges] => Stripe\Collection Object
// (
// [object] => list
// [data] => Array
// (
// [0] => Stripe\Charge Object
// (
// [id] => ch_1H4xD0Kmol8YQE9Ds9b1ZWjw
// [object] => charge
// [amount] => 1000
// [amount_refunded] => 0
// [application] =>
// [application_fee] =>
// [application_fee_amount] =>
// [balance_transaction] => txn_1H4xD1Kmol8YQE9DE9qFoO0R
// [billing_details] => Stripe\StripeObject Object
// (
// [address] => Stripe\StripeObject Object
// (
// [city] =>
// [country] =>
// [line1] =>
// [line2] =>
// [postal_code] => 42334
// [state] =>
// )
// [email] =>
// [name] => sds
// [phone] =>
// )
// [calculated_statement_descriptor] => NODDY
// [captured] => 1
// [created] => 1594768006
// [currency] => usd
// [customer] => cus_He4VEiYldHJWqG
// [description] => Invoice 0023 for 10 for client Corwin Group
// [destination] =>
// [dispute] =>
// [disputed] =>
// [failure_code] =>
// [failure_message] =>
// [fraud_details] => Array
// (
// )
// [invoice] =>
// [livemode] =>
// [metadata] => Stripe\StripeObject Object
// (
// )
// [on_behalf_of] =>
// [order] =>
// [outcome] => Stripe\StripeObject Object
// (
// [network_status] => approved_by_network
// [reason] =>
// [risk_level] => normal
// [risk_score] => 13
// [seller_message] => Payment complete.
// [type] => authorized
// )
// [paid] => 1
// [payment_intent] => pi_1H4xD0Kmol8YQE9DKhrvV6Nc
// [payment_method] => pm_1H4mNAKmol8YQE9DUMRsuTXs
// [payment_method_details] => Stripe\StripeObject Object
// (
// [card] => Stripe\StripeObject Object
// (
// [brand] => visa
// [checks] => Stripe\StripeObject Object
// (
// [address_line1_check] =>
// [address_postal_code_check] => pass
// [cvc_check] =>
// )
// [country] => US
// [exp_month] => 4
// [exp_year] => 2024
// [fingerprint] => oCjEXlb4syFKwgbJ
// [funding] => credit
// [installments] =>
// [last4] => 4242
// [network] => visa
// [three_d_secure] =>
// [wallet] =>
// )
// [type] => card
// )
// [receipt_email] =>
// [receipt_number] =>
// [receipt_url] => https://pay.stripe.com/receipts/acct_19DXXPKmol8YQE9D/ch_1H4xD0Kmol8YQE9Ds9b1ZWjw/rcpt_HeFiiwzRZtnOpvHyohNN5JXtCYe8Rdc
// [refunded] =>
// [refunds] => Stripe\Collection Object
// (
// [object] => list
// [data] => Array
// (
// )
// [has_more] =>
// [total_count] => 0
// [url] => /v1/charges/ch_1H4xD0Kmol8YQE9Ds9b1ZWjw/refunds
// )
// [review] =>
// [shipping] =>
// [source] =>
// [source_transfer] =>
// [statement_descriptor] =>
// [statement_descriptor_suffix] =>
// [status] => succeeded
// [transfer_data] =>
// [transfer_group] =>
// )
// )
// [has_more] =>
// [total_count] => 1
// [url] => /v1/charges?payment_intent=pi_1H4xD0Kmol8YQE9DKhrvV6Nc
// )
// [client_secret] => pi_1H4xD0Kmol8YQE9DKhrvV6Nc_secret_TyE8n3Y3oaMqgqQvXvtKDOnYT
// [confirmation_method] => automatic
// [created] => 1594768006
// [currency] => usd
// [customer] => cus_He4VEiYldHJWqG
// [description] => Invoice 0023 for 10 for client Corwin Group
// [invoice] =>
// [last_payment_error] =>
// [livemode] =>
// [metadata] => Stripe\StripeObject Object
// (
// )
// [next_action] =>
// [next_source_action] =>
// [on_behalf_of] =>
// [payment_method] => pm_1H4mNAKmol8YQE9DUMRsuTXs
// [payment_method_options] => Stripe\StripeObject Object
// (
// [card] => Stripe\StripeObject Object
// (
// [installments] =>
// [network] =>
// [request_three_d_secure] => automatic
// )
// )
// [payment_method_types] => Array
// (
// [0] => card
// )
// [receipt_email] =>
// [review] =>
// [setup_future_usage] =>
// [shipping] =>
// [source] =>
// [statement_descriptor] =>
// [statement_descriptor_suffix] =>
// [status] => succeeded
// [transfer_data] =>
// [transfer_group] =>
// )

View File

@ -18,7 +18,6 @@ use App\Http\Requests\ClientPortal\PaymentMethod\VerifyPaymentMethodRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject; use App\Jobs\Mail\NinjaMailerObject;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Mail\Gateways\ACHVerificationNotification; use App\Mail\Gateways\ACHVerificationNotification;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -160,14 +159,7 @@ class CreditCard
public function processUnsuccessfulPayment($server_response) public function processUnsuccessfulPayment($server_response)
{ {
PaymentFailureMailer::dispatch($this->stripe->client, $server_response->cancellation_reason, $this->stripe->client->company, $server_response->amount); $this->stripe->sendFailureMail($server_response->cancellation_reason);
PaymentFailureMailer::dispatch(
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$server_response->amount
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -119,12 +118,7 @@ class EPS
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -119,12 +118,7 @@ class GIROPAY
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -119,12 +118,7 @@ class PRZELEWY24
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@ namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -120,12 +119,7 @@ class SEPA
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -115,12 +114,7 @@ class SOFORT
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Stripe; namespace App\PaymentDrivers\Stripe;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -119,12 +118,7 @@ class iDeal
{ {
$server_response = $this->stripe->payment_hash->data; $server_response = $this->stripe->payment_hash->data;
PaymentFailureMailer::dispatch( $this->stripe->sendFailureMail($server_response);
$this->stripe->client,
$server_response,
$this->stripe->client->company,
$this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency())
);
$message = [ $message = [
'server_response' => $server_response, 'server_response' => $server_response,

View File

@ -13,9 +13,11 @@
namespace App\PaymentDrivers\WePay; namespace App\PaymentDrivers\WePay;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
use App\Models\SystemLog;
use App\PaymentDrivers\WePayPaymentDriver; use App\PaymentDrivers\WePayPaymentDriver;
use App\PaymentDrivers\WePay\WePayCommon; use App\PaymentDrivers\WePay\WePayCommon;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
@ -68,6 +70,23 @@ class ACH
]); ]);
} }
catch(\Exception $e){ catch(\Exception $e){
$this->wepay_payment_driver->sendFailureMail($e->getMessage());
$message = [
'server_response' => $e->getMessage(),
'data' => $this->wepay_payment_driver->payment_hash->data,
];
SystemLogger::dispatch(
$e->getMessage(),
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_WEPAY,
$this->wepay_payment_driver->client,
$this->wepay_payment_driver->client->company,
);
throw new PaymentFailed($e->getMessage(), 400); throw new PaymentFailed($e->getMessage(), 400);
} }
// display the response // display the response

View File

@ -14,7 +14,6 @@ namespace App\PaymentDrivers\WePay;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
@ -153,6 +152,8 @@ use WePayCommon;
$app_fee = (config('ninja.wepay.fee_cc_multiplier') * $this->wepay_payment_driver->payment_hash->data->amount_with_fee) + config('ninja.wepay.fee_fixed'); $app_fee = (config('ninja.wepay.fee_cc_multiplier') * $this->wepay_payment_driver->payment_hash->data->amount_with_fee) + config('ninja.wepay.fee_fixed');
// charge the credit card // charge the credit card
try {
$response = $this->wepay_payment_driver->wepay->request('checkout/create', array( $response = $this->wepay_payment_driver->wepay->request('checkout/create', array(
'unique_id' => Str::random(40), 'unique_id' => Str::random(40),
'account_id' => $this->wepay_payment_driver->company_gateway->getConfigField('accountId'), 'account_id' => $this->wepay_payment_driver->company_gateway->getConfigField('accountId'),
@ -171,6 +172,28 @@ use WePayCommon;
) )
) )
)); ));
}
catch(\Exception $e){
$this->wepay_payment_driver->sendFailureMail($e->getMessage());
$message = [
'server_response' => $e->getMessage(),
'data' => $this->wepay_payment_driver->payment_hash->data,
];
SystemLogger::dispatch(
$e->getMessage(),
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_WEPAY,
$this->wepay_payment_driver->client,
$this->wepay_payment_driver->client->company,
);
throw new PaymentFailed($e->getMessage(), 500);
}
/* Merge all data and store in the payment hash*/ /* Merge all data and store in the payment hash*/
$state = [ $state = [

View File

@ -12,7 +12,6 @@
namespace App\PaymentDrivers\WePay; namespace App\PaymentDrivers\WePay;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\PaymentType; use App\Models\PaymentType;
@ -21,7 +20,6 @@ use App\Models\SystemLog;
trait WePayCommon trait WePayCommon
{ {
private function processSuccessfulPayment($response, $payment_status, $gateway_type, $return_payment = false) private function processSuccessfulPayment($response, $payment_status, $gateway_type, $return_payment = false)
{ {
@ -56,14 +54,7 @@ trait WePayCommon
private function processUnSuccessfulPayment($response, $payment_status) private function processUnSuccessfulPayment($response, $payment_status)
{ {
PaymentFailureMailer::dispatch($this->wepay_payment_driver->client, $response->state, $this->wepay_payment_driver->client->company, $response->amount); $this->wepay_payment_driver->sendFailureMail($response->state);
PaymentFailureMailer::dispatch(
$this->wepay_payment_driver->client,
$response,
$this->wepay_payment_driver->client->company,
$response->gross
);
$message = [ $message = [
'server_response' => $response, 'server_response' => $response,

View File

@ -222,15 +222,15 @@ class BaseRepository
$this->saveDocuments($data['documents'], $model); $this->saveDocuments($data['documents'], $model);
/* Marks whether the client contact should receive emails based on the send_email property */ /* Marks whether the client contact should receive emails based on the send_email property */
if (isset($data['client_contacts'])) { // if (isset($data['client_contacts'])) {
foreach ($data['client_contacts'] as $contact) { // foreach ($data['client_contacts'] as $contact) {
if ($contact['send_email'] == 1 && is_string($contact['id'])) { // if ($contact['send_email'] == 1 && is_string($contact['id'])) {
$client_contact = ClientContact::find($this->decodePrimaryKey($contact['id'])); // $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id']));
$client_contact->send_email = true; // $client_contact->send_email = true;
$client_contact->save(); // $client_contact->save();
} // }
} // }
} // }
/* If invitations are present we need to filter existing invitations with the new ones */ /* If invitations are present we need to filter existing invitations with the new ones */
if (isset($data['invitations'])) { if (isset($data['invitations'])) {
@ -285,10 +285,8 @@ class BaseRepository
} }
} }
$model->load('invitations');
/* If no invitations have been created, this is our fail safe to maintain state*/ /* If no invitations have been created, this is our fail safe to maintain state*/
if ($model->invitations->count() == 0) if ($model->invitations()->count() == 0)
$model->service()->createInvitations(); $model->service()->createInvitations();
/* Recalculate invoice amounts */ /* Recalculate invoice amounts */

View File

@ -107,7 +107,7 @@ class PaymentMigrationRepository extends BaseRepository
/*Ensure payment number generated*/ /*Ensure payment number generated*/
if (! $payment->number || strlen($payment->number) == 0) { if (! $payment->number || strlen($payment->number) == 0) {
$payment->number = $payment->client->getNextPaymentNumber($payment->client); $payment->number = $payment->client->getNextPaymentNumber($payment->client, $payment);
} }
$invoice_totals = 0; $invoice_totals = 0;

View File

@ -111,7 +111,7 @@ class PaymentRepository extends BaseRepository {
/*Ensure payment number generated*/ /*Ensure payment number generated*/
if (! $payment->number || strlen($payment->number) == 0) { if (! $payment->number || strlen($payment->number) == 0) {
$payment->number = $payment->client->getNextPaymentNumber($payment->client); $payment->number = $payment->client->getNextPaymentNumber($payment->client, $payment);
} }
/*Set local total variables*/ /*Set local total variables*/

View File

@ -37,7 +37,7 @@ class ApplyNumber extends AbstractService
return $this->credit; return $this->credit;
} }
$this->credit->number = $this->getNextCreditNumber($this->client); $this->credit->number = $this->getNextCreditNumber($this->client, $this->credit);
return $this->credit; return $this->credit;
} }

View File

@ -58,14 +58,14 @@ class ApplyPaymentAmount extends AbstractService
$payment->amount = $this->amount; $payment->amount = $this->amount;
$payment->applied = min($this->amount, $this->invoice->balance); $payment->applied = min($this->amount, $this->invoice->balance);
$payment->number = $this->getNextPaymentNumber($this->invoice->client); $payment->number = $this->getNextPaymentNumber($this->invoice->client, $payment);
$payment->status_id = Payment::STATUS_COMPLETED; $payment->status_id = Payment::STATUS_COMPLETED;
$payment->client_id = $this->invoice->client_id; $payment->client_id = $this->invoice->client_id;
$payment->transaction_reference = ctrans('texts.manual_entry'); $payment->transaction_reference = ctrans('texts.manual_entry');
$payment->currency_id = $this->invoice->client->getSetting('currency_id'); $payment->currency_id = $this->invoice->client->getSetting('currency_id');
$payment->is_manual = true; $payment->is_manual = true;
/* Create a payment relationship to the invoice entity */ /* Create a payment relationship to the invoice entity */
$payment->save(); $payment->saveQuietly();
$this->setExchangeRate($payment); $this->setExchangeRate($payment);
@ -103,6 +103,8 @@ class ApplyPaymentAmount extends AbstractService
$this->invoice->service()->workFlow()->save(); $this->invoice->service()->workFlow()->save();
event('eloquent.created: App\Models\Payment', $payment);
return $this->invoice; return $this->invoice;
} }
@ -120,7 +122,7 @@ class ApplyPaymentAmount extends AbstractService
//$payment->exchange_currency_id = $client_currency; // 23/06/2021 //$payment->exchange_currency_id = $client_currency; // 23/06/2021
$payment->exchange_currency_id = $company_currency; $payment->exchange_currency_id = $company_currency;
$payment->save(); $payment->saveQuietly();
} }

View File

@ -39,11 +39,11 @@ class ApplyRecurringNumber extends AbstractService
switch ($this->client->getSetting('counter_number_applied')) { switch ($this->client->getSetting('counter_number_applied')) {
case 'when_saved': case 'when_saved':
$this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client); $this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client, $this->invoice);
break; break;
case 'when_sent': case 'when_sent':
if ($this->invoice->status_id == Invoice::STATUS_SENT) { if ($this->invoice->status_id == Invoice::STATUS_SENT) {
$this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client); $this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client, $this->invoice);
} }
break; break;

View File

@ -107,7 +107,7 @@ class AutoBillInvoice extends AbstractService
/* Build payment hash */ /* Build payment hash */
$payment_hash = PaymentHash::create([ $payment_hash = PaymentHash::create([
'hash' => Str::random(64), 'hash' => Str::random(64),
'data' => ['invoices' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount]]], 'data' => ['invoices' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount, 'invoice_number' => $this->invoice->number]]],
'fee_total' => $fee, 'fee_total' => $fee,
'fee_invoice_id' => $this->invoice->id, 'fee_invoice_id' => $this->invoice->id,
]); ]);
@ -175,6 +175,8 @@ class AutoBillInvoice extends AbstractService
} }
event('eloquent.created: App\Models\Payment', $payment);
$payment->ledger() $payment->ledger()
->updatePaymentBalance($amount * -1) ->updatePaymentBalance($amount * -1)
->save(); ->save();
@ -190,6 +192,7 @@ class AutoBillInvoice extends AbstractService
->updateCreditBalance($amount * -1, "Credit {$current_credit->number} used to pay down Invoice {$this->invoice->number}") ->updateCreditBalance($amount * -1, "Credit {$current_credit->number} used to pay down Invoice {$this->invoice->number}")
->save(); ->save();
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars())); event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
return $this->invoice return $this->invoice

View File

@ -43,9 +43,9 @@ class CreateInvitations extends AbstractService
} }
$contacts->each(function ($contact) { $contacts->each(function ($contact) {
$invitation = InvoiceInvitation::whereCompanyId($this->invoice->company_id) $invitation = InvoiceInvitation::where('company_id', $this->invoice->company_id)
->whereClientContactId($contact->id) ->where('client_contact_id', $contact->id)
->whereInvoiceId($this->invoice->id) ->where('invoice_id', $this->invoice->id)
->withTrashed() ->withTrashed()
->first(); ->first();

View File

@ -494,6 +494,6 @@ class InvoiceService
{ {
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();
return $this->invoice; return $this->invoice->fresh();
} }
} }

View File

@ -52,7 +52,7 @@ class MarkPaid extends AbstractService
$payment->amount = $this->invoice->balance; $payment->amount = $this->invoice->balance;
$payment->applied = $this->invoice->balance; $payment->applied = $this->invoice->balance;
$payment->number = $this->getNextPaymentNumber($this->invoice->client); $payment->number = $this->getNextPaymentNumber($this->invoice->client, $payment);
$payment->status_id = Payment::STATUS_COMPLETED; $payment->status_id = Payment::STATUS_COMPLETED;
$payment->client_id = $this->invoice->client_id; $payment->client_id = $this->invoice->client_id;
$payment->transaction_reference = ctrans('texts.manual_entry'); $payment->transaction_reference = ctrans('texts.manual_entry');
@ -64,7 +64,7 @@ class MarkPaid extends AbstractService
if((int)$payment_type_id > 0) if((int)$payment_type_id > 0)
$payment->type_id = (int)$payment_type_id; $payment->type_id = (int)$payment_type_id;
$payment->save(); $payment->saveQuietly();
$this->setExchangeRate($payment); $this->setExchangeRate($payment);
@ -73,6 +73,8 @@ class MarkPaid extends AbstractService
'amount' => $payment->amount, 'amount' => $payment->amount,
]); ]);
event('eloquent.created: App\Models\Payment', $payment);
$this->invoice->next_send_date = null; $this->invoice->next_send_date = null;
$this->invoice->service() $this->invoice->service()
@ -84,8 +86,8 @@ class MarkPaid extends AbstractService
->deletePdf() ->deletePdf()
->save(); ->save();
if ($this->invoice->client->getSetting('client_manual_payment_notification')) // if ($this->invoice->client->getSetting('client_manual_payment_notification'))
$payment->service()->sendEmail(); // $payment->service()->sendEmail();
/* Update Invoice balance */ /* Update Invoice balance */
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));

View File

@ -33,15 +33,18 @@ class MarkSent extends AbstractService
{ {
/* Return immediately if status is not draft */ /* Return immediately if status is not draft */
if ($this->invoice->status_id != Invoice::STATUS_DRAFT) { if ($this->invoice->fresh()->status_id != Invoice::STATUS_DRAFT) {
return $this->invoice; return $this->invoice;
} }
$this->invoice->markInvitationsSent(); /*Set status*/
$this->invoice $this->invoice
->service() ->service()
->setStatus(Invoice::STATUS_SENT) ->setStatus(Invoice::STATUS_SENT)
->save();
$this->invoice
->service()
->applyNumber() ->applyNumber()
->setDueDate() ->setDueDate()
->updateBalance($this->invoice->amount) ->updateBalance($this->invoice->amount)
@ -49,9 +52,18 @@ class MarkSent extends AbstractService
->setReminder() ->setReminder()
->save(); ->save();
$this->client->service()->updateBalance($this->invoice->balance)->save(); $this->invoice->markInvitationsSent();
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, "Invoice {$this->invoice->number} marked as sent."); /*Adjust client balance*/
$this->client
->service()
->updateBalance($this->invoice->balance)
->save();
/*Update ledger*/
$this->invoice
->ledger()
->updateInvoiceBalance($this->invoice->balance, "Invoice {$this->invoice->number} marked as sent.");
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));

View File

@ -34,7 +34,7 @@ class ApplyNumber extends AbstractService
return $this->payment; return $this->payment;
} }
$this->payment->number = $this->getNextPaymentNumber($this->client); $this->payment->number = $this->getNextPaymentNumber($this->client, $this->payment);
return $this->payment; return $this->payment;
} }

View File

@ -39,12 +39,14 @@ class PaymentService
$payment->transaction_reference = ctrans('texts.manual_entry'); $payment->transaction_reference = ctrans('texts.manual_entry');
$payment->currency_id = $invoice->client->getSetting('currency_id'); $payment->currency_id = $invoice->client->getSetting('currency_id');
/* Create a payment relationship to the invoice entity */ /* Create a payment relationship to the invoice entity */
$payment->save(); $payment->saveQuietly();
$payment->invoices()->attach($invoice->id, [ $payment->invoices()->attach($invoice->id, [
'amount' => $payment->amount, 'amount' => $payment->amount,
]); ]);
event('eloquent.created: App\Models\Payment', $payment);
return $payment; return $payment;
} }
@ -145,7 +147,7 @@ class PaymentService
public function save() public function save()
{ {
$this->payment->save(); $this->payment->saveQuietly();
return $this->payment->fresh(); return $this->payment->fresh();
} }

View File

@ -33,11 +33,11 @@ class ApplyNumber
switch ($this->client->getSetting('counter_number_applied')) { switch ($this->client->getSetting('counter_number_applied')) {
case 'when_saved': case 'when_saved':
$quote->number = $this->getNextQuoteNumber($this->client); $quote->number = $this->getNextQuoteNumber($this->client, $quote);
break; break;
case 'when_sent': case 'when_sent':
if ($quote->status_id == Quote::STATUS_SENT) { if ($quote->status_id == Quote::STATUS_SENT) {
$quote->number = $this->getNextQuoteNumber($this->client); $quote->number = $this->getNextQuoteNumber($this->client, $quote);
} }
break; break;

View File

@ -13,6 +13,8 @@
namespace App\Services\Quote; namespace App\Services\Quote;
use App\Factory\CloneQuoteToInvoiceFactory; use App\Factory\CloneQuoteToInvoiceFactory;
use App\Factory\InvoiceInvitationFactory;
use App\Models\Invoice;
use App\Models\Quote; use App\Models\Quote;
use App\Repositories\InvoiceRepository; use App\Repositories\InvoiceRepository;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
@ -39,14 +41,20 @@ class ConvertQuote
{ {
$invoice = CloneQuoteToInvoiceFactory::create($quote, $quote->user_id); $invoice = CloneQuoteToInvoiceFactory::create($quote, $quote->user_id);
$invoice->design_id = $this->decodePrimaryKey($this->client->getSetting('invoice_design_id')); $invoice->design_id = $this->decodePrimaryKey($this->client->getSetting('invoice_design_id'));
$invoice = $this->invoice_repo->save($invoice->toArray(), $invoice);
//create invitations here before the repo save()
//we need to do this here otherwise the repo_save will create
//invitations for ALL contacts
$invites = $this->createConversionInvitations($invoice, $quote);
$invoice_array = $invoice->toArray();
$invoice_array['invitations'] = $invites;
$invoice = $this->invoice_repo->save($invoice_array, $invoice);
$invoice->fresh(); $invoice->fresh();
$invoice->service() $invoice->service()
->fillDefaults() ->fillDefaults()
// ->markSent()
// ->createInvitations()
->save(); ->save();
$quote->invoice_id = $invoice->id; $quote->invoice_id = $invoice->id;
@ -56,4 +64,26 @@ class ConvertQuote
// maybe should return invoice here // maybe should return invoice here
return $invoice; return $invoice;
} }
/**
* Only create the invitations that are defined on the quote.
*
* @return Invoice $invoice
*/
private function createConversionInvitations($invoice, $quote)
{
$invites = [];
foreach($quote->invitations as $quote_invitation){
$ii = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->client_contact_id = $quote_invitation->client_contact_id;
$invites[] = $ii;
}
return $invites;
}
} }

View File

@ -12,6 +12,7 @@
namespace App\Services\Quote; namespace App\Services\Quote;
use App\Events\Quote\QuoteWasApproved; use App\Events\Quote\QuoteWasApproved;
use App\Factory\InvoiceInvitationFactory;
use App\Jobs\Util\UnlinkFile; use App\Jobs\Util\UnlinkFile;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Quote; use App\Models\Quote;
@ -117,7 +118,6 @@ class QuoteService
$this->invoice $this->invoice
->service() ->service()
->markSent() ->markSent()
->createInvitations()
->deletePdf() ->deletePdf()
->save(); ->save();

View File

@ -36,7 +36,7 @@ class ApplyNumber extends AbstractService
if ($this->recurring_entity->number != '') if ($this->recurring_entity->number != '')
return $this->recurring_entity; return $this->recurring_entity;
$this->recurring_entity->number = $this->getNextRecurringInvoiceNumber($this->client); $this->recurring_entity->number = $this->getNextRecurringInvoiceNumber($this->client, $this->recurring_entity);
return $this->recurring_entity; return $this->recurring_entity;
} }

View File

@ -54,8 +54,6 @@ class RecurringService
return $this; return $this;
} }
// $this->createInvitations()->setStatus(RecurringInvoice::STATUS_ACTIVE);
$this->setStatus(RecurringInvoice::STATUS_ACTIVE); $this->setStatus(RecurringInvoice::STATUS_ACTIVE);
return $this; return $this;

View File

@ -172,7 +172,9 @@ trait GeneratesCounter
*/ */
public function getNextInvoiceNumber(Client $client, ?Invoice $invoice, $is_recurring = false) :string public function getNextInvoiceNumber(Client $client, ?Invoice $invoice, $is_recurring = false) :string
{ {
return $this->getNextEntityNumber(Invoice::class, $client, $is_recurring); $entity_number = $this->getNextEntityNumber(Invoice::class, $client, $is_recurring);
return $this->replaceUserVars($invoice, $entity_number);
} }
/** /**
@ -182,9 +184,12 @@ trait GeneratesCounter
* *
* @return string The next credit number. * @return string The next credit number.
*/ */
public function getNextCreditNumber(Client $client) :string public function getNextCreditNumber(Client $client, ?Credit $credit) :string
{ {
return $this->getNextEntityNumber(Credit::class, $client); $entity_number = $this->getNextEntityNumber(Credit::class, $client);
return $this->replaceUserVars($credit, $entity_number);
} }
/** /**
@ -194,19 +199,28 @@ trait GeneratesCounter
* *
* @return string The next credit number. * @return string The next credit number.
*/ */
public function getNextQuoteNumber(Client $client) public function getNextQuoteNumber(Client $client, ?Quote $quote)
{ {
return $this->getNextEntityNumber(Quote::class, $client); $entity_number = $this->getNextEntityNumber(Quote::class, $client);
return $this->replaceUserVars($quote, $entity_number);
} }
public function getNextRecurringInvoiceNumber(Client $client) public function getNextRecurringInvoiceNumber(Client $client, $recurring_invoice)
{ {
return $this->getNextEntityNumber(RecurringInvoice::class, $client); $entity_number = $this->getNextEntityNumber(RecurringInvoice::class, $client);
return $this->replaceUserVars($recurring_invoice, $entity_number);
} }
public function getNextRecurringQuoteNumber(Client $client) public function getNextRecurringQuoteNumber(Client $client, $recurring_quote)
{ {
return $this->getNextEntityNumber(RecurringQuote::class, $client); $entity_number = $this->getNextEntityNumber(RecurringQuote::class, $client);
return $this->replaceUserVars($recurring_quote, $entity_number);
} }
/** /**
@ -216,9 +230,12 @@ trait GeneratesCounter
* *
* @return string The next payment number. * @return string The next payment number.
*/ */
public function getNextPaymentNumber(Client $client) :string public function getNextPaymentNumber(Client $client, ?Payment $payment) :string
{ {
return $this->getNextEntityNumber(Payment::class, $client); $entity_number = $this->getNextEntityNumber(Payment::class, $client);
return $this->replaceUserVars($payment, $entity_number);
} }
/** /**
@ -241,7 +258,10 @@ trait GeneratesCounter
$this->incrementCounter($setting_entity, 'client_number_counter'); $this->incrementCounter($setting_entity, 'client_number_counter');
return $client_number; $entity_number = $client_number;
return $this->replaceUserVars($client, $entity_number);
} }
@ -262,7 +282,10 @@ trait GeneratesCounter
$this->incrementCounter($vendor->company, 'vendor_number_counter'); $this->incrementCounter($vendor->company, 'vendor_number_counter');
return $vendor_number; $entity_number = $vendor_number;
return $this->replaceUserVars($vendor, $entity_number);
} }
/** /**
@ -281,7 +304,10 @@ trait GeneratesCounter
$this->incrementCounter($project->company, 'project_number_counter'); $this->incrementCounter($project->company, 'project_number_counter');
return $project_number; $entity_number = $project_number;
return $this->replaceUserVars($project, $entity_number);
} }
@ -302,7 +328,10 @@ trait GeneratesCounter
$this->incrementCounter($task->company, 'task_number_counter'); $this->incrementCounter($task->company, 'task_number_counter');
return $task_number; $entity_number = $task_number;
return $this->replaceUserVars($task, $entity_number);
} }
/** /**
@ -322,7 +351,10 @@ trait GeneratesCounter
$this->incrementCounter($expense->company, 'expense_number_counter'); $this->incrementCounter($expense->company, 'expense_number_counter');
return $expense_number; $entity_number = $expense_number;
return $this->replaceUserVars($expense, $entity_number);
} }
/** /**
@ -351,7 +383,10 @@ trait GeneratesCounter
$this->incrementCounter($expense->company, 'recurring_expense_number_counter'); $this->incrementCounter($expense->company, 'recurring_expense_number_counter');
return $expense_number; $entity_number = $expense_number;
return $this->replaceUserVars($expense, $entity_number);
} }
@ -713,6 +748,18 @@ trait GeneratesCounter
$replace[] = $client->id_number; $replace[] = $client->id_number;
} }
return str_replace($search, $replace, $pattern);
}
private function replaceUserVars($entity, $pattern)
{
if(!$entity)
return $pattern;
$search = [];
$replace = [];
$search[] = '{$user_custom1}'; $search[] = '{$user_custom1}';
$replace[] = $entity->user->custom_value1; $replace[] = $entity->user->custom_value1;
@ -722,10 +769,10 @@ trait GeneratesCounter
$search[] = '{$user_custom3}'; $search[] = '{$user_custom3}';
$replace[] = $entity->user->custom_value3; $replace[] = $entity->user->custom_value3;
$search[] = '{$client_custom4}'; $search[] = '{$user_custom4}';
$replace[] = $entity->user->custom_value4; $replace[] = $entity->user->custom_value4;
return str_replace($search, $replace, $pattern); return str_replace($search, $replace, $pattern);
} }
} }

View File

@ -65,7 +65,7 @@ trait Refundable
$line_items[] = $credit_line_item; $line_items[] = $credit_line_item;
$credit_note->save(); $credit_note->save();
$credit_note->number = $this->client->getNextCreditNumber($this->client); $credit_note->number = $this->client->getNextCreditNumber($this->client, $credit_note);
$credit_note->save(); $credit_note->save();
$this->createActivity($data, $credit_note->id); $this->createActivity($data, $credit_note->id);
@ -165,7 +165,7 @@ trait Refundable
$credit_note->line_items = $line_items; $credit_note->line_items = $line_items;
$credit_note->save(); $credit_note->save();
$credit_note->number = $this->client->getNextCreditNumber($this->client); $credit_note->number = $this->client->getNextCreditNumber($this->client, $credit_note);
$credit_note->save(); $credit_note->save();
if ($data['gateway_refund'] !== false && $total_refund > 0) { if ($data['gateway_refund'] !== false && $total_refund > 0) {

View File

@ -129,7 +129,7 @@ return [
// This optional option determines the channel name sent with the // This optional option determines the channel name sent with the
// message in the 'facility' field. Default is equal to app.env // message in the 'facility' field. Default is equal to app.env
// configuration value // configuration value
'name' => 'my-custom-name', 'name' => 'v5_app',
// This optional option determines the system name sent with the // This optional option determines the system name sent with the
// message in the 'source' field. When forgotten or set to null, // message in the 'source' field. When forgotten or set to null,

View File

@ -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.23', 'app_version' => '5.3.25',
'app_tag' => '5.3.23', 'app_tag' => '5.3.25',
'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', ''),

View File

@ -3,7 +3,7 @@ const MANIFEST = 'flutter-app-manifest';
const TEMP = 'flutter-temp-cache'; const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache'; const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = { const RESOURCES = {
"version.json": "9ec5e3813adc4bfd8713556c5059e97d", "version.json": "07a43895b172742ab22bb808918b117a",
"favicon.ico": "51636d3a390451561744c42188ccd628", "favicon.ico": "51636d3a390451561744c42188ccd628",
"favicon.png": "dca91c54388f52eded692718d5a98b8b", "favicon.png": "dca91c54388f52eded692718d5a98b8b",
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1", "assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
@ -32,9 +32,9 @@ const RESOURCES = {
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "174c02fc4609e8fc4389f5d21f16a296", "assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "174c02fc4609e8fc4389f5d21f16a296",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed", "icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35", "icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"main.dart.js": "82d7e86713b1926dbaeab50acc790835", "main.dart.js": "6d7015b94cf66c9fd426081b7bfb5b97",
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40", "manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"/": "6678b7e5f2e2345446d76f99aea6141a" "/": "4da4247bb7f072054c574b10e7370438"
}; };
// The application shell files that are downloaded before a service worker can // The application shell files that are downloaded before a service worker can

113703
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

116649
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

116677
public/main.next.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"app_name":"invoiceninja_flutter","version":"5.0.59","build_number":"59"} {"app_name":"invoiceninja_flutter","version":"5.0.60","build_number":"60"}

View File

@ -4329,6 +4329,8 @@ $LANG = array(
'eps' => 'EPS', 'eps' => 'EPS',
'you_need_to_accept_the_terms_before_proceeding' => 'You need to accept the terms before proceeding.', 'you_need_to_accept_the_terms_before_proceeding' => 'You need to accept the terms before proceeding.',
'direct_debit' => 'Direct Debit', 'direct_debit' => 'Direct Debit',
'clone_to_expense' => 'Clone to expense',
'checkout' => 'Checkout',
); );
return $LANG; return $LANG;

View File

@ -90,7 +90,7 @@
<div class="col-span-12 xl:col-span-4 bg-white flex flex-col items-center lg:h-screen"> <div class="col-span-12 xl:col-span-4 bg-white flex flex-col items-center lg:h-screen">
<div class="w-full p-10 md:p-24 xl:mt-32 md:max-w-3xl"> <div class="w-full p-10 md:p-24 xl:mt-32 md:max-w-3xl">
<div class="col-span-12 w-full xl:col-span-9"> <div class="col-span-12 w-full xl:col-span-9">
<h2 class="text-2xl font-bold tracking-wide">{{ $heading_text ?? ctrans('texts.login') }}</h2> <h2 class="text-2xl font-bold tracking-wide">{{ $heading_text ?? ctrans('texts.checkout') }}</h2>
@if (session()->has('message')) @if (session()->has('message'))
@component('portal.ninja2020.components.message') @component('portal.ninja2020.components.message')
{{ session('message') }} {{ session('message') }}

View File

@ -215,7 +215,7 @@ Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{compa
->middleware(['guest']) ->middleware(['guest'])
->name('payment_notification_webhook'); ->name('payment_notification_webhook');
Route::post('api/v1/postmark_webhook', 'PostMarkController@webhook'); Route::post('api/v1/postmark_webhook', 'PostMarkController@webhook')->middleware(['throttle:5000,1']);
Route::get('token_hash_router', 'OneTimeTokenController@router'); Route::get('token_hash_router', 'OneTimeTokenController@router');
Route::get('webcron', 'WebCronController@index'); Route::get('webcron', 'WebCronController@index');
Route::post('api/v1/get_migration_account', 'HostedMigrationController@getAccount')->middleware('guest'); Route::post('api/v1/get_migration_account', 'HostedMigrationController@getAccount')->middleware('guest');

View File

@ -698,7 +698,7 @@ class PaymentTest extends TestCase
$payment->amount = 10; $payment->amount = 10;
$payment->client_id = $client->id; $payment->client_id = $client->id;
$payment->date = now(); $payment->date = now();
$payment->number = $client->getNextPaymentNumber($client); $payment->number = $client->getNextPaymentNumber($client, $payment);
$payment->save(); $payment->save();
$data = [ $data = [

View File

@ -11,6 +11,7 @@
namespace Tests; namespace Tests;
use App\DataMapper\ClientRegistrationFields;
use App\DataMapper\ClientSettings; use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings; use App\DataMapper\CompanySettings;
use App\Factory\CompanyUserFactory; use App\Factory\CompanyUserFactory;
@ -173,6 +174,8 @@ trait MockAccountData
'account_id' => $this->account->id, 'account_id' => $this->account->id,
]); ]);
$this->company->client_registration_fields = ClientRegistrationFields::generate();
Storage::makeDirectory($this->company->company_key.'/documents', 0755, true); Storage::makeDirectory($this->company->company_key.'/documents', 0755, true);
Storage::makeDirectory($this->company->company_key.'/images', 0755, true); Storage::makeDirectory($this->company->company_key.'/images', 0755, true);
@ -397,7 +400,7 @@ trait MockAccountData
$this->quote = $this->quote_calc->getQuote(); $this->quote = $this->quote_calc->getQuote();
$this->quote->status_id = Quote::STATUS_SENT; $this->quote->status_id = Quote::STATUS_SENT;
$this->quote->number = $this->getNextQuoteNumber($this->client); $this->quote->number = $this->getNextQuoteNumber($this->client, $this->quote);
//$this->quote->service()->createInvitations()->markSent(); //$this->quote->service()->createInvitations()->markSent();
@ -448,7 +451,7 @@ trait MockAccountData
$this->client->service()->adjustCreditBalance($this->credit->balance)->save(); $this->client->service()->adjustCreditBalance($this->credit->balance)->save();
$this->credit->ledger()->updateCreditBalance($this->credit->balance)->save(); $this->credit->ledger()->updateCreditBalance($this->credit->balance)->save();
$this->credit->number = $this->getNextCreditNumber($this->client); $this->credit->number = $this->getNextCreditNumber($this->client, $this->credit);
CreditInvitation::factory()->create([ CreditInvitation::factory()->create([

Some files were not shown because too many files have changed in this diff Show More