261 lines
9.4 KiB
Dart
261 lines
9.4 KiB
Dart
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import '../../../events/eventbus.dart';
|
|
import '../../../events/events.dart';
|
|
import '../../../generated/l10n.dart';
|
|
import '../../../models/product.dart';
|
|
import '../../../models/product_option.dart';
|
|
import '../../../utils/utils.dart';
|
|
|
|
import 'options_base.dart';
|
|
import 'rules.dart';
|
|
|
|
class RadioOptions extends OptionsBase {
|
|
RadioOptions({@required Product product, @required int index, @required Map<String, dynamic> selections})
|
|
: super(product: product, index: index, selections: selections);
|
|
|
|
@override
|
|
State<StatefulWidget> createState() {
|
|
return new RadioOptionsState();
|
|
}
|
|
}
|
|
|
|
class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
|
Map<String, dynamic> optionsState = new Map();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
|
|
return new ListView.builder(
|
|
itemCount: 2,
|
|
itemBuilder: (context, index) {
|
|
if (index == 0) {
|
|
return new Container(
|
|
padding: new EdgeInsets.all(10.0),
|
|
child: new Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
new Text(
|
|
S.of(context).radio_option_select_token(product.productAttributes[this.index].name),
|
|
style: new TextStyle(
|
|
fontSize: 12.5,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
new Text(
|
|
product.productAttributes[this.index].required ? S.of(context).radio_option_is_required : S.of(context).radio_option_is_optional,
|
|
style: new TextStyle(
|
|
fontSize: 10.0,
|
|
color: new Color(0xFF999999)
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
return _getOptionWidget();
|
|
}
|
|
);
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
setState(() {
|
|
product = widget.product;
|
|
selections = widget.selections;
|
|
index = widget.index;
|
|
});
|
|
eventBus.on<OnAttributePageChanged>().listen((event) {
|
|
setState(() {
|
|
index = event.index;
|
|
});
|
|
});
|
|
}
|
|
|
|
void _onOptionTappedCallback(name, quantity, adjustAmount, int optIndex, ProductOption productOption) {
|
|
Map<String, dynamic> opt = {
|
|
'name': name,
|
|
'quantity': quantity,
|
|
'adjust_amount': adjustAmount
|
|
};
|
|
var cloneSelections = json.decode(json.encode(selections));
|
|
if (product.productAttributes[index].required) {
|
|
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
|
} else {
|
|
if (cloneSelections.containsKey(product.productAttributes[index].name.toUpperCase())
|
|
&& Utils.equalsIgnoreCase(cloneSelections[product.productAttributes[index].name.toUpperCase()][0]['name'], name)) {
|
|
cloneSelections.remove(product.productAttributes[index].name.toUpperCase());
|
|
} else {
|
|
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
|
}
|
|
}
|
|
|
|
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
|
if (extraJson != null) {
|
|
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
|
extraJson, Rule.RULE_EXCLUSIVE_SELECTION);
|
|
if (exclusiveRule != null) {
|
|
if (_checkOptionIsCheck(productOption.name)) {
|
|
setOptionsStateDisabled(product.productAttributes[index].name, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
setState(() {
|
|
selections = cloneSelections;
|
|
});
|
|
eventBus.fire(new OnAttributeSelectionsChanged(selections));
|
|
}
|
|
|
|
Widget _getOptionWidget() {
|
|
var row = Wrap(
|
|
children: <Widget>[],
|
|
);
|
|
|
|
List<ProductOption> productOptions = product.productAttributes[index].productOptions;
|
|
|
|
if (!optionsState.containsKey(product.productAttributes[index].name)) {
|
|
List<Map<String, dynamic>> optionState = [];
|
|
for (var i = 0; i < productOptions.length; i++) {
|
|
optionState.add({'name': product.productAttributes[index].productOptions[i].name, 'disabled': false, 'check': false});
|
|
}
|
|
optionsState[product.productAttributes[index].name] = optionState;
|
|
}
|
|
|
|
for (var i = 0; i < productOptions.length; i++) {
|
|
Map<String, dynamic> extraJson = Utils.stringToJson(productOptions[i].extra);
|
|
if (extraJson != null) {
|
|
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
|
extraJson, Rule.RULE_EXCLUSIVE_SELECTION);
|
|
if (exclusiveRule != null) {
|
|
if (_checkOptionIsCheck(productOptions[i].name)) {
|
|
setOptionsStateDisabled(product.productAttributes[index].name, true);
|
|
optionsState[product.productAttributes[index].name][i]['disabled'] = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
List<Map<String, dynamic>> optionState = optionsState[product.productAttributes[index].name];
|
|
for (var i = 0; i < optionState.length; i++) {
|
|
Widget optionWidget = _getOptionRadio(
|
|
product.productAttributes[index].productOptions[i], optionState[i]['disabled'], i);
|
|
row.children.add(optionWidget);
|
|
}
|
|
return row;
|
|
}
|
|
|
|
bool _checkOptionIsCheck(String name) {
|
|
if (Utils.selectionsContains(selections, product.productAttributes[index].name, name) != -1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Widget _getOptionRadio(ProductOption productOption, bool optDisabled, int optIndex) {
|
|
bool disabled = optDisabled;
|
|
bool check = _checkOptionIsCheck(productOption.name);
|
|
|
|
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
|
// Utils.jsonPrettyPrint(extraJson);
|
|
|
|
double extraAdjustAmount = 0.0;
|
|
|
|
if (extraJson != null) {
|
|
var sizeBaseAdjustment = Rule.getRule(extraJson, Rule.RULE_ADJUSTMENT_BASED_ON_SELECTED_FIELD_VALUE);
|
|
if (sizeBaseAdjustment != null) {
|
|
if (sizeBaseAdjustment is List) {
|
|
for (var i = 0; i < (sizeBaseAdjustment as List).length; i++) {
|
|
Map<String, dynamic> sizeBaseAdjustment1 = sizeBaseAdjustment[i];
|
|
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
|
if (attValues.length > 0 && sizeBaseAdjustment1.containsKey(attValues[0])) {
|
|
extraAdjustAmount += sizeBaseAdjustment1[attValues[0]];
|
|
}
|
|
}
|
|
} else {
|
|
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
|
if (attValues.length > 0 && sizeBaseAdjustment.containsKey(attValues[0])) {
|
|
extraAdjustAmount += sizeBaseAdjustment[attValues[0]];
|
|
}
|
|
}
|
|
}
|
|
|
|
var disabledRule = Rule.getRule(extraJson, Rule.RULE_DISABLED_IF_FIELD_EQUALS_TO);
|
|
if (disabledRule != null) {
|
|
if (disabledRule is List) {
|
|
for (var i = 0; i < (disabledRule as List).length; i++) {
|
|
Map<String, dynamic> disabledRule1 = disabledRule[i];
|
|
List<String> attValues = Utils.getSelectedAttributeValue(selections, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
|
if (attValues.length > 0 && disabledRule1.containsKey(attValues[0])) {
|
|
disabled = true;
|
|
}
|
|
}
|
|
} else {
|
|
List<String> attValues = Utils.getSelectedAttributeValue(selections, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
|
if (attValues.length > 0 && disabledRule.containsKey(attValues[0])) {
|
|
disabled = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return new GestureDetector(
|
|
child: new Container(
|
|
width: 100.0,
|
|
height: 70.0,
|
|
decoration: BoxDecoration(
|
|
color: disabled ? disabledBackgroundColor : (check ? selectedBackgroundColor : deselectBackgroundColor),
|
|
shape: BoxShape.rectangle,
|
|
border: new Border.all(
|
|
color: check ? selectedBorderColor : deselectBorderColor,
|
|
width: 1.0,
|
|
),
|
|
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
|
),
|
|
padding: new EdgeInsets.all(4.0),
|
|
margin: new EdgeInsets.all(10.0).copyWith(right: 0.0),
|
|
child: new Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
new Text(
|
|
productOption.name,
|
|
style: new TextStyle(
|
|
fontSize: 14.0,
|
|
color: check ? selectedTextColor : deselectTextColor,
|
|
),
|
|
maxLines: 2,
|
|
softWrap: true,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
new Text(
|
|
(productOption.adjustAmount + extraAdjustAmount) > 0 ? '+${(productOption.adjustAmount + extraAdjustAmount).toStringAsFixed(2)}' : '',
|
|
style: new TextStyle(
|
|
fontSize: 11.0,
|
|
color: check ? selectedTextColor : new Color(0xFFABABAB),
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
)
|
|
],
|
|
),
|
|
),
|
|
onTap: () => disabled ? null : _onOptionTappedCallback(
|
|
productOption.name, 0, productOption.adjustAmount + extraAdjustAmount, optIndex, productOption),
|
|
);
|
|
}
|
|
|
|
void setOptionsStateDisabled(String attrName, bool disabled) {
|
|
if (optionsState.containsKey(attrName)) {
|
|
Map<String, dynamic> optionState = optionsState[attrName];
|
|
for (var i = 0; i < optionState.length; i++) {
|
|
optionState[i]['disabled'] = disabled;
|
|
}
|
|
}
|
|
}
|
|
} |