MatchedScoreV2 constructor
Implementation
MatchedScoreV2(
final Product product,
final ProductPreferencesManager productPreferencesManager,
) : barcode = product.barcode! {
_score = 0;
_debug = '';
final List<AttributeGroup>? attributeGroups = product.attributeGroups;
if (attributeGroups == null) {
// the product does not have the attribute_groups field
_status = MatchedProductStatusV2.UNKNOWN_MATCH;
_debug = 'no attribute_groups';
return;
}
int sumOfFactors = 0;
int sumOfFactorsForUnknownAttributes = 0;
bool mayNotMatch = false;
bool doesNotMatch = false;
bool isUnknown = false;
for (final AttributeGroup group in attributeGroups) {
if (group.attributes == null) {
continue;
}
for (final Attribute attribute in group.attributes!) {
final String attributeId = attribute.id!;
final double match = attribute.match ?? 0;
final String importanceId = productPreferencesManager
.getImportanceIdForAttributeId(attributeId);
if (importanceId == PreferenceImportance.ID_NOT_IMPORTANT) {
// Ignore attribute
_debug += '$attributeId $importanceId\n';
continue;
}
final int factor = _preferencesFactors[importanceId]!;
sumOfFactors += factor;
if (attribute.status == Attribute.STATUS_UNKNOWN) {
sumOfFactorsForUnknownAttributes += factor;
if (importanceId == PreferenceImportance.ID_MANDATORY) {
isUnknown = true;
}
} else {
_score += match * factor;
_debug += '$attributeId $importanceId - match: $match\n';
if (importanceId == PreferenceImportance.ID_MANDATORY) {
if (match <= 10) {
// Mandatory attribute with a very bad score (e.g. contains an allergen) -> status: does not match
doesNotMatch = true;
}
// Mandatory attribute with a bad score (e.g. may contain traces of an allergen) -> status: may not match
else if (match <= 50) {
mayNotMatch = true;
}
}
}
}
}
// Normalize the score from 0 to 100
if (sumOfFactors == 0) {
_score = 0;
} else {
_score /= sumOfFactors;
}
// If one of the attributes does not match, the product does not match
if (doesNotMatch) {
// Set score to 0 for products that do not match
_score = 0;
_status = MatchedProductStatusV2.DOES_NOT_MATCH;
} else if (mayNotMatch) {
_status = MatchedProductStatusV2.MAY_NOT_MATCH;
} else if (isUnknown) {
_status = MatchedProductStatusV2.UNKNOWN_MATCH;
}
// If too many attributes are unknown, set an unknown match
else if (sumOfFactorsForUnknownAttributes >= sumOfFactors / 2) {
_status = MatchedProductStatusV2.UNKNOWN_MATCH;
}
// If the product matches, check how well it matches user preferences
else if (score >= 75) {
_status = MatchedProductStatusV2.VERY_GOOD_MATCH;
} else if (score >= 50) {
_status = MatchedProductStatusV2.GOOD_MATCH;
} else {
_status = MatchedProductStatusV2.POOR_MATCH;
}
}