mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 21:16:48 +00:00
* Change from fontawesome to tabler icons - Consistent with the frontend * Cleanup conflicts * Use double quotes * remove unused import * Update release notes * Migrate some google icons to tabler icons * Icon update * Properly support display of custom icons * Fix lookup
176 lines
4.4 KiB
Dart
176 lines
4.4 KiB
Dart
import "package:flutter/material.dart";
|
|
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
|
import "package:inventree/api_form.dart";
|
|
|
|
import "package:inventree/inventree/part.dart";
|
|
import "package:inventree/inventree/sales_order.dart";
|
|
import "package:one_context/one_context.dart";
|
|
|
|
import "package:inventree/l10.dart";
|
|
|
|
import "package:inventree/barcode/barcode.dart";
|
|
import "package:inventree/barcode/handler.dart";
|
|
import "package:inventree/barcode/tones.dart";
|
|
|
|
import "package:inventree/widget/snacks.dart";
|
|
|
|
|
|
/*
|
|
* Barcode handler class for scanning a new part into a SalesOrder
|
|
*/
|
|
|
|
class SOAddItemBarcodeHandler extends BarcodeHandler {
|
|
|
|
SOAddItemBarcodeHandler({this.salesOrder});
|
|
|
|
InvenTreeSalesOrder? salesOrder;
|
|
|
|
@override
|
|
String getOverlayText(BuildContext context) => L10().barcodeScanPart;
|
|
|
|
@override
|
|
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
|
|
|
|
// Extract the part ID from the returned data
|
|
int part_id = -1;
|
|
|
|
if (data.containsKey("part")) {
|
|
part_id = (data["part"] ?? {} as Map<String, dynamic>)["pk"] as int;
|
|
}
|
|
|
|
if (part_id <= 0) {
|
|
return onBarcodeUnknown(data);
|
|
}
|
|
|
|
// Request the part from the server
|
|
var part = await InvenTreePart().get(part_id);
|
|
|
|
if (part is InvenTreePart) {
|
|
|
|
if (part.isSalable) {
|
|
// Dispose of the barcode scanner
|
|
if (OneContext.hasContext) {
|
|
OneContext().pop();
|
|
}
|
|
|
|
final context = OneContext().context!;
|
|
|
|
var fields = InvenTreeSOLineItem().formFields();
|
|
|
|
fields["order"]?["value"] = salesOrder!.pk;
|
|
fields["order"]?["hidden"] = true;
|
|
|
|
fields["part"]?["value"] = part.pk;
|
|
fields["part"]?["hidden"] = false;
|
|
|
|
InvenTreeSOLineItem().createForm(
|
|
context,
|
|
L10().lineItemAdd,
|
|
fields: fields,
|
|
);
|
|
|
|
} else {
|
|
barcodeFailureTone();
|
|
showSnackIcon(L10().partNotSalable, success: false);
|
|
}
|
|
|
|
} else {
|
|
// Failed to fetch part
|
|
return onBarcodeUnknown(data);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
class SOAllocateStockHandler extends BarcodeHandler {
|
|
|
|
SOAllocateStockHandler({this.salesOrder, this.lineItem, this.shipment});
|
|
|
|
InvenTreeSalesOrder? salesOrder;
|
|
InvenTreeSOLineItem? lineItem;
|
|
InvenTreeSalesOrderShipment? shipment;
|
|
|
|
@override
|
|
String getOverlayText(BuildContext context) => L10().allocateStock;
|
|
|
|
@override
|
|
Future<void> processBarcode(String barcode,
|
|
{
|
|
String url = "barcode/so-allocate/",
|
|
Map<String, dynamic> extra_data = const {}}) {
|
|
|
|
final so_extra_data = {
|
|
"sales_order": salesOrder?.pk,
|
|
"shipment": shipment?.pk,
|
|
"line": lineItem?.pk,
|
|
...extra_data
|
|
};
|
|
|
|
return super.processBarcode(barcode, url: url, extra_data: so_extra_data);
|
|
}
|
|
|
|
@override
|
|
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
|
|
if (!data.containsKey("line_item")) {
|
|
return onBarcodeUnknown(data);
|
|
}
|
|
|
|
barcodeSuccess(L10().allocated);
|
|
}
|
|
|
|
@override
|
|
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
|
|
|
|
if (!data.containsKey("action_required") || !data.containsKey("line_item")) {
|
|
return super.onBarcodeUnhandled(data);
|
|
}
|
|
|
|
// Prompt user for extra information to create the allocation
|
|
var fields = InvenTreeSOLineItem().allocateFormFields();
|
|
|
|
// Update fields with data gathered from the API response
|
|
fields["line_item"]?["value"] = data["line_item"];
|
|
|
|
Map<String, dynamic> stock_filters = {
|
|
"in_stock": true,
|
|
"available": true,
|
|
};
|
|
|
|
if (data.containsKey("part")) {
|
|
stock_filters["part"] = data["part"];
|
|
}
|
|
|
|
fields["stock_item"]?["filters"] = stock_filters;
|
|
fields["stock_item"]?["value"] = data["stock_item"];
|
|
|
|
fields["quantity"]?["value"] = data["quantity"];
|
|
|
|
fields["shipment"]?["value"] = data["shipment"];
|
|
fields["shipment"]?["filters"] = {
|
|
"order": salesOrder!.pk.toString()
|
|
};
|
|
|
|
final context = OneContext().context!;
|
|
|
|
launchApiForm(
|
|
context,
|
|
L10().allocateStock,
|
|
salesOrder!.allocate_url,
|
|
fields,
|
|
method: "POST",
|
|
icon: TablerIcons.transition_right,
|
|
onSuccess: (data) async {
|
|
showSnackIcon(L10().allocated, success: true);
|
|
});
|
|
}
|
|
|
|
@override
|
|
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
|
|
barcodeFailureTone();
|
|
showSnackIcon(
|
|
data["error"] as String? ?? L10().barcodeError,
|
|
success: false
|
|
);
|
|
}
|
|
} |