Implement pricing model for LRS based on the statements per billing period.
- Learnexa - All the sites will have the same subscription period (which is configured at super site.)
- LRS - As expertus one customers each of them may have different billing periods (some may have annual, some may have quarterly), each site's billing period is configured differently per site.
- Super admin can set offline payment to any subsite under site subscription page(This will be like flag super site admin can set it, if it set's true to any subsite that site should not have the “subscribe now” notification bar)
LRS pricing model implementation is similar to learnexa pricing model, Subsite can be billable based on the statements per period. So the plan is similar to learnexa where admin can set the subscription setting, subscription plan and that can be used for subsite subscription. If the price of the subscription changes then the user shall be notified, A User will have an option to Un-subscribe at any time. User can change the pricing plan either by the end of the period or middle of the period.
Trail period
There will be a trail period for few days that can be configured by super site admin in the subscription settings under the site subscription tab.
Subscription
There will be a various subscription plan which can be created and maintained by the super site admin. Super site admin can assign the default/custom subscription to the subsite. Subsite admin has to subscribe in order to use the site and the statements,Which is similar to learnexa. eg:
a) FREE - 500 Statements - $0.00 b) PlanA - 2000 Statements - $20.00 c) PlanB - 5000 Statements - $40.00 d) PlanC - 10000 Statements - $70.00
Subscription Type
a) Day b) Week c) 2Week d) Monthly e) Quarterly f) Yearly
Overage Statements
Statements count will be tracked, if the statement count exceeds the subscribed plan count, overage statements will be notified to the user and that will be billable, The overage statement and the pricing information will be shown under the Billing tab, Subsite admin has to pay it from billing page.
The following Models will be used for Implementation
class Company < ActiveRecord::Base #This model already exists just add below association belongs_to :site_subscription has_one :merchant_account, :as => :owner has_many :statements, :through => :client_applications has_many :site_orders, :through => :site_subscription end class SubscriptionSetting < ActiveRecord::Base end class SubscriptionPlan < ActiveRecord::Base has_many :site_subscriptions has_many :site_orders has_many :site_custom_plans , :dependent => :destroy end class SiteCustomPlan < ActiveRecord::Base belongs_to :subscription_plan belongs_to :site_subscription end class SiteSubscription < ActiveRecord::Base belongs_to :subscription_plan has_one :company, :dependent => :destroy has_many :site_orders has_many :site_order_items, :through => :site_orders, :dependent => :destroy has_many :payments_made, :class_name => "SitePayment", :foreign_key => "payer_id" has_many :site_usages has_one :site_custom_plan, :dependent => :destroy has_one :custom_plan, :through => :site_custom_plan, :source => :subscription_plan end class SiteOrder < ActiveRecord::Base belongs_to :site_subscription belongs_to :subscription_plan has_one :site_payment, :dependent => :destroy has_many :site_order_items, :dependent => :destroy end class SiteOrderItem < ActiveRecord::Base belongs_to :site_order belongs_to :item, :polymorphic => true end class SitePayment < ActiveRecord::Base belongs_to :site_order belongs_to :payer, :class_name => "SiteSubscription" belongs_to :user_paid, :class_name => "User", :foreign_key => "payer_user_id" end
Table Name: companies(This table already exists. Just add following columns)
| Column_name | type | Description |
|---|---|---|
| site_subscription_id | integer | ID of the subscription ID corresponding to the company |
Table Name: subscription_settings
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| trial_period | string | day/week/2 week/month/quarter/year |
| delete_lag | integer | Time left to delete the site after expiry |
| expiry_reminder_lag | string | Time before expiry date to send trial expiry reminder |
| expired_notification_lag | string | Time after expiry to send trial expired notification |
| site_lock_lag | integer | Time left to lock the site after the auto renewal of subscription failed |
| create_at | date_time | created date |
| updated_at | date_time | updated date |
Table Name: subscription_plans
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| name | string | subscription name |
| code | string | subscription unique code |
| subscription_period | string | day/week/2 week/month/quarter/year |
| price | Float | Subscription Price |
| statement_pack_size(Learnexa: max_active_user_count) | integer | Maximum Statement for the price |
| additional_per_statement_cost(Learnexa: per_user_cost ) | float | Additional statement fees |
| additional_statement_pack_size(Learnexa: user_pack_size) | integer | Additional statement pack size for the above additional statement fees |
| custom | boolean | Default/Custom plan |
| active | boolean | plan active status |
| create_at | date_time | created date |
| updated_at | date_time | updated date |
Table Name: site_custom_plan
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| site_subscription_id | integer | Reference to site subscription table |
| subscription_plan_id | integer | Reference to subscription plan table |
Table Name: site_subscriptions
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| status | integer | (Can be TRIAL, TRIAL_EXPIRED, TRIAL_EXPIRED_DELETE, SUBSCRIBED, SUBSCRIPTION_CANCELED, SUBSCRIPTION_EXPIRED, SUBSCRIPTION_EXPIRED_DELETE) |
| status_changed_at | datetime | datetime when the status field was updated |
| status_change_notified | boolean | Indicates whether the site owner is notified about the recent status change or not |
| start_at | datetime | When the subscription period starts |
| end_at | datetime | When the subscription period ends |
| next_renewal_at | datetime | When the subscription will be renewed. Usually based on subscription type |
| preapproval_id | integer | Preapproval ID returned by wepay, used when charging the customer via a background job |
| last_payment_id | integer | ID of corresponding payment record |
| last_payment_status | string | (SUCCESS, FAILURE) |
| subscription_plan_id | integer | The latest subscription plan of this company. Foreign key for subscription_plans |
| subscription_period | string | The latest subscription period |
| price | float | The latest subscription price |
| statement_pack_size | integer | Total number of statement allowed for the subscription |
| additional_per_statement_cost | float | Per statement cost for the overage statement |
| additional_statement_pack_size | float | Additional/Overage statement pack size |
| period_started_at | datetime | subscription started date |
| previous_status | integer | Previous subscription status |
| previous_subscription_plan_id | integer | reference id for previous subscription plan |
| previous_status_start_at | datetime | Previous subscription start date |
| previous_status_end_at | datetime | Previous subscription end date |
| renew_billing_order_id | integer | reference id for previous subscription plan |
| renew_subscription_plan_id | integer | reference id for previous subscription plan |
| site_locked_type | string | Site locked Reason |
| notified_type | integer | Last email notified type eg: trail reminder/expired, subscription renewal/expired |
| retry_payment | boolean | Retry payment if the payment is failed true/false |
| retry_at | datetime | Datetime to retry the subscription payment |
| canceled_by_user_id | integer | User who canceled the subscription |
| offline_payment | Boolean | Whether the site has enabled offline payment mode/online payment mode |
| created_at | datetime | site subscription created date |
| updated_at | datetime | site subscription updated date |
Table Name: site_orders
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| site_subscription_id | integer | Reference to site subscription table |
| subscription_plan_id | integer | Reference to subscription plan table |
| payment_status | string | Set to SUCCESS if payment was successful and FAILURE otherwise. Initially the value can be NULL and later based on how the payment went through this can be set to SUCCESS or FAILURE |
| discount | decimal | |
| sub_total | decimal | |
| total | decimal | |
| description | string | |
| reference_id | integer | |
| pay_again | boolean | |
| subscription_period | string | |
| created_at | datetime | site order created date |
| updated_at | datetime | site order updated date |
Table Name: site_order_items
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| site_order_id | integer | |
| item_type | String | Can by subscription, additional statement etc…Currently the value will be 'subscription' |
| item_id | integer | |
| price | Float | |
| quantity | integer | |
| created_at | datetime | created date |
| updated_at | datetime | updated date |
Table Name: site_payments
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| site_order_id | integer | Order for which this payment was made. |
| ip_address | string | IP address of the payer |
| payer_id | integer | site_subscrituion_id of the company who is paying |
| status | string | SUCCESS or FAILURE |
| amount | float | |
| payment_method | string | Currently only WEPAY |
| params | text | data that was passed to the gateway |
| response | text | response that was returned by the gateway |
| checkout_id | string | Checkout id |
| payer_user_id | integer | Payee user id |
| name_on_card | text | Name of the card holder |
| refunded_at | datetime | Refunded date |
| payment_redirected | boolean | payment redirected status |
| error_code | string | payment error code |
| created_at | datetime | created date |
| updated_at | datetime | updated date |
Table Name: site_usages
Saves the statement details for each and every billing cycle at the end of the billing cycle.
| Column_name | type | Description |
|---|---|---|
| id | integer | primary key |
| site_subscription_id | integer | Foreign key to site_subscriptions table |
| billing_period_start_time | datetime | When a given billing period starts. |
| billing_period_end_time | datetime | When a given billing period ends. |
| max_allowed_statement_count | integer | Maximum allowed statements count in the given billing period. |
| statement_geneareted_count | integer | The actual statement in the billing period. |
| created_at | datetime | created date |
| updated_at | datetime | updated date |
Wepay payment gateway will be used for payment subscription similar to learnexa.
When company purchases subscription
Offline Payment process
When the user upgrade the subscription in the middle of the subscription period,
» Uday: For now, this just works like learnexa, plan features are upgraded immediately but users are charged extra amounts only from next billing cycle. Will confirm this with Murali.
» Murali: Correct
a) public/javascripts/base_packaged.js b) public/stylesheets/application.css c) public/stylesheets/base_packaged.css d) public/stylesheets/client.css e) public/stylesheets/columns.css f) public/stylesheets/forms.css g) public/stylesheets/ie.css h) public/stylesheets/layers.css i) public/stylesheets/lightbox.css j) public/stylesheets/panels.css k) public/stylesheets/site_frame.css l) public/stylesheets/tabs.css m) public/stylesheets/tincan.css n) public/stylesheets/typography.css