Skip to content

Commit 9db5c5e

Browse files
feat: 5553 - add prices for category products (#6552)
* feat: 5553 - add prices for category products New files: * `price_category_input_page.dart`: Page that lets the user type in and select a single category for prices. * `price_per_extension.dart`: Extension for PricePer. Impacted files: * `app_en.arb`: added 4 labels related to category and prices * `app_fr.arb`: added 4 labels related to category and prices * `background_task_add_other_price.dart`: added parameters related to category prices * `background_task_add_price.dart`: added parameters related to category prices * `background_task_price.dart`: added parameters related to category prices * `price_add_product_card.dart`: added an "add category product" button * `price_amount_card.dart`: added a DropDownButton for "price per" for category product * `price_amount_model.dart`: taken category prices into consideration * `price_existing_amount_card.dart`: unrelated localization * `price_meta_product.dart`: added a new meta product, related to category * `price_model.dart`: added parameters related to category prices * `smooth_autocomplete_text_field.dart`: added an "onSelected" optional parameter, in order to be able to select immediately a suggestion * `smooth_dropdown.dart`: added an "isExpanded" optional parameter, in order to match the screen width * minor refactoring and localizations Impacted files: * `app_en.arb`: additional translations for "price per" * `app_fr.arb`: additional translations for "price per" * `price_existing_amount_field.dart`: localization * `price_meta_product.dart`: minor refactoring * `price_per_extension.dart`: additional translations for "price per" * reformatting * added origins and prepared code for labels Impacted files: * `app_en.arb`: improved a label and added 3 labels * `app_fr.arb`: improved a label and added 3 labels * `background_task_add_other_price.dart`: now setting origins and labels * `background_task_add_price.dart`: now setting origins and labels * `background_task_price.dart`: now setting origins and labels * `price_add_product_card.dart`: refactored as we now set origins too (in addition to just category) * `price_category_input_page.dart`: refactored as we now set origins too (in addition to just category) * `price_existing_amount_card.dart`: display origins too * `price_meta_product.dart`: now setting and displaying origins too * `price_model.dart`: we now set origins too, and prepared code for labels when ready on the "prices" side * `price_product_list_tile.dart`: now displaying origins too * someone moved a file and that's not nice ;) * explicit 1 line for autocomplete
1 parent 12c2569 commit 9db5c5e

17 files changed

+646
-20
lines changed

packages/smooth_app/lib/background/background_task_add_other_price.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class BackgroundTaskAddOtherPrice extends BackgroundTaskPrice {
2323
required super.locationOSMType,
2424
// multi
2525
required super.barcodes,
26+
required super.categories,
27+
required super.origins,
28+
required super.labels,
29+
required super.pricePers,
2630
required super.pricesAreDiscounted,
2731
required super.prices,
2832
required super.pricesWithoutDiscount,
@@ -54,6 +58,10 @@ class BackgroundTaskAddOtherPrice extends BackgroundTaskPrice {
5458
required final int locationOSMId,
5559
required final LocationOSMType locationOSMType,
5660
required final List<String> barcodes,
61+
required final List<String> categories,
62+
required final List<List<String>> origins,
63+
required final List<List<String>> labels,
64+
required final List<String> pricePers,
5765
required final List<bool> pricesAreDiscounted,
5866
required final List<double> prices,
5967
required final List<double?> pricesWithoutDiscount,
@@ -68,6 +76,10 @@ class BackgroundTaskAddOtherPrice extends BackgroundTaskPrice {
6876
locationOSMId: locationOSMId,
6977
locationOSMType: locationOSMType,
7078
barcodes: barcodes,
79+
categories: categories,
80+
origins: origins,
81+
labels: labels,
82+
pricePers: pricePers,
7183
pricesAreDiscounted: pricesAreDiscounted,
7284
prices: prices,
7385
pricesWithoutDiscount: pricesWithoutDiscount,
@@ -91,6 +103,10 @@ class BackgroundTaskAddOtherPrice extends BackgroundTaskPrice {
91103
required final int locationOSMId,
92104
required final LocationOSMType locationOSMType,
93105
required final List<String> barcodes,
106+
required final List<String> categories,
107+
required final List<List<String>> origins,
108+
required final List<List<String>> labels,
109+
required final List<String> pricePers,
94110
required final List<bool> pricesAreDiscounted,
95111
required final List<double> prices,
96112
required final List<double?> pricesWithoutDiscount,
@@ -104,6 +120,10 @@ class BackgroundTaskAddOtherPrice extends BackgroundTaskPrice {
104120
locationOSMId: locationOSMId,
105121
locationOSMType: locationOSMType,
106122
barcodes: barcodes,
123+
categories: categories,
124+
origins: origins,
125+
labels: labels,
126+
pricePers: pricePers,
107127
pricesAreDiscounted: pricesAreDiscounted,
108128
prices: prices,
109129
pricesWithoutDiscount: pricesWithoutDiscount,

packages/smooth_app/lib/background/background_task_add_price.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class BackgroundTaskAddPrice extends BackgroundTaskPrice {
3737
required super.locationOSMType,
3838
// multi
3939
required super.barcodes,
40+
required super.categories,
41+
required super.origins,
42+
required super.labels,
43+
required super.pricePers,
4044
required super.pricesAreDiscounted,
4145
required super.prices,
4246
required super.pricesWithoutDiscount,
@@ -98,6 +102,10 @@ class BackgroundTaskAddPrice extends BackgroundTaskPrice {
98102
required final int locationOSMId,
99103
required final LocationOSMType locationOSMType,
100104
required final List<String> barcodes,
105+
required final List<String> categories,
106+
required final List<List<String>> origins,
107+
required final List<List<String>> labels,
108+
required final List<String> pricePers,
101109
required final List<bool> pricesAreDiscounted,
102110
required final List<double> prices,
103111
required final List<double?> pricesWithoutDiscount,
@@ -113,6 +121,10 @@ class BackgroundTaskAddPrice extends BackgroundTaskPrice {
113121
locationOSMId: locationOSMId,
114122
locationOSMType: locationOSMType,
115123
barcodes: barcodes,
124+
categories: categories,
125+
origins: origins,
126+
labels: labels,
127+
pricePers: pricePers,
116128
pricesAreDiscounted: pricesAreDiscounted,
117129
prices: prices,
118130
pricesWithoutDiscount: pricesWithoutDiscount,
@@ -137,6 +149,10 @@ class BackgroundTaskAddPrice extends BackgroundTaskPrice {
137149
required final int locationOSMId,
138150
required final LocationOSMType locationOSMType,
139151
required final List<String> barcodes,
152+
required final List<String> categories,
153+
required final List<List<String>> origins,
154+
required final List<List<String>> labels,
155+
required final List<String> pricePers,
140156
required final List<bool> pricesAreDiscounted,
141157
required final List<double> prices,
142158
required final List<double?> pricesWithoutDiscount,
@@ -157,6 +173,10 @@ class BackgroundTaskAddPrice extends BackgroundTaskPrice {
157173
locationOSMType: locationOSMType,
158174
eraserCoordinates: cropObject.eraserCoordinates,
159175
barcodes: barcodes,
176+
categories: categories,
177+
origins: origins,
178+
labels: labels,
179+
pricePers: pricePers,
160180
pricesAreDiscounted: pricesAreDiscounted,
161181
prices: prices,
162182
pricesWithoutDiscount: pricesWithoutDiscount,

packages/smooth_app/lib/background/background_task_price.dart

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
2121
required this.locationOSMType,
2222
// multi
2323
required this.barcodes,
24+
required this.categories,
25+
required this.origins,
26+
required this.labels,
27+
required this.pricePers,
2428
required this.pricesAreDiscounted,
2529
required this.prices,
2630
required this.pricesWithoutDiscount,
@@ -35,6 +39,13 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
3539
barcodes = json.containsKey(_jsonTagBarcode)
3640
? <String>[json[_jsonTagBarcode] as String]
3741
: _fromJsonListString(json[_jsonTagBarcodes])!,
42+
categories =
43+
_fromJsonListString(json[_jsonTagCategories]) ?? <String>[],
44+
origins =
45+
_fromJsonListListString(json[_jsonTagOrigins]) ?? <List<String>>[],
46+
labels =
47+
_fromJsonListListString(json[_jsonTagLabels]) ?? <List<String>>[],
48+
pricePers = _fromJsonListString(json[_jsonTagPricePers]) ?? <String>[],
3849
pricesAreDiscounted = json.containsKey(_jsonTagIsDiscounted)
3950
? <bool>[json[_jsonTagIsDiscounted] as bool]
4051
: _fromJsonListBool(json[_jsonTagAreDiscounted])!,
@@ -51,6 +62,10 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
5162
static const String _jsonTagOSMId = 'osmId';
5263
static const String _jsonTagOSMType = 'osmType';
5364
static const String _jsonTagBarcodes = 'barcodes';
65+
static const String _jsonTagCategories = 'categories';
66+
static const String _jsonTagOrigins = 'origins';
67+
static const String _jsonTagLabels = 'labels';
68+
static const String _jsonTagPricePers = 'pricePers';
5469
static const String _jsonTagAreDiscounted = 'areDiscounted';
5570
static const String _jsonTagPrices = 'prices';
5671
static const String _jsonTagPricesWithoutDiscount = 'pricesWithoutDiscount';
@@ -98,6 +113,23 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
98113
return result;
99114
}
100115

116+
static List<List<String>>? _fromJsonListListString(
117+
final List<dynamic>? input,
118+
) {
119+
if (input == null) {
120+
return null;
121+
}
122+
final List<List<String>> result = <List<String>>[];
123+
for (final dynamic item in input) {
124+
final List<String> list = <String>[];
125+
for (final dynamic string in item) {
126+
list.add(string as String);
127+
}
128+
result.add(list);
129+
}
130+
return result;
131+
}
132+
101133
static List<bool>? _fromJsonListBool(final List<dynamic>? input) {
102134
if (input == null) {
103135
return null;
@@ -116,6 +148,10 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
116148

117149
// per line
118150
final List<String> barcodes;
151+
final List<String> categories;
152+
final List<List<String>> origins;
153+
final List<List<String>> labels;
154+
final List<String> pricePers;
119155
final List<bool> pricesAreDiscounted;
120156
final List<double> prices;
121157
final List<double?> pricesWithoutDiscount;
@@ -128,6 +164,10 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
128164
result[_jsonTagOSMId] = locationOSMId;
129165
result[_jsonTagOSMType] = locationOSMType.offTag;
130166
result[_jsonTagBarcodes] = barcodes;
167+
result[_jsonTagCategories] = categories;
168+
result[_jsonTagOrigins] = origins;
169+
result[_jsonTagLabels] = labels;
170+
result[_jsonTagPricePers] = pricePers;
131171
result[_jsonTagAreDiscounted] = pricesAreDiscounted;
132172
result[_jsonTagPrices] = prices;
133173
result[_jsonTagPricesWithoutDiscount] = pricesWithoutDiscount;
@@ -179,16 +219,22 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
179219
}) async {
180220
for (int i = 0; i < barcodes.length; i++) {
181221
final String barcode = barcodes[i];
222+
final bool isProduct = barcode.isNotEmpty;
182223
final Price newPrice = Price()
183224
..date = date
184225
..currency = currency
185226
..locationOSMId = locationOSMId
186227
..locationOSMType = locationOSMType
187228
..proofId = proofId
229+
..productCode = isProduct ? barcode : null
230+
..categoryTag = isProduct ? null : categories[i]
231+
..originsTags = isProduct ? null : origins[i]
232+
..labelsTags = isProduct ? null : labels[i]
233+
..pricePer = isProduct ? null : PricePer.fromOffTag(pricePers[i])
234+
..type = isProduct ? PriceType.product : PriceType.category
188235
..priceIsDiscounted = pricesAreDiscounted[i]
189236
..price = prices[i]
190-
..priceWithoutDiscount = pricesWithoutDiscount[i]
191-
..productCode = barcode;
237+
..priceWithoutDiscount = pricesWithoutDiscount[i];
192238

193239
// create price
194240
final MaybeError<Price?> addedPrice =
@@ -200,7 +246,9 @@ abstract class BackgroundTaskPrice extends BackgroundTask {
200246
if (addedPrice.isError) {
201247
throw Exception('Could not add price: ${addedPrice.error}');
202248
}
203-
ProductPriceRefresher.setLatestUpdate(barcode);
249+
if (isProduct) {
250+
ProductPriceRefresher.setLatestUpdate(barcode);
251+
}
204252
}
205253
localDatabase.notifyListeners();
206254
}

packages/smooth_app/lib/l10n/app_en.arb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,26 @@
23182318
}
23192319
},
23202320
"prices_barcode_enter": "Enter the Barcode",
2321+
"prices_category_enter": "Item without barcode",
2322+
"prices_per_kilogram": "Price per kilogram",
2323+
"@prices_per_kilogram": {
2324+
"description": "Title for PricePer.kilogram"
2325+
},
2326+
"prices_per_unit": "Price per unit",
2327+
"@prices_per_unit": {
2328+
"description": "Title for PricePer.unit"
2329+
},
2330+
"prices_per_kilogram_short": " / kg",
2331+
"@prices_per_kilogram_short": {
2332+
"description": "Short title for PricePer.kilogram"
2333+
},
2334+
"prices_per_unit_short": " / unit",
2335+
"@prices_per_unit_short": {
2336+
"description": "Short title for PricePer.unit"
2337+
},
2338+
"prices_category_mandatory": "Mandatory",
2339+
"prices_category_optional": "Optional",
2340+
"prices_category_error_mandatory": "The category is mandatory",
23212341
"prices_barcode_reader_action": "Barcode reader",
23222342
"prices_view_prices": "View the prices",
23232343
"prices_product_accessibility_summary": "{count,plural, =1{1 price} other{{count} prices}} for {product}",
@@ -2465,6 +2485,7 @@
24652485
}
24662486
}
24672487
},
2488+
"prices_amount_existing_subtitle": "Price previously added",
24682489
"prices_amount_subtitle": "Amount",
24692490
"prices_amount_is_discounted": "Is discounted?",
24702491
"prices_amount_price_normal": "Price",

packages/smooth_app/lib/l10n/app_fr.arb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,26 @@
23182318
}
23192319
},
23202320
"prices_barcode_enter": "Saisie du code-barres",
2321+
"prices_category_enter": "Article sans code-barres",
2322+
"prices_per_kilogram": "Prix au kilo",
2323+
"@prices_per_kilogram": {
2324+
"description": "Title for PricePer.kilogram"
2325+
},
2326+
"prices_per_unit": "Prix à l'unité",
2327+
"@prices_per_unit": {
2328+
"description": "Title for PricePer.unit"
2329+
},
2330+
"prices_per_kilogram_short": " / kg",
2331+
"@prices_per_kilogram_short": {
2332+
"description": "Short title for PricePer.kilogram"
2333+
},
2334+
"prices_per_unit_short": " / unité",
2335+
"@prices_per_unit_short": {
2336+
"description": "Short title for PricePer.unit"
2337+
},
2338+
"prices_category_mandatory": "Obligatoire",
2339+
"prices_category_optional": "Facultatif",
2340+
"prices_category_error_mandatory": "La catégorie est obligatoire",
23212341
"prices_barcode_reader_action": "Lecteur de code-barres",
23222342
"prices_view_prices": "Voir les prix",
23232343
"prices_product_accessibility_summary": "{count,plural, =1{1 prix} other{{count} prix}} pour {product}",
@@ -2465,6 +2485,7 @@
24652485
}
24662486
}
24672487
},
2488+
"prices_amount_existing_subtitle": "Prix déjà ajouté",
24682489
"prices_amount_subtitle": "Montant",
24692490
"prices_amount_is_discounted": "En promotion ?",
24702491
"prices_amount_price_normal": "Prix",

packages/smooth_app/lib/pages/input/smooth_autocomplete_text_field.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class SmoothAutocompleteTextField extends StatefulWidget {
2626
this.padding,
2727
this.textStyle,
2828
this.textCapitalization,
29+
this.onSelected,
2930
});
3031

3132
final FocusNode focusNode;
@@ -42,6 +43,9 @@ class SmoothAutocompleteTextField extends StatefulWidget {
4243
final TextStyle? textStyle;
4344
final TextCapitalization? textCapitalization;
4445

46+
/// Additional specific action when a suggested item is selected.
47+
final Function(String)? onSelected;
48+
4549
@override
4650
State<SmoothAutocompleteTextField> createState() =>
4751
_SmoothAutocompleteTextFieldState();
@@ -89,8 +93,13 @@ class _SmoothAutocompleteTextFieldState
8993
FocusNode focusNode,
9094
VoidCallback onFieldSubmitted) =>
9195
TextField(
96+
maxLines: 1,
9297
controller: widget.controller,
93-
onChanged: (_) => setState(() => _selectedSearch = null),
98+
onChanged: (_) {
99+
if (mounted) {
100+
setState(() => _selectedSearch = null);
101+
}
102+
},
94103
inputFormatters: <TextInputFormatter>[
95104
if (!widget.allowEmojis)
96105
FilteringTextInputFormatter.deny(TextHelper.emojiRegex),
@@ -138,6 +147,7 @@ class _SmoothAutocompleteTextFieldState
138147
onSelected: (String search) {
139148
_selectedSearch = search;
140149
_setLoading(false);
150+
widget.onSelected?.call(search);
141151
},
142152
optionsViewBuilder: (
143153
BuildContext lContext,
@@ -177,7 +187,7 @@ class _SmoothAutocompleteTextFieldState
177187
if (_loading != loading) {
178188
WidgetsBinding.instance.addPostFrameCallback(
179189
(_) {
180-
if (context.mounted) {
190+
if (mounted) {
181191
setState(() => _loading = loading);
182192
}
183193
},

0 commit comments

Comments
 (0)