On 16/07/13 12:12 +0300, Giedrius Slavinskas wrote: > 2013/7/15 Cédric Krier <[email protected]> > > > 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: [email protected]
Website: http://www.b2ck.com/
pgpmS2016I0HA.pgp
Description: PGP signature
