diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index a9659470bc5d..6b0dd86aa216 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -212,7 +212,7 @@ class AccountController extends BaseController $days_total = $planDetails['paid']->diff($planDetails['expires'])->days; $percent_used = $days_used / $days_total; - $credit = $planDetails['plan_price'] * (1 - $percent_used); + $credit = floatval($company->payment->amount) * (1 - $percent_used); } if ($newPlan['price'] > $credit) { @@ -224,7 +224,9 @@ class AccountController extends BaseController } } else { - if ($plan != PLAN_FREE) { + if ($plan == PLAN_FREE) { + $company->discount = 0; + } else { $company->plan_term = $term; $company->plan_price = $newPlan['price']; $company->num_users = $numUsers; diff --git a/app/Models/Company.php b/app/Models/Company.php index 847289a88eb2..5826de25c37e 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -1,7 +1,10 @@ belongsTo('App\Models\Payment'); } + + public function hasActivePromo() + { + if ($this->discount_expires) { + return false; + } + + return $this->promo_expires && $this->promo_expires->gte(Carbon::today()); + } + + // handle promos and discounts + public function hasActiveDiscount() + { + if ( ! $this->discount) { + return false; + } + + return $this->discount_expires && $this->discount_expires->gt(Carbon::today()); + } + + public function discountedPrice($price) + { + if ( ! $this->hasActivePromo() && ! $this->hasActiveDiscount()) { + return $price; + } + + return $price - ($price * $this->discount); + } + + public function hasEarnedPromo() + { + if ( ! Utils::isNinjaProd() || Utils::isPro()) { + return false; + } + + // if they've already had a discount or a promotion is active return false + if ($this->discount_expires || $this->hasActivePromo()) { + return false; + } + + // after 52 weeks, offer a 50% discount for 3 days + $discounts = [ + 52 => [.5, 3], + 16 => [.5, 3], + 10 => [.25, 5], + ]; + + foreach ($discounts as $weeks => $promo) { + list($discount, $validFor) = $promo; + $difference = $this->created_at->diffInWeeks(); + if ($difference >= $weeks) { + $this->discount = $discount; + $this->promo_expires = date_create()->modify($validFor . ' days')->format('Y-m-d'); + $this->save(); + return true; + } + } + + return false; + } } diff --git a/app/Ninja/PaymentDrivers/BasePaymentDriver.php b/app/Ninja/PaymentDrivers/BasePaymentDriver.php index 991717bd7704..2c819b95556b 100644 --- a/app/Ninja/PaymentDrivers/BasePaymentDriver.php +++ b/app/Ninja/PaymentDrivers/BasePaymentDriver.php @@ -667,6 +667,11 @@ class BasePaymentDriver $company->plan_expires = DateTime::createFromFormat('Y-m-d', $account->company->plan_paid) ->modify($term == PLAN_TERM_MONTHLY ? '+1 month' : '+1 year')->format('Y-m-d'); + if ($company->hasActivePromo()) { + $company->discount_expires = date_create()->modify('1 year')->format('Y-m-d'); + $company->promo_expires = null; + } + $company->save(); } } diff --git a/app/Ninja/Presenters/CompanyPresenter.php b/app/Ninja/Presenters/CompanyPresenter.php new file mode 100644 index 000000000000..730b4f5cfd00 --- /dev/null +++ b/app/Ninja/Presenters/CompanyPresenter.php @@ -0,0 +1,29 @@ +entity->hasActivePromo()) { + return ''; + } + + return trans('texts.promo_message', [ + 'expires' => $this->entity->promo_expires->format('M dS, Y'), + 'amount' => (int)($this->discount * 100) + ]); + } + + public function discountMessage() + { + if ( ! $this->entity->hasActiveDiscount()) { + return ''; + } + + return trans('texts.discount_message', [ + 'expires' => $this->entity->discount_expires->format('M dS, Y'), + 'amount' => (int)($this->discount * 100) + ]); + } + +} diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index 25818db30d8d..78983a9e4f8c 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -289,6 +289,16 @@ class AccountRepository $invoice->invoice_date = $clientAccount->getRenewalDate(); $invoice->amount = $invoice->balance = $plan_cost - $credit; $invoice->invoice_type_id = INVOICE_TYPE_STANDARD; + + // check for promo/discount + $clientCompany = $clientAccount->company; + if ($clientCompany->hasActivePromo() || $clientCompany->hasActiveDiscount()) { + $discount = $invoice->amount * $clientCompany->discount; + $invoice->discount = $clientCompany->discount * 100; + $invoice->amount -= $discount; + $invoice->balance -= $discount; + } + $invoice->save(); if ($credit) { diff --git a/database/migrations/2016_12_13_113955_add_pro_plan_discount.php b/database/migrations/2016_12_13_113955_add_pro_plan_discount.php new file mode 100644 index 000000000000..c04b810e2b20 --- /dev/null +++ b/database/migrations/2016_12_13_113955_add_pro_plan_discount.php @@ -0,0 +1,37 @@ +float('discount'); + $table->date('discount_expires')->nullable(); + $table->date('promo_expires')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('companies', function ($table) + { + $table->dropColumn('discount'); + $table->dropColumn('discount_expires'); + $table->dropColumn('promo_expires'); + }); + } +} diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index c6710967ea52..c0df57548e89 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2267,6 +2267,8 @@ $LANG = array( 'contact_us' => 'Contact Us', 'support_forum' => 'Support Forum', 'user_guide' => 'User Guide', + 'promo_message' => 'Upgrade before :expires and get :amount% OFF your first year of our Pro or Enterprise packages.', + 'discount_message' => ':amount% off expires :expires', ); diff --git a/resources/views/accounts/management.blade.php b/resources/views/accounts/management.blade.php index c94733ba5c9d..2f21b048a7fb 100644 --- a/resources/views/accounts/management.blade.php +++ b/resources/views/accounts/management.blade.php @@ -50,6 +50,12 @@
+ + @if ($account->company->hasActiveDiscount()) + {!! Former::plaintext('discount') + ->value($account->company->present()->discountMessage) !!} + @endif + @if (Utils::isNinjaProd()) {!! Former::actions( Button::info(trans('texts.plan_change'))->large()->withAttributes(['onclick' => 'showChangePlan()'])->appendIcon(Icon::create('edit'))) !!} @endif @@ -120,6 +126,9 @@ ->addOption(trans('texts.plan_term_yearly'), PLAN_TERM_YEARLY) ->inlineHelp(trans('texts.enterprise_plan_features', ['link' => link_to(NINJA_WEB_URL . '/plans-pricing', trans('texts.click_here'), ['target' => '_blank'])])) !!} + {!! Former::plaintext(' ') + ->inlineHelp($account->company->present()->promoMessage) !!} + -@if($showBlueVinePromo) + +@if ($account->company->hasEarnedPromo()) + @include('partials/discount_promo') +@elseif ($showBlueVinePromo) @include('partials/bluevine_promo') @endif +{{ trans('texts.pay_annually_discount') }}
@@ -155,7 +162,7 @@
{{ trans('texts.pay_annually_discount') }}