Merge pull request #27783 from hrwX/subscription_generation_fix_develop
fix(Subscription): reorder updation of end date
This commit is contained in:
commit
bd310e2816
@ -33,7 +33,7 @@ class Subscription(Document):
|
|||||||
# update start just before the subscription doc is created
|
# update start just before the subscription doc is created
|
||||||
self.update_subscription_period(self.start_date)
|
self.update_subscription_period(self.start_date)
|
||||||
|
|
||||||
def update_subscription_period(self, date=None):
|
def update_subscription_period(self, date=None, return_date=False):
|
||||||
"""
|
"""
|
||||||
Subscription period is the period to be billed. This method updates the
|
Subscription period is the period to be billed. This method updates the
|
||||||
beginning of the billing period and end of the billing period.
|
beginning of the billing period and end of the billing period.
|
||||||
@ -41,28 +41,41 @@ class Subscription(Document):
|
|||||||
The beginning of the billing period is represented in the doctype as
|
The beginning of the billing period is represented in the doctype as
|
||||||
`current_invoice_start` and the end of the billing period is represented
|
`current_invoice_start` and the end of the billing period is represented
|
||||||
as `current_invoice_end`.
|
as `current_invoice_end`.
|
||||||
"""
|
|
||||||
self.set_current_invoice_start(date)
|
|
||||||
self.set_current_invoice_end()
|
|
||||||
|
|
||||||
def set_current_invoice_start(self, date=None):
|
If return_date is True, it wont update the start and end dates.
|
||||||
|
This is implemented to get the dates to check if is_current_invoice_generated
|
||||||
"""
|
"""
|
||||||
This sets the date of the beginning of the current billing period.
|
_current_invoice_start = self.get_current_invoice_start(date)
|
||||||
|
_current_invoice_end = self.get_current_invoice_end(_current_invoice_start)
|
||||||
|
|
||||||
|
if return_date:
|
||||||
|
return _current_invoice_start, _current_invoice_end
|
||||||
|
|
||||||
|
self.current_invoice_start = _current_invoice_start
|
||||||
|
self.current_invoice_end = _current_invoice_end
|
||||||
|
|
||||||
|
def get_current_invoice_start(self, date=None):
|
||||||
|
"""
|
||||||
|
This returns the date of the beginning of the current billing period.
|
||||||
If the `date` parameter is not given , it will be automatically set as today's
|
If the `date` parameter is not given , it will be automatically set as today's
|
||||||
date.
|
date.
|
||||||
"""
|
"""
|
||||||
if self.is_new_subscription() and self.trial_period_end and getdate(self.trial_period_end) > getdate(self.start_date):
|
_current_invoice_start = None
|
||||||
self.current_invoice_start = add_days(self.trial_period_end, 1)
|
|
||||||
elif self.trial_period_start and self.is_trialling():
|
|
||||||
self.current_invoice_start = self.trial_period_start
|
|
||||||
elif date:
|
|
||||||
self.current_invoice_start = date
|
|
||||||
else:
|
|
||||||
self.current_invoice_start = nowdate()
|
|
||||||
|
|
||||||
def set_current_invoice_end(self):
|
if self.is_new_subscription() and self.trial_period_end and getdate(self.trial_period_end) > getdate(self.start_date):
|
||||||
|
_current_invoice_start = add_days(self.trial_period_end, 1)
|
||||||
|
elif self.trial_period_start and self.is_trialling():
|
||||||
|
_current_invoice_start = self.trial_period_start
|
||||||
|
elif date:
|
||||||
|
_current_invoice_start = date
|
||||||
|
else:
|
||||||
|
_current_invoice_start = nowdate()
|
||||||
|
|
||||||
|
return _current_invoice_start
|
||||||
|
|
||||||
|
def get_current_invoice_end(self, date=None):
|
||||||
"""
|
"""
|
||||||
This sets the date of the end of the current billing period.
|
This returns the date of the end of the current billing period.
|
||||||
|
|
||||||
If the subscription is in trial period, it will be set as the end of the
|
If the subscription is in trial period, it will be set as the end of the
|
||||||
trial period.
|
trial period.
|
||||||
@ -71,44 +84,47 @@ class Subscription(Document):
|
|||||||
current billing period where `x` is the billing interval from the
|
current billing period where `x` is the billing interval from the
|
||||||
`Subscription Plan` in the `Subscription`.
|
`Subscription Plan` in the `Subscription`.
|
||||||
"""
|
"""
|
||||||
if self.is_trialling() and getdate(self.current_invoice_start) < getdate(self.trial_period_end):
|
_current_invoice_end = None
|
||||||
self.current_invoice_end = self.trial_period_end
|
|
||||||
|
if self.is_trialling() and getdate(date) < getdate(self.trial_period_end):
|
||||||
|
_current_invoice_end = self.trial_period_end
|
||||||
else:
|
else:
|
||||||
billing_cycle_info = self.get_billing_cycle_data()
|
billing_cycle_info = self.get_billing_cycle_data()
|
||||||
if billing_cycle_info:
|
if billing_cycle_info:
|
||||||
if self.is_new_subscription() and getdate(self.start_date) < getdate(self.current_invoice_start):
|
if self.is_new_subscription() and getdate(self.start_date) < getdate(date):
|
||||||
self.current_invoice_end = add_to_date(self.start_date, **billing_cycle_info)
|
_current_invoice_end = add_to_date(self.start_date, **billing_cycle_info)
|
||||||
|
|
||||||
# For cases where trial period is for an entire billing interval
|
# For cases where trial period is for an entire billing interval
|
||||||
if getdate(self.current_invoice_end) < getdate(self.current_invoice_start):
|
if getdate(self.current_invoice_end) < getdate(date):
|
||||||
self.current_invoice_end = add_to_date(self.current_invoice_start, **billing_cycle_info)
|
_current_invoice_end = add_to_date(date, **billing_cycle_info)
|
||||||
else:
|
else:
|
||||||
self.current_invoice_end = add_to_date(self.current_invoice_start, **billing_cycle_info)
|
_current_invoice_end = add_to_date(date, **billing_cycle_info)
|
||||||
else:
|
else:
|
||||||
self.current_invoice_end = get_last_day(self.current_invoice_start)
|
_current_invoice_end = get_last_day(date)
|
||||||
|
|
||||||
if self.follow_calendar_months:
|
if self.follow_calendar_months:
|
||||||
billing_info = self.get_billing_cycle_and_interval()
|
billing_info = self.get_billing_cycle_and_interval()
|
||||||
billing_interval_count = billing_info[0]['billing_interval_count']
|
billing_interval_count = billing_info[0]['billing_interval_count']
|
||||||
calendar_months = get_calendar_months(billing_interval_count)
|
calendar_months = get_calendar_months(billing_interval_count)
|
||||||
calendar_month = 0
|
calendar_month = 0
|
||||||
current_invoice_end_month = getdate(self.current_invoice_end).month
|
current_invoice_end_month = getdate(_current_invoice_end).month
|
||||||
current_invoice_end_year = getdate(self.current_invoice_end).year
|
current_invoice_end_year = getdate(_current_invoice_end).year
|
||||||
|
|
||||||
for month in calendar_months:
|
for month in calendar_months:
|
||||||
if month <= current_invoice_end_month:
|
if month <= current_invoice_end_month:
|
||||||
calendar_month = month
|
calendar_month = month
|
||||||
|
|
||||||
if cint(calendar_month - billing_interval_count) <= 0 and \
|
if cint(calendar_month - billing_interval_count) <= 0 and \
|
||||||
getdate(self.current_invoice_start).month != 1:
|
getdate(date).month != 1:
|
||||||
calendar_month = 12
|
calendar_month = 12
|
||||||
current_invoice_end_year -= 1
|
current_invoice_end_year -= 1
|
||||||
|
|
||||||
self.current_invoice_end = get_last_day(cstr(current_invoice_end_year) + '-' \
|
_current_invoice_end = get_last_day(cstr(current_invoice_end_year) + '-' + cstr(calendar_month) + '-01')
|
||||||
+ cstr(calendar_month) + '-01')
|
|
||||||
|
|
||||||
if self.end_date and getdate(self.current_invoice_end) > getdate(self.end_date):
|
if self.end_date and getdate(_current_invoice_end) > getdate(self.end_date):
|
||||||
self.current_invoice_end = self.end_date
|
_current_invoice_end = self.end_date
|
||||||
|
|
||||||
|
return _current_invoice_end
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_plans_billing_cycle(billing_cycle_data):
|
def validate_plans_billing_cycle(billing_cycle_data):
|
||||||
@ -488,8 +504,9 @@ class Subscription(Document):
|
|||||||
|
|
||||||
def is_current_invoice_generated(self):
|
def is_current_invoice_generated(self):
|
||||||
invoice = self.get_current_invoice()
|
invoice = self.get_current_invoice()
|
||||||
|
_current_start_date, _current_end_date = self.update_subscription_period(date=add_days(self.current_invoice_end, 1), return_date=True)
|
||||||
|
|
||||||
if invoice and getdate(self.current_invoice_start) <= getdate(invoice.posting_date) <= getdate(self.current_invoice_end):
|
if invoice and getdate(_current_start_date) <= getdate(invoice.posting_date) <= getdate(_current_end_date):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -542,15 +559,15 @@ class Subscription(Document):
|
|||||||
else:
|
else:
|
||||||
self.set_status_grace_period()
|
self.set_status_grace_period()
|
||||||
|
|
||||||
if getdate() > getdate(self.current_invoice_end):
|
|
||||||
self.update_subscription_period(add_days(self.current_invoice_end, 1))
|
|
||||||
|
|
||||||
# Generate invoices periodically even if current invoice are unpaid
|
# Generate invoices periodically even if current invoice are unpaid
|
||||||
if self.generate_new_invoices_past_due_date and not self.is_current_invoice_generated() and (self.is_postpaid_to_invoice()
|
if self.generate_new_invoices_past_due_date and not self.is_current_invoice_generated() and (self.is_postpaid_to_invoice()
|
||||||
or self.is_prepaid_to_invoice()):
|
or self.is_prepaid_to_invoice()):
|
||||||
prorate = frappe.db.get_single_value('Subscription Settings', 'prorate')
|
prorate = frappe.db.get_single_value('Subscription Settings', 'prorate')
|
||||||
self.generate_invoice(prorate)
|
self.generate_invoice(prorate)
|
||||||
|
|
||||||
|
if getdate() > getdate(self.current_invoice_end):
|
||||||
|
self.update_subscription_period(add_days(self.current_invoice_end, 1))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_paid(invoice):
|
def is_paid(invoice):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -18,6 +18,7 @@ from frappe.utils.data import (
|
|||||||
|
|
||||||
from erpnext.accounts.doctype.subscription.subscription import get_prorata_factor
|
from erpnext.accounts.doctype.subscription.subscription import get_prorata_factor
|
||||||
|
|
||||||
|
test_dependencies = ("UOM", "Item Group", "Item")
|
||||||
|
|
||||||
def create_plan():
|
def create_plan():
|
||||||
if not frappe.db.exists('Subscription Plan', '_Test Plan Name'):
|
if not frappe.db.exists('Subscription Plan', '_Test Plan Name'):
|
||||||
@ -68,7 +69,6 @@ def create_plan():
|
|||||||
supplier.insert()
|
supplier.insert()
|
||||||
|
|
||||||
class TestSubscription(unittest.TestCase):
|
class TestSubscription(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
create_plan()
|
create_plan()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user