Skip to content

Commit 21b220d

Browse files
committed
[FIX] round in all cases to the required decimal precision
1 parent a8c15b6 commit 21b220d

5 files changed

Lines changed: 60 additions & 25 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "odoo-rapid-quant"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
license = "LGPL-3.0-or-later"
55
edition = "2024"
66
rust-version = "1.85"

src/dialect/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ use crate::{
1313

1414
pub mod v15;
1515

16+
pub fn dp_from_rounding(rounding: Decimal) -> u32 {
17+
if rounding >= Decimal::ONE {
18+
0
19+
} else {
20+
rounding.scale()
21+
}
22+
}
23+
1624
#[async_trait]
1725
pub trait OdooAdapter: Send + Sync {
1826
fn major(&self) -> OdooVersion;

src/dialect/v15.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rust_decimal::{Decimal, RoundingStrategy};
77
use sqlx::{PgPool, QueryBuilder};
88

99
use crate::{
10-
dialect::OdooAdapter,
10+
dialect::{OdooAdapter, dp_from_rounding},
1111
odoo::OdooVersion,
1212
product::{Product, ProductId, Quant},
1313
warehouse::Warehouse,
@@ -80,7 +80,7 @@ impl OdooAdapter for Adapter {
8080
.fetch(pool);
8181

8282
while let Some((product_id, rounding)) = simple_stream.try_next().await? {
83-
let _ = catalogue.insert(product_id, Product::Simple(rounding.scale()));
83+
let _ = catalogue.insert(product_id, Product::Simple(dp_from_rounding(rounding)));
8484
let _ = graph.add_node(product_id);
8585
}
8686

@@ -105,7 +105,8 @@ impl OdooAdapter for Adapter {
105105
.build_query_as::<(ProductId, Decimal)>()
106106
.fetch(pool);
107107
while let Some((product_id, rounding)) = stream.try_next().await? {
108-
let _ = catalogue.insert(product_id, Product::Commingled(rounding.scale()));
108+
let _ =
109+
catalogue.insert(product_id, Product::Commingled(dp_from_rounding(rounding)));
109110
let _ = graph.add_node(product_id);
110111
}
111112
}
@@ -146,9 +147,8 @@ impl OdooAdapter for Adapter {
146147
.fetch(pool);
147148

148149
while let Some((product_id, bom_type, quantity, rounding)) = stream.try_next().await? {
149-
let dp = rounding.scale();
150-
let quantity =
151-
quantity.round_dp_with_strategy(dp, RoundingStrategy::MidpointAwayFromZero);
150+
let dp = dp_from_rounding(rounding);
151+
let quantity = quantity.round_dp_with_strategy(dp, RoundingStrategy::ToZero);
152152
let product = match bom_type.as_str() {
153153
"phantom" => Product::MrpPhantom(quantity, dp),
154154
"normal" => Product::MrpNormal(quantity, dp),
@@ -207,8 +207,8 @@ impl OdooAdapter for Adapter {
207207
while let Some((parent, child, child_qty, rounding)) = stream.try_next().await? {
208208
if graph.contains_node(parent) && graph.contains_node(child) {
209209
let child_qty = child_qty.round_dp_with_strategy(
210-
rounding.scale(),
211-
RoundingStrategy::MidpointAwayFromZero,
210+
dp_from_rounding(rounding),
211+
RoundingStrategy::ToZero,
212212
);
213213
let _ = graph.add_edge(child, parent, child_qty);
214214
}

src/product.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,23 @@ impl Graph {
373373
)
374374
});
375375
if info.is_simple() {
376+
let dp = info.dp();
376377
let mut avail = Availability::default();
377378

378379
if let Some(quant) = raw_quants.get(&product) {
379-
avail.quantity = quant.quantity;
380-
avail.reserved = quant.reserved;
381-
382-
avail.incoming = quant.incoming;
383-
avail.outgoing = quant.outgoing;
380+
avail.quantity = quant
381+
.quantity
382+
.round_dp_with_strategy(dp, RoundingStrategy::ToZero);
383+
avail.reserved = quant
384+
.reserved
385+
.round_dp_with_strategy(dp, RoundingStrategy::ToZero);
386+
387+
avail.incoming = quant
388+
.incoming
389+
.round_dp_with_strategy(dp, RoundingStrategy::ToZero);
390+
avail.outgoing = quant
391+
.outgoing
392+
.round_dp_with_strategy(dp, RoundingStrategy::ToZero);
384393
// Required to seed the buildable for future things
385394
// Realistically this isn't actually helpful as a figure for a simple, but this
386395
// is the least impactful solution here
@@ -403,23 +412,41 @@ impl Graph {
403412
for edge in graph.edges_directed(product, petgraph::Incoming) {
404413
let (dependency, required_qty) = (edge.source(), *edge.weight());
405414
if let Some(dependency_stock) = stock_cache.get(&dependency) {
406-
// only do this work if we need to
407-
quantity.push(dependency_stock.quantity / required_qty);
408-
reserved.push(dependency_stock.reserved / required_qty);
409-
410-
incoming.push(dependency_stock.incoming / required_qty);
411-
outgoing.push(dependency_stock.outgoing / required_qty);
412-
413-
free_imm.push(dependency_stock.free_immediately() / required_qty);
414-
virtual_avail.push(dependency_stock.virtual_available() / required_qty);
415-
416415
let dependency_dp = catalogue.get(&product).unwrap_or_else(|| {
417416
panic!(
418417
"Somehow we have a product in the graph not in the catalogue?!: {:?}",
419418
product
420419
)
421420
}).dp();
422421

422+
// only do this work if we need to
423+
quantity.push(
424+
(dependency_stock.quantity / required_qty)
425+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
426+
);
427+
reserved.push(
428+
(dependency_stock.reserved / required_qty)
429+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
430+
);
431+
432+
incoming.push(
433+
(dependency_stock.incoming / required_qty)
434+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
435+
);
436+
outgoing.push(
437+
(dependency_stock.outgoing / required_qty)
438+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
439+
);
440+
441+
free_imm.push(
442+
(dependency_stock.free_immediately() / required_qty)
443+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
444+
);
445+
virtual_avail.push(
446+
(dependency_stock.virtual_available() / required_qty)
447+
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),
448+
);
449+
423450
buildable.push(
424451
(dependency_stock.buildable / required_qty)
425452
.round_dp_with_strategy(dependency_dp, RoundingStrategy::ToZero),

0 commit comments

Comments
 (0)