Pricing matrix
This commit is contained in:
@@ -709,25 +709,121 @@ class Component(ModelSQL, ModelView):
|
||||
triggers = fields.One2Many('pricing.trigger','component',"Period rules")
|
||||
pricing_date = fields.Date("Pricing date max")
|
||||
|
||||
def get_rec_name(self, name=None):
|
||||
if self.price_index:
|
||||
return '[' + self.fix_type.name + '] ' + self.price_index.price_index
|
||||
else:
|
||||
return '[' + self.fix_type.name + '] '
|
||||
|
||||
def get_cur(self,name):
|
||||
if self.price_index:
|
||||
PI = Pool().get('price.price')
|
||||
pi = PI(self.price_index)
|
||||
return pi.price_currency
|
||||
|
||||
def get_nbdays(self, name):
|
||||
days = 0
|
||||
if self.triggers:
|
||||
for t in self.triggers:
|
||||
l,l2 = t.getApplicationListDates(self.calendar)
|
||||
days += len(l)
|
||||
return days
|
||||
def get_rec_name(self, name=None):
|
||||
if self.price_index:
|
||||
return '[' + self.fix_type.name + '] ' + self.price_index.price_index
|
||||
if self.price_matrix:
|
||||
return '[' + self.fix_type.name + '] ' + self.price_matrix.name
|
||||
else:
|
||||
return '[' + self.fix_type.name + '] '
|
||||
|
||||
def get_cur(self,name):
|
||||
if self.price_index:
|
||||
PI = Pool().get('price.price')
|
||||
pi = PI(self.price_index)
|
||||
return pi.price_currency
|
||||
if self.price_matrix:
|
||||
return self.price_matrix.currency
|
||||
|
||||
def get_calendar(self):
|
||||
if self.calendar:
|
||||
return self.calendar
|
||||
if self.price_matrix:
|
||||
return self.price_matrix.calendar
|
||||
|
||||
@staticmethod
|
||||
def _record_id(record):
|
||||
return getattr(record, 'id', record)
|
||||
|
||||
@classmethod
|
||||
def _matches_optional_field(cls, matrix_line, field_name, target):
|
||||
value = getattr(matrix_line, field_name, None)
|
||||
if not value:
|
||||
return True, 0
|
||||
if target and cls._record_id(value) == cls._record_id(target):
|
||||
return True, 1
|
||||
return False, 0
|
||||
|
||||
def _matrix_valid_on(self, price_date):
|
||||
if not self.price_matrix:
|
||||
return False
|
||||
if hasattr(price_date, 'date'):
|
||||
price_date = price_date.date()
|
||||
valid_from = getattr(self.price_matrix, 'valid_from', None)
|
||||
valid_to = getattr(self.price_matrix, 'valid_to', None)
|
||||
if valid_from and price_date < valid_from:
|
||||
return False
|
||||
if valid_to and price_date > valid_to:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_matrix_owner_values(self):
|
||||
line = getattr(self, 'line', None) or getattr(self, 'sale_line', None)
|
||||
document = getattr(line, 'purchase', None) or getattr(line, 'sale', None)
|
||||
return {
|
||||
'origin': getattr(document, 'from_location', None),
|
||||
'destination': getattr(document, 'to_location', None),
|
||||
'product': getattr(line, 'product', None),
|
||||
'quality': getattr(line, 'quality', None),
|
||||
}
|
||||
|
||||
def _get_matrix_line(self):
|
||||
MatrixLine = Pool().get('price.matrix.line')
|
||||
lines = MatrixLine.search([('matrix', '=', self.price_matrix.id)])
|
||||
owner_values = self._get_matrix_owner_values()
|
||||
best_line = None
|
||||
best_score = -1
|
||||
for line in lines:
|
||||
score = 0
|
||||
for field_name, target in owner_values.items():
|
||||
matches, field_score = self._matches_optional_field(
|
||||
line, field_name, target)
|
||||
if not matches:
|
||||
break
|
||||
score += field_score
|
||||
else:
|
||||
if score > best_score:
|
||||
best_line = line
|
||||
best_score = score
|
||||
return best_line
|
||||
|
||||
def _convert_matrix_price(self, price, unit, currency):
|
||||
price_qt = Decimal(str(price or 0))
|
||||
matrix_unit = getattr(self.price_matrix, 'unit', None)
|
||||
matrix_currency = getattr(self.price_matrix, 'currency', None)
|
||||
if matrix_unit and unit:
|
||||
Uom = Pool().get('product.uom')
|
||||
price_qt *= Decimal(str(
|
||||
Uom.compute_qty(unit, float(1), matrix_unit)))
|
||||
if matrix_currency and currency and currency != matrix_currency:
|
||||
Currency = Pool().get('currency.currency')
|
||||
rates = Currency._get_rate([matrix_currency])
|
||||
rate = rates.get(matrix_currency.id)
|
||||
if rate:
|
||||
price_qt *= Decimal(str(rate))
|
||||
return round(price_qt, 4)
|
||||
|
||||
def get_price(self, price_date, unit, currency, last=False):
|
||||
if self.price_source_type == 'curve' and self.price_index:
|
||||
PI = Pool().get('price.price')
|
||||
pi = PI(self.price_index)
|
||||
return pi.get_price(price_date, unit, currency, last)
|
||||
if self.price_source_type == 'matrix' and self.price_matrix:
|
||||
if not self._matrix_valid_on(price_date):
|
||||
return Decimal(0)
|
||||
line = self._get_matrix_line()
|
||||
if line:
|
||||
return self._convert_matrix_price(
|
||||
line.price_value, unit, currency)
|
||||
return Decimal(0)
|
||||
|
||||
def get_nbdays(self, name):
|
||||
days = 0
|
||||
if self.triggers:
|
||||
for t in self.triggers:
|
||||
l,l2 = t.getApplicationListDates(self.get_calendar())
|
||||
days += len(l)
|
||||
return days
|
||||
|
||||
@classmethod
|
||||
def delete(cls, components):
|
||||
@@ -1171,17 +1267,20 @@ class Trigger(ModelSQL,ModelView):
|
||||
current_date += datetime.timedelta(days=1)
|
||||
return l, lprice
|
||||
|
||||
def getprice(self,current_date):
|
||||
PI = Pool().get('price.price')
|
||||
PC = Pool().get('pricing.component')
|
||||
pc = PC(self.component)
|
||||
pi = PI(pc.price_index)
|
||||
val = {}
|
||||
val['date'] = current_date
|
||||
val['price'] = pi.get_price(current_date,pc.line.unit if pc.line else pc.sale_line.unit,pc.line.currency if pc.line else pc.sale_line.currency,self.last)
|
||||
val['avg'] = val['price']
|
||||
val['avg_minus_1'] = val['price']
|
||||
val['isAvg'] = self.average
|
||||
def getprice(self,current_date):
|
||||
PC = Pool().get('pricing.component')
|
||||
pc = PC(self.component)
|
||||
val = {}
|
||||
val['date'] = current_date
|
||||
line = pc.line if pc.line else pc.sale_line
|
||||
val['price'] = pc.get_price(
|
||||
current_date,
|
||||
line.unit,
|
||||
line.currency,
|
||||
self.last)
|
||||
val['avg'] = val['price']
|
||||
val['avg_minus_1'] = val['price']
|
||||
val['isAvg'] = self.average
|
||||
return val
|
||||
|
||||
class Period(ModelSQL,ModelView):
|
||||
|
||||
Reference in New Issue
Block a user