Skip to content

Commit

Permalink
[Issue #174] refactored the get_price function of the product
Browse files Browse the repository at this point in the history
  • Loading branch information
scaphilo committed Sep 4, 2018
1 parent 2e1078c commit aabe8b4
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 31 deletions.
11 changes: 4 additions & 7 deletions koalixcrm/crm/product/currency_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@
class CurrencyTransform(models.Model):
from_currency = models.ForeignKey('Currency',
verbose_name=_("From Currency"),
related_name="db_reltransfromfromcurrency")
related_name="db_reltransformfromcurrency")
to_currency = models.ForeignKey('Currency',
verbose_name=_("To Currency"),
related_name="db_reltransfromtocurrency")
related_name="db_reltransformtocurrency")
product = models.ForeignKey('Product',
verbose_name=_("Product"))
factor = models.IntegerField(verbose_name=_("Factor between From and To Currency"),
blank=True,
null=True)

def transform(self, currency):
if self.from_currency == currency:
return self.to_currency
else:
return None
def get_transform_factor(self):
return self.factor

def __str__(self):
return "From " + self.from_currency.short_name + " to " + self.to_currency.short_name
Expand Down
3 changes: 3 additions & 0 deletions koalixcrm/crm/product/customer_group_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def transform(self, customer_group):
else:
return None

def get_transform_factor(self):
return self.factor

def __str__(self):
return "From " + self.from_customer_group.name + " to " + self.to_customer_group.name

Expand Down
64 changes: 45 additions & 19 deletions koalixcrm/crm/product/price.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,42 +71,68 @@ def is_unit_criteria_fulfilled(self, unit):
else:
return False

def get_currency_transform_factor(self, currency):
def is_date_in_range(self, date):
if (self.valid_from <= date) and (date <= self.valid_until):
return True
else:
return False

def get_currency_transform_factor(self, currency, product):
"""check currency conditions and factor"""
if self.currency == currency:
currency_factor = 1
elif CurrencyTransform.currency_transfrom_exists(from_currency=self.currency,
to_currency=currency):
currency_factor = CurrencyTransform.currency_transfrom(from_currency=self.currency,
to_currency=currency)
else:
currency_factor = 0
currency_transform = CurrencyTransform.objects.get(from_currency=self.currency,
to_currency=currency,
product=product)
if currency_transform:
currency_transform.get_transfrom_factor()
else:
currency_factor = 0
return currency_factor

def get_unit_transform_factor(self, unit):
def get_unit_transform_factor(self, unit, product):
"""check unit conditions and factor"""
if self.unit == unit:
unit_factor = 1
elif UnitTransform.unit_transfrom_exists(from_unit=self.unit,
to_unit=unit):
unit_factor = UnitTransform.unit_transfrom(from_unit=self.unit,
to_unit=unit)
else:
unit_factor = 0
unit_transform = UnitTransform.objects.get(from_unit=self.unit,
to_unit=unit,
product=product)
if unit_transform:
unit_transform.get_transfrom_factor()
else:
unit_factor = 0
return unit_factor

def get_customer_group_transform_factor(self, customer):
"""check currency conditions and factor"""
def get_customer_group_transform_factor(self, customer, product):
"""The function searches through all customer_groups in which the customer is member of
from these customer_groups, the function returns the customer_group with the perfect match
or it returns the factor with the lowest transform factor
Args:
koalixcrm.crm.contact.customer customer
koalixcrm.crm.product.product product
Returns:
Decimal factor
Raises:
No exceptions planned"""
customer_groups = CustomerGroup.objects.filter(customer=customer)
customer_group_factor = 0
for customer_group in customer_groups:
if self.customer_group == customer_group:
customer_group_factor = 1
elif CustomerGroupTransform.group_transfrom_exists(from_group=self.customer_group,
to_group=customer_group):
customer_group_factor = CustomerGroupTransform.group_transform(from_group=self.customer_group,
to_group=customer_group)
"""Stop for loop when a perfect match is found"""
break
else:
customer_group_factor = 0
customer_group = CustomerGroupTransform.objects.get(from_customer_group=self.customer_group,
to_customer_group=customer_group,
product=product)
if customer_group:
if customer_group_factor > customer_group.get_transfrom_factor():
customer_group_factor = customer_group.get_transfrom_factor()
return customer_group_factor

def matches_date_unit_customer_group_currency(self, date, unit, customer_group, currency):
Expand Down
25 changes: 22 additions & 3 deletions koalixcrm/crm/product/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,35 @@ class Product(models.Model):
blank="True")

def get_price(self, date, unit, customer, currency):
"""The function searches for a valid price and returns the price of the product as a decimal value.
Args:
koalixcrm.crm.contact.customer customer
koalixcrm.crm.product.unit unit
koalixcrm.crm.product.currency currency
datetime.date date
Returns:
when a match is found: dict customer_group_factors name=customer_group, value=factor
when no match is found: customer_group_factors is None
Raises:
In case the algorithm does not find a valid product price, the function raises a
NoPriceFound Exception"""
prices = Price.objects.filter(product=self.id)
valid_prices = list()
for price in list(prices):
currency_factor = price.get_currency_transform_factor(price)
unit_factor = price.get_unit_transform_factor(price)
group_factor = price.get_customer_group_transform_factor(customer)
group_factors = price.get_customer_group_transform_factor(customer)
date_in_range = price.is_date_in_range(date)
if currency_factor != 0 and \
group_factor != 0 and \
group_factors != 0 and \
date_in_range and \
unit_factor != 0:
valid_prices.append(price)

transformed_price = price.price*group_factors*unit_factor*unit_factor
valid_prices.append(transformed_price)
if len(valid_prices) > 0:
lowest_price = valid_prices[0]
for price in valid_prices:
Expand Down
3 changes: 3 additions & 0 deletions koalixcrm/crm/product/unit_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def transform(self, unit):
else:
return None

def get_transform_factor(self):
return self.factor

def __str__(self):
return "From " + self.from_unit.short_name + " to " + self.to_unit.short_name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ class EstimationOfResourceConsumption(models.Model):
null=True)

def calculated_costs(self):
res
currency = self.task.project.default_currency
unit = self.resource_type.default_unit

self.resource_type.get_costs(self, date, unit, customer, currency)

def __str__(self):
return _("Estimation of Resource Consumption") + ": " + str(self.id)
Expand Down
4 changes: 4 additions & 0 deletions koalixcrm/crm/reporting/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class Project(models.Model):
verbose_name=_("Default Template Set"),
null=True,
blank=True)
default_currency = models.ForeignKey("Currency",
verbose_name=_("Default Currency"),
null=False,
blank=False)
date_of_creation = models.DateTimeField(verbose_name=_("Created at"),
auto_now_add=True)
last_modification = models.DateTimeField(verbose_name=_("Last modified"),
Expand Down
1 change: 0 additions & 1 deletion koalixcrm/crm/tests/test_task_planned_effort.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def setUp(self):

@pytest.mark.back_end_tests
def test_planned_effort(self):
datetime_now = make_date_utc(datetime.datetime(2024, 1, 1, 0, 00))
self.assertEqual(
(self.test_1st_task.planned_duration()).__str__(), "60")
self.assertEqual(
Expand Down

0 comments on commit aabe8b4

Please sign in to comment.