=== Subscription === Goal - LRS subsite should be billable based on the statements. There will be a trail period for few days that can be done by super site admin under site subscription. - Once the trail period is expired subsite admin should subscribe the plan based on the statements e.g : (Ex- Free - 500 statements, plan A - 2000, plan B - 5000, plan C - 9000 and etc.) - We should be able to track the statements of every period and be able to charge subsite as per different plans. Also, if the statement count exceeds the allowed plan's count, overage statements are billable - A Super site admin can set up a subscription settings and different types of subscription plan - Subscription plan will have different subscription type(Day/Week/2Week/Monthly/Quarterly/Yearly) which can be given to various subsite. - 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. == Models == The following Models will be used for Implementation class Company < ActiveRecord::Base #This model already exists just add below association belongs_to :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 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 SiteCustomPlan < ActiveRecord::Base belongs_to :subscription_plan belongs_to :site_subscription 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 == DB Schema == 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 | | subscription_period | string | day/week/2 week/month/quarter/year | | price | Float | Subscription Price | | max_statement_count | integer | Included Statement for the price | | per_statment_cost | float | Additional statement fees | | statement pack size | string | Additional statement pack size for the above additional statement fees | | 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 | | 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| | 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 | | | previous_status | integer | Previous subscription status | | description | string | | | 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 | | |qty | 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 | |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_statement_count| integer| Maximum allowed statements count in the given billing period.| |statement_count | integer | The actual statement in the billing period.| |created_at| datetime |created date | |updated_at| datetime |updated date | __General flow of record creation__ When company purchases subscription - Create a record in site_orders and site_order_items. At present the items for an order will always be 1 viz. subscription. Set payment_status = NIL - Generate the parameters that need to be sent to payment gateway and based on those parameters and the site_order_id create a record in site_payments table. Set 'status' column to NIL. After the response from the gateway is received, update the 'response' column of site_payments and based on the success or failure update the 'status' column. Also update the payment_status column in site_orders table to proper value i.e. success or failure. - Also if payment was successful then update the site_subscriptions table with proper status, preapproval_id and last_payment_id and last_payment_status Recurring Billing - Run the cron job which will run the task to check the site billing period end time from site_usages table and make the recurring billing and follow the above payment process steps Overage statements - Subsite admin has to pay from billing page, The overage statement and the pricing information will be shown.