From 9427f5180fbca21141d7e71411d4a0a7ff3a759c Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 15 Jul 2014 23:36:40 +0300 Subject: [PATCH] Working on self hosting --- .env.development.php | 1 - Gruntfile.js | 2 +- app/controllers/AccountController.php | 5 - app/controllers/HomeController.php | 18 +- app/controllers/InvoiceController.php | 2 +- app/controllers/PaymentController.php | 220 +- .../2014_07_13_142654_one_click_install.php | 58 + app/filters.php | 10 +- app/libraries/utils.php | 13 +- app/models/Activity.php | 8 +- app/models/Affiliate.php | 7 + app/models/License.php | 7 + app/models/Payment.php | 7 +- app/ninja/repositories/AccountRepository.php | 2 +- app/routes.php | 55 +- app/views/accounts/payments.blade.php | 2 + app/views/header.blade.php | 1 + app/views/invoices/edit.blade.php | 1 - app/views/master.blade.php | 3 - app/views/payments/payment.blade.php | 113 +- app/views/public/header.blade.php | 31 +- public/built.css | 77 +- public/built.js | 15265 +++++++++++++++- public/built.public.css | 11 +- public/css/splash.css | 5 +- 25 files changed, 15551 insertions(+), 373 deletions(-) create mode 100644 app/database/migrations/2014_07_13_142654_one_click_install.php create mode 100644 app/models/Affiliate.php create mode 100644 app/models/License.php diff --git a/.env.development.php b/.env.development.php index 53166e5b13..bfe98cf916 100644 --- a/.env.development.php +++ b/.env.development.php @@ -2,7 +2,6 @@ return array( - //'DISABLE_REGISTRATION' => true, //'TAG_MANAGER_KEY' => '', //'ANALYTICS_KEY' => '', diff --git a/Gruntfile.js b/Gruntfile.js index 4d1a419684..6846e4c0b7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,7 @@ module.exports = function(grunt) { js: { src: [ 'public/vendor/jquery/dist/jquery.js', - 'public/vendor/jquery-ui/jquery-ui.min.js', + 'public/vendor/jquery-ui/ui/jquery-ui.js', 'public/vendor/bootstrap/dist/js/bootstrap.min.js', 'public/vendor/datatables/media/js/jquery.dataTables.js', 'public/vendor/datatables-bootstrap3/BS3/assets/js/datatables.js', diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index b43ced30d3..985ca19293 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -21,11 +21,6 @@ class AccountController extends \BaseController { public function getStarted() { - if (Utils::isRegistrationDisabled()) - { - return Redirect::away(NINJA_URL.'/invoice_now'); - } - if (Auth::check()) { return Redirect::to('invoices/create'); diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index dcf8f30fe3..d05a1a9b75 100755 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -14,9 +14,23 @@ class HomeController extends BaseController { $this->mailer = $mailer; } - public function showWelcome() + public function showIndex() { - return View::make('public.splash'); + if (Utils::isNinja()) + { + return View::make('public.splash'); + } + else + { + if (Account::count() == 0) + { + return Redirect::to('/invoice_now'); + } + else + { + return Redirect::to('/login'); + } + } } public function showAboutUs() diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 0f6bbb9c6a..019dc223a4 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -126,7 +126,7 @@ class InvoiceController extends \BaseController { $invoice->is_pro = $client->account->isPro(); $data = array( - 'hideHeader' => $client->account->isPro() && Utils::isNinjaProd(), + 'hideHeader' => true, 'showBreadcrumbs' => false, 'invoice' => $invoice->hidePrivateFields(), 'invitation' => $invitation, diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index 680dec1256..4d428f4229 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -2,17 +2,19 @@ use ninja\repositories\PaymentRepository; use ninja\repositories\InvoiceRepository; +use ninja\repositories\AccountRepository; class PaymentController extends \BaseController { protected $creditRepo; - public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo) + public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo) { parent::__construct(); $this->paymentRepo = $paymentRepo; $this->invoiceRepo = $invoiceRepo; + $this->accountRepo = $accountRepo; } public function index() @@ -120,16 +122,51 @@ class PaymentController extends \BaseController $gateway->$function($val); } - /* if (!Utils::isProd()) { $gateway->setTestMode(true); - } - */ + } return $gateway; } + private function getLicensePaymentDetails($input) + { + $data = self::convertInputForOmnipay($input); + $card = new CreditCard($data); + + return [ + 'amount' => LICENSE_PRICE, + 'card' => $card, + 'currency' => 'USD', + 'returnUrl' => URL::to('license_complete'), + 'cancelUrl' => URL::to('/') + ]; + + } + + private function convertInputForOmnipay($input) + { + return [ + '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'] + ]; + } + private function getPaymentDetails($invoice, $input = null) { $key = $invoice->invoice_number . '_details'; @@ -138,24 +175,7 @@ class PaymentController extends \BaseController if ($input && $paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) { - $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'], - ]; + $data = self::convertInputForOmnipay($input); Session::put($key, $data); } @@ -258,19 +278,167 @@ class PaymentController extends \BaseController $data = [ 'showBreadcrumbs' => false, - 'hideHeader' => $client->account->isPro() && Utils::isNinjaProd(), - 'invitationKey' => $invitationKey, - 'invoice' => $invoice, + 'hideHeader' => true, + 'url' => 'payment/' . $invitationKey, + 'amount' => $invoice->amount, 'client' => $client, 'contact' => $invitation->contact, 'paymentLibrary' => $paymentLibrary, 'gateway' => $gateway, 'acceptedCreditCardTypes' => $acceptedCreditCardTypes, - 'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), + 'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), + 'currencyId' => $client->currency_id ]; return View::make('payments.payment', $data); } + + public function show_license_payment() + { + if (Input::has('return_url')) + { + Session::set('return_url', Input::get('return_url')); + } + + if (Input::has('affiliate_key')) + { + if ($affiliate = Affiliate::where('affiliate_key', '=', Input::get('affiliate_key'))->first()) + { + Session::set('affiliate_id', $affiliate->id); + } + } + + if (!Session::get('return_url') || !Session::get('affiliate_id')) + { + return Utils::fatalError(); + } + + if (Input::has('test_mode')) + { + Session::set('test_mode', Input::get('test_mode')); + } + + + $account = $this->accountRepo->getNinjaAccount(); + $account->load('account_gateways.gateway'); + $accountGateway = $account->account_gateways[0]; + $gateway = $accountGateway->gateway; + $paymentLibrary = $gateway->paymentlibrary; + $acceptedCreditCardTypes = $accountGateway->getCreditcardTypes(); + + $affiliate = Affiliate::find(Session::get('affiliate_id')); + + $data = [ + 'showBreadcrumbs' => false, + 'hideHeader' => true, + 'url' => 'license', + 'amount' => LICENSE_PRICE, + 'client' => false, + 'contact' => false, + 'paymentLibrary' => $paymentLibrary, + 'gateway' => $gateway, + 'acceptedCreditCardTypes' => $acceptedCreditCardTypes, + 'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), + 'currencyId' => 1, + 'paymentTitle' => $affiliate->payment_title, + 'paymentSubtitle' => $affiliate->payment_subtitle + ]; + + return View::make('payments.payment', $data); + } + + public function do_license_payment() + { + $testMode = Session::get('test_mode') === 'true'; + + $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('license') + ->withErrors($validator); + } + + $account = $this->accountRepo->getNinjaAccount(); + $account->load('account_gateways.gateway'); + $accountGateway = $account->account_gateways[0]; + + try + { + if ($testMode) + { + $ref = 'TEST_MODE'; + } + else + { + $gateway = self::createGateway($accountGateway); + $details = self::getLicensePaymentDetails(Input::all()); + + if (!$ref) + { + Session::flash('error', $response->getMessage()); + return Redirect::to('license')->withInput(); + } + + if (!$response->isSuccessful()) + { + Session::flash('error', $response->getMessage()); + Utils::logError($response->getMessage()); + return Redirect::to('license')->withInput(); + } + + } + + $license = new License; + $license->first_name = Input::get('first_name'); + $license->last_name = Input::get('last_name'); + $license->email = Input::get('email'); + $license->transaction_reference = $ref; + $license->license_key = Utils::generateLicense(); + $license->affiliate_id = Session::get('affiliate_id'); + $license->save(); + + return Redirect::away(Session::get('return_url') . "?license_key={$license->license_key}"); + } + catch (\Exception $e) + { + $errorMessage = trans('texts.payment_error'); + Session::flash('error', $errorMessage); + Utils::logError($e->getMessage()); + return Redirect::to('license')->withInput(); + } + } + + public function claim_license() + { + $license = License::where('license_key', '=', Input::get('key')) + ->where('is_claimed', '=', false)->first(); + + if ($license) + { + $license->is_claimed = true; + $license->save(); + + return 'valid'; + } + else + { + return 'invalid'; + } + } public function do_payment($invitationKey, $onSite = true) { diff --git a/app/database/migrations/2014_07_13_142654_one_click_install.php b/app/database/migrations/2014_07_13_142654_one_click_install.php new file mode 100644 index 0000000000..943117bed3 --- /dev/null +++ b/app/database/migrations/2014_07_13_142654_one_click_install.php @@ -0,0 +1,58 @@ +increments('id'); + $table->timestamps(); + $table->softDeletes(); + + $table->string('name'); + $table->string('affiliate_key')->unique(); + + $table->text('payment_title'); + $table->text('payment_subtitle'); + }); + + Schema::create('licenses', function($table) + { + $table->increments('id'); + $table->timestamps(); + $table->softDeletes(); + $table->unsignedInteger('affiliate_id'); + + $table->string('first_name'); + $table->string('last_name'); + $table->string('email'); + + $table->string('license_key')->unique(); + $table->boolean('is_claimed'); + $table->string('transaction_reference'); + + $table->foreign('affiliate_id')->references('id')->on('affiliates'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('licenses'); + Schema::dropIfExists('affiliates'); + } + +} diff --git a/app/filters.php b/app/filters.php index d88215d70d..ec8e64a3d2 100755 --- a/app/filters.php +++ b/app/filters.php @@ -70,11 +70,11 @@ App::after(function($request, $response) Route::filter('auth', function() { if (Auth::guest()) { - if(Utils::isNinja()) { - return Redirect::guest('/'); - } else { - return Redirect::guest('/login'); - } + if(Utils::isNinja()) { + return Redirect::guest('/'); + } else { + return Redirect::guest('/login'); + } } }); diff --git a/app/libraries/utils.php b/app/libraries/utils.php index c2fe77501a..f2ae828a1a 100755 --- a/app/libraries/utils.php +++ b/app/libraries/utils.php @@ -31,11 +31,6 @@ class Utils { return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV']; } - - public static function isRegistrationDisabled() - { - return isset($_ENV['DISABLE_REGISTRATION']) && $_ENV['DISABLE_REGISTRATION']; - } public static function isPro() { @@ -446,4 +441,12 @@ class Utils return $message; } + + public static function generateLicense() { + $parts = []; + for ($i=0; $i<5; $i++) { + $parts[] = strtoupper(str_random(4)); + } + return join('-', $parts); + } } \ No newline at end of file diff --git a/app/models/Activity.php b/app/models/Activity.php index fd728b373f..2dde981347 100755 --- a/app/models/Activity.php +++ b/app/models/Activity.php @@ -263,12 +263,12 @@ class Activity extends Eloquent { $activity = Activity::getBlank($client); $activity->contact_id = $payment->contact_id; - $activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered payment'); + $activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered ' . $payment->getName()); } else { $activity = Activity::getBlank(); - $message = $payment->payment_type_id == PAYMENT_TYPE_CREDIT ? 'applied credit' : 'entered payment'; + $message = $payment->payment_type_id == PAYMENT_TYPE_CREDIT ? 'applied credit' : 'entered ' . $payment->getName(); $activity->message = Utils::encodeActivity(Auth::user(), $message); } @@ -310,7 +310,7 @@ class Activity extends Eloquent $activity->client_id = $invoice->client_id; $activity->invoice_id = $invoice->id; $activity->activity_type_id = ACTIVITY_TYPE_DELETE_PAYMENT; - $activity->message = Utils::encodeActivity(Auth::user(), 'deleted payment'); + $activity->message = Utils::encodeActivity(Auth::user(), 'deleted ' . $payment->getName()); $activity->balance = $client->balance; $activity->adjustment = $payment->amount; $activity->save(); @@ -357,7 +357,7 @@ class Activity extends Eloquent $activity->invoice_id = $invoice->id; $activity->client_id = $client->id; $activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_PAYMENT; - $activity->message = Utils::encodeActivity(Auth::user(), 'archived payment'); + $activity->message = Utils::encodeActivity(Auth::user(), 'archived ' . $payment->getName()); $activity->balance = $client->balance; $activity->adjustment = 0; $activity->save(); diff --git a/app/models/Affiliate.php b/app/models/Affiliate.php new file mode 100644 index 0000000000..912260cf35 --- /dev/null +++ b/app/models/Affiliate.php @@ -0,0 +1,7 @@ +belongsTo('Contact'); } + public function getAmount() + { + return Utils::formatMoney($this->amount, $this->client->currency_id); + } + public function getName() { - return ''; + return trim("payment {$this->transaction_reference}"); } public function getEntityType() diff --git a/app/ninja/repositories/AccountRepository.php b/app/ninja/repositories/AccountRepository.php index 63aeb24ec4..bb2b13b94a 100755 --- a/app/ninja/repositories/AccountRepository.php +++ b/app/ninja/repositories/AccountRepository.php @@ -147,7 +147,7 @@ class AccountRepository return $invoice; } - private function getNinjaAccount() + public function getNinjaAccount() { $account = Account::whereAccountKey(NINJA_ACCOUNT_KEY)->first(); diff --git a/app/routes.php b/app/routes.php index 5218d5fbdf..d4c253597c 100755 --- a/app/routes.php +++ b/app/routes.php @@ -22,39 +22,33 @@ //dd(gethostname()); //Log::error('test'); -//if(Utils::isNinja()) { +Route::get('/', 'HomeController@showIndex'); +Route::get('/rocksteady', 'HomeController@showIndex'); +Route::get('/about', 'HomeController@showAboutUs'); +Route::get('/terms', 'HomeController@showTerms'); +Route::get('/contact', 'HomeController@showContactUs'); +Route::get('/plans', 'HomeController@showPlans'); +Route::post('/contact_submit', 'HomeController@doContactUs'); +Route::get('/faq', 'HomeController@showFaq'); +Route::get('/features', 'HomeController@showFeatures'); +Route::get('/testimonials', 'HomeController@showTestimonials'); - Route::get('/', 'HomeController@showWelcome'); - Route::get('/rocksteady', 'HomeController@showWelcome'); - Route::get('/about', 'HomeController@showAboutUs'); - Route::get('/terms', 'HomeController@showTerms'); - Route::get('/contact', 'HomeController@showContactUs'); - Route::get('/plans', 'HomeController@showPlans'); - Route::post('/contact_submit', 'HomeController@doContactUs'); - Route::get('/faq', 'HomeController@showFaq'); - Route::get('/features', 'HomeController@showFeatures'); - Route::get('/secure_payment', 'HomeController@showSecurePayment'); - Route::get('/testimonials', 'HomeController@showTestimonials'); +Route::get('log_error', 'HomeController@logError'); +Route::get('invoice_now', 'HomeController@invoiceNow'); +Route::post('get_started', 'AccountController@getStarted'); - Route::get('log_error', 'HomeController@logError'); - Route::get('invoice_now', 'HomeController@invoiceNow'); - Route::post('get_started', 'AccountController@getStarted'); +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::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::get('license', 'PaymentController@show_license_payment'); +Route::post('license', 'PaymentController@do_license_payment'); +Route::get('claim_license', 'PaymentController@claim_license'); - Route::post('signup/validate', 'AccountController@checkEmail'); - Route::post('signup/submit', 'AccountController@submitSignup'); +Route::post('signup/validate', 'AccountController@checkEmail'); +Route::post('signup/submit', 'AccountController@submitSignup'); -/* -} else { - Route::get('/', function() { - return Redirect::to('dashboard'); - }); -} -*/ // Confide routes @@ -227,9 +221,10 @@ define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h'); define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET); define('NINJA_GATEWAY_CONFIG', '{"apiLoginId":"626vWcD5","transactionKey":"4bn26TgL9r4Br4qJ","testMode":"","developerMode":""}'); define('NINJA_URL', 'https://www.invoiceninja.com'); -define('NINJA_VERSION', '1.2.0'); -define('PRO_PLAN_PRICE', 50); +define('NINJA_VERSION', '1.2.2'); +define('PRO_PLAN_PRICE', 50); +define('LICENSE_PRICE', 30); /* define('GATEWAY_AMAZON', 30); diff --git a/app/views/accounts/payments.blade.php b/app/views/accounts/payments.blade.php index 447e121681..0f3d9f4552 100755 --- a/app/views/accounts/payments.blade.php +++ b/app/views/accounts/payments.blade.php @@ -22,6 +22,7 @@ +
{{ Former::radios('recommendedGateway_id')->label('Recommended Gateways') diff --git a/app/views/header.blade.php b/app/views/header.blade.php index 49f0d3b653..de07dfa47d 100755 --- a/app/views/header.blade.php +++ b/app/views/header.blade.php @@ -6,6 +6,7 @@ - -