2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-05-10 19:28:51 +00:00
inventree-app/lib/inventree/purchase_order.dart
Oliver 76b6191a67
Token auth (#434)
* Embed device platform information into token request

* Remove username and password from userProfile

* Display icon to show if profile has associated user token

* Remove username / password from login settings screen

* Refactor login procedure around token auth

* Refactoring

* Add profile login screen

- Username / password values are not stored
- Just to fetch api token

* Login with basic auth

* Pass profile to API when connecting

* Remove _BASE_URL accessor

- Fixes URL caching bug

* Add more context to login screen

* Add helper functions for unit tests

- Change default port to 8000 (makes testing easier with local inventree instance)

* api.dart handles basic auth now

* fix api_test.dart

* Further test improvements

* linting fixes

* Provide feedback when login fails

* More linting

* Record user details on login, and display in "about" widget

* Fix string lookup

* Add extra debug

* Fix auth values

* Fix user profile test
2023-10-23 01:29:16 +11:00

314 lines
7.5 KiB
Dart

import "package:inventree/api.dart";
import "package:inventree/helpers.dart";
import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/model.dart";
const int PO_STATUS_PENDING = 10;
const int PO_STATUS_PLACED = 20;
const int PO_STATUS_COMPLETE = 30;
const int PO_STATUS_CANCELLED = 40;
const int PO_STATUS_LOST = 50;
const int PO_STATUS_RETURNED = 60;
class InvenTreePurchaseOrder extends InvenTreeModel {
InvenTreePurchaseOrder() : super();
InvenTreePurchaseOrder.fromJson(Map<String, dynamic> json) : super.fromJson(json);
@override
String get URL => "order/po/";
@override
List<String> get rolesRequired => ["purchase_order"];
String get receive_url => "${url}receive/";
@override
Map<String, dynamic> formFields() {
var fields = {
"reference": {},
"supplier": {
"filters": {
"is_supplier": true,
},
},
"supplier_reference": {},
"description": {},
"project_code": {},
"target_date": {},
"link": {},
"responsible": {},
"contact": {
"filters": {
"company": supplierId,
}
},
};
if (!InvenTreeAPI().supportsProjectCodes) {
fields.remove("project_code");
}
return fields;
}
@override
Map<String, String> defaultGetFilters() {
return {
"supplier_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return {
"supplier_detail": "true",
};
}
String get issueDate => getString("issue_date");
String get completeDate => getString("complete_date");
String get creationDate => getString("creation_date");
String get targetDate => getString("target_date");
int get lineItemCount => getInt("line_items", backup: 0);
bool get overdue => getBool("overdue");
String get reference => getString("reference");
int get responsibleId => getInt("responsible");
int get supplierId => getInt("supplier");
// Project code information
int get projectCodeId => getInt("project_code");
String get projectCode => getString("code", subKey: "project_code_detail");
String get projectCodeDescription => getString("description", subKey: "project_code_detail");
bool get hasProjectCode => projectCode.isNotEmpty;
InvenTreeCompany? get supplier {
dynamic supplier_detail = jsondata["supplier_detail"];
if (supplier_detail == null) {
return null;
} else {
return InvenTreeCompany.fromJson(supplier_detail as Map<String, dynamic>);
}
}
String get supplierReference => getString("supplier_reference");
int get status => getInt("status");
String get statusText => getString("status_text");
bool get isOpen => status == PO_STATUS_PENDING || status == PO_STATUS_PLACED;
bool get isPending => status == PO_STATUS_PENDING;
bool get isPlaced => status == PO_STATUS_PLACED;
bool get isFailed => status == PO_STATUS_CANCELLED || status == PO_STATUS_LOST || status == PO_STATUS_RETURNED;
double? get totalPrice {
String price = getString("total_price");
if (price.isEmpty) {
return null;
} else {
return double.tryParse(price);
}
}
// Return the currency for this order
// Note that the nomenclature in the API changed at some point
String get totalPriceCurrency {
if (jsondata.containsKey("order_currency")) {
return getString("order_currency");
} else if (jsondata.containsKey("total_price_currency")) {
return getString("total_price_currency");
} else {
return "";
}
}
Future<List<InvenTreePOLineItem>> getLineItems() async {
final results = await InvenTreePOLineItem().list(
filters: {
"order": "${pk}",
}
);
List<InvenTreePOLineItem> items = [];
for (var result in results) {
if (result is InvenTreePOLineItem) {
items.add(result);
}
}
return items;
}
@override
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePurchaseOrder.fromJson(json);
/// Mark this order as "placed" / "issued"
Future<void> issueOrder() async {
// Order can only be placed when the order is 'pending'
if (!isPending) {
return;
}
await api.post("${url}issue/", expectedStatusCode: 201);
}
/// Mark this order as "cancelled"
Future<void> cancelOrder() async {
if (!isOpen) {
return;
}
await api.post("${url}cancel/", expectedStatusCode: 201);
}
}
class InvenTreePOLineItem extends InvenTreeModel {
InvenTreePOLineItem() : super();
InvenTreePOLineItem.fromJson(Map<String, dynamic> json) : super.fromJson(json);
@override
String get URL => "order/po-line/";
@override
List<String> get rolesRequired => ["purchase_order"];
@override
Map<String, dynamic> formFields() {
return {
"part": {
// We cannot edit the supplier part field here
"hidden": true,
},
"order": {
// We cannot edit the order field here
"hidden": true,
},
"reference": {},
"quantity": {},
"purchase_price": {},
"purchase_price_currency": {},
"destination": {},
"notes": {},
"link": {},
};
}
@override
Map<String, String> defaultGetFilters() {
return {
"part_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return {
"part_detail": "true",
};
}
bool get isComplete => received >= quantity;
double get quantity => getDouble("quantity");
double get received => getDouble("received");
String get progressString => simpleNumberString(received) + " / " + simpleNumberString(quantity);
double get outstanding => quantity - received;
String get reference => getString("reference");
int get orderId => getInt("order");
int get supplierPartId => getInt("part");
InvenTreePart? get part {
dynamic part_detail = jsondata["part_detail"];
if (part_detail == null) {
return null;
} else {
return InvenTreePart.fromJson(part_detail as Map<String, dynamic>);
}
}
int get partId => getInt("pk", subKey: "part_detail");
String get partName => getString("name", subKey: "part_detail");
String get partImage => getString("thumbnail", subKey: "part_detail");
InvenTreeSupplierPart? get supplierPart {
dynamic detail = jsondata["supplier_part_detail"];
if (detail == null) {
return null;
} else {
return InvenTreeSupplierPart.fromJson(detail as Map<String, dynamic>);
}
}
String get SKU => getString("SKU", subKey: "supplier_part_detail");
double get purchasePrice => getDouble("purchase_price");
String get purchasePriceCurrency => getString("purchase_price_currency");
String get purchasePriceString => getString("purchase_price_string");
int get destination => getInt("destination");
Map<String, dynamic> get destinationDetail => getMap("destination_detail");
@override
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePOLineItem.fromJson(json);
}
/*
* Class representing an attachment file against a StockItem object
*/
class InvenTreePurchaseOrderAttachment extends InvenTreeAttachment {
InvenTreePurchaseOrderAttachment() : super();
InvenTreePurchaseOrderAttachment.fromJson(Map<String, dynamic> json) : super.fromJson(json);
@override
String get REFERENCE_FIELD => "order";
@override
String get URL => "order/po/attachment/";
@override
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePurchaseOrderAttachment.fromJson(json);
}