diff --git a/lib/inventree/stock.dart b/lib/inventree/stock.dart index 50ff635a..baaf4151 100644 --- a/lib/inventree/stock.dart +++ b/lib/inventree/stock.dart @@ -179,15 +179,7 @@ class InvenTreeStockItem extends InvenTreeModel { Future addStock(double quan) async { - // Cannot add stock to a serialized StockItem - if (isSerialized()) { - return null; - } - - // Cannot add negative stock - if (quan <= 0) { - return null; - } + if (isSerialized() || quan <= 0) return null; return api.post("/stock/add/", body: { "item": { @@ -197,6 +189,18 @@ class InvenTreeStockItem extends InvenTreeModel { }); } + Future removeStock(double quan) async { + + if (isSerialized() || quan <= 0) return null; + + return api.post("/stock/remove/", body: { + "item": { + "pk": "${pk}", + "quantity": "${quan}", + } + }); + } + } diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart index 7e88d375..de365939 100644 --- a/lib/widget/stock_detail.dart +++ b/lib/widget/stock_detail.dart @@ -28,7 +28,7 @@ class StockDetailWidget extends StatefulWidget { class _StockItemDisplayState extends State { final _addStockKey = GlobalKey(); - final _takeStockKey = GlobalKey(); + final _removeStockKey = GlobalKey(); final _countStockKey = GlobalKey(); final _moveStockKey = GlobalKey(); @@ -82,7 +82,7 @@ class _StockItemDisplayState extends State { decoration: InputDecoration( labelText: "Add stock", ), - keyboardType: TextInputType.numberWithOptions(signed:false, decimal:true), + keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), validator: (value) { if (value.isEmpty) return "Value cannot be empty"; @@ -104,8 +104,65 @@ class _StockItemDisplayState extends State { // TODO - Form for adding stock } - void _removeStock() { - // TODO - Form for removing stock + void _removeStock(double quantity) async { + Navigator.of(context).pop(); + + var response = await item.removeStock(quantity); + + // TODO - Handle error cases + + await item.reload(); + + setState(() {}); + } + + void _removeStockDialog() { + showDialog(context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text("Remove Stock"), + actions: [ + FlatButton( + child: Text("Remove"), + onPressed: () { + _removeStockKey.currentState.validate(); + }, + ) + ], + content: Form( + key: _removeStockKey, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Current quantity: ${item.quantity}"), + TextFormField( + decoration: InputDecoration( + labelText: "Remove stock", + ), + keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), + validator: (value) { + if (value.isEmpty) return "Value cannot be empty"; + + double quantity = double.tryParse(value); + + if (quantity == null) return "Value cannot be converted to a number"; + if (quantity <= 0) return "Value must be positive"; + + if (quantity > item.quantity) return "Cannot take more than current quantity"; + + _removeStock(quantity); + + return null; + }, + ) + ], + ) + ), + ); + } + ); } void _countStock(double quantity) async { @@ -169,7 +226,12 @@ class _StockItemDisplayState extends State { ); } - void _transferStock() { + + void _transferStock(int location) { + // TODO + } + + void _transferStockDialog() { // TODO - Form for transferring stock } @@ -326,7 +388,7 @@ class _StockItemDisplayState extends State { buttons.add(SpeedDialChild( child: Icon(FontAwesomeIcons.minusCircle), label: "Remove Stock", - onTap: _removeStock, + onTap: _removeStockDialog, ), ); @@ -340,7 +402,7 @@ class _StockItemDisplayState extends State { buttons.add(SpeedDialChild( child: Icon(FontAwesomeIcons.exchangeAlt), label: "Transfer Stock", - onTap: _transferStock, + onTap: _transferStockDialog, )); return buttons;