Add full app source
Adds the Flutter inventory app source, cleaned up for a shared repo: generic package name, no hardcoded ERP endpoints (moved to gitignored local config), no dead auth code, no debug logging of session data.
This commit is contained in:
139
lib/models/product.dart
Normal file
139
lib/models/product.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
import 'package:inventory_app/utils.dart';
|
||||
|
||||
class Product {
|
||||
Unit? unit;
|
||||
Unit? purchaseUnit;
|
||||
String? code;
|
||||
String? name;
|
||||
int? id;
|
||||
int? version;
|
||||
String? productTypeSelect; // must be int, not String
|
||||
int? familleProduit; // will be sent as object {id: X}
|
||||
int? sousFamilleProduit; // same
|
||||
String? internalDescription; // custom logic (not Axelor default field)
|
||||
String? serialNumber;
|
||||
String? description;
|
||||
MetaFile? picture;
|
||||
String? procurementMethodSelect = 'buy';
|
||||
|
||||
Product({
|
||||
this.unit,
|
||||
this.purchaseUnit,
|
||||
this.code,
|
||||
this.name,
|
||||
this.id,
|
||||
this.version,
|
||||
this.productTypeSelect, // use 0,1,2
|
||||
this.familleProduit,
|
||||
this.sousFamilleProduit,
|
||||
this.internalDescription,
|
||||
this.serialNumber,
|
||||
this.description,
|
||||
this.picture,
|
||||
this.procurementMethodSelect,
|
||||
});
|
||||
|
||||
Product.fromJson(Map<String, dynamic> json) {
|
||||
unit = json['unit'] != null ? Unit.fromJson(json['unit']) : null;
|
||||
purchaseUnit =
|
||||
json['purchaseUnit'] != null
|
||||
? Unit.fromJson(json['purchaseUnit'])
|
||||
: null;
|
||||
code = json['code'];
|
||||
name = json['name'];
|
||||
id = json['id'];
|
||||
version = json['version'];
|
||||
productTypeSelect = json['productTypeSelect'];
|
||||
familleProduit = json['familleProduit']?['id']; // Axelor wraps it in object
|
||||
sousFamilleProduit = json['sousFamilleProduit']?['id'];
|
||||
internalDescription = json['internalDescription'];
|
||||
serialNumber = json['serialNumber'];
|
||||
description = json['description'];
|
||||
picture =
|
||||
json['picture'] != null ? MetaFile.fromJson(json['picture']) : null;
|
||||
procurementMethodSelect = json['procurementMethodSelect'] ?? 'buy';
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = {};
|
||||
|
||||
if (unit != null) {
|
||||
data['unit'] = unit!.toJson();
|
||||
}
|
||||
if (purchaseUnit != null) {
|
||||
data['purchaseUnit'] = purchaseUnit!.toJson();
|
||||
}
|
||||
if (code != null) data['code'] = code;
|
||||
if (name != null) data['name'] = name;
|
||||
if (id != null) data['id'] = id;
|
||||
if (version != null) data['version'] = version;
|
||||
|
||||
if (productTypeSelect != null) {
|
||||
data['productTypeSelect'] = productTypeSelect; // ✅ must be int
|
||||
}
|
||||
|
||||
// ✅ Axelor expects {"id": X}, NOT raw int
|
||||
if (familleProduit != null) {
|
||||
data['familleProduit'] = {'id': familleProduit};
|
||||
}
|
||||
if (sousFamilleProduit != null) {
|
||||
data['sousFamilleProduit'] = {'id': sousFamilleProduit};
|
||||
}
|
||||
|
||||
data['internalDescription'] = internalDescription;
|
||||
data['serialNumber'] = serialNumber;
|
||||
data['description'] = description;
|
||||
data['procurementMethodSelect'] = procurementMethodSelect;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Product{unit: $unit, code: $code, name: $name, id: $id, version: $version, productTypeSelect: $productTypeSelect, familleProduit: $familleProduit, sousFamilleProduit: $sousFamilleProduit, internalDescription: $internalDescription, serialNumber: $serialNumber, description: $description}';
|
||||
}
|
||||
|
||||
/// 👇 Get full image URL (you can customize baseUrl to be from `AxelorClient.baseUrl`)
|
||||
String? get imageUrl {
|
||||
if (picture?.id != null) {
|
||||
return '${Utils.url}/ws/rest/com.axelor.meta.db.MetaFile/${picture!.id}/content/download';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class Unit {
|
||||
String? name;
|
||||
int? id;
|
||||
int? version;
|
||||
|
||||
Unit({this.name, this.id, this.version});
|
||||
|
||||
Unit.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
id = json['id'];
|
||||
version = json['version'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'name': name, 'id': id, 'version': version};
|
||||
}
|
||||
}
|
||||
|
||||
class MetaFile {
|
||||
String? fileName;
|
||||
int? id;
|
||||
int? version;
|
||||
|
||||
MetaFile({this.fileName, this.id, this.version});
|
||||
|
||||
MetaFile.fromJson(Map<String, dynamic> json) {
|
||||
fileName = json['fileName'];
|
||||
id = json['id'];
|
||||
version = json['$version'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'fileName': fileName, 'id': id, '\$version': version};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user