chnaged expense type to category

This commit is contained in:
Vaibhav Surve 2025-11-10 16:39:25 +05:30
parent 8d688f2575
commit b1f5fb8d78
3 changed files with 146 additions and 66 deletions

View File

@ -319,7 +319,7 @@ class ExpenseList extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
MyText.bodyMedium(expense.expensesType.name, MyText.bodyMedium(expense.expenseCategory.name,
fontWeight: 600), fontWeight: 600),
Row( Row(
children: [ children: [

View File

@ -8,21 +8,22 @@ ExpenseResponse expenseResponseFromJson(String str) =>
String expenseResponseToJson(ExpenseResponse data) => String expenseResponseToJson(ExpenseResponse data) =>
json.encode(data.toJson()); json.encode(data.toJson());
/// --- Top-level Response ---
class ExpenseResponse { class ExpenseResponse {
final bool success; final bool success;
final String message; final String message;
final ExpenseData data; final ExpenseData data;
final dynamic errors; final dynamic errors;
final int statusCode; final int? statusCode;
final DateTime timestamp; final DateTime? timestamp;
ExpenseResponse({ ExpenseResponse({
required this.success, required this.success,
required this.message, required this.message,
required this.data, required this.data,
required this.errors, this.errors,
required this.statusCode, this.statusCode,
required this.timestamp, this.timestamp,
}); });
factory ExpenseResponse.fromJson(Map<String, dynamic> json) { factory ExpenseResponse.fromJson(Map<String, dynamic> json) {
@ -34,8 +35,10 @@ class ExpenseResponse {
? ExpenseData.fromJson(dataField) ? ExpenseData.fromJson(dataField)
: ExpenseData.empty(), : ExpenseData.empty(),
errors: json["errors"], errors: json["errors"],
statusCode: json["statusCode"] ?? 0, statusCode: json["statusCode"],
timestamp: DateTime.tryParse(json["timestamp"] ?? '') ?? DateTime.now(), timestamp: json["timestamp"] != null
? DateTime.tryParse(json["timestamp"])
: null,
); );
} }
@ -45,19 +48,20 @@ class ExpenseResponse {
"data": data.toJson(), "data": data.toJson(),
"errors": errors, "errors": errors,
"statusCode": statusCode, "statusCode": statusCode,
"timestamp": timestamp.toIso8601String(), "timestamp": timestamp?.toIso8601String(),
}; };
} }
/// --- Expense Data ---
class ExpenseData { class ExpenseData {
final Filter? filter; final Filter? currentFilter;
final int currentPage; final int currentPage;
final int totalPages; final int totalPages;
final int totalEntites; final int totalEntites;
final List<ExpenseModel> data; final List<ExpenseModel> data;
ExpenseData({ ExpenseData({
required this.filter, required this.currentFilter,
required this.currentPage, required this.currentPage,
required this.totalPages, required this.totalPages,
required this.totalEntites, required this.totalEntites,
@ -65,7 +69,9 @@ class ExpenseData {
}); });
factory ExpenseData.fromJson(Map<String, dynamic> json) => ExpenseData( factory ExpenseData.fromJson(Map<String, dynamic> json) => ExpenseData(
filter: json["filter"] != null ? Filter.fromJson(json["filter"]) : null, currentFilter: json["currentFilter"] != null
? Filter.fromJson(json["currentFilter"])
: null,
currentPage: json["currentPage"] ?? 0, currentPage: json["currentPage"] ?? 0,
totalPages: json["totalPages"] ?? 0, totalPages: json["totalPages"] ?? 0,
totalEntites: json["totalEntites"] ?? 0, totalEntites: json["totalEntites"] ?? 0,
@ -75,7 +81,7 @@ class ExpenseData {
); );
factory ExpenseData.empty() => ExpenseData( factory ExpenseData.empty() => ExpenseData(
filter: null, currentFilter: null,
currentPage: 0, currentPage: 0,
totalPages: 0, totalPages: 0,
totalEntites: 0, totalEntites: 0,
@ -83,7 +89,7 @@ class ExpenseData {
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"filter": filter?.toJson(), "currentFilter": currentFilter?.toJson(),
"currentPage": currentPage, "currentPage": currentPage,
"totalPages": totalPages, "totalPages": totalPages,
"totalEntites": totalEntites, "totalEntites": totalEntites,
@ -91,33 +97,51 @@ class ExpenseData {
}; };
} }
/// --- Filter ---
class Filter { class Filter {
final List<String> projectIds; final List<String>? projectIds;
final List<String> statusIds; final List<String>? statusIds;
final List<String> createdByIds; final List<String>? createdByIds;
final List<String> paidById; final List<String>? paidById;
final List<String>? expenseCategoryIds;
final bool? isTransactionDate;
final DateTime? startDate; final DateTime? startDate;
final DateTime? endDate; final DateTime? endDate;
Filter({ Filter({
required this.projectIds, this.projectIds,
required this.statusIds, this.statusIds,
required this.createdByIds, this.createdByIds,
required this.paidById, this.paidById,
required this.startDate, this.expenseCategoryIds,
required this.endDate, this.isTransactionDate,
this.startDate,
this.endDate,
}); });
factory Filter.fromJson(Map<String, dynamic> json) => Filter( factory Filter.fromJson(Map<String, dynamic> json) => Filter(
projectIds: List<String>.from(json["projectIds"] ?? []), projectIds: json["projectIds"] != null
statusIds: List<String>.from(json["statusIds"] ?? []), ? List<String>.from(json["projectIds"])
createdByIds: List<String>.from(json["createdByIds"] ?? []), : null,
paidById: List<String>.from(json["paidById"] ?? []), statusIds: json["statusIds"] != null
? List<String>.from(json["statusIds"])
: null,
createdByIds: json["createdByIds"] != null
? List<String>.from(json["createdByIds"])
: null,
paidById: json["paidById"] != null
? List<String>.from(json["paidById"])
: null,
expenseCategoryIds: json["expenseCategoryIds"] != null
? List<String>.from(json["expenseCategoryIds"])
: null,
isTransactionDate: json["isTransactionDate"],
startDate: json["startDate"] != null startDate: json["startDate"] != null
? DateTime.tryParse(json["startDate"]) ? DateTime.tryParse(json["startDate"])
: null, : null,
endDate: endDate: json["endDate"] != null
json["endDate"] != null ? DateTime.tryParse(json["endDate"]) : null, ? DateTime.tryParse(json["endDate"])
: null,
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
@ -125,25 +149,32 @@ class Filter {
"statusIds": statusIds, "statusIds": statusIds,
"createdByIds": createdByIds, "createdByIds": createdByIds,
"paidById": paidById, "paidById": paidById,
"expenseCategoryIds": expenseCategoryIds,
"isTransactionDate": isTransactionDate,
"startDate": startDate?.toIso8601String(), "startDate": startDate?.toIso8601String(),
"endDate": endDate?.toIso8601String(), "endDate": endDate?.toIso8601String(),
}; };
} }
// --- ExpenseModel and other classes remain same as you wrote --- /// --- Expense Model ---
// I will include them here for completeness.
class ExpenseModel { class ExpenseModel {
final String id; final String id;
final Project project; final Project project;
final ExpenseType expensesType; final ExpenseType expenseCategory;
final PaymentMode paymentMode; final PaymentMode paymentMode;
final PaidBy paidBy; final PaidBy paidBy;
final CreatedBy createdBy; final CreatedBy createdBy;
final DateTime transactionDate; final DateTime transactionDate;
final DateTime createdAt; final DateTime createdAt;
final String supplerName; final String supplerName;
final String expenseUId;
final String? paymentRequestUID;
final String transactionId;
final double amount; final double amount;
final Currency currency;
final String description;
final double? baseAmount;
final double? taxAmount;
final Status status; final Status status;
final List<Status> nextStatus; final List<Status> nextStatus;
final bool preApproved; final bool preApproved;
@ -151,24 +182,30 @@ class ExpenseModel {
ExpenseModel({ ExpenseModel({
required this.id, required this.id,
required this.project, required this.project,
required this.expensesType, required this.expenseCategory,
required this.paymentMode, required this.paymentMode,
required this.paidBy, required this.paidBy,
required this.createdBy, required this.createdBy,
required this.transactionDate, required this.transactionDate,
required this.createdAt, required this.createdAt,
required this.supplerName, required this.supplerName,
required this.expenseUId,
this.paymentRequestUID,
required this.transactionId,
required this.amount, required this.amount,
required this.currency,
required this.description,
this.baseAmount,
this.taxAmount,
required this.status, required this.status,
required this.nextStatus, required this.nextStatus,
required this.preApproved, required this.preApproved,
}); });
/// Comma-separated amount getter with currency symbol
String get formattedAmount { String get formattedAmount {
final formatter = NumberFormat.currency( final formatter = NumberFormat.currency(
locale: 'en_IN', locale: 'en_IN',
symbol: ' ', symbol: '${currency.symbol} ',
decimalDigits: 2, decimalDigits: 2,
); );
return formatter.format(amount); return formatter.format(amount);
@ -177,15 +214,27 @@ class ExpenseModel {
factory ExpenseModel.fromJson(Map<String, dynamic> json) => ExpenseModel( factory ExpenseModel.fromJson(Map<String, dynamic> json) => ExpenseModel(
id: json["id"] ?? '', id: json["id"] ?? '',
project: Project.fromJson(json["project"] ?? {}), project: Project.fromJson(json["project"] ?? {}),
expensesType: ExpenseType.fromJson(json["expensesType"] ?? {}), expenseCategory: ExpenseType.fromJson(json["expenseCategory"] ?? {}),
paymentMode: PaymentMode.fromJson(json["paymentMode"] ?? {}), paymentMode: PaymentMode.fromJson(json["paymentMode"] ?? {}),
paidBy: PaidBy.fromJson(json["paidBy"] ?? {}), paidBy: PaidBy.fromJson(json["paidBy"] ?? {}),
createdBy: CreatedBy.fromJson(json["createdBy"] ?? {}), createdBy: CreatedBy.fromJson(json["createdBy"] ?? {}),
transactionDate: transactionDate:
DateTime.tryParse(json["transactionDate"] ?? '') ?? DateTime.now(), DateTime.tryParse(json["transactionDate"] ?? '') ?? DateTime.now(),
createdAt: DateTime.tryParse(json["createdAt"] ?? '') ?? DateTime.now(), createdAt:
DateTime.tryParse(json["createdAt"] ?? '') ?? DateTime.now(),
supplerName: json["supplerName"] ?? '', supplerName: json["supplerName"] ?? '',
expenseUId: json["expenseUId"] ?? '',
paymentRequestUID: json["paymentRequestUID"],
transactionId: json["transactionId"] ?? '',
amount: (json["amount"] ?? 0).toDouble(), amount: (json["amount"] ?? 0).toDouble(),
currency: Currency.fromJson(json["currency"] ?? {}),
description: json["description"] ?? '',
baseAmount: json["baseAmount"] != null
? (json["baseAmount"] as num).toDouble()
: null,
taxAmount: json["taxAmount"] != null
? (json["taxAmount"] as num).toDouble()
: null,
status: Status.fromJson(json["status"] ?? {}), status: Status.fromJson(json["status"] ?? {}),
nextStatus: (json["nextStatus"] as List<dynamic>? ?? []) nextStatus: (json["nextStatus"] as List<dynamic>? ?? [])
.map((x) => Status.fromJson(x)) .map((x) => Status.fromJson(x))
@ -196,20 +245,28 @@ class ExpenseModel {
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"project": project.toJson(), "project": project.toJson(),
"expensesType": expensesType.toJson(), "expenseCategory": expenseCategory.toJson(),
"paymentMode": paymentMode.toJson(), "paymentMode": paymentMode.toJson(),
"paidBy": paidBy.toJson(), "paidBy": paidBy.toJson(),
"createdBy": createdBy.toJson(), "createdBy": createdBy.toJson(),
"transactionDate": transactionDate.toIso8601String(), "transactionDate": transactionDate.toIso8601String(),
"createdAt": createdAt.toIso8601String(), "createdAt": createdAt.toIso8601String(),
"supplerName": supplerName, "supplerName": supplerName,
"expenseUId": expenseUId,
"paymentRequestUID": paymentRequestUID,
"transactionId": transactionId,
"amount": amount, "amount": amount,
"currency": currency.toJson(),
"description": description,
"baseAmount": baseAmount,
"taxAmount": taxAmount,
"status": status.toJson(), "status": status.toJson(),
"nextStatus": List<dynamic>.from(nextStatus.map((x) => x.toJson())), "nextStatus": List<dynamic>.from(nextStatus.map((x) => x.toJson())),
"preApproved": preApproved, "preApproved": preApproved,
}; };
} }
/// --- Project ---
class Project { class Project {
final String id; final String id;
final String name; final String name;
@ -237,7 +294,8 @@ class Project {
shortName: json["shortName"] ?? '', shortName: json["shortName"] ?? '',
projectAddress: json["projectAddress"] ?? '', projectAddress: json["projectAddress"] ?? '',
contactPerson: json["contactPerson"] ?? '', contactPerson: json["contactPerson"] ?? '',
startDate: DateTime.tryParse(json["startDate"] ?? '') ?? DateTime.now(), startDate:
DateTime.tryParse(json["startDate"] ?? '') ?? DateTime.now(),
endDate: DateTime.tryParse(json["endDate"] ?? '') ?? DateTime.now(), endDate: DateTime.tryParse(json["endDate"] ?? '') ?? DateTime.now(),
projectStatusId: json["projectStatusId"] ?? '', projectStatusId: json["projectStatusId"] ?? '',
); );
@ -254,6 +312,7 @@ class Project {
}; };
} }
/// --- Expense Type ---
class ExpenseType { class ExpenseType {
final String id; final String id;
final String name; final String name;
@ -282,6 +341,7 @@ class ExpenseType {
}; };
} }
/// --- Payment Mode ---
class PaymentMode { class PaymentMode {
final String id; final String id;
final String name; final String name;
@ -306,6 +366,7 @@ class PaymentMode {
}; };
} }
/// --- PaidBy & CreatedBy ---
class PaidBy { class PaidBy {
final String id; final String id;
final String firstName; final String firstName;
@ -342,24 +403,18 @@ class PaidBy {
}; };
} }
class CreatedBy { class CreatedBy extends PaidBy {
final String id;
final String firstName;
final String lastName;
final String photo;
final String jobRoleId;
final String? jobRoleName;
CreatedBy({ CreatedBy({
required this.id, required super.id,
required this.firstName, required super.firstName,
required this.lastName, required super.lastName,
required this.photo, required super.photo,
required this.jobRoleId, required super.jobRoleId,
this.jobRoleName, super.jobRoleName,
}); });
factory CreatedBy.fromJson(Map<String, dynamic> json) => CreatedBy( factory CreatedBy.fromJson(Map<String, dynamic> json) =>
CreatedBy(
id: json["id"] ?? '', id: json["id"] ?? '',
firstName: json["firstName"] ?? '', firstName: json["firstName"] ?? '',
lastName: json["lastName"] ?? '', lastName: json["lastName"] ?? '',
@ -367,17 +422,9 @@ class CreatedBy {
jobRoleId: json["jobRoleId"] ?? '', jobRoleId: json["jobRoleId"] ?? '',
jobRoleName: json["jobRoleName"], jobRoleName: json["jobRoleName"],
); );
Map<String, dynamic> toJson() => {
"id": id,
"firstName": firstName,
"lastName": lastName,
"photo": photo,
"jobRoleId": jobRoleId,
"jobRoleName": jobRoleName,
};
} }
/// --- Status ---
class Status { class Status {
final String id; final String id;
final String name; final String name;
@ -413,3 +460,36 @@ class Status {
"isSystem": isSystem, "isSystem": isSystem,
}; };
} }
/// --- Currency ---
class Currency {
final String id;
final String currencyCode;
final String currencyName;
final String symbol;
final bool isActive;
Currency({
required this.id,
required this.currencyCode,
required this.currencyName,
required this.symbol,
required this.isActive,
});
factory Currency.fromJson(Map<String, dynamic> json) => Currency(
id: json["id"] ?? '',
currencyCode: json["currencyCode"] ?? '',
currencyName: json["currencyName"] ?? '',
symbol: json["symbol"] ?? '',
isActive: json["isActive"] ?? false,
);
Map<String, dynamic> toJson() => {
"id": id,
"currencyCode": currencyCode,
"currencyName": currencyName,
"symbol": symbol,
"isActive": isActive,
};
}

View File

@ -67,7 +67,7 @@ class _ExpenseMainScreenState extends State<ExpenseMainScreen>
final filtered = expenseController.expenses.where((e) { final filtered = expenseController.expenses.where((e) {
return query.isEmpty || return query.isEmpty ||
e.expensesType.name.toLowerCase().contains(query) || e.expenseCategory.name.toLowerCase().contains(query) ||
e.supplerName.toLowerCase().contains(query) || e.supplerName.toLowerCase().contains(query) ||
e.paymentMode.name.toLowerCase().contains(query); e.paymentMode.name.toLowerCase().contains(query);
}).toList() }).toList()