fix proration logic to reduce possibility of rounding errors
This commit is contained in:
parent
79a01561d5
commit
024c28acf7
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils.data import nowdate, getdate, cint, add_days, date_diff, get_last_day, add_to_date
|
from frappe.utils.data import nowdate, getdate, cint, add_days, date_diff, get_last_day, add_to_date, flt
|
||||||
|
|
||||||
|
|
||||||
class Subscriptions(Document):
|
class Subscriptions(Document):
|
||||||
@ -304,7 +304,7 @@ class Subscriptions(Document):
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif plan_items:
|
elif plan_items:
|
||||||
prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
|
prorate_factor = self.get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
|
||||||
|
|
||||||
item_names = frappe.db.sql(
|
item_names = frappe.db.sql(
|
||||||
'select item as item_code, cost * %s as rate from `tabSubscription Plan` where name in %s',
|
'select item as item_code, cost * %s as rate from `tabSubscription Plan` where name in %s',
|
||||||
@ -420,6 +420,18 @@ class Subscriptions(Document):
|
|||||||
else:
|
else:
|
||||||
frappe.throw(_('You cannot restart a Subscription that is not cancelled.'))
|
frappe.throw(_('You cannot restart a Subscription that is not cancelled.'))
|
||||||
|
|
||||||
|
def get_prorata_factor(self, period_end, period_start):
|
||||||
|
diff = flt(date_diff(nowdate(), period_start) + 1)
|
||||||
|
plan_days = flt(date_diff(period_end, period_start) + 1)
|
||||||
|
prorate_factor = diff / plan_days
|
||||||
|
|
||||||
|
return prorate_factor
|
||||||
|
|
||||||
|
def get_precision(self):
|
||||||
|
invoice = self.get_current_invoice()
|
||||||
|
if invoice:
|
||||||
|
return invoice.precision('grand_total')
|
||||||
|
|
||||||
|
|
||||||
def process_all():
|
def process_all():
|
||||||
"""
|
"""
|
||||||
@ -456,14 +468,6 @@ def process(data):
|
|||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_prorata_factor(period_end, period_start):
|
|
||||||
diff = date_diff(nowdate(), period_start) + 1
|
|
||||||
plan_days = date_diff(period_end, period_start) + 1
|
|
||||||
prorate_factor = diff/plan_days
|
|
||||||
|
|
||||||
return prorate_factor
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def cancel_subscription(name):
|
def cancel_subscription(name):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -6,8 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.accounts.doctype.subscriptions.subscriptions import get_prorata_factor
|
from frappe.utils.data import nowdate, add_days, add_to_date, add_months, date_diff, flt
|
||||||
from frappe.utils.data import nowdate, add_days, add_to_date, add_months, date_diff
|
|
||||||
|
|
||||||
|
|
||||||
def create_plan():
|
def create_plan():
|
||||||
@ -275,6 +274,11 @@ class TestSubscriptions(unittest.TestCase):
|
|||||||
subscription.delete()
|
subscription.delete()
|
||||||
|
|
||||||
def test_subscription_cancellation_invoices(self):
|
def test_subscription_cancellation_invoices(self):
|
||||||
|
settings = frappe.get_single('Subscription Settings')
|
||||||
|
to_prorate = settings.prorate
|
||||||
|
settings.prorate = 1
|
||||||
|
settings.save()
|
||||||
|
|
||||||
subscription = frappe.new_doc('Subscriptions')
|
subscription = frappe.new_doc('Subscriptions')
|
||||||
subscription.subscriber = '_Test Customer'
|
subscription.subscriber = '_Test Customer'
|
||||||
subscription.append('plans', {'plan': '_Test Plan Name'})
|
subscription.append('plans', {'plan': '_Test Plan Name'})
|
||||||
@ -287,18 +291,22 @@ class TestSubscriptions(unittest.TestCase):
|
|||||||
self.assertEqual(len(subscription.invoices), 1)
|
self.assertEqual(len(subscription.invoices), 1)
|
||||||
|
|
||||||
invoice = subscription.get_current_invoice()
|
invoice = subscription.get_current_invoice()
|
||||||
diff = date_diff(nowdate(), subscription.current_invoice_start) + 1
|
diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1)
|
||||||
plan_days = date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1
|
plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1)
|
||||||
prorate_factor = diff/plan_days
|
prorate_factor = flt(diff/plan_days)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start),
|
flt(
|
||||||
prorate_factor
|
subscription.get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start),
|
||||||
|
2),
|
||||||
|
flt(prorate_factor, 2)
|
||||||
)
|
)
|
||||||
self.assertEqual(invoice.grand_total, prorate_factor * 900)
|
self.assertEqual(flt(invoice.grand_total, 2), flt(prorate_factor * 900, 2))
|
||||||
self.assertEqual(subscription.status, 'Canceled')
|
self.assertEqual(subscription.status, 'Canceled')
|
||||||
|
|
||||||
subscription.delete()
|
subscription.delete()
|
||||||
|
settings.prorate = to_prorate
|
||||||
|
settings.save()
|
||||||
|
|
||||||
def test_subscription_cancellation_invoices_with_prorata_false(self):
|
def test_subscription_cancellation_invoices_with_prorata_false(self):
|
||||||
settings = frappe.get_single('Subscription Settings')
|
settings = frappe.get_single('Subscription Settings')
|
||||||
@ -333,11 +341,11 @@ class TestSubscriptions(unittest.TestCase):
|
|||||||
subscription.cancel_subscription()
|
subscription.cancel_subscription()
|
||||||
|
|
||||||
invoice = subscription.get_current_invoice()
|
invoice = subscription.get_current_invoice()
|
||||||
diff = date_diff(nowdate(), subscription.current_invoice_start) + 1
|
diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1)
|
||||||
plan_days = date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1
|
plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1)
|
||||||
prorate_factor = diff/plan_days
|
prorate_factor = flt(diff / plan_days)
|
||||||
|
|
||||||
self.assertEqual(invoice.grand_total, prorate_factor * 900)
|
self.assertEqual(flt(invoice.grand_total, 2), flt(prorate_factor * 900, 2))
|
||||||
|
|
||||||
settings.prorate = to_prorate
|
settings.prorate = to_prorate
|
||||||
settings.save()
|
settings.save()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user