Compare commits

...

10 Commits

Author SHA1 Message Date
bossanyit
7e3d99b9a3 v1.1.4 getPropertyDate 2023-06-26 20:49:43 +02:00
bossanyit
3bc2b74f74 v1.1.3 CupertinoPicker Error fix 2023-05-15 18:04:03 +02:00
bossanyit
a0108baffd v1.1.2 Flutter SDK update 2023-05-15 17:41:07 +02:00
bossanyit
eda8ea7d6a v1.1.1 2023-05-14 10:02:25 +02:00
bossanyit
14731c5ee7 v1.1 dart fix 2023-05-14 09:53:18 +02:00
bossanyit
7e4934f15e v1.0.29 2023-05-11 08:10:17 +02:00
bossanyit
adddf41a01 v1.0.28 2023-05-09 07:53:00 +02:00
bossanyit
928396112a v1.0.27 2023-05-08 19:42:08 +02:00
bossanyit
16603f00bd v1.27 membership improvement 2023-05-07 10:47:00 +02:00
Tibor Bossanyi
652104b403 v1.0.26 no webapi 2023-04-18 08:17:31 +02:00
18 changed files with 242 additions and 114 deletions

4
.gitignore vendored
View File

@ -28,5 +28,5 @@ migrate_working_dir/
.packages
build/
.dart_tool/
/.flutter-plugins
/.flutter-plugins-dependencies
.flutter-plugins
.flutter-plugins-dependencies

View File

@ -1,5 +1,33 @@
Workout Test and Diet 4 You Common Util Functions
### Version 1.1.4
- customer.getPropertyDate
### Version 1.1.3
- CupertinoPicker error in Flutter 3.10 stable
### Version 1.1.2
- Flutter SDK < 4.0.0
### Version 1.1.1
- pub.dev dependencies for Flutter 3.10
### Version 1.1.0
- Flutter 3.10, dart fix
### Version 1.0.29
- gpt4 model
### Version 1.0.28
- api isWeb
### Version 1.0.27
- customer_membership end_date
### Version 1.0.25
- http get utf8

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:workouttest_util/model/cache.dart';
import 'package:workouttest_util/service/customer_service.dart';
import 'package:workouttest_util/service/openai_service.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();

View File

@ -481,7 +481,7 @@ class Cache with Logging {
_exercisesTrainee = null;
_traineeExercisePlan = null;
_exercises = [];
_myExercisesPlanDetails = LinkedHashMap();
_myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
log("Trainees is null? ${_trainee == null}");
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
await setPreferences(prefs, SharePrefsChange.logout, 0, "");
@ -637,7 +637,7 @@ class Cache with Logging {
void initBadges() {
CustomerRepository customerRepository = CustomerRepository();
_badges = LinkedHashMap();
_badges = LinkedHashMap<String, int>();
if (userLoggedIn == null) {
return;
}

View File

@ -133,6 +133,18 @@ class Customer {
}
}
String getPropertyDate(String propertyName) {
if (properties[propertyName] == null) {
return "";
} else {
if (properties[propertyName]!.dateAdd == null) {
return "";
} else {
return DateFormat('yyyy-MM-dd').format(properties[propertyName]!.dateAdd!);
}
}
}
setProperty(String propertyName, double value) {
properties[propertyName]!.propertyValue = value;
}

View File

@ -4,17 +4,20 @@ class CustomerMembership {
late int membershipId;
int? customerId;
DateTime? startDate;
DateTime? endDate;
CustomerMembership.fromJson(Map json) {
membershipId = json['membershipId'];
customerId = json['customerId'] ?? 0;
startDate = json['startDate'] == null ? null : DateTime.parse(json['startDate']);
endDate = json['endDate'] == null ? null : DateTime.parse(json['endDate']);
}
Map<String, dynamic> toJson() => {
"membershipId": membershipId,
"customerId": customerId ?? 0,
"startDate": startDate == null ? "" : DateFormat('yyyy-MM-dd HH:mm:ss').format(startDate!),
"endDate": startDate == null ? "" : DateFormat('yyyy-MM-dd HH:mm:ss').format(endDate!),
};
@override

View File

@ -1,21 +1,36 @@
enum DurationType { free, subscription, lifetime, limited }
extension DurationTypeExt on DurationType {
String enumToString() => toString().split(".").last;
DurationType getType(String type) => DurationType.values.firstWhere((e) => e.enumToString() == type);
}
enum DurationUnit { day, week, month, year }
extension DurationUnitExt on DurationUnit {
String enumToString() => toString().split(".").last;
DurationUnit getType(String type) => DurationUnit.values.firstWhere((e) => e.enumToString() == type);
}
class Membership {
late int membershipId;
late String name;
String? description;
late int duration;
late String durationType;
late String durationUnit;
late DurationType durationType;
late DurationUnit durationUnit;
int? trainingPlanId;
String? trainingPlanDayIds;
Membership();
Membership.fromJson(Map json) {
membershipId = json['membershipId'];
name = json['name'];
description = json['description'] ?? "";
duration = json['duration'];
durationUnit = json['durationUnit'];
durationType = json['durationType'];
durationType = DurationType.free.getType(json['durationType']);
durationUnit = DurationUnit.day.getType(json['durationUnit']);
trainingPlanId = json['trainingPlanId'] ?? 0;
trainingPlanDayIds = json['trainingPlanDayIds'] ?? "";
}
@ -25,8 +40,8 @@ Map<String, dynamic> toJson() => {
"name": name,
"description": description,
"duration": duration,
"durationUnit": durationUnit,
"durationType": durationType,
'durationType': durationType.enumToString(),
'durationUnit': durationUnit.enumToString(),
"trainingPlanId": trainingPlanId,
"trainingPlanDayIds": trainingPlanDayIds,
};

View File

@ -6,7 +6,7 @@ class ExerciseDeviceRepository {
List<ExerciseDevice> _devices = [];
List<ExerciseDevice> getDevices() {
return this._devices;
return _devices;
}
void setDevices(List<ExerciseDevice> list) {
@ -14,15 +14,15 @@ class ExerciseDeviceRepository {
}
Future<List<ExerciseDevice>> getDBDevices() async {
this._devices = await ExerciseDeviceApi().getDevices();
return this._devices;
_devices = await ExerciseDeviceApi().getDevices();
return _devices;
}
bool isGym(int deviceId) {
bool isGym = false;
_devices.forEach((element) {
for (var element in _devices) {
isGym = isGymElement(element.name);
});
}
return isGym;
}
@ -42,11 +42,11 @@ class ExerciseDeviceRepository {
if (_devices.isEmpty) {
_devices = Cache().getDevices()!;
}
_devices.forEach((element) {
for (var element in _devices) {
if (isGymElement(element.name)) {
gymDevices.add(element);
}
});
}
return gymDevices;
}
}

View File

@ -20,21 +20,21 @@ class TrainingPlanRepository with Common, Logging {
final List<ExerciseTree>? exerciseTree = Cache().getExerciseTree();
int? parentId;
if (exerciseTree != null) {
exerciseTree.forEach((element) {
for (var element in exerciseTree) {
if (element.internalName == parent) {
parentId = element.treeId;
parentTree = element;
}
});
}
}
final List<TrainingPlan>? plans = Cache().getTrainingPlans();
if (plans != null && parentId != null) {
plans.forEach((element) {
for (var element in plans) {
if (element.treeId == parentId) {
resultList.add(element);
}
});
}
}
return resultList;
}
@ -48,12 +48,12 @@ class TrainingPlanRepository with Common, Logging {
log(" **** Activate Plan: $trainingPlanId");
// 1. deactivate
if (Cache().getCustomerTrainingPlans() != null) {
Cache().getCustomerTrainingPlans()!.forEach((plan) {
for (var plan in Cache().getCustomerTrainingPlans()!) {
plan.active = false;
if (plan.customerTrainingPlanId != null) {
//TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
}
});
}
}
CustomerTrainingPlan plan = CustomerTrainingPlan();
@ -72,14 +72,14 @@ class TrainingPlanRepository with Common, Logging {
// 3 calculate weights
int index = 0;
int exerciseTypeIdOrig = 0;
trainingPlan.details!.forEach((elem) {
for (var elem in trainingPlan.details!) {
List<CustomerTrainingPlanDetails> list = createDetail(plan, elem, exerciseTypeIdOrig, index);
exerciseTypeIdOrig = elem.exerciseTypeId;
list.forEach((element) {
for (var element in list) {
plan.details.add(element);
index++;
});
});
}
}
Cache().myTrainingPlan = plan;
@ -251,21 +251,21 @@ class TrainingPlanRepository with Common, Logging {
// reverse
return a.dateAdd!.compareTo(b.dateAdd!);
});
exercises.forEach((exercise) {
for (var exercise in exercises) {
if (exercise.exerciseTypeId == exerciseTypeId && exercise.dateAdd!.compareTo(dt) >= 0) {
detail.weight = weight;
lastExercise1RM = exercise;
//print("last exercise: $exercise");
}
});
}
if (lastExercise1RM == null || lastExercise1RM!.unitQuantity == null) {
if (lastExercise1RM == null || lastExercise1RM.unitQuantity == null) {
detail.weight = weight;
detail.isTest = true;
return detail;
}
double oneRepMax = calculateMax1RMSameDay(lastExercise1RM!);
double oneRepMax = calculateMax1RMSameDay(lastExercise1RM);
// Common.calculate1RM(lastExercise1RM!.unitQuantity!, lastExercise1RM!.quantity!);
//print("Exercise $exerciseTypeId - 1RM : $oneRepMax");
weight = oneRepMax * Common.get1RMPercent(detail.repeats!);
@ -286,7 +286,7 @@ class TrainingPlanRepository with Common, Logging {
List<Exercise> exercises = Cache().getExercises()!;
double max1RM = 0.0;
exercises.forEach((exercise) {
for (var exercise in exercises) {
if (actual.exerciseTypeId == exercise.exerciseTypeId &&
actual.dateAdd!.year == exercise.dateAdd!.year &&
actual.dateAdd!.month == exercise.dateAdd!.month &&
@ -296,7 +296,7 @@ class TrainingPlanRepository with Common, Logging {
max1RM = oneRepMax;
}
}
});
}
return max1RM;
}
@ -307,11 +307,11 @@ class TrainingPlanRepository with Common, Logging {
return 0;
}
int originalRepeats = 0;
plan.details!.forEach((element) {
for (var element in plan.details!) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalRepeats = element.repeats ?? 0;
}
});
}
return originalRepeats;
}
@ -321,11 +321,11 @@ class TrainingPlanRepository with Common, Logging {
return 0;
}
double originalWeight = 0;
plan.details!.forEach((element) {
for (var element in plan.details!) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalWeight = element.weight ?? 0;
}
});
}
return originalWeight;
}
@ -371,11 +371,11 @@ class TrainingPlanRepository with Common, Logging {
// 1.b get the original detail's repeat
int originalRepeats = detail.repeats!;
plan.details!.forEach((element) {
for (var element in plan.details!) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalRepeats = element.repeats ?? 0;
}
});
}
// 2 get recalculated repeats
recalculatedDetail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble());

View File

@ -36,10 +36,7 @@ class APIClient with Common, Logging {
request.headers.contentType = ContentType('application', 'json', charset: 'utf-8');
request.headers.set('Authorization', '1');
final body = jsonEncode(<String, String>{
'username': email,
'password': password
});
final body = jsonEncode(<String, String>{'username': email, 'password': password});
request.write(body);
HttpClientResponse result = await request.close();

View File

@ -128,32 +128,32 @@ class CustomerApi with Logging {
if (properties != null) {
// reset Properties
properties.forEach((property) {
for (var property in properties) {
CustomerProperty customerProperty =
CustomerProperty(propertyId: property.propertyId, customerId: customer.customerId!, dateAdd: DateTime.now(), propertyValue: 0);
customer.properties[property.propertyName] = customerProperty;
});
}
customerProperties!.forEach((customerProperty) {
properties.forEach((property) {
for (var customerProperty in customerProperties!) {
for (var property in properties) {
if (customerProperty.propertyId == property.propertyId) {
customer.properties[property.propertyName] = customerProperty;
}
});
});
}
}
}
}
Future<Customer> getTrainee(int customerId) async {
String body = "";
Customer customer;
log(" ===== get Trainee customer by id: " + customerId.toString());
log(" ===== get Trainee customer by id: $customerId");
try {
final String responseBody = await _client.get("customers/" + customerId.toString(), body);
final String responseBody = await _client.get("customers/$customerId", body);
customer = Customer.fromJson(jsonDecode(responseBody));
log(" --- Trainee: " + customer.toJson().toString());
log(" --- Trainee: ${customer.toJson()}");
} catch (exception) {
log("Exception: " + exception.toString());
log("Exception: $exception");
throw Exception(exception);
}
return customer;
@ -164,11 +164,11 @@ class CustomerApi with Logging {
log("Get trainees list");
try {
String body = "";
final String responseBody = await _client.get("customers/trainees/" + trainerId.toString(), body);
final String responseBody = await _client.get("customers/trainees/$trainerId", body);
final Iterable json = jsonDecode(responseBody);
trainees = json.map((customer) => Customer.fromJson(customer)).toList();
} catch (exception) {
log("Exception: " + exception.toString());
log("Exception: $exception");
throw Exception(exception);
}
return trainees;
@ -195,45 +195,45 @@ class CustomerApi with Logging {
}
Future<CustomerProperty> addProperty(CustomerProperty property) async {
String body = JsonEncoder().convert(property.toJson());
log(" ===== add new customer property: " + body);
String body = const JsonEncoder().convert(property.toJson());
log(" ===== add new customer property: $body");
CustomerProperty customerProperty;
String? responseBody;
try {
responseBody = await _client.post("customer_property", body);
log(" responseBody: " + responseBody);
log(" responseBody: $responseBody");
int? status = jsonDecode(responseBody)['status'];
if (status != null) {
throw new Exception(jsonDecode(responseBody)['error']);
throw Exception(jsonDecode(responseBody)['error']);
} else {
customerProperty = CustomerProperty.fromJson(jsonDecode(responseBody));
}
} on FormatException {
throw new Exception(responseBody);
throw Exception(responseBody);
} on Exception catch (e) {
throw new Exception(e);
throw Exception(e);
}
return customerProperty;
}
Future<CustomerProperty> updateProperty(CustomerProperty property) async {
String body = JsonEncoder().convert(property.toJson());
String body = const JsonEncoder().convert(property.toJson());
CustomerProperty? customerProperty;
log(" ===== update customer property: " + body);
log(" ===== update customer property: $body");
String? responseBody;
try {
responseBody = await _client.post("customer_property/update/" + property.customerPropertyId.toString(), body);
log(" responseBody: " + responseBody);
responseBody = await _client.post("customer_property/update/${property.customerPropertyId}", body);
log(" responseBody: $responseBody");
int? status = jsonDecode(responseBody)['status'];
if (status != null) {
throw new Exception(jsonDecode(responseBody)['error']);
throw Exception(jsonDecode(responseBody)['error']);
} else {
customerProperty = CustomerProperty.fromJson(jsonDecode(responseBody));
}
} on FormatException {
throw new Exception(responseBody);
throw Exception(responseBody);
} on Exception catch (e) {
throw new Exception(e);
throw Exception(e);
}
return customerProperty;
}

View File

@ -51,7 +51,7 @@ class ExerciseTreeApi with Logging {
int treeIndex = 0;
copyList.forEach((element) async {
int index = 0;
exerciseTreeParents.forEach((parent) {
for (var parent in exerciseTreeParents) {
if (parent.exerciseTreeChildId == element.treeId) {
if (index > 0) {
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
@ -64,7 +64,7 @@ class ExerciseTreeApi with Logging {
}
index++;
}
});
}
treeIndex++;
});
return exerciseTree;

View File

@ -9,7 +9,7 @@ import 'package:workouttest_util/util/logging.dart';
class OpenAIApi with Logging {
final String modelDavinci = "text-davinci-003";
final String modelGpt35 = "gpt-3.5-turbo";
final String modelGpt4 = "gpt-4-32k";
final String modelGpt4 = "gpt-4";
final String modelAda = "text-embedding-ada-002";
final APIClient _client = APIClient();

View File

@ -134,7 +134,7 @@ class PackageApi {
int treeIndex = 0;
copyList.forEach((element) async {
int index = 0;
exerciseTreeParents.forEach((parent) {
for (var parent in exerciseTreeParents) {
if (parent.exerciseTreeChildId == element.treeId) {
if (index > 0) {
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
@ -148,7 +148,7 @@ class PackageApi {
}
index++;
}
});
}
treeIndex++;
});

View File

@ -67,7 +67,7 @@ class NumberPickerWidgetState extends State<NumberPickerWidget> {
scrollController: _scrollController,
useMagnifier: true,
magnification: 1.2,
diameterRatio: widget.diameterRatio!,
//diameterRatio: widget.diameterRatio!,
backgroundColor: Colors.transparent,
selectionOverlay: Container(),
onSelectedItemChanged: (x) {
@ -80,10 +80,8 @@ class NumberPickerWidgetState extends State<NumberPickerWidget> {
widget.onChange(value);
},
itemExtent: widget.itemExtent!,
children: List.generate(
widget.maxValue,
(index) => Text('$index ${widget.unit}',
style: TextStyle(color: widget.color, fontSize: widget.fontSize, fontWeight: widget.fontWeight))),
children: List.generate(widget.maxValue,
(index) => Text('$index ${widget.unit}', style: TextStyle(color: widget.color, fontSize: widget.fontSize, fontWeight: widget.fontWeight))),
);
}

View File

@ -1,9 +1,9 @@
name: workouttest_util
description: Workout Test app and web functions.
version: 1.0.25
version: 1.1.4
environment:
sdk: ">=2.18.6 <3.0.0"
sdk: ">=2.18.6 <4.0.0"
flutter: ">=1.17.0"
dependencies:
@ -12,24 +12,24 @@ dependencies:
crypto: ^3.0.2
firebase_auth: ^4.3.0
firebase_analytics: ^10.1.6
firebase_core: ^2.8.0
firebase_messaging: ^14.3.0
firebase_remote_config: ^3.0.15
flutter_facebook_auth: ^5.0.7
firebase_auth: ^4.6.0
firebase_analytics: ^10.4.0
firebase_core: ^2.12.0
firebase_messaging: ^14.6.0
firebase_remote_config: ^4.2.0
flutter_facebook_auth: ^5.0.11
flutter_dotenv: ^5.0.2
google_sign_in: ^6.0.2
google_sign_in: ^6.1.0
http: ^0.13.5
http: ^0.13.6
intl: ^0.17.0
intl: ^0.18.0
sign_in_with_apple: ^4.3.0
matomo_tracker: ^2.0.0
matomo_tracker: ^3.1.0
package_info_plus: ^3.0.2
package_info_plus: ^3.1.2
sentry_flutter: ^7.3.0
shared_preferences: ^2.0.20
@ -42,7 +42,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter_lints: ^2.0.1
flutter:
assets:

View File

@ -1,13 +1,16 @@
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:workouttest_util/model/cache.dart';
import 'package:workouttest_util/model/customer.dart';
import 'package:workouttest_util/model/customer_property.dart';
import 'package:workouttest_util/model/property.dart';
import 'package:workouttest_util/repository/customer_repository.dart';
main() {
setUp(() {
setUp(() async {
await dotenv.load(fileName: "assets/.env");
String propertyJson = '''
[
{
@ -113,4 +116,27 @@ main() {
expect(customer.getProperty("Weight"), 66);
});
});
test('getPropertyDate', () {
var customer = Customer();
var propertyName = 'testDate';
var testDate = DateTime.now();
var expectedDate = DateFormat('yyyy-MM-dd').format(testDate);
String json = '''{
"customerPropertyId": 41,
"propertyId": 1,
"propertyValue": 82.0,
"dateAdd": "$expectedDate",
"goal": false
}''';
CustomerProperty property = CustomerProperty.fromJson(jsonDecode(json));
customer.properties[propertyName] = property;
var actualDate = customer.getPropertyDate(propertyName);
expect(actualDate, equals(expectedDate));
});
}

View File

@ -0,0 +1,50 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:workouttest_util/model/membership.dart';
void main() {
group('Membership', () {
test('fromJson() correctly sets properties', () {
final json = {
'membershipId': 1,
'name': 'Basic Membership',
'description': 'This is a basic membership',
'duration': 30,
'durationType': 'subscription',
'durationUnit': 'day',
'trainingPlanId': null,
'trainingPlanDayIds': null,
};
final membership = Membership.fromJson(json);
expect(membership.membershipId, 1);
expect(membership.name, 'Basic Membership');
expect(membership.description, 'This is a basic membership');
expect(membership.duration, 30);
expect(membership.durationType, DurationType.subscription);
expect(membership.durationUnit, DurationUnit.day);
expect(membership.trainingPlanId, 0);
expect(membership.trainingPlanDayIds, '');
});
test('toJson() correctly returns a Map', () {
final membership = Membership()
..membershipId = 1
..name = 'Basic Membership'
..description = 'This is a basic membership'
..duration = 30
..durationType = DurationType.subscription
..durationUnit = DurationUnit.day
..trainingPlanId = null
..trainingPlanDayIds = null;
final json = membership.toJson();
expect(json['membershipId'], 1);
expect(json['name'], 'Basic Membership');
expect(json['description'], 'This is a basic membership');
expect(json['duration'], 30);
expect(json['durationType'], 'subscription');
expect(json['durationUnit'], 'day');
expect(json['trainingPlanId'], null);
expect(json['trainingPlanDayIds'], null);
});
});
}