mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 13:36:50 +00:00
Add support for "modern" stock actions via the API
- In the future, will have to deprecate support for the old ways - Probably v0.6.x?
This commit is contained in:
parent
91ec55967d
commit
ba41ebde73
10
lib/api.dart
10
lib/api.dart
@ -225,6 +225,8 @@ class InvenTreeAPI {
|
|||||||
// API version of the connected server
|
// API version of the connected server
|
||||||
int _apiVersion = 1;
|
int _apiVersion = 1;
|
||||||
|
|
||||||
|
int get apiVersion => _apiVersion;
|
||||||
|
|
||||||
// Getter for server version information
|
// Getter for server version information
|
||||||
String get version => _version;
|
String get version => _version;
|
||||||
|
|
||||||
@ -244,10 +246,14 @@ class InvenTreeAPI {
|
|||||||
// Ensure we only ever create a single instance of the API class
|
// Ensure we only ever create a single instance of the API class
|
||||||
static final InvenTreeAPI _api = InvenTreeAPI._internal();
|
static final InvenTreeAPI _api = InvenTreeAPI._internal();
|
||||||
|
|
||||||
|
// API endpoint for receiving purchase order line items was introduced in v12
|
||||||
bool supportPoReceive() {
|
bool supportPoReceive() {
|
||||||
|
return apiVersion >= 12;
|
||||||
|
}
|
||||||
|
|
||||||
// API endpoint for receiving purchase order line items was introduced in v12
|
// "Modern" API transactions were implemented in API v14
|
||||||
return _apiVersion >= 12;
|
bool supportModernStockTransactions() {
|
||||||
|
return apiVersion >= 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,6 +115,16 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
@override
|
@override
|
||||||
String get URL => "stock/";
|
String get URL => "stock/";
|
||||||
|
|
||||||
|
// URLs for performing stock actions
|
||||||
|
|
||||||
|
static String transferStockUrl() => "stock/transfer/";
|
||||||
|
|
||||||
|
static String countStockUrl() => "stock/count/";
|
||||||
|
|
||||||
|
static String addStockUrl() => "stock/add/";
|
||||||
|
|
||||||
|
static String removeStockUrl() => "stock/remove/";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get WEB_URL => "stock/item/";
|
String get WEB_URL => "stock/item/";
|
||||||
|
|
||||||
@ -474,7 +484,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
return response.isValid();
|
return response.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this once the server supports API metadata for this action
|
// TODO: Remove this function when we deprecate support for the old API
|
||||||
Future<bool> countStock(BuildContext context, double q, {String? notes}) async {
|
Future<bool> countStock(BuildContext context, double q, {String? notes}) async {
|
||||||
|
|
||||||
final bool result = await adjustStock(context, "/stock/count/", q, notes: notes);
|
final bool result = await adjustStock(context, "/stock/count/", q, notes: notes);
|
||||||
@ -482,7 +492,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this once the server supports API metadata for this action
|
// TODO: Remove this function when we deprecate support for the old API
|
||||||
Future<bool> addStock(BuildContext context, double q, {String? notes}) async {
|
Future<bool> addStock(BuildContext context, double q, {String? notes}) async {
|
||||||
|
|
||||||
final bool result = await adjustStock(context, "/stock/add/", q, notes: notes);
|
final bool result = await adjustStock(context, "/stock/add/", q, notes: notes);
|
||||||
@ -490,7 +500,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this once the server supports API metadata for this action
|
// TODO: Remove this function when we deprecate support for the old API
|
||||||
Future<bool> removeStock(BuildContext context, double q, {String? notes}) async {
|
Future<bool> removeStock(BuildContext context, double q, {String? notes}) async {
|
||||||
|
|
||||||
final bool result = await adjustStock(context, "/stock/remove/", q, notes: notes);
|
final bool result = await adjustStock(context, "/stock/remove/", q, notes: notes);
|
||||||
@ -498,7 +508,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this once the server supports API metadata for this action
|
// TODO: Remove this function when we deprecate support for the old API
|
||||||
Future<bool> transferStock(int location, {double? quantity, String? notes}) async {
|
Future<bool> transferStock(int location, {double? quantity, String? notes}) async {
|
||||||
if ((quantity == null) || (quantity < 0) || (quantity > this.quantity)) {
|
if ((quantity == null) || (quantity < 0) || (quantity > this.quantity)) {
|
||||||
quantity = this.quantity;
|
quantity = this.quantity;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
import "package:flutter/cupertino.dart";
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
|
import "package:dropdown_search/dropdown_search.dart";
|
||||||
|
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||||
|
|
||||||
import "package:inventree/app_colors.dart";
|
import "package:inventree/app_colors.dart";
|
||||||
import "package:inventree/barcode.dart";
|
import "package:inventree/barcode.dart";
|
||||||
import "package:inventree/inventree/model.dart";
|
import "package:inventree/inventree/model.dart";
|
||||||
@ -12,15 +18,11 @@ import "package:inventree/widget/refreshable_state.dart";
|
|||||||
import "package:inventree/widget/snacks.dart";
|
import "package:inventree/widget/snacks.dart";
|
||||||
import "package:inventree/widget/stock_item_test_results.dart";
|
import "package:inventree/widget/stock_item_test_results.dart";
|
||||||
import "package:inventree/widget/stock_notes.dart";
|
import "package:inventree/widget/stock_notes.dart";
|
||||||
import "package:flutter/cupertino.dart";
|
|
||||||
import "package:flutter/material.dart";
|
|
||||||
|
|
||||||
import "package:inventree/l10.dart";
|
import "package:inventree/l10.dart";
|
||||||
import "package:inventree/helpers.dart";
|
import "package:inventree/helpers.dart";
|
||||||
import "package:inventree/api.dart";
|
import "package:inventree/api.dart";
|
||||||
|
import "package:inventree/api_form.dart";
|
||||||
|
|
||||||
import "package:dropdown_search/dropdown_search.dart";
|
|
||||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
|
||||||
|
|
||||||
class StockDetailWidget extends StatefulWidget {
|
class StockDetailWidget extends StatefulWidget {
|
||||||
|
|
||||||
@ -140,6 +142,39 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
Future <void> _addStockDialog() async {
|
Future <void> _addStockDialog() async {
|
||||||
|
|
||||||
|
// TODO: In future, deprecate support for older API
|
||||||
|
if (InvenTreeAPI().supportModernStockTransactions()) {
|
||||||
|
|
||||||
|
Map<String, dynamic> fields = {
|
||||||
|
"pk": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"hidden": true,
|
||||||
|
"value": item.pk,
|
||||||
|
},
|
||||||
|
"quantity": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"value": 0,
|
||||||
|
},
|
||||||
|
"notes": {},
|
||||||
|
};
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
L10().addStock,
|
||||||
|
InvenTreeStockItem.addStockUrl(),
|
||||||
|
fields,
|
||||||
|
method: "POST",
|
||||||
|
icon: FontAwesomeIcons.plusCircle,
|
||||||
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_quantityController.clear();
|
_quantityController.clear();
|
||||||
_notesController.clear();
|
_notesController.clear();
|
||||||
|
|
||||||
@ -186,6 +221,38 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
void _removeStockDialog() {
|
void _removeStockDialog() {
|
||||||
|
|
||||||
|
// TODO: In future, deprecate support for the older API
|
||||||
|
if (InvenTreeAPI().supportModernStockTransactions()) {
|
||||||
|
Map<String, dynamic> fields = {
|
||||||
|
"pk": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"hidden": true,
|
||||||
|
"value": item.pk,
|
||||||
|
},
|
||||||
|
"quantity": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"value": 0,
|
||||||
|
},
|
||||||
|
"notes": {},
|
||||||
|
};
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
L10().addStock,
|
||||||
|
InvenTreeStockItem.removeStockUrl(),
|
||||||
|
fields,
|
||||||
|
method: "POST",
|
||||||
|
icon: FontAwesomeIcons.minusCircle,
|
||||||
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_quantityController.clear();
|
_quantityController.clear();
|
||||||
_notesController.clear();
|
_notesController.clear();
|
||||||
|
|
||||||
@ -225,6 +292,39 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
Future <void> _countStockDialog() async {
|
Future <void> _countStockDialog() async {
|
||||||
|
|
||||||
|
// TODO: In future, deprecate support for older API
|
||||||
|
if (InvenTreeAPI().supportModernStockTransactions()) {
|
||||||
|
|
||||||
|
Map<String, dynamic> fields = {
|
||||||
|
"pk": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"hidden": true,
|
||||||
|
"value": item.pk,
|
||||||
|
},
|
||||||
|
"quantity": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"value": item.quantity,
|
||||||
|
},
|
||||||
|
"notes": {},
|
||||||
|
};
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
L10().addStock,
|
||||||
|
InvenTreeStockItem.countStockUrl(),
|
||||||
|
fields,
|
||||||
|
method: "POST",
|
||||||
|
icon: FontAwesomeIcons.plusCircle,
|
||||||
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_quantityController.text = item.quantity.toString();
|
_quantityController.text = item.quantity.toString();
|
||||||
_notesController.clear();
|
_notesController.clear();
|
||||||
|
|
||||||
@ -271,6 +371,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Delete this function once support for old API is deprecated
|
||||||
Future <void> _transferStock(int locationId) async {
|
Future <void> _transferStock(int locationId) async {
|
||||||
|
|
||||||
double quantity = double.tryParse(_quantityController.text) ?? item.quantity;
|
double quantity = double.tryParse(_quantityController.text) ?? item.quantity;
|
||||||
@ -288,8 +389,45 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Launches an API Form to transfer this stock item to a new location
|
||||||
|
*/
|
||||||
Future <void> _transferStockDialog(BuildContext context) async {
|
Future <void> _transferStockDialog(BuildContext context) async {
|
||||||
|
|
||||||
|
// TODO: In future, deprecate support for older API
|
||||||
|
if (InvenTreeAPI().supportModernStockTransactions()) {
|
||||||
|
|
||||||
|
Map<String, dynamic> fields = {
|
||||||
|
"pk": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"hidden": true,
|
||||||
|
"value": item.pk,
|
||||||
|
},
|
||||||
|
"quantity": {
|
||||||
|
"parent": "items",
|
||||||
|
"nested": true,
|
||||||
|
"value": item.quantity,
|
||||||
|
},
|
||||||
|
"location": {},
|
||||||
|
"notes": {},
|
||||||
|
};
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
L10().transferStock,
|
||||||
|
InvenTreeStockItem.transferStockUrl(),
|
||||||
|
fields,
|
||||||
|
method: "POST",
|
||||||
|
icon: FontAwesomeIcons.dolly,
|
||||||
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int? location_pk;
|
int? location_pk;
|
||||||
|
|
||||||
_quantityController.text = "${item.quantity}";
|
_quantityController.text = "${item.quantity}";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user