diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 1b1f4ac70f39..482700f1bdcd 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -117,10 +117,10 @@ class PaymentController extends Controller }); if($invoice) - $invoice->service()->addGatewayFee($payable_invoice['amount']); + $invoice->service()->addGatewayFee($payable_invoice['amount'])->save(); } - /*Format invoices*/ + /*Format invoices we need to use fresh() here to bring in the gateway fees*/ $invoices->fresh()->map(function ($invoice) { $invoice->balance = Number::formatMoney($invoice->balance, $invoice->client); $invoice->due_date = $this->formatDate($invoice->due_date, $invoice->client->date_format()); diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index e5b0cfc10be4..586187ad8df6 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -211,6 +211,20 @@ class CompanyGateway extends BaseModel return $this->getConfigField('publishableKey'); } + public function getFeesAndLimits() + { + if (is_null($this->fees_and_limits)) + return false; + + $fees_and_limits = new \stdClass; + + foreach($this->fees_and_limits as $key => $value) { + $fees_and_limits = $this->fees_and_limits->{$key}; + } + + return $fees_and_limits; + } + /** * Returns the formatted fee amount for the gateway * @@ -238,15 +252,11 @@ class CompanyGateway extends BaseModel public function calcGatewayFee($amount) { - if (is_null($this->fees_and_limits)) { + + $fees_and_limits = $this->getFeesAndLimits(); + + if(!$fees_and_limits) return 0; - } - - $fees_and_limits = new \stdClass; - - foreach($this->fees_and_limits as $key => $value) { - $fees_and_limits = $this->fees_and_limits->{$key}; - } $fee = 0; diff --git a/app/Services/Invoice/AddGatewayFee.php b/app/Services/Invoice/AddGatewayFee.php index f6e8891d9b38..8a231513ce66 100644 --- a/app/Services/Invoice/AddGatewayFee.php +++ b/app/Services/Invoice/AddGatewayFee.php @@ -45,6 +45,8 @@ class AddGatewayFee extends AbstractService { $gateway_fee = $this->company_gateway->calcGatewayFee($this->amount); + $this->cleanPendingGatewayFees(); + if($gateway_fee > 0) return $this->processGatewayFee($gateway_fee); @@ -53,15 +55,69 @@ class AddGatewayFee extends AbstractService } + private function cleanPendingGatewayFees() + { + $invoice_items = $this->invoice->line_items; + + $invoice_items = collect($invoice_items)->filter(function ($item){ + return $item->type_id != 3; + }); + + $this->invoice->line_items = $invoice_items; + + return $this; + } + private function processGatewayFee($gateway_fee) { $invoice_item = new InvoiceItem; $invoice_item->type_id = 3; - $invoice_item->notes = ctrans('texts.Gateway Fee Surcharge'); + $invoice_item->product_key = ctrans('texts.surcharge'); + $invoice_item->notes = ctrans('texts.online_payment_surcharge'); + $invoice_item->quantity = 1; + $invoice_item->cost = $gateway_fee; + + if($fees_and_limits = $this->company_gateway->getFeesAndLimits()) + { + $invoice_item->tax_rate1 = $fees_and_limits->fee_tax_rate1; + $invoice_item->tax_rate2 = $fees_and_limits->fee_tax_rate2; + $invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3; + } + + $invoice_items = $this->invoice->line_items; + $invoice_items[] = $invoice_item; + + $this->invoice->line_items = $invoice_items; + + $this->invoice = $this->invoice->calc()->getInvoice(); + + return $this->invoice; + } private function processGatewayDiscount($gateway_fee) { - + $invoice_item = new InvoiceItem; + $invoice_item->type_id = 3; + $invoice_item->product_key = ctrans('texts.discount'); + $invoice_item->notes = ctrans('texts.online_payment_discount'); + $invoice_item->quantity = 1; + $invoice_item->cost = $gateway_fee; + + if($fees_and_limits = $this->company_gateway->getFeesAndLimits()) + { + $invoice_item->tax_rate1 = $fees_and_limits->fee_tax_rate1; + $invoice_item->tax_rate2 = $fees_and_limits->fee_tax_rate2; + $invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3; + } + + $invoice_items = $this->invoice->line_items; + $invoice_items[] = $invoice_item; + + $this->invoice->line_items = $invoice_items; + + $this->invoice = $this->invoice->calc()->getInvoice(); + + return $this->invoice; } } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index ef36b58cb37c..f86c2736d64a 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -79,7 +79,7 @@ class InvoiceService public function addGatewayFee(CompanyGateway $company_gateway, float $amount) { - $this->invoice = (new AddGatewayFee($company_gateway, $this->invoice, $amoun))->run(); + $this->invoice = (new AddGatewayFee($company_gateway, $this->invoice, $amount))->run(); return $this; } diff --git a/tests/Feature/CompanyGatewayTest.php b/tests/Feature/CompanyGatewayTest.php index ebb994a88349..f874653153af 100644 --- a/tests/Feature/CompanyGatewayTest.php +++ b/tests/Feature/CompanyGatewayTest.php @@ -49,6 +49,7 @@ class CompanyGatewayTest extends TestCase $data[1]['fee_tax_rate2'] = ''; $data[1]['fee_tax_name3'] = ''; $data[1]['fee_tax_rate3'] = 0; + $data[1]['fee_cap'] = 0; $cg = new CompanyGateway; $cg->company_id = $this->company->id; @@ -107,4 +108,42 @@ class CompanyGatewayTest extends TestCase return $passes; } + + public function testFeesAreAppendedToInvoice() + { + + $data = []; + $data[1]['min_limit'] = -1; + $data[1]['max_limit'] = -1; + $data[1]['fee_amount'] = 1.00; + $data[1]['fee_percent'] = 0.000; + $data[1]['fee_tax_name1'] = ''; + $data[1]['fee_tax_rate1'] = 0; + $data[1]['fee_tax_name2'] = ''; + $data[1]['fee_tax_rate2'] = 0; + $data[1]['fee_tax_name3'] = ''; + $data[1]['fee_tax_rate3'] = 0; + $data[1]['fee_cap'] = 0; + + $cg = new CompanyGateway; + $cg->company_id = $this->company->id; + $cg->user_id = $this->user->id; + $cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23'; + $cg->require_cvv = true; + $cg->show_billing_address = true; + $cg->show_shipping_address = true; + $cg->update_details = true; + $cg->config = encrypt(config('ninja.testvars.stripe')); + $cg->fees_and_limits = $data; + $cg->save(); + + $balance = $this->invoice->balance; + + $this->invoice = $this->invoice->service()->addGatewayFee($cg, $this->invoice->balance)->save(); + $this->invoice = $this->invoice->calc()->getInvoice(); + + $items = $this->invoice->line_items; + + $this->assertEquals(($balance+1), $this->invoice->balance); + } } \ No newline at end of file