From fb17dd7e0b5c05c8847e892c4b7d6d6c397ff919 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 26 May 2021 16:04:38 +1000 Subject: [PATCH 1/2] Force stripe amount to int --- app/Console/Commands/CreateSingleAccount.php | 24 +++++ app/Jobs/Cron/AutoBillCron.php | 108 +++++++++++++++++++ app/PaymentDrivers/Stripe/Utilities.php | 2 +- app/Services/Invoice/AutoBillInvoice.php | 9 +- database/factories/TaxRateFactory.php | 38 +++++++ 5 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 app/Jobs/Cron/AutoBillCron.php create mode 100644 database/factories/TaxRateFactory.php diff --git a/app/Console/Commands/CreateSingleAccount.php b/app/Console/Commands/CreateSingleAccount.php index b8d425ce8413..5e7a40ee3d6f 100644 --- a/app/Console/Commands/CreateSingleAccount.php +++ b/app/Console/Commands/CreateSingleAccount.php @@ -34,6 +34,7 @@ use App\Models\Project; use App\Models\Quote; use App\Models\RecurringInvoice; use App\Models\Task; +use App\Models\TaxRate; use App\Models\User; use App\Models\Vendor; use App\Models\VendorContact; @@ -154,6 +155,29 @@ class CreateSingleAccount extends Command 'company_id' => $company->id, ]); + + TaxRate::factory()->create([ + 'user_id' => $user->id, + 'company_id' => $company->id, + 'name' => 'GST', + 'rate' => 10 + ]); + + TaxRate::factory()->create([ + 'user_id' => $user->id, + 'company_id' => $company->id, + 'name' => 'VAT', + 'rate' => 17.5 + ]); + + TaxRate::factory()->create([ + 'user_id' => $user->id, + 'company_id' => $company->id, + 'name' => 'CA Sales Tax', + 'rate' => 5 + ]); + + $this->info('Creating '.$this->count.' clients'); for ($x = 0; $x < $this->count; $x++) { diff --git a/app/Jobs/Cron/AutoBillCron.php b/app/Jobs/Cron/AutoBillCron.php new file mode 100644 index 000000000000..6f9bf09c303e --- /dev/null +++ b/app/Jobs/Cron/AutoBillCron.php @@ -0,0 +1,108 @@ +format('Y-m-d h:i:s')); + + if (! config('ninja.db.multi_db_enabled')) { + + $auto_bill_partial_invoices = Invoice::whereDate('partial_due_date', '<=', now()) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('auto_bill_enabled', true) + ->where('balance', '>', 0) + ->with('company') + ->cursor(); + + $auto_bill_partial_invoices->each(function ($invoice){ + $this->runAutoBiller($invoice); + }); + + $auto_bill_invoices = Invoice::whereDate('due_date', '<=', now()) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('auto_bill_enabled', true) + ->where('balance', '>', 0) + ->with('company') + ->cursor(); + + $auto_bill_invoices->each(function ($invoice){ + $this->runAutoBiller($invoice); + }); + + + } else { + //multiDB environment, need to + foreach (MultiDB::$dbs as $db) { + MultiDB::setDB($db); + + $auto_bill_partial_invoices = Invoice::whereDate('partial_due_date', '<=', now()) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('auto_bill_enabled', true) + ->where('balance', '>', 0) + ->with('company') + ->cursor(); + + $auto_bill_partial_invoices->each(function ($invoice){ + $this->runAutoBiller($invoice); + }); + + $auto_bill_invoices = Invoice::whereDate('due_date', '<=', now()) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('auto_bill_enabled', true) + ->where('balance', '>', 0) + ->with('company') + ->cursor(); + + $auto_bill_invoices->each(function ($invoice){ + $this->runAutoBiller($invoice); + }); + + } + } + } + + private function runAutoBiller(Invoice $invoice) + { + $invoice->service()->autoBill()->save(); + } +} diff --git a/app/PaymentDrivers/Stripe/Utilities.php b/app/PaymentDrivers/Stripe/Utilities.php index a61ca2505909..9f9e34746d73 100644 --- a/app/PaymentDrivers/Stripe/Utilities.php +++ b/app/PaymentDrivers/Stripe/Utilities.php @@ -21,6 +21,6 @@ trait Utilities public function convertToStripeAmount($amount, $precision) { - return $amount * pow(10, $precision); + return (int)($amount * pow(10, $precision)); } } diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index 3be132848d3b..4b9ff0a41a02 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -40,6 +40,8 @@ class AutoBillInvoice extends AbstractService public function run() { + $is_partial = false; + /* Is the invoice payable? */ if (! $this->invoice->isPayable()) return $this->invoice; @@ -57,6 +59,8 @@ class AutoBillInvoice extends AbstractService /* Determine $amount */ if ($this->invoice->partial > 0) { + $is_partial = true; + $invoice_total = $this->invoice->amount; $amount = $this->invoice->partial; } elseif ($this->invoice->balance > 0) { $amount = $this->invoice->balance; @@ -77,7 +81,10 @@ class AutoBillInvoice extends AbstractService //$fee = $gateway_token->gateway->calcGatewayFee($amount, $gateway_token->gateway_type_id, $this->invoice->uses_inclusive_taxes); $this->invoice = $this->invoice->service()->addGatewayFee($gateway_token->gateway, $gateway_token->gateway_type_id, $amount)->save(); - $fee = $this->invoice->amount - $amount; + if($is_partial) + $fee = $this->invoice->amount - $invoice_total; + else + $fee = $this->invoice->amount - $amount; /* Build payment hash */ $payment_hash = PaymentHash::create([ diff --git a/database/factories/TaxRateFactory.php b/database/factories/TaxRateFactory.php new file mode 100644 index 000000000000..a4230bce1246 --- /dev/null +++ b/database/factories/TaxRateFactory.php @@ -0,0 +1,38 @@ + $this->faker->word(3), + 'rate' => rand(1,20) + ]; + } +} From e76567f337ab821f891611e1b383f68ff0fb9bd2 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 26 May 2021 16:14:47 +1000 Subject: [PATCH 2/2] Fixes for creating an account using OAuth --- app/Console/Commands/CheckData.php | 2 +- app/Http/Controllers/Auth/LoginController.php | 2 +- app/Services/Invoice/AutoBillInvoice.php | 64 ------------------- 3 files changed, 2 insertions(+), 66 deletions(-) diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index 6a68546d6e18..b9b288616666 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -65,7 +65,7 @@ class CheckData extends Command /** * @var string */ - protected $signature = 'ninja:check-data {--database=} {--fix=}'; + protected $signature = 'ninja:check-data {--database=} {--fix=} {--client_id=}'; /** * @var string diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 6e6419becf98..274db4e67635 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -449,7 +449,7 @@ class LoginController extends BaseController MultiDB::setDefaultDatabase(); - $account = CreateAccount::dispatchNow($new_account); + $account = CreateAccount::dispatchNow($new_account, request()->getClientIp()); Auth::login($account->default_company->owner(), true); diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index 4b9ff0a41a02..54ac624ac833 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -347,68 +347,4 @@ class AutoBillInvoice extends AbstractService return $this; } - /** - * Removes any existing unpaid gateway fees - * due to previous payment failure. - * - * @return $this - */ - // private function purgeStaleGatewayFees() - // { - // $starting_amount = $this->invoice->amount; - - // $line_items = $this->invoice->line_items; - - // $new_items = []; - - // foreach($line_items as $item) - // { - - // if($item->type_id != 3) - // $new_items[] = $item; - - // } - - // $this->invoice->line_items = $new_items; - // $this->invoice->save(); - - // $this->invoice = $this->invoice->calc()->getInvoice(); - - // if($starting_amount != $this->invoice->amount && $this->invoice->status_id != Invoice::STATUS_DRAFT){ - // $this->invoice->client->service()->updateBalance($this->invoice->amount - $starting_amount)->save(); - // $this->invoice->ledger()->updateInvoiceBalance($this->invoice->amount - $starting_amount, 'Invoice balance updated after stale gateway fee removed')->save(); - // } - - // return $this; - // } - - // /** - // * Checks whether a given gateway token is able - // * to process the payment after passing through the - // * fees and limits check. - // * - // * @param CompanyGateway $cg The CompanyGateway instance - // * @param float $amount The amount to be paid - // * @return bool - // */ - // public function validGatewayLimits($cg, $amount) : bool - // { - // if (isset($cg->fees_and_limits)) { - // $fees_and_limits = $cg->fees_and_limits->{'1'}; - // } else { - // return true; - // } - - // if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $amount < $fees_and_limits->min_limit) { - // info("amount {$amount} less than ".$fees_and_limits->min_limit); - // $passes = false; - // } elseif ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $amount > $fees_and_limits->max_limit) { - // info("amount {$amount} greater than ".$fees_and_limits->max_limit); - // $passes = false; - // } else { - // $passes = true; - // } - - // return $passes; - // } }