Skip to content

Commit

Permalink
feat: 986 - new Prices fields
Browse files Browse the repository at this point in the history
New file:
* `location_type.dart`: Type of the Location.

Impacted files:
* `api_prices_test.dart`: refactored with the additional fields
* `location.dart`: added fields `locationType` and `websiteUrl`
* `location.g.dart`: generated
* `maybe_error.dart`: now we accept valid but unreadable responses
* `open_prices_api_client.dart`: safer `createPrice` method; refactored with the additional fields
* `openfoodfacts.dart`: added file `location_type.dart`
* `price.dart`: added field `receiptQuantity`
* `price.g.dart`: generated
* `price_total_stats.dart`: added fields `locationTypeOsmCount`, `locationTypeOnlineCount`, `proofTypeGdprRequestCount` and `proofTypeShopImportCount`
* `price_total_stats.g.dart`: generated
* `proof.dart`: added fields `receiptPriceCount` and `receiptPriceTotal`
* `proof.g.dart`: generated
* `update_price_parameters.dart`: added field `receiptQuantity`
* `update_proof_parameters.dart`: added fields `receiptPriceCount`, `receiptPriceTotal`, `locationOSMId` and `locationOSMType`
  • Loading branch information
monsieurtanuki committed Oct 28, 2024
1 parent b99f119 commit 65010ba
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 20 deletions.
1 change: 1 addition & 0 deletions lib/openfoodfacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export 'src/prices/get_users_parameters.dart';
export 'src/prices/get_users_result.dart';
export 'src/prices/location.dart';
export 'src/prices/location_osm_type.dart';
export 'src/prices/location_type.dart';
export 'src/prices/maybe_error.dart';
export 'src/prices/order_by.dart';
export 'src/prices/price.dart';
Expand Down
17 changes: 15 additions & 2 deletions lib/src/open_prices_api_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,12 @@ class OpenPricesAPIClient {
return MaybeError<bool>.responseError(response);
}

static Future<MaybeError<Price>> createPrice({
/// Adds a price. Returns an error, or either the added price or null.
///
/// Returned price can be null if we cannot decode it (but the status code is
/// good enough to say "price added!", even if we have trouble decoding the
/// price).
static Future<MaybeError<Price?>> createPrice({
required final Price price,
required final String bearerToken,
final UriProductHelper uriHelper = uriHelperFoodProd,
Expand All @@ -348,6 +353,8 @@ class OpenPricesAPIClient {
'location_osm_id': price.locationOSMId,
'location_osm_type': price.locationOSMType.offTag,
'date': GetParametersHelper.formatDate(price.date),
if (price.receiptQuantity != null)
'receipt_quantity': price.receiptQuantity,
};
final Response response = await HttpHelper().doPostJsonRequest(
uri,
Expand All @@ -360,7 +367,7 @@ class OpenPricesAPIClient {
final Map<String, dynamic> json = HttpHelper().jsonDecodeUtf8(response);
return MaybeError<Price>.value(Price.fromJson(json));
} catch (e) {
//
return MaybeError<Price>.unreadableResponse(response);
}
}
return MaybeError<Price>.responseError(response);
Expand Down Expand Up @@ -454,6 +461,8 @@ class OpenPricesAPIClient {
final LocationOSMType? locationOSMType,
final DateTime? date,
final Currency? currency,
final int? receiptPriceCount,
final num? receiptPriceTotal,
required final String bearerToken,
final UriProductHelper uriHelper = uriHelperFoodProd,
}) async {
Expand All @@ -475,6 +484,10 @@ class OpenPricesAPIClient {
'location_osm_type': locationOSMType.offTag,
if (date != null) 'date': GetParametersHelper.formatDate(date),
if (currency != null) 'currency': currency.name,
if (receiptPriceCount != null)
'receipt_price_count': receiptPriceCount.toString(),
if (receiptPriceTotal != null)
'receipt_price_total': receiptPriceTotal.toString(),
},
);
final List<int> fileBytes = await UriReader.instance.readAsBytes(imageUri);
Expand Down
8 changes: 8 additions & 0 deletions lib/src/prices/location.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:json_annotation/json_annotation.dart';

import 'location_osm_type.dart';
import 'location_type.dart';
import '../interface/json_object.dart';
import '../utils/json_helper.dart';

Expand All @@ -15,6 +16,10 @@ class Location extends JsonObject {
@JsonKey(name: 'osm_id')
late int osmId;

/// Type of the location object.
@JsonKey(name: 'type')
late LocationType locationType;

/// Type of the OpenStreetMap location object.
///
/// Stores can be represented as nodes, ways or relations in OpenStreetMap.
Expand Down Expand Up @@ -73,6 +78,9 @@ class Location extends JsonObject {
@JsonKey(name: 'osm_lon')
double? longitude;

@JsonKey(name: 'website_url')
String? websiteUrl;

/// Date when the product was bought.
@JsonKey(fromJson: JsonHelper.stringTimestampToDate)
late DateTime created;
Expand Down
9 changes: 9 additions & 0 deletions lib/src/prices/location.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions lib/src/prices/location_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:json_annotation/json_annotation.dart';

import '../model/off_tagged.dart';

/// Type of the Location.
enum LocationType implements OffTagged {
@JsonValue('OSM')
osm(offTag: 'OSM'),
@JsonValue('ONLINE')
online(offTag: 'ONLINE');

const LocationType({
required this.offTag,
});

@override
final String offTag;

/// Returns the first [LocationType] that matches the [offTag].
static LocationType? fromOffTag(final String? offTag) =>
OffTagged.fromOffTag(offTag, LocationType.values) as LocationType?;
}
17 changes: 12 additions & 5 deletions lib/src/prices/maybe_error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,29 @@ import 'package:http/http.dart';
class MaybeError<T> {
const MaybeError.value(T this._value)
: error = null,
statusCode = null;
statusCode = null,
isError = false;
MaybeError.responseError(final Response response)
: _value = null,
error = utf8.decode(response.bodyBytes),
statusCode = response.statusCode;
statusCode = response.statusCode,
isError = true;
MaybeError.unreadableResponse(final Response response)
: _value = null,
error = utf8.decode(response.bodyBytes),
statusCode = response.statusCode,
isError = false;
MaybeError.error({
required String this.error,
required int this.statusCode,
}) : _value = null;
}) : _value = null,
isError = true;

final T? _value;
final bool isError;
final String? error;
final int? statusCode;

bool get isError => _value == null;

T get value => _value!;

String get detailError {
Expand Down
4 changes: 4 additions & 0 deletions lib/src/prices/price.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ class Price extends JsonObject {
@JsonKey()
PriceProduct? product;

/// Receipt's price quantity (user input).
@JsonKey(name: 'receipt_quantity')
int? receiptQuantity;

/// Owner. Read-only.
@JsonKey()
late String owner;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/prices/price.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions lib/src/prices/price_total_stats.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class PriceTotalStats extends JsonObject {
@JsonKey(name: 'location_with_price_count')
int? locationWithPriceCount;

@JsonKey(name: 'location_type_osm_count')
int? locationTypeOsmCount;

@JsonKey(name: 'location_type_online_count')
int? locationTypeOnlineCount;

@JsonKey(name: 'proof_count')
int? proofCount;

Expand All @@ -43,6 +49,12 @@ class PriceTotalStats extends JsonObject {
@JsonKey(name: 'proof_type_receipt_count')
int? proofTypeReceiptCount;

@JsonKey(name: 'proof_type_gdpr_request_count')
int? proofTypeGdprRequestCount;

@JsonKey(name: 'proof_type_shop_import_count')
int? proofTypeShopImportCount;

@JsonKey(name: 'user_count')
int? userCount;

Expand Down
12 changes: 12 additions & 0 deletions lib/src/prices/price_total_stats.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions lib/src/prices/proof.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ class Proof extends JsonObject {
@JsonKey(name: 'price_count')
late int priceCount;

/// Receipt's number of prices (user input).
@JsonKey(name: 'receipt_price_count')
int? receiptPriceCount;

/// Receipt's total amount (user input).
@JsonKey(name: 'receipt_price_total')
num? receiptPriceTotal;

/// ID of the location in OpenStreetMap.
///
/// The store where the product was bought.
Expand Down
4 changes: 4 additions & 0 deletions lib/src/prices/proof.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/src/prices/update_price_parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class UpdatePriceParameters extends JsonObject {
/// Date when the product was bought.
DateTime? date;

/// Receipt's price quantity (user input).
int? receiptQuantity;

@override
Map<String, dynamic> toJson() => <String, dynamic>{
if (pricePer != null) 'price_per': pricePer!.offTag,
Expand All @@ -34,5 +37,6 @@ class UpdatePriceParameters extends JsonObject {
if (price != null) 'price': price,
if (currency != null) 'currency': currency!.name,
if (date != null) 'date': GetParametersHelper.formatDate(date!),
if (receiptQuantity != null) 'receipt_quantity': receiptQuantity,
};
}
18 changes: 18 additions & 0 deletions lib/src/prices/update_proof_parameters.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '../interface/json_object.dart';
import 'currency.dart';
import 'get_parameters_helper.dart';
import 'location_osm_type.dart';
import 'proof_type.dart';

/// Parameters for the "update proof" API query.
Expand All @@ -16,10 +17,27 @@ class UpdateProofParameters extends JsonObject {
/// Currency of the price.
Currency? currency;

/// ID of the location in OpenStreetMap.
int? locationOSMId;

/// Type of the OpenStreetMap location object.
LocationOSMType? locationOSMType;

/// Receipt's number of prices.
int? receiptPriceCount;

/// Receipt's total amount (user input).
num? receiptPriceTotal;

@override
Map<String, dynamic> toJson() => <String, dynamic>{
if (type != null) 'type': type!.offTag,
if (date != null) 'date': GetParametersHelper.formatDate(date!),
if (currency != null) 'currency': currency!.name,
if (locationOSMId != null) 'location_osm_id': locationOSMId,
if (locationOSMType != null)
'location_osm_type': locationOSMType!.offTag,
if (receiptPriceCount != null) 'receipt_price_count': receiptPriceCount,
if (receiptPriceTotal != null) 'receipt_price_total': receiptPriceTotal,
};
}
Loading

0 comments on commit 65010ba

Please sign in to comment.