diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 1b8b5907d3c1..6516bd846298 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -430,7 +430,7 @@ class AccountController extends \BaseController { $account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null; $account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null; $account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null; - $account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null; + $account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; $account->invoice_terms = Input::get('invoice_terms'); $account->email_footer = Input::get('email_footer'); diff --git a/app/controllers/ClientController.php b/app/controllers/ClientController.php index 59b38e482c80..73243348f5cb 100755 --- a/app/controllers/ClientController.php +++ b/app/controllers/ClientController.php @@ -186,7 +186,7 @@ class ClientController extends \BaseController { $client->private_notes = trim(Input::get('private_notes')); $client->size_id = Input::get('size_id') ? Input::get('size_id') : null; $client->industry_id = Input::get('industry_id') ? Input::get('industry_id') : null; - $client->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null; + $client->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; $client->payment_terms = Input::get('payment_terms'); $client->website = trim(Input::get('website')); diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 0c178e1efdc8..4715c41de333 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -148,146 +148,6 @@ class InvoiceController extends \BaseController { return View::make('invoices.view', $data); } - private function createGateway($accountGateway) - { - $gateway = Omnipay::create($accountGateway->gateway->provider); - $config = json_decode($accountGateway->config); - - /* - $gateway->setSolutionType ("Sole"); - $gateway->setLandingPage("Billing"); - */ - - foreach ($config as $key => $val) - { - if (!$val) - { - continue; - } - - $function = "set" . ucfirst($key); - $gateway->$function($val); - } - - return $gateway; - } - - private function getPaymentDetails($invoice) - { - $data = array( - 'firstName' => '', - 'lastName' => '', - ); - - $card = new CreditCard($data); - - return [ - 'amount' => $invoice->amount, - 'card' => $card, - 'currency' => 'USD', - 'returnUrl' => URL::to('complete'), - 'cancelUrl' => URL::to('/'), - ]; - } - - public function show_payment($invitationKey) - { - $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail(); - $invoice = $invitation->invoice; - $accountGateway = $invoice->client->account->account_gateways[0]; - $gateway = InvoiceController::createGateway($accountGateway); - - try - { - $details = InvoiceController::getPaymentDetails($invoice); - $response = $gateway->purchase($details)->send(); - $ref = $response->getTransactionReference(); - - if (!$ref) - { - return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $response->getMessage()); - } - - $payment = Payment::createNew(); - $payment->invitation_id = $invitation->id; - $payment->account_gateway_id = $accountGateway->id; - $payment->invoice_id = $invoice->id; - $payment->amount = $invoice->amount; - $payment->client_id = $invoice->client_id; - $payment->contact_id = $invitation->contact_id; - $payment->transaction_reference = $ref; - $payment->payment_date = date_create(); - $payment->save(); - - if ($response->isSuccessful()) - { - - } - else if ($response->isRedirect()) - { - $response->redirect(); - } - else - { - return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
'); - } - } - catch (\Exception $e) - { - return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $e); - } - } - - public function do_payment() - { - $payerId = Request::query('PayerID'); - $token = Request::query('token'); - - $payment = Payment::with('invitation', 'invoice.invoice_items')->where('transaction_reference','=',$token)->firstOrFail(); - $invoice = Invoice::with('client.account.account_gateways.gateway')->where('id', '=', $payment->invoice_id)->firstOrFail(); - $accountGateway = $invoice->client->account->account_gateways[0]; - $gateway = InvoiceController::createGateway($accountGateway); - - try - { - $details = InvoiceController::getPaymentDetails($payment->invoice); - $response = $gateway->completePurchase($details)->send(); - $ref = $response->getTransactionReference(); - - if ($response->isSuccessful()) - { - $payment->payer_id = $payerId; - $payment->transaction_reference = $ref; - $payment->save(); - - if ($payment->amount >= $invoice->amount) - { - $invoice->invoice_status_id = INVOICE_STATUS_PAID; - } - else - { - $invoice->invoice_status_id = INVOICE_STATUS_PARTIAL; - } - - $invoice->save(); - - Event::fire('invoice.paid', $payment); - - Session::flash('message', 'Successfully applied payment'); - return Redirect::to('view/' . $payment->invitation->invitation_key); - } - else - { - return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $response->getMessage()); - } - } - catch (\Exception $e) - { - return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $e); - } - } - - public function edit($publicId) { $invoice = Invoice::scope($publicId)->with('account.country', 'client.contacts', 'client.country', 'invoice_items')->firstOrFail(); diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index a5ec29bc4544..3fcfdeba633a 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -95,6 +95,228 @@ class PaymentController extends \BaseController return View::make('payments.edit', $data); } + private function createGateway($accountGateway) + { + $gateway = Omnipay::create($accountGateway->gateway->provider); + $config = json_decode($accountGateway->config); + + /* + $gateway->setSolutionType ("Sole"); + $gateway->setLandingPage("Billing"); + */ + + foreach ($config as $key => $val) + { + if (!$val) + { + continue; + } + + $function = "set" . ucfirst($key); + $gateway->$function($val); + } + + return $gateway; + } + + private function getPaymentDetails($invoice, $input = null) + { + if ($input) + { + $data = [ + 'firstName' => $input['first_name'], + 'lastName' => $input['last_name'], + 'number' => $input['card_number'], + 'expiryMonth' => $input['expiration_month'], + 'expiryYear' => $input['expiration_year'], + 'cvv' => $input['cvv'], + 'billingAddress1' => $input['address1'], + 'billingAddress2' => $input['address2'], + 'billingCity' => $input['city'], + 'billingState' => $input['state'], + 'billingPostcode' => $input['postal_code'], + 'shippingAddress1' => $input['address1'], + 'shippingAddress2' => $input['address2'], + 'shippingCity' => $input['city'], + 'shippingState' => $input['state'], + 'shippingPostcode' => $input['postal_code'], + ]; + + Session::put($invoice->invoice_number . '_details', $data); + } + else + { + $data = Session::get($invoice->invoice_number . '_details'); + } + + $card = new CreditCard($data); + + return [ + 'amount' => $invoice->amount, + 'card' => $card, + 'currency' => $invoice->client->currency->code, + 'returnUrl' => URL::to('complete'), + 'cancelUrl' => URL::to('/'), + ]; + } + + public function show_payment($invitationKey) + { + $invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail(); + $invoice = $invitation->invoice; + $client = $invoice->client; + + $data = [ + 'invitationKey' => $invitationKey, + 'invoice' => $invoice, + 'client' => $client, + 'contact' => $invitation->contact + ]; + + return View::make('payments.payment', $data); + } + + public function do_payment($invitationKey) + { + $rules = array( + 'first_name' => 'required', + 'last_name' => 'required', + 'card_number' => 'required', + 'expiration_month' => 'required', + 'expiration_year' => 'required', + 'cvv' => 'required', + 'address1' => 'required', + 'city' => 'required', + 'state' => 'required', + 'postal_code' => 'required', + ); + + $validator = Validator::make(Input::all(), $rules); + + if ($validator->fails()) + { + return Redirect::to('payment/' . $invitationKey) + ->withErrors($validator); + } + else + { + $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail(); + $invoice = $invitation->invoice; + $accountGateway = $invoice->client->account->account_gateways[0]; + $gateway = self::createGateway($accountGateway); + + try + { + $details = self::getPaymentDetails($invoice, Input::all()); + $response = $gateway->purchase($details)->send(); + $ref = $response->getTransactionReference(); + + if (!$ref) + { + Session::flash('error', $response->getMessage()); + return Redirect::to('payment/' . $invitationKey) + ->withInput(); + } + + if ($response->isSuccessful()) + { + self::createPayment($invitation, $ref); + + $invoice->invoice_status_id = INVOICE_STATUS_PAID; + $invoice->save(); + + Event::fire('invoice.paid', $payment); + + Session::flash('message', 'Successfully applied payment'); + return Redirect::to('view/' . $payment->invitation->invitation_key); + } + else if ($response->isRedirect()) + { + $invitation->transaction_reference = $ref; + $invitation->save(); + + $response->redirect(); + } + else + { + return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
'); + } + } + catch (\Exception $e) + { + Session::flash('error', $e->getMessage()); + return Redirect::to('payment/' . $invitationKey) + ->withInput(); + } + } + } + + private function createPayment($invitation, $ref, $payerId = null) + { + $invoice = $invitation->invoice; + $accountGateway = $invoice->client->account->account_gateways[0]; + + $payment = Payment::createNew(); + $payment->invitation_id = $invitation->id; + $payment->account_gateway_id = $accountGateway->id; + $payment->invoice_id = $invoice->id; + $payment->amount = $invoice->amount; + $payment->client_id = $invoice->client_id; + $payment->contact_id = $invitation->contact_id; + $payment->transaction_reference = $ref; + $payment->payment_date = date_create()->format('Y-m-d'); + + if ($payerId) + { + $payment->payer_id = $payerId; + } + + $payment->save(); + + return $payment; + } + + public function offsite_payment() + { + $payerId = Request::query('PayerID'); + $token = Request::query('token'); + + $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail(); + $invoice = $invitation->invoice; + + $accountGateway = $invoice->client->account->account_gateways[0]; + $gateway = self::createGateway($accountGateway); + + try + { + $details = self::getPaymentDetails($invoice); + $response = $gateway->completePurchase($details)->send(); + $ref = $response->getTransactionReference(); + + if ($response->isSuccessful()) + { + $payment = self::createPayment($invitation, $ref, $payerId); + + $invoice->invoice_status_id = INVOICE_STATUS_PAID; + $invoice->save(); + + Event::fire('invoice.paid', $payment); + + Session::flash('message', 'Successfully applied payment'); + return Redirect::to('view/' . $invitation->invitation_key); + } + else + { + return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $response->getMessage()); + } + } + catch (\Exception $e) + { + return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.
', $e); + } + } + + public function store() { return $this->save(); diff --git a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php index b1d16d6272b2..b5a5c31e2443 100755 --- a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php +++ b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php @@ -106,6 +106,7 @@ class ConfideSetupUsersTable extends Migration { $t->string('precision'); $t->string('thousand_separator'); $t->string('decimal_separator'); + $t->string('code'); }); Schema::create('sizes', function($t) @@ -230,7 +231,7 @@ class ConfideSetupUsersTable extends Migration { $t->increments('id'); $t->unsignedInteger('user_id'); $t->unsignedInteger('account_id')->index(); - $t->unsignedInteger('currency_id')->default(1)->nullable(); + $t->unsignedInteger('currency_id')->default(1); $t->timestamps(); $t->softDeletes(); @@ -353,6 +354,7 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); + $t->string('transaction_reference'); $t->timestamp('sent_date'); $t->timestamp('viewed_date'); diff --git a/app/database/seeds/ConstantsSeeder.php b/app/database/seeds/ConstantsSeeder.php index 3a3ebf8fe7e2..fa70a9700ae4 100755 --- a/app/database/seeds/ConstantsSeeder.php +++ b/app/database/seeds/ConstantsSeeder.php @@ -118,9 +118,9 @@ class ConstantsSeeder extends Seeder PaymentTerm::create(array('num_days' => 30, 'name' => 'Net 30')); PaymentTerm::create(array('num_days' => 60, 'name' => 'Net 60')); - Currency::create(array('name' => 'US Dollar', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); - Currency::create(array('name' => 'Pound Sterling', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); - Currency::create(array('name' => 'Euro', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'US Dollar', 'code' => 'USD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Pound Sterling', 'code' => 'GBP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); DatetimeFormat::create(array('format' => 'd/M/Y g:i a', 'label' => '10/Mar/2013')); diff --git a/app/models/Client.php b/app/models/Client.php index e1b6eb0261c0..9458b43cc2e8 100755 --- a/app/models/Client.php +++ b/app/models/Client.php @@ -37,6 +37,11 @@ class Client extends EntityModel return $this->belongsTo('Country'); } + public function currency() + { + return $this->belongsTo('Currency'); + } + public function size() { return $this->belongsTo('Size'); diff --git a/app/ninja/repositories/ClientRepository.php b/app/ninja/repositories/ClientRepository.php index 80b861f4e7e4..5625a6b77d38 100755 --- a/app/ninja/repositories/ClientRepository.php +++ b/app/ninja/repositories/ClientRepository.php @@ -53,7 +53,7 @@ class ClientRepository $client->private_notes = trim($data['private_notes']); $client->size_id = $data['size_id'] ? $data['size_id'] : null; $client->industry_id = $data['industry_id'] ? $data['industry_id'] : null; - $client->currency_id = $data['currency_id'] ? $data['currency_id'] : null; + $client->currency_id = $data['currency_id'] ? $data['currency_id'] : 1; $client->payment_terms = $data['payment_terms']; $client->website = trim($data['website']); $client->save(); diff --git a/app/routes.php b/app/routes.php index b8ba6b5ef3cc..0b2064af0da8 100755 --- a/app/routes.php +++ b/app/routes.php @@ -64,9 +64,10 @@ Route::get('/rocksteady', 'HomeController@showWelcome'); Route::get('log_error', 'HomeController@logError'); Route::post('get_started', 'AccountController@getStarted'); -Route::get('view/{invoice_key}', 'InvoiceController@view'); -Route::get('payment/{invoice_key}', 'InvoiceController@show_payment'); -Route::get('complete', 'InvoiceController@do_payment'); +Route::get('view/{invitation_key}', 'InvoiceController@view'); +Route::get('payment/{invitation_key}', 'PaymentController@show_payment'); +Route::post('payment/{invitation_key}', 'PaymentController@do_payment'); +Route::get('complete', 'PaymentController@offsite_payment'); Route::post('signup/validate', 'AccountController@checkEmail'); Route::post('signup/submit', 'AccountController@submitSignup'); diff --git a/app/views/header.blade.php b/app/views/header.blade.php index 2f69fe6efcba..62e2e5f4b173 100755 --- a/app/views/header.blade.php +++ b/app/views/header.blade.php @@ -70,7 +70,7 @@ - Invoice Ninja BETA + Invoice Ninja