From a33c781919684b964474574c62cb09cab9847bb7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 18 Jan 2021 08:31:49 +1100 Subject: [PATCH 1/3] Payment notifications for online payments to the client --- app/PaymentDrivers/BaseDriver.php | 3 +++ app/Services/Invoice/InvoiceService.php | 5 ----- app/Services/Invoice/MarkPaid.php | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index d99ca01a11c0..87c2f85aaa27 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -228,6 +228,9 @@ class BaseDriver extends AbstractPaymentDriver $payment->service()->updateInvoicePayment($this->payment_hash); + if ($this->client->getSetting('client_online_payment_notification')) + $payment->service()->sendEmail(); + event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars())); return $payment->service()->applyNumber()->save(); diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 603bb30dc269..7b9fc1a13b3c 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -375,11 +375,6 @@ class InvoiceService if (!isset($this->invoice->terms)) { $this->invoice->terms = $settings->invoice_terms; } - - if(!isset($this->invoice->public_notes)) { - $this->invoice->public_notes = $settings->public_notes; - } - return $this; } diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php index 67810c3d8800..2800e673660d 100644 --- a/app/Services/Invoice/MarkPaid.php +++ b/app/Services/Invoice/MarkPaid.php @@ -74,9 +74,8 @@ class MarkPaid extends AbstractService ->applyNumber() ->save(); - if ($this->invoice->client->getSetting('client_manual_payment_notification')) { - EmailPayment::dispatch($payment, $payment->company, $payment->client->primary_contact()->first()); - } + if ($this->invoice->client->getSetting('client_manual_payment_notification')) + $payment->service()->sendEmail(); /* Update Invoice balance */ event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars())); From 6f957159175f6ae15176ddf39fa33b8b30df9e9a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 18 Jan 2021 10:01:37 +1100 Subject: [PATCH 2/3] Update model exchange rate if client currency differs from company --- app/Repositories/BaseRepository.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index ad6d5df21a3f..6fce805e8390 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -202,6 +202,11 @@ class BaseRepository /* Model now persisted, now lets do some child tasks */ + /* If client currency differs from the company default currency, then insert the client exchange rate on the model.*/ + if($client->currency()->id != (int) $model->company->settings->currency_id) + $model->exchange_rate = $client->currency()->exchange_rate; + + /* Save any documents */ if (array_key_exists('documents', $data)) $this->saveDocuments($data['documents'], $model); From bd5defe45534d6ff11259fa0cda1a79796d44fae Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 18 Jan 2021 12:36:13 +1100 Subject: [PATCH 3/3] Refactor getPaymentMethods() --- app/Services/Client/PaymentMethod.php | 240 ++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 app/Services/Client/PaymentMethod.php diff --git a/app/Services/Client/PaymentMethod.php b/app/Services/Client/PaymentMethod.php new file mode 100644 index 000000000000..35fe8de2f735 --- /dev/null +++ b/app/Services/Client/PaymentMethod.php @@ -0,0 +1,240 @@ +client = $client; + $this->amount = $amount; + } + + public function run() :Credit + { + + $this->getGateways() + ->getMethods() + ->buildUrls(); + } + + public function getPaymentUrls() + { + return $this->payment_urls; + } + + public function getPaymentMethods() + { + return $this->payment_methods; + } + + private function getGateways() + { + + $company_gateways = $this->client->getSetting('company_gateway_ids'); + + //we need to check for "0" here as we disable a payment gateway for a client with the number "0" + if ($company_gateways || $company_gateways == '0') { + + $transformed_ids = $this->transformKeys(explode(',', $company_gateways)); + + $this->gateways = $this->client + ->company + ->company_gateways + ->whereIn('id', $transformed_ids) + ->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa') + ->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority + return array_search($model->id, $transformed_ids);// this closure sorts for us + }); + + } else { + + $this->gateways = $this->client + ->company + ->company_gateways + ->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa') + ->where('is_deleted', false); + + } + + + return $this; + } + + + private function getCustomGateways() + { + + $company_gateways = $this->client->getSetting('company_gateway_ids'); + + //we need to check for "0" here as we disable a payment gateway for a client with the number "0" + if ($company_gateways || $company_gateways == '0') { + + $transformed_ids = $this->transformKeys(explode(',', $company_gateways)); + + $this->gateways = $this->client + ->company + ->company_gateways + ->whereIn('id', $transformed_ids) + ->where('gateway_key', '=', '54faab2ab6e3223dbe848b1686490baa') + ->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority + return array_search($model->id, $transformed_ids);// this closure sorts for us + }); + + } else { + + $this->gateways = $this->client + ->company + ->company_gateways + ->where('gateway_key', '=', '54faab2ab6e3223dbe848b1686490baa') + ->where('is_deleted', false); + + } + + + return $this; + } + + private function getMethods() + { + // we should prefilter $gateway->driver($this)->gatewayTypes() + // and only include the enabled payment methods on the gateway + $this->$this->payment_methods = []; + + foreach ($this->gateways as $gateway) { + foreach ($gateway->driver($this)->gatewayTypes() as $type) { + if (isset($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, $type)) { + if ($this->validGatewayForAmount($gateway->fees_and_limits->{$type}, $amount)) { + $this->payment_methods[] = [$gateway->id => $type]; + } + } else { + $this->payment_methods[] = [$gateway->id => $type]; + } + } + } + + //transform from Array to Collection + $payment_methods_collections = collect($this->payment_methods); + + //** Plucks the remaining keys into its own collection + $this->payment_methods = $payment_methods_collections->intersectByKeys($payment_methods_collections->flatten(1)->unique()); + + /* Loop through custom gateways if any exist and append them to the methods collection*/ + $this->getCustomGateways(); + + //note we have to use GatewayType::CREDIT_CARD as alias for CUSTOM + foreach ($this->gateways as $gateway) { + foreach ($gateway->driver($this)->gatewayTypes() as $type) { + if (isset($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, $type)) { + if ($this->validGatewayForAmount($gateway->fees_and_limits->{GatewayType::CREDIT_CARD}, $amount)) { + $this->payment_methods->push([$gateway->id => $type]); + } + } else { + $this->payment_methods->push([$gateway->id => NULL]); + } + } + } + + } + + private function buildUrls() + { + + foreach ($payment_methods_intersect as $key => $child_array) { + foreach ($child_array as $gateway_id => $gateway_type_id) { + $gateway = CompanyGateway::find($gateway_id); + + $fee_label = $gateway->calcGatewayFeeLabel($amount, $this); + + if(!$gateway_type_id){ + + $this->payment_urls[] = [ + 'label' => $gateway->getConfigField('name') . $fee_label, + 'company_gateway_id' => $gateway_id, + 'gateway_type_id' => GatewayType::CREDIT_CARD, + ]; + } + else + { + $this->payment_urls[] = [ + 'label' => $gateway->getTypeAlias($gateway_type_id) . $fee_label, + 'company_gateway_id' => $gateway_id, + 'gateway_type_id' => $gateway_type_id, + ]; + } + } + } + + if (($this->client->getSetting('use_credits_payment') == 'option' || $this->client->getSetting('use_credits_payment') == 'always') && $this->client->service()->getCreditBalance() > 0) { + + // Show credits as only payment option if both statements are true. + if ( + $this->client->service()->getCreditBalance() > $amount + && $this->client->getSetting('use_credits_payment') == 'always') { + $payment_urls = []; + } + + $payment_urls[] = [ + 'label' => ctrans('texts.apply_credit'), + 'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT, + 'gateway_type_id' => GatewayType::CREDIT, + ]; + } + + return $this; + + } + + private function validGatewayForAmount($fees_and_limits_for_payment_type, $amount) :bool + { + if (isset($fees_and_limits_for_payment_type)) { + $fees_and_limits = $fees_and_limits_for_payment_type; + } else { + return true; + } + + if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $fees_and_limits->min_limit != -1 && $amount < $fees_and_limits->min_limit) { + return false; + } + + if ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $fees_and_limits->max_limit != -1 && $amount > $fees_and_limits->max_limit) { + return false; + } + + return true; + } +} + +