2023-03-18 20:28:30 +01:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:localstore/localstore.dart';
|
2023-03-24 17:47:47 +01:00
|
|
|
import 'package:outbag_app/tools/assets.dart';
|
2023-03-29 15:14:27 +02:00
|
|
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
2023-03-18 20:28:30 +01:00
|
|
|
|
|
|
|
class RoomVisibility {
|
|
|
|
final int type;
|
|
|
|
const RoomVisibility(this.type);
|
|
|
|
|
|
|
|
static RoomVisibility get private {
|
|
|
|
return const RoomVisibility(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomVisibility get local {
|
|
|
|
return const RoomVisibility(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomVisibility get public {
|
|
|
|
return const RoomVisibility(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconData get icon {
|
|
|
|
if (type == 2) {
|
|
|
|
return Icons.public;
|
|
|
|
} else if (type == 1) {
|
|
|
|
return Icons.home;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Icons.lock;
|
|
|
|
}
|
|
|
|
|
2023-03-29 15:14:27 +02:00
|
|
|
String text(BuildContext context) {
|
|
|
|
final trans = AppLocalizations.of(context);
|
|
|
|
|
2023-03-18 20:28:30 +01:00
|
|
|
if (type == 2) {
|
2023-03-29 15:14:27 +02:00
|
|
|
return trans!.roomVisibilityGlobal;
|
2023-03-18 20:28:30 +01:00
|
|
|
} else if (type == 1) {
|
2023-03-29 15:14:27 +02:00
|
|
|
return trans!.roomVisibilityLocal;
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
|
|
|
|
2023-03-29 15:14:27 +02:00
|
|
|
return trans!.roomVisibilityPrivate;
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static List<RoomVisibility> list() {
|
|
|
|
return [
|
|
|
|
RoomVisibility.private,
|
|
|
|
RoomVisibility.local,
|
|
|
|
RoomVisibility.public,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class RoomIcon {
|
|
|
|
final String type;
|
|
|
|
RoomIcon({required this.type});
|
|
|
|
|
|
|
|
static RoomIcon get love {
|
|
|
|
return RoomIcon(type: "Love");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get sports {
|
|
|
|
return RoomIcon(type: "Sports");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get pets {
|
|
|
|
return RoomIcon(type: "Pets");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get vacation {
|
|
|
|
return RoomIcon(type: "Vacation");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get gifts {
|
|
|
|
return RoomIcon(type: "Gifts");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get groceries {
|
|
|
|
return RoomIcon(type: "Groceries");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get fashion {
|
|
|
|
return RoomIcon(type: "Fashion");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get art {
|
|
|
|
return RoomIcon(type: "Art");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get tech {
|
|
|
|
return RoomIcon(type: "Tech");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get home {
|
|
|
|
return RoomIcon(type: "Home");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get family {
|
|
|
|
return RoomIcon(type: "Family");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get social {
|
|
|
|
return RoomIcon(type: "Social");
|
|
|
|
}
|
|
|
|
|
|
|
|
static RoomIcon get other {
|
|
|
|
return RoomIcon(type: "Other");
|
|
|
|
}
|
|
|
|
|
|
|
|
static List<RoomIcon> list() {
|
|
|
|
return [
|
|
|
|
RoomIcon.love,
|
|
|
|
RoomIcon.sports,
|
|
|
|
RoomIcon.pets,
|
|
|
|
RoomIcon.vacation,
|
|
|
|
RoomIcon.gifts,
|
|
|
|
RoomIcon.groceries,
|
|
|
|
RoomIcon.fashion,
|
|
|
|
RoomIcon.art,
|
|
|
|
RoomIcon.tech,
|
|
|
|
RoomIcon.home,
|
|
|
|
RoomIcon.family,
|
|
|
|
RoomIcon.social,
|
|
|
|
RoomIcon.other,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
String get text {
|
|
|
|
switch (type.toLowerCase()) {
|
|
|
|
case 'love':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Friends';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'sports':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Sports';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'pets':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Pets';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'vacation':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Vacation';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'gifts':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Gifts';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'groceries':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Groceries';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'fashion':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Clothing';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'art':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Arts & Crafts';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'tech':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Electronics';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'home':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Home supplies';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'family':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Family';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'social':
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Social';
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'other':
|
|
|
|
default:
|
2023-04-01 20:13:03 +02:00
|
|
|
return 'Other';
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// return image name
|
|
|
|
String get img {
|
2023-03-24 17:47:47 +01:00
|
|
|
String path = "";
|
2023-03-18 20:28:30 +01:00
|
|
|
switch (type.toLowerCase()) {
|
|
|
|
case 'love':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_couple.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'sports':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_greek_freak.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'pets':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_dog.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'vacation':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_trip.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'gifts':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_gifts.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'groceries':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_gone_shopping.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'fashion':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_jewelry.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'art':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_sculpting.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'tech':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_progressive_app.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'home':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_under_construction.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'family':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_family.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'social':
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_pizza_sharing.svg';
|
|
|
|
break;
|
2023-03-18 20:28:30 +01:00
|
|
|
case 'other':
|
|
|
|
default:
|
2023-04-01 20:13:03 +02:00
|
|
|
path = 'undraw/undraw_file_manager.svg';
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
2023-03-24 17:47:47 +01:00
|
|
|
|
|
|
|
return asset(path);
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Room {
|
2023-03-23 14:48:53 +01:00
|
|
|
String id;
|
|
|
|
String serverTag;
|
|
|
|
String name;
|
|
|
|
String description;
|
2023-03-18 20:28:30 +01:00
|
|
|
RoomIcon? icon = RoomIcon.other;
|
|
|
|
RoomVisibility? visibility = RoomVisibility.private;
|
|
|
|
|
|
|
|
Room(
|
2023-04-01 20:13:03 +02:00
|
|
|
{required this.id,
|
2023-03-18 20:28:30 +01:00
|
|
|
required this.serverTag,
|
|
|
|
this.name = "",
|
|
|
|
this.description = "",
|
|
|
|
this.icon,
|
|
|
|
this.visibility});
|
|
|
|
|
2023-03-31 21:52:14 +02:00
|
|
|
@override
|
|
|
|
bool operator ==(Object r) {
|
|
|
|
if (r.runtimeType != runtimeType) {
|
|
|
|
return false;
|
|
|
|
}
|
2023-03-23 14:48:53 +01:00
|
|
|
final me = humanReadable;
|
2023-03-31 21:52:14 +02:00
|
|
|
final other = (r as Room).humanReadable;
|
2023-03-23 14:48:53 +01:00
|
|
|
|
2023-03-31 21:52:14 +02:00
|
|
|
return me == other;
|
2023-03-23 14:48:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
String get humanReadable {
|
|
|
|
return '$id@$serverTag';
|
|
|
|
}
|
|
|
|
|
2023-03-18 20:28:30 +01:00
|
|
|
// get list of all known rooms
|
|
|
|
static Future<List<Room>> listRooms() async {
|
|
|
|
final db = Localstore.instance;
|
|
|
|
final rooms = (await db.collection('rooms').get())!;
|
|
|
|
List<Room> builder = [];
|
|
|
|
for (MapEntry entry in rooms.entries) {
|
|
|
|
try {
|
|
|
|
builder.add(Room.fromMap(entry.value));
|
|
|
|
} catch (e) {
|
|
|
|
// skip invalid rooms
|
|
|
|
// NOTE: might want to autodelete them in the future
|
|
|
|
// although keeping them might be ok,
|
|
|
|
// in case we ever get a new dataset to fix the current state
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return builder;
|
|
|
|
}
|
|
|
|
|
|
|
|
// listen to room change
|
|
|
|
static listen(Function(Map<String, dynamic>) cb) async {
|
|
|
|
final db = Localstore.instance;
|
|
|
|
final stream = db.collection('rooms').stream;
|
|
|
|
stream.listen(cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
factory Room.fromMap(Map<String, dynamic> map) {
|
|
|
|
return Room(
|
2023-04-01 20:13:03 +02:00
|
|
|
id: map['id'],
|
|
|
|
serverTag: map['server'],
|
|
|
|
name: map['name'],
|
|
|
|
description: map['description'] ?? '',
|
|
|
|
icon: RoomIcon(type: map['icon'] ?? 'Other'),
|
|
|
|
visibility: RoomVisibility(map['visibility'] ?? 0));
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
return {
|
|
|
|
'id': id,
|
|
|
|
'server': serverTag,
|
|
|
|
'description': description,
|
|
|
|
'name': name,
|
|
|
|
'icon': icon?.type,
|
|
|
|
'visibility': visibility?.type
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-03-20 20:45:49 +01:00
|
|
|
factory Room.fromJSON(dynamic json) {
|
|
|
|
return Room(
|
2023-04-01 20:13:03 +02:00
|
|
|
id: json['name'],
|
|
|
|
serverTag: json['server'],
|
|
|
|
name: json['title'],
|
|
|
|
description: json['description'],
|
|
|
|
icon: RoomIcon(type: json['icon']),
|
|
|
|
visibility: RoomVisibility(json['visibility']));
|
2023-03-20 20:45:49 +01:00
|
|
|
}
|
|
|
|
|
2023-03-18 20:28:30 +01:00
|
|
|
Future<void> toDisk() async {
|
|
|
|
final db = Localstore.instance;
|
|
|
|
await db.collection('rooms').doc('$id@$serverTag').set(toMap());
|
|
|
|
}
|
2023-03-22 21:12:04 +01:00
|
|
|
|
2023-03-23 08:58:34 +01:00
|
|
|
Future<void> removeDisk() async {
|
|
|
|
final db = Localstore.instance;
|
|
|
|
// NOTE: Because categories, products and entries
|
|
|
|
// are supposed to be stored in the room object
|
|
|
|
// (they are just not read by Room.fromDisk)
|
|
|
|
// deleting the document from the collection
|
|
|
|
// should also get rid of affiliated collections
|
|
|
|
await db.collection('rooms').doc('$id@$serverTag').delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<Room> fromDisk(
|
2023-04-01 20:13:03 +02:00
|
|
|
{required String id, required String serverTag}) async {
|
2023-03-22 21:12:04 +01:00
|
|
|
final db = Localstore.instance;
|
|
|
|
final raw = await db.collection('rooms').doc('$id@$serverTag').get();
|
|
|
|
return Room.fromMap(raw!);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class RoomMember {
|
|
|
|
final String id;
|
|
|
|
final String serverTag;
|
|
|
|
final bool isAdmin;
|
|
|
|
|
|
|
|
const RoomMember(
|
2023-04-01 20:13:03 +02:00
|
|
|
{required this.id, required this.serverTag, required this.isAdmin});
|
2023-03-22 21:12:04 +01:00
|
|
|
|
|
|
|
factory RoomMember.fromJSON(dynamic json) {
|
|
|
|
return RoomMember(
|
2023-04-01 20:13:03 +02:00
|
|
|
id: json['name'],
|
|
|
|
serverTag: json['server'],
|
|
|
|
isAdmin: json['admin'] == 1);
|
2023-03-24 21:10:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
String get humanReadableName {
|
|
|
|
return '$id@$serverTag';
|
2023-03-22 21:12:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class RoomInfo {
|
|
|
|
final String owner;
|
|
|
|
final bool isAdmin;
|
|
|
|
final bool isOwner;
|
|
|
|
final int permissions;
|
|
|
|
|
|
|
|
const RoomInfo(
|
2023-04-01 20:13:03 +02:00
|
|
|
{required this.permissions,
|
2023-03-22 21:12:04 +01:00
|
|
|
required this.owner,
|
|
|
|
required this.isAdmin,
|
|
|
|
required this.isOwner});
|
|
|
|
|
|
|
|
factory RoomInfo.fromJSON(dynamic json) {
|
|
|
|
return RoomInfo(
|
2023-04-01 20:13:03 +02:00
|
|
|
permissions: json['rights'],
|
|
|
|
owner: json['owner'],
|
|
|
|
isAdmin: json['isAdmin'],
|
|
|
|
isOwner: json['isOwner']);
|
2023-03-22 21:12:04 +01:00
|
|
|
}
|
2023-03-18 20:28:30 +01:00
|
|
|
}
|
2023-03-31 21:52:14 +02:00
|
|
|
|
|
|
|
class RoomCategory {
|
|
|
|
final int id;
|
|
|
|
final String name;
|
|
|
|
final ColorSwatch<int> color;
|
|
|
|
|
|
|
|
const RoomCategory(
|
2023-04-01 20:13:03 +02:00
|
|
|
{required this.id, required this.name, required this.color});
|
2023-03-31 21:52:14 +02:00
|
|
|
|
|
|
|
factory RoomCategory.fromJSON(dynamic json) {
|
|
|
|
return RoomCategory(
|
2023-04-01 20:13:03 +02:00
|
|
|
id: json['id'],
|
|
|
|
name: json['title'],
|
|
|
|
color: colorFromString(json['color']));
|
|
|
|
}
|
2023-04-04 10:29:29 +02:00
|
|
|
factory RoomCategory.other(BuildContext context) {
|
|
|
|
return RoomCategory(
|
|
|
|
id: -1,
|
|
|
|
name: AppLocalizations.of(context)!.categoryNameOther,
|
|
|
|
color: Colors.grey
|
|
|
|
);
|
|
|
|
}
|
2023-04-01 20:13:03 +02:00
|
|
|
|
|
|
|
static List<ColorSwatch<int>> listColors() {
|
|
|
|
return [
|
|
|
|
"red",
|
|
|
|
"green",
|
|
|
|
"yellow",
|
|
|
|
"blue",
|
|
|
|
"aqua",
|
|
|
|
"purple",
|
|
|
|
"red-acc",
|
|
|
|
"green-acc",
|
|
|
|
"yellow-acc",
|
|
|
|
"blue-acc",
|
|
|
|
"aqua-acc",
|
|
|
|
"purple-acc",
|
|
|
|
].map((txt) => colorFromString(txt)).toList();
|
2023-03-31 21:52:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ColorSwatch<int> colorFromString(String text) {
|
|
|
|
switch (text.toLowerCase()) {
|
|
|
|
case 'red-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.redAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'green-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.greenAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'yellow-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.yellowAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'blue-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.blueAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'aqua-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.tealAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'purple-acc':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.purpleAccent;
|
2023-03-31 21:52:14 +02:00
|
|
|
|
|
|
|
case 'red':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.red;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'green':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.green;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'yellow':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.yellow;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'blue':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.blue;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'aqua':
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.teal;
|
2023-03-31 21:52:14 +02:00
|
|
|
case 'purple':
|
|
|
|
default:
|
2023-04-01 20:13:03 +02:00
|
|
|
return Colors.purple;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String colorIdFromColor(ColorSwatch<int> color) {
|
|
|
|
if (color == Colors.redAccent) {
|
|
|
|
return 'red-acc';
|
|
|
|
}
|
|
|
|
if (color == Colors.greenAccent) {
|
|
|
|
return 'green-acc';
|
|
|
|
}
|
|
|
|
if (color == Colors.yellowAccent) {
|
|
|
|
return 'yellow-acc';
|
|
|
|
}
|
|
|
|
if (color == Colors.blueAccent) {
|
|
|
|
return 'blue-acc';
|
|
|
|
}
|
|
|
|
if (color == Colors.tealAccent) {
|
|
|
|
return 'teal-acc';
|
2023-03-31 21:52:14 +02:00
|
|
|
}
|
2023-04-01 20:13:03 +02:00
|
|
|
if (color == Colors.purpleAccent) {
|
|
|
|
return 'purple-acc';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (color == Colors.red) {
|
|
|
|
return 'red';
|
|
|
|
}
|
|
|
|
if (color == Colors.green) {
|
|
|
|
return 'green';
|
|
|
|
}
|
|
|
|
if (color == Colors.yellow) {
|
|
|
|
return 'yellow';
|
|
|
|
}
|
|
|
|
if (color == Colors.blue) {
|
|
|
|
return 'blue';
|
|
|
|
}
|
|
|
|
if (color == Colors.teal) {
|
|
|
|
return 'teal';
|
|
|
|
}
|
|
|
|
if (color == Colors.purple) {
|
|
|
|
return 'purple';
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'purple';
|
2023-03-31 21:52:14 +02:00
|
|
|
}
|
2023-04-04 10:29:29 +02:00
|
|
|
|
|
|
|
class RoomProduct {
|
|
|
|
int id;
|
|
|
|
String name;
|
|
|
|
String description;
|
|
|
|
// category ID
|
|
|
|
// or null for category: "other"
|
|
|
|
int? category;
|
|
|
|
// unitID
|
|
|
|
int defaultUnit;
|
|
|
|
// NOTE: has to be string,
|
|
|
|
// as it may hold plain text,
|
|
|
|
// integers or doubles
|
|
|
|
String defaultValue;
|
|
|
|
String? ean;
|
|
|
|
// parent product ID
|
|
|
|
int? parent;
|
|
|
|
|
|
|
|
RoomProduct(
|
|
|
|
{required this.id,
|
|
|
|
required this.name,
|
|
|
|
this.description = '',
|
|
|
|
this.category = -1,
|
|
|
|
this.defaultUnit = 0,
|
|
|
|
this.defaultValue = '',
|
|
|
|
this.ean,
|
|
|
|
this.parent});
|
|
|
|
|
|
|
|
factory RoomProduct.fromJSON(dynamic json) {
|
|
|
|
return RoomProduct(
|
|
|
|
id: json['listProdID'],
|
|
|
|
name: json['title'],
|
|
|
|
description: json['description'],
|
|
|
|
category: json['category'],
|
|
|
|
defaultUnit: json['defUnit'],
|
|
|
|
defaultValue: json['defValue'],
|
|
|
|
ean: json['ean'],
|
|
|
|
parent: json['parent']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class RoomItem {
|
|
|
|
int id;
|
|
|
|
int state;
|
|
|
|
String name;
|
|
|
|
String description;
|
|
|
|
// may link to a category
|
|
|
|
// null for other
|
|
|
|
int? category;
|
|
|
|
|
|
|
|
int unit;
|
|
|
|
String value;
|
|
|
|
// may link to a product
|
|
|
|
int? link;
|
|
|
|
|
|
|
|
RoomItem(
|
|
|
|
{required this.id,
|
|
|
|
required this.name,
|
|
|
|
this.description = '',
|
|
|
|
this.state = 0,
|
|
|
|
this.category = -1,
|
|
|
|
this.unit = 0,
|
|
|
|
this.value = '',
|
|
|
|
this.link});
|
|
|
|
|
|
|
|
factory RoomItem.fromJSON(dynamic json) {
|
|
|
|
return RoomItem(
|
|
|
|
id: json['listItemID'],
|
|
|
|
name: json['title'],
|
|
|
|
description: json['description'],
|
|
|
|
category: json['listCatID'],
|
|
|
|
state: json['state'],
|
|
|
|
unit: json['unit'],
|
|
|
|
value: json['value'],
|
|
|
|
link: json['listProdID']);
|
|
|
|
}
|
|
|
|
|
|
|
|
RoomItem clone() {
|
|
|
|
return RoomItem(
|
|
|
|
id: id,
|
|
|
|
name: name,
|
|
|
|
description: description,
|
|
|
|
category: category,
|
|
|
|
unit: unit,
|
|
|
|
value: value,
|
|
|
|
link: link);
|
|
|
|
}
|
|
|
|
}
|