On 16/07/13 12:12 +0300, Giedrius Slavinskas wrote: > 2013/7/15 Cédric Krier <cedric.kr...@b2ck.com> > > > On 15/07/13 10:25 +0300, Giedrius Slavinskas wrote: > > So let's introduce it. > > > > > > class Measure(namedtuple('Measure', ['quantity', 'unit'])): > > __slots__ = () > > > > def convert_to(self, uom, round=True): > > Uom = Pool().get('product.uom') > > return Measure(Uom.compute_qty(self.unit, self.quantity, uom, > > round=round), uom) > > > > > > Which will make: > > > > Measure(1000, gr).convert_to(kg) == Measure(1, kg) > > > I suggest more intuitive interface/naming. Here is just the idea, > nothing mean to work. > > class Quantity(namedtuple('Quantity', ['units', 'uom'])):
I don't understand why using "units" ? For me, it sounds wrong. unit is what is called uom == Unit of Measure. Quantity sounds like it is a scalar, when measure sounds better especially because we already use "Unit of Measure". > __slots__ = () > > def convert(self, to_uom, round=False): # round=False is more common > usage Aggre about the round because it should be done most of the time at the end (see below). But the name convert_to is more explicite. > Uom = Pool().get('product.uom') > return Quantity(Uom.compute_qty(self.uom, self.units, to_uom, > round=round), to_uom) > > def __add__(self, other): # same for __sub__, __mul__, etc > if isinstance(other, Quantity): > other = other.convert(self.uom, round=False).units > return Quantity(self.units + other, self.uom) This makes the addition not commutative. > def __eq__(self, other): # same for __le__, __gt__, etc > if isinstance(other, Quantity): > other = other.convert(self.uom, round=False).units > return self.units == other > > def round(self): > # round self.units by self.uom.digits > > Then such class could be used as field on model: > > class StockMove: > units = fields.Float("Quantity") > uom = fields.Many2One("product.uom", "Uom") > > # changing the quantity it changes units and uom and vice versa. > # This field should not hold values, but only references. > quantity = fields.Function(Quantity('units', 'uom')) > > internal_units = fields.Float('Internal Quantity', readonly=True, > required=True) > internal_quantity = fields.Function(Quantity('internal_units', > 'product.default_uom')) > > def do_something(self, moves): > """Usage example""" > for move in moves: > self.quantity += move.quantity * 2 This must not be a function field but a property or a descriptor. The descriptor could be set with a classmethod like: measure = Measure.descriptor('quantity', 'unit') The setter should take care of rounding the quantity before storing it on the instance. -- Cédric Krier B2CK SPRL Rue de Rotterdam, 4 4000 Liège Belgium Tel: +32 472 54 46 59 Email/Jabber: cedric.kr...@b2ck.com Website: http://www.b2ck.com/
pgpmS2016I0HA.pgp
Description: PGP signature