This commit is contained in:
Hillel Coren 2019-08-26 07:08:26 +03:00
parent 0d7847b5e3
commit 6005996fa5
7 changed files with 53 additions and 48 deletions

View File

@ -4,14 +4,18 @@ class DecoratedFormField extends StatelessWidget {
const DecoratedFormField({
@required this.controller,
@required this.label,
this.autovalidate = false,
this.validator,
this.keyboardType,
this.maxLines,
});
final TextEditingController controller;
final String label;
final Function(String) validator;
final TextInputType keyboardType;
final int maxLines;
final bool autovalidate;
@override
Widget build(BuildContext context) {
@ -24,6 +28,8 @@ class DecoratedFormField extends StatelessWidget {
),
validator: validator,
keyboardType: null,
maxLines: maxLines,
autovalidate: autovalidate,
);
}
}

View File

@ -1,5 +1,6 @@
import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/invoice_item_view.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart';
@ -217,20 +218,14 @@ class ItemEditDetailsState extends State<ItemEditDetails> {
),
],
),
TextFormField(
autocorrect: false,
DecoratedFormField(
label: localization.product,
controller: _productKeyController,
decoration: InputDecoration(
labelText: localization.product,
),
),
TextFormField(
autocorrect: false,
DecoratedFormField(
label: localization.description,
controller: _notesController,
maxLines: 4,
decoration: InputDecoration(
labelText: localization.description,
),
),
CustomField(
controller: _custom1Controller,
@ -242,31 +237,25 @@ class ItemEditDetailsState extends State<ItemEditDetails> {
labelText: company.getCustomFieldLabel(CustomFieldType.product2),
options: company.getCustomFieldValues(CustomFieldType.product2),
),
TextFormField(
DecoratedFormField(
label: localization.unitCost,
controller: _costController,
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: localization.unitCost,
),
),
company.hasInvoiceField('quantity')
? TextFormField(
? DecoratedFormField(
label: localization.quantity,
controller: _qtyController,
keyboardType:
TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: localization.quantity,
),
)
: Container(),
company.hasInvoiceField('discount')
? TextFormField(
? DecoratedFormField(
label: localization.discount,
controller: _discountController,
keyboardType:
TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: localization.discount,
),
)
: Container(),
company.enableInvoiceItemTaxes

View File

@ -172,6 +172,7 @@ class _InvoiceItemSelectorState extends State<InvoiceItemSelector>
)
: IconButton(
icon: Icon(Icons.add_circle_outline),
tooltip: localization.createNew,
onPressed: () => _addBlankItem(),
),
],

View File

@ -1,6 +1,7 @@
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/foundation.dart';
@ -148,25 +149,18 @@ class _ProductEditState extends State<ProductEdit> {
children: <Widget>[
FormCard(
children: <Widget>[
TextFormField(
key: Key(localization.productKey),
DecoratedFormField(
label: localization.product,
controller: _productKeyController,
autocorrect: false,
decoration: InputDecoration(
labelText: localization.product,
),
validator: (val) => val.isEmpty || val.trim().isEmpty
? localization.pleaseEnterAProductKey
: null,
autovalidate: autoValidate,
),
TextFormField(
key: Key(localization.notes),
DecoratedFormField(
label: localization.description,
controller: _notesController,
maxLines: 4,
decoration: InputDecoration(
labelText: localization.notes,
),
),
CustomField(
controller: _custom1Controller,
@ -182,14 +176,11 @@ class _ProductEditState extends State<ProductEdit> {
options:
company.getCustomFieldValues(CustomFieldType.product2),
),
TextFormField(
key: Key(localization.cost),
DecoratedFormField(
label: localization.cost,
controller: _costController,
keyboardType:
TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: localization.cost,
),
),
company.enableInvoiceItemTaxes
? TaxRateDropdown(

View File

@ -12,6 +12,9 @@ void main() {
final clientName = makeUnique(faker.company.name());
final poNumber =
faker.randomGenerator.integer(999999, min: 100000).toString();
final productKey = makeUnique(faker.food.cuisine());
final description = faker.lorem.sentences(5).toString();
final cost = faker.randomGenerator.decimal(min: 50, scale: 10).toStringAsFixed(2);
final updatedPoNumber =
faker.randomGenerator.integer(999999, min: 100000).toString();
@ -61,15 +64,29 @@ void main() {
print('Tap new invoice');
await driver.tap(find.byTooltip(localization.newInvoice));
print('Fill form: $clientName');
print('Create new client: $clientName');
await driver.tap(find.byValueKey(localization.client));
await driver.tap(find.byTooltip(localization.createNew));
print('Fill the client form');
await fillTextField(
driver: driver, field: localization.name, value: clientName);
await driver.tap(find.text(localization.save));
print('Fill the invoice form');
await driver.tap(find.byTooltip(localization.addItem));
await driver.tap(find.byTooltip(localization.createNew));
await fillTextFields(driver, <String, String>{
localization.product: productKey,
localization.description: description,
localization.unitCost: cost,
localization.quantity: '1',
});
await driver.tap(find.text(localization.done));
await driver.tap(find.text(localization.details));
await fillAndSaveForm(driver, <String, String>{
localization.poNumber: poNumber,
});

View File

@ -10,11 +10,11 @@ void main() {
FlutterDriver driver;
final productKey = makeUnique(faker.food.cuisine());
final notes = faker.food.dish();
final description = faker.food.dish();
final cost = faker.randomGenerator.decimal(min: 50).toStringAsFixed(2);
final updatedProductKey = makeUnique(faker.food.cuisine());
final updatedNotes = faker.food.dish();
final updatedDescription = faker.food.dish();
final updatedCost =
faker.randomGenerator.decimal(min: 50).toStringAsFixed(2);
@ -65,8 +65,8 @@ void main() {
print('Fill form: $productKey');
await fillAndSaveForm(driver, <String, dynamic>{
localization.productKey: productKey,
localization.notes: notes,
localization.product: productKey,
localization.description: description,
localization.cost: cost,
});
@ -91,8 +91,8 @@ void main() {
await driver.tap(find.text(localization.edit));
await fillAndSaveForm(driver, <String, dynamic>{
localization.productKey: updatedProductKey,
localization.notes: updatedNotes,
localization.product: updatedProductKey,
localization.description: updatedDescription,
localization.cost: updatedCost,
});
});

View File

@ -34,13 +34,15 @@ Future<void> login(FlutterDriver driver,
String loginSecret = Config.TEST_SECRET}) async {
final localization = TestLocalization('en');
if (selfHosted) {
await driver.tap(find.byValueKey(localization.selfhostLogin));
}
await fillTextFields(driver, <String, dynamic>{
localization.email: loginEmail,
localization.password: loginPassword,
});
if (selfHosted) {
await driver.tap(find.byValueKey(localization.selfhostLogin));
await fillTextFields(driver, <String, dynamic>{
localization.url: loginUrl,
localization.secret: loginSecret,
@ -104,7 +106,6 @@ Future<void> checkTextFields(
Future<void> fillAndSaveForm(
FlutterDriver driver, Map<String, dynamic> values) async {
final localization = TestLocalization('en');
print('Fill in form');