# Cross UOM categories

**URL:** <https://discuss.tryton.org/t/cross-uom-categories/2790>\
**Category:** Feature\
**Created:** [May 28, 2020, 2:02pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790 "2020-05-28T14:02:34Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxx](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/maxx/32/2320_2.png) [@maxx](https://discuss.tryton.org/u/maxx)\
**Post date:** [May 28, 2020, 2:02pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/1 "2020-05-28T14:02:34Z")

</div>

## Rational

Some uom are a combination of multiple uoms. Defining this combination would allow to calculate a variable depending of the uom categories implied in the combination.  
Some examples: Speed = length /time (km/h), Density = weight/volume (Kg/m³) or even existing Tryton uom categories : Surface = length \* length , Volume = Surface \* length

## Proposal

Defining a new model “cross\_uom” that would define uom categories “linked” together. Considering uom\_category\_1 \* uom\_category\_2 = uom\_category\_result \* coefficient(1 by default).  
Each uom\_category will use by default the base uom.  
Combination of the 3 uom\_categories would be unique.

- uom\_category\_1
- uom\_category\_2
- operation : \* or / or ..
- uom\_category\_result
- coefficient : default 1

## Implementation

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [May 28, 2020, 3:10pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/2 "2020-05-28T15:10:49Z")

</div>

I think it will be good to define how the API to make conversion will look.

> [@maxx](#):
>
> Combination of the 3 uom\_categories would be unique.

I think this can be achieved by storing in a column the ordered list of the three category ids.

---

<div class="post-metadata">

**Author:** ![pokoli](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/pokoli/32/22_2.png) [@pokoli](https://discuss.tryton.org/u/pokoli)\
**Post date:** [May 29, 2020, 7:02am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/3 "2020-05-29T07:02:04Z")

</div>

I think we need to store which units are used to compute the base unit. For example, in density we use Kg/m3, which mixes Kg and m3.

So if we have a product of 100g, witha a volume of 0.1 liters it does not make sense to expres density as g/liter. We need to convert both units first to kg and m3 and then do the operation between them.

As there are combinations that use division and others multiplication I think we should also store the operation used to produce the combined unit.

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [May 29, 2020, 7:12am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/4 "2020-05-29T07:12:28Z")

</div>

> [@pokoli](#):
>
> I think we need to store which units are used to compute the base unit.

It is not needed as we already the base unit defined as the unit with factor 1.

---

<div class="post-metadata">

**Author:** ![maxx](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/maxx/32/2320_2.png) [@maxx](https://discuss.tryton.org/u/maxx)\
**Post date:** [May 29, 2020, 7:48am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/5 "2020-05-29T07:48:55Z")

</div>

> [@ced](#):
>
> It is not needed as we already the base unit defined as the unit with factor 1.

For “composed” uom, we will have to split to convert from base unit ?  
I mean, i’ll create a new uom category “Density”, i’ll add an uom “gr/mm³” and define as base unit.(factor 1). To do calculations with cross uom, i’ll have to split “gr/mm³” in “gr” and "mm³) to apply factor on Weight and Volume following their base unit ?  
Or by default, as Density is a cross unit, their will be a base uom which will be base uom from both uom composing cross uom… So Density is Weight/Volume . Default will be Kg/l ?

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [May 29, 2020, 8:01am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/6 "2020-05-29T08:01:05Z")

</div>

> [@maxx](#):
>
> For “composed” uom, we will have to split to convert from base unit ?

Split what?

> [@maxx](#):
>
> To do calculations with cross uom, i’ll have to split “gr/mm³” in “gr” and "mm³) to apply factor on Weight and Volume following their base unit ?

No you do not need because the factor will be in the `coefficient`.

---

<div class="post-metadata">

**Author:** ![maxx](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/maxx/32/2320_2.png) [@maxx](https://discuss.tryton.org/u/maxx)\
**Post date:** [May 29, 2020, 12:02pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/7 "2020-05-29T12:02:23Z")

</div>

> [@ced](#):
>
> No you do not need because the factor will be in the `coefficient` .

And what about rate and factor when defining uom ?  
For Density, 1 Kg/l = 1gr/Cm³ … so in cross uom … coefficient will be 1 and i could have multiple uom as base unit in the same category ?  
And if i prefer to have a default uom for Density in gr/mm³ , i define this uom with a factor/rate=1 to be the base unit and in cross-uom, coefficient will be 0,001 then.

So method to calculate would be:  
def calculate (uom1, value1, uom2, value2):  
((uom1.factor \* value1) [operation (\* or /)] (uom2.factor \* value2)) \* coefficient = result in uom3.base  
but this calculation should evolve following uom passed in arguments:  
A/B = C is standard case, but we could have A,C to find B, so it will be A/C=B and third case with C and B as parameters : C \* B = A (operation will be inversed)

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [May 29, 2020, 12:22pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/8 "2020-05-29T12:22:28Z")

</div>

> [@maxx](#):
>
> i could have multiple uom as base unit in the same category ?

Yes you can if they express the same quantity.

> [@maxx](#):
>
> but this calculation should evolve following uom passed in arguments:

For me, the API should be:

```auto
def convert(value1, uom1, value2, uom2, to_uom):

```

So you will have the target uom from which you can apply the conversion factor against its base unit.

---

<div class="post-metadata">

**Author:** ![maxx](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/maxx/32/2320_2.png) [@maxx](https://discuss.tryton.org/u/maxx)\
**Post date:** [June 16, 2020, 9:43am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/9 "2020-06-16T09:43:21Z")

</div>

> [@ced](#):
>
> I think this can be achieved by storing in a column the ordered list of the three category ids.

Can’t i use the Unique sql constraint on the three category ids instead of a column ?

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [June 16, 2020, 9:47am UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/10 "2020-06-16T09:47:58Z")

</div>

> [@maxx](#):
>
> Can’t i use the Unique sql constraint on the three category ids instead of a column ?

Then it won’t check against different order.

---

<div class="post-metadata">

**Author:** ![maxx](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/maxx/32/2320_2.png) [@maxx](https://discuss.tryton.org/u/maxx)\
**Post date:** [June 16, 2020, 1:48pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/11 "2020-06-16T13:48:58Z")

</div>

> [@ced](#):
>
> Then it won’t check against different order.

Ok, so it would be:  
unique\_key = fields.Function(fields.Char(‘Unique Key’), ‘on\_change\_with\_unique\_key’)  
unique\_key\_storage = fields.Char(“Unique Key”)

unique\_key field would be a join of each uom category id… ex: id1, id2, id3  
I add a unique constraint on unique\_key\_storage. And when saving i update unique\_key\_storage = unique\_key  
Is it the good way ? Or too complicated ?

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [June 16, 2020, 1:54pm UTC](https://discuss.tryton.org/t/cross-uom-categories/2790/12 "2020-06-16T13:54:09Z")

</div>

I think you do not need to create a Function field `unique_key` but simply ensure that `unique_key_storage` is updated on each `create` and `write` calls.
