diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index fe8d6adf2a1e..4269038b3909 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -113,6 +113,8 @@ class InvoiceController extends Controller 'total' => $total, ]; + //REFACTOR entry point for online payments starts here + return $this->render('invoices.payment', $data); } diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index d5cf93add9b0..ce8d9dcd211c 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -72,11 +72,29 @@ class PaymentController extends Controller */ public function process() { - $invoices = Invoice::whereIn('id', $this->transformKeys(request()->invoices)) - ->where('company_id', auth('contact')->user()->company->id) - ->get(); + //REFACTOR - Here the request will contain an array of invoices and the amount to be charged for the invoice + //REFACTOR - At this point, we will also need to modify the invoice to include a line item for a gateway fee if applicable + // 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(); - $amount = $invoices->sum('balance'); + + $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($request()->invoices, 'invoice_id')))->get(); + + //old + // $amount = $invoices->sum('balance'); $invoices = $invoices->filter(function ($invoice) { return $invoice->isPayable(); @@ -88,6 +106,14 @@ class PaymentController extends Controller ->with(['warning' => 'No payable invoices selected.']); } + foreach(request()->invoices as $payable_invoice) + { + $invoice = Invoice::find($this->decodePrimaryKey($payable_invoice['invoice_id'])); + + $invoice->service()->addGatewayFee($payable_invoice['amount']); + } + + $invoices->map(function ($invoice) { $invoice->balance = Number::formatMoney($invoice->balance, $invoice->client); $invoice->due_date = $this->formatDate($invoice->due_date, $invoice->client->date_format()); @@ -127,6 +153,21 @@ class PaymentController extends Controller { $gateway = CompanyGateway::find($request->input('company_gateway_id')); + //REFACTOR - Entry point for the gateway response - we don't need to do anything at this point. + // + // - Inside each gateway driver, we should use have a generic code path (in BaseDriver.php)for successful/failed payment + // + // Success workflow + // + // - Rehydrate the hash and iterate through the invoices and update the balances + // - Update the type_id of the gateway fee to type_id 4 + // - Link invoices to payment + // + // Failure workflow + // + // - Rehydrate hash, iterate through invoices and remove type_id 3's + // - Recalcuate invoice totals + return $gateway ->driver(auth()->user()->client) ->setPaymentMethod($request->input('payment_method_id')) diff --git a/app/Models/PaymentHash.php b/app/Models/PaymentHash.php new file mode 100644 index 000000000000..d9c2c2541052 --- /dev/null +++ b/app/Models/PaymentHash.php @@ -0,0 +1,28 @@ + 'object' + ]; + + + public function invoices() + { + return $this->data->invoices; + } +} diff --git a/app/Services/Invoice/AddGatewayFee.php b/app/Services/Invoice/AddGatewayFee.php new file mode 100644 index 000000000000..f6e8891d9b38 --- /dev/null +++ b/app/Services/Invoice/AddGatewayFee.php @@ -0,0 +1,67 @@ +company_gateway = $company_gateway; + + $this->invoice = $invoice; + + $this->amount = $amount; + } + + public function run() + { + $gateway_fee = $this->company_gateway->calcGatewayFee($this->amount); + + if($gateway_fee > 0) + return $this->processGatewayFee($gateway_fee); + + return $this->processGatewayDiscount($gateway_fee); + + + } + + private function processGatewayFee($gateway_fee) + { + $invoice_item = new InvoiceItem; + $invoice_item->type_id = 3; + $invoice_item->notes = ctrans('texts.Gateway Fee Surcharge'); + } + + private function processGatewayDiscount($gateway_fee) + { + + } +} diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 714b2727ea05..ef36b58cb37c 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -11,6 +11,7 @@ namespace App\Services\Invoice; +use App\Models\CompanyGateway; use App\Models\Invoice; use App\Models\Payment; use App\Services\Client\ClientService; @@ -76,6 +77,12 @@ class InvoiceService return $this; } + public function addGatewayFee(CompanyGateway $company_gateway, float $amount) + { + $this->invoice = (new AddGatewayFee($company_gateway, $this->invoice, $amoun))->run(); + + return $this; + } /** * Update an invoice balance * @param float $balance_adjustment The amount to adjust the invoice by diff --git a/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php b/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php index 784db3ae356f..92c6b9627c22 100644 --- a/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php +++ b/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php @@ -35,6 +35,12 @@ class AddIsPublicToDocumentsTable extends Migration $table->softDeletes('deleted_at', 6); }); + Schema::create('payment_hashes', function ($table) { + $table->increments('id'); + $table->string('hash', 255); + $table->mediumText('data'); + $table->timestamps(6); + }); }