Skip to content

Commit 08a44e3

Browse files
committed
Use integers for packages.totalVolumeUnits(). Fixes #5002.
1 parent f033638 commit 08a44e3

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\Migrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
final class Version20250522125927 extends AbstractMigration
11+
{
12+
public function getDescription(): string
13+
{
14+
return 'Use integers for "packages.totalVolumeUnits()" pricing expressions using "in" operator.';
15+
}
16+
17+
public function up(Schema $schema): void
18+
{
19+
$stmt = $this->connection->prepare('SELECT id, expression FROM pricing_rule');
20+
21+
$result = $stmt->execute();
22+
while ($pricingRule = $result->fetchAssociative()) {
23+
24+
if (1 === preg_match('/packages\.totalVolumeUnits\(\) in ([0-9\.]+)/', $pricingRule['expression'], $matches)) {
25+
26+
$range = $matches[1];
27+
28+
if (1 === preg_match('/([0-9\.]+)\.\.([0-9\.]+)/', $range, $rangeMatches)) {
29+
30+
[ $whole, $start, $end ] = $rangeMatches;
31+
32+
$hasFloat = false;
33+
34+
if (false !== strpos($start, '.')) {
35+
$hasFloat = true;
36+
$start = (int) round((float) $start, 0, PHP_ROUND_HALF_ODD);
37+
}
38+
39+
if (false !== strpos($end, '.')) {
40+
$hasFloat = true;
41+
$end = (int) round((float) $end, 0, PHP_ROUND_HALF_ODD);
42+
}
43+
44+
if ($hasFloat) {
45+
$expression = str_replace($matches[0], sprintf('packages.totalVolumeUnits() in %d..%d', $start, $end), $pricingRule['expression']);
46+
47+
$this->addSql('UPDATE pricing_rule SET expression = :expression WHERE id = :id', [
48+
'expression' => $expression,
49+
'id' => $pricingRule['id']
50+
]);
51+
}
52+
}
53+
}
54+
}
55+
56+
}
57+
58+
public function down(Schema $schema): void
59+
{
60+
$this->throwIrreversibleMigrationException();
61+
}
62+
}

js/app/delivery/pricing/components/RulePickerLine/index.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ const formatValue = (value, type) => {
6262
return numbro.unformat(value) * (isK(type) ? 1000 : 1)
6363
}
6464

65+
const getStepForType = (type) => {
66+
67+
// As it returns float, it will never work when comparing to floats
68+
// https://github.com/coopcycle/coopcycle-web/issues/5002
69+
if (type === 'packages.totalVolumeUnits()') {
70+
return '1';
71+
}
72+
73+
return '0.1';
74+
}
75+
6576
class RulePickerLine extends React.Component {
6677

6778
constructor (props) {
@@ -237,10 +248,10 @@ class RulePickerLine extends React.Component {
237248
return (
238249
<div className="d-flex justify-content-between">
239250
<div className="mr-2">
240-
<input className="form-control input-sm" value={ (this.state.value[0] / (isK(this.state.type) ? 1000 : 1)) } onChange={this.handleFirstBoundChange} type="number" min="0" required step="0.1"></input>
251+
<input className="form-control input-sm" value={ (this.state.value[0] / (isK(this.state.type) ? 1000 : 1)) } onChange={this.handleFirstBoundChange} type="number" min="0" required step={ getStepForType(this.state.type) }></input>
241252
</div>
242253
<div>
243-
<input className="form-control input-sm" value={ (this.state.value[1] / (isK(this.state.type) ? 1000 : 1)) } onChange={this.handleSecondBoundChange} type="number" min="0" required step="0.1"></input>
254+
<input className="form-control input-sm" value={ (this.state.value[1] / (isK(this.state.type) ? 1000 : 1)) } onChange={this.handleSecondBoundChange} type="number" min="0" required step={ getStepForType(this.state.type) }></input>
244255
</div>
245256
</div>
246257
)

0 commit comments

Comments
 (0)