From 79e0fa56e2ae22121828abd2522f56bde709d28d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 26 Aug 2020 10:47:50 +1000 Subject: [PATCH] Convert currency string to float --- .../ClientPortal/InvoiceController.php | 3 +- .../ClientPortal/PaymentController.php | 79 +++++++++++-------- app/Utils/Number.php | 30 ++++++- .../authorize/credit_card_payment.blade.php | 34 ++++++-- .../ninja2020/invoices/payment.blade.php | 15 ++-- tests/Unit/NumberTest.php | 28 +++++++ 6 files changed, 136 insertions(+), 53 deletions(-) diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index 4269038b39..91b5f37848 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -96,7 +96,8 @@ class InvoiceController extends Controller } $invoices->map(function ($invoice) { - $invoice->balance = Number::formatMoney($invoice->balance, $invoice->client); + $invoice->balance = Number::formatValue($invoice->balance, $invoice->client->currency()); + $invoice->partial = Number::formatValue($invoice->partial, $invoice->client->currency()); return $invoice; }); diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 482700f1bd..f76ec3ae1d 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -18,12 +18,14 @@ use App\Jobs\Invoice\InjectSignature; use App\Models\CompanyGateway; use App\Models\Invoice; use App\Models\Payment; +use App\Models\PaymentHash; use App\Utils\Number; use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesHash; use Cache; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Str; use Yajra\DataTables\Facades\DataTables; /** @@ -77,24 +79,12 @@ class PaymentController extends Controller // This is tagged with a type_id of 3 which is for a pending gateway fee. //REFACTOR - In order to preserve state we should save the array of invoices and amounts and store it in db/cache and use a HASH // to rehydrate these values in the payment response. - // [ - // 'invoices' => - // [ - // 'invoice_id' => 'xx', - // 'amount' => 'yy', - // ] - // ] - - //old - // $invoices = Invoice::whereIn('id', $this->transformKeys(request()->invoices)) - // ->where('company_id', auth('contact')->user()->company->id) - // ->get(); +// dd(request()->all()); + $gateway = CompanyGateway::find(request()->input('company_gateway_id')); /*find invoices*/ - $invoices = Invoice::whereIn('id', $this->transformKeys(array_column(request()->invoices, 'invoice_id')))->get(); - - //old - // $amount = $invoices->sum('balance'); + $payable_invoices = request()->payable_invoices; + $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payable_invoices, 'invoice_id')))->get(); /*filter only payable invoices*/ $invoices = $invoices->filter(function ($invoice) { @@ -109,24 +99,37 @@ class PaymentController extends Controller ->with(['warning' => 'No payable invoices selected.']); } - /*iterate through invoices and add gateway fees*/ - foreach(request()->invoices as $payable_invoice) + /*iterate through invoices and add gateway fees and other payment metadata*/ + + foreach($payable_invoices as $key => $payable_invoice) { + $payable_invoice[$key]['amount'] = Number::parseFloat($payable_invoice[$key]['amount']); + $invoice = $invoices->first(function ($inv) use($payable_invoice) { - return $payable_invoice['invoice_id'] == $inv->hashed_id; + return $payable_invoice[$key]['invoice_id'] == $inv->hashed_id; }); if($invoice) - $invoice->service()->addGatewayFee($payable_invoice['amount'])->save(); - } + $invoice->service()->addGatewayFee($gateway, $payable_invoice[$key]['amount'])->save(); - /*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()); - - return $invoice; - }); + /*Update the payable amount to include the fee*/ + $gateway_fee = $gateway->calcGatewayFee($payable_invoice[$key]['amount']); + + $payable_invoice[$key]['amount_with_fee'] += $gateway_fee; + $payable_invoice[$key]['fee'] = $gateway_fee; + $payable_invoice[$key]['due_date'] = $this->formatDate($invoice->due_date, $invoice->client->date_format()); + $payable_invoice[$key]['invoice_number'] = $invoice->number; + + if(isset($invoice->po_number)) + $additional_info = $invoice->po_number; + elseif(isset($invoice->public_notes)) + $additional_info = $invoice->public_notes; + else + $additional_info = $invoice->date; + + $payable_invoice[$key]['additional_info'] = $additional_info; + + } if ((bool) request()->signature) { $invoices->each(function ($invoice) { @@ -135,19 +138,25 @@ class PaymentController extends Controller } $payment_methods = auth()->user()->client->getPaymentMethods($amount); - $gateway = CompanyGateway::find(request()->input('company_gateway_id')); $payment_method_id = request()->input('payment_method_id'); - // Place to calculate gateway fee. + $payment_hash = new PaymentHash; + $payment_hash->hash = Str::random(128); + $payment_hash->data = $payable_invoices; + $payment_hash->save(); + + $totals = [ + 'invoice_totals' => array_sum(array_column($payable_invoices,'amount')), + 'fee_totals' => array_sum(array_column($payable_invoices, 'fee')), + 'amount_with_fee' => array_sum(array_column($payable_invoices, 'amount_with_fee')), + ]; $data = [ - 'invoices' => $invoices, - 'amount' => $amount, - 'fee' => $gateway->calcGatewayFee($amount), - 'amount_with_fee' => $amount + $gateway->calcGatewayFee($amount), + 'payment_hash' => $payment_hash->hash, + 'total' => $totals, + 'invoices' => $payable_invoices, 'token' => auth()->user()->client->gateway_token($gateway->id, $payment_method_id), 'payment_method_id' => $payment_method_id, - 'hashed_ids' => request()->invoices, ]; return $gateway diff --git a/app/Utils/Number.php b/app/Utils/Number.php index 008a067ebb..858af3f8ed 100644 --- a/app/Utils/Number.php +++ b/app/Utils/Number.php @@ -33,12 +33,12 @@ class Number /** * Formats a given value based on the clients currency * - * @param float $value The number to be formatted + * @param float $value The number to be formatted * @param object $currency The client currency object * - * @return float The formatted value + * @return string The formatted value */ - public static function formatValue($value, $currency) : float + public static function formatValue($value, $currency) :string { $value = floatval($value); @@ -49,6 +49,30 @@ class Number return number_format($value, $precision, $decimal, $thousand); } + /** + * Formats a given value based on the clients currency + * BACK to a float + * + * @param string $value The formatted number to be converted back to float + * @param object $currency The client currency object + * + * @return float The formatted value + */ + public static function parseFloat($value) + { + // convert "," to "." + $s = str_replace(',', '.', $value); + + // remove everything except numbers and dot "." + $s = preg_replace("/[^0-9\.]/", "", $s); + + // remove all seperators from first part and keep the end + $s = str_replace('.', '',substr($s, 0, -3)) . substr($s, -3); + + // return float + return (float) $s; + } + /** * Formats a given value based on the clients currency AND country * diff --git a/resources/views/portal/ninja2020/gateways/authorize/credit_card_payment.blade.php b/resources/views/portal/ninja2020/gateways/authorize/credit_card_payment.blade.php index 7f7c5ec2e5..b25731d22b 100644 --- a/resources/views/portal/ninja2020/gateways/authorize/credit_card_payment.blade.php +++ b/resources/views/portal/ninja2020/gateways/authorize/credit_card_payment.blade.php @@ -13,9 +13,7 @@ @section('body')
@csrf - @foreach($invoices as $invoice) - - @endforeach + @@ -23,7 +21,7 @@ - +
@@ -39,11 +37,23 @@ @if($tokens->count() == 0)
+
+ {{ ctrans('texts.totals') }} +
+
+ {{ App\Utils\Number::formatMoney($total['invoice_totals'], $client) }} +
+
+ {{ ctrans('texts.gateway_fees') }} +
+
+ {{ App\Utils\Number::formatMoney($total['fee_totals'], $client) }} +
{{ ctrans('texts.amount') }}
- {{ App\Utils\Number::formatMoney($amount_with_fee, $client) }} + {{ App\Utils\Number::formatMoney($total['amount_with_fee'], $client) }}
@@ -67,11 +77,23 @@
+
+ {{ ctrans('texts.totals') }} +
+
+ {{ App\Utils\Number::formatMoney($total['invoice_totals'], $client) }} +
+
+ {{ ctrans('texts.gateway_fees') }} +
+
+ {{ App\Utils\Number::formatMoney($total['fee_totals'], $client) }} +
{{ ctrans('texts.amount') }}
- {{ App\Utils\Number::formatMoney($amount_with_fee, $client) }} + {{ App\Utils\Number::formatMoney($total['amount_with_fee'], $client) }}
@foreach($tokens as $token) diff --git a/resources/views/portal/ninja2020/invoices/payment.blade.php b/resources/views/portal/ninja2020/invoices/payment.blade.php index 7bfa33a112..0a1838e033 100644 --- a/resources/views/portal/ninja2020/invoices/payment.blade.php +++ b/resources/views/portal/ninja2020/invoices/payment.blade.php @@ -10,13 +10,10 @@ @section('body')
@csrf - @foreach($invoices as $invoice) - - @endforeach -
+
@@ -63,7 +60,8 @@
- @foreach($invoices as $invoice) + @foreach($invoices as $key => $invoice) +

@@ -104,7 +102,7 @@ @elseif($invoice->public_notes) {{ $invoice->public_notes }} @else - {{ $invoice->invoice_date}} + {{ $invoice->date}} @endif

@@ -113,7 +111,8 @@ {{ ctrans('texts.amount') }}
- {{ App\Utils\Number::formatMoney($invoice->amount, $invoice->client) }} + +
@@ -123,7 +122,7 @@
- + @include('portal.ninja2020.invoices.includes.terms') @include('portal.ninja2020.invoices.includes.signature') @endsection diff --git a/tests/Unit/NumberTest.php b/tests/Unit/NumberTest.php index f46c2e7d2b..c2c67fd78b 100644 --- a/tests/Unit/NumberTest.php +++ b/tests/Unit/NumberTest.php @@ -2,6 +2,7 @@ namespace Tests\Unit; +use App\Models\Currency; use App\Utils\Number; use Tests\TestCase; @@ -31,4 +32,31 @@ class NumberTest extends TestCase $this->assertEquals(2.15, $rounded); } + + public function testParsingFloats() + { + + Currency::all()->each(function ($currency){ + + $amount = 123456789.12; + + $formatted_amount = Number::formatValue($amount, $currency); + + info($formatted_amount); + + $float_amount = Number::parseFloat($formatted_amount); + + info($float_amount); + info($currency->id); + info($currency->code); + + if($currency->precision == 0){ + $this->assertEquals(123456789, $float_amount); + } + else + $this->assertEquals($amount, $float_amount); + + }); + + } }