Refactor counter/patterns to allow User variables

This commit is contained in:
David Bomba 2021-10-17 13:49:32 +11:00
parent 94785fae50
commit ba2f78dad0
17 changed files with 110 additions and 358 deletions

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,9 +70,14 @@ 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

@ -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

@ -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

@ -126,7 +126,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 +152,6 @@ 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]);
} }
public function failed($exception = null) public function failed($exception = null)

View File

@ -214,7 +214,7 @@ class AuthorizeCreditCard
PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransId(), $this->authorize->client->company, $amount); PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransId(), $this->authorize->client->company, $amount);
$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

@ -373,11 +373,14 @@ class BaseDriver extends AbstractPaymentDriver
} else } else
$error = $e->getMessage(); $error = $e->getMessage();
$amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
PaymentFailureMailer::dispatch( PaymentFailureMailer::dispatch(
$gateway->client, $gateway->client,
$error, $error,
$gateway->client->company, $gateway->client->company,
$this->payment_hash $amount
); );
SystemLogger::dispatch( SystemLogger::dispatch(

View File

@ -81,13 +81,8 @@ 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,
@ -183,303 +177,4 @@ class Charge
break; break;
} }
} }
} }
// 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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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, ?RecurringQuote $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,19 +748,31 @@ trait GeneratesCounter
$replace[] = $client->id_number; $replace[] = $client->id_number;
} }
$search[] = '{$user_custom1}';
$replace[] = $entity->user->custom_value1;
$search[] = '{$user_custom2}';
$replace[] = $entity->user->custom_value2;
$search[] = '{$user_custom3}';
$replace[] = $entity->user->custom_value3;
$search[] = '{$client_custom4}';
$replace[] = $entity->user->custom_value4;
return str_replace($search, $replace, $pattern); return str_replace($search, $replace, $pattern);
} }
private function replaceUserVars($entity, $pattern)
{
if(!$entity)
return $pattern;
$search = [];
$replace = [];
$search[] = '{$user_custom1}';
$replace[] = $entity->user->custom_value1;
$search[] = '{$user_custom2}';
$replace[] = $entity->user->custom_value2;
$search[] = '{$user_custom3}';
$replace[] = $entity->user->custom_value3;
$search[] = '{$user_custom4}';
$replace[] = $entity->user->custom_value4;
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) {