asset
This commit is contained in:
parent
36847aaf87
commit
eb94390961
@ -47,6 +47,9 @@ class ApiEndpoints {
|
|||||||
static String designationById(String id) => '/masters/designations/$id';
|
static String designationById(String id) => '/masters/designations/$id';
|
||||||
static const String plants = '/masters/plants';
|
static const String plants = '/masters/plants';
|
||||||
static String plantById(String id) => '/masters/plants/$id';
|
static String plantById(String id) => '/masters/plants/$id';
|
||||||
|
static const String locations = '/masters/locations';
|
||||||
|
static String locationById(String id) => '/masters/locations/$id';
|
||||||
|
static const String locationStates = '/masters/locations/states';
|
||||||
static const String uom = '/masters/uom';
|
static const String uom = '/masters/uom';
|
||||||
static String uomById(String id) => '/masters/uom/$id';
|
static String uomById(String id) => '/masters/uom/$id';
|
||||||
static const String itemCategories = '/masters/item-categories';
|
static const String itemCategories = '/masters/item-categories';
|
||||||
@ -148,6 +151,11 @@ class ApiEndpoints {
|
|||||||
static const String assetDepreciationCalculate = '/assets/depreciation/calculate';
|
static const String assetDepreciationCalculate = '/assets/depreciation/calculate';
|
||||||
static const String assetAlertsExpiry = '/assets/alerts/expiry';
|
static const String assetAlertsExpiry = '/assets/alerts/expiry';
|
||||||
static const String assetAlertsService = '/assets/alerts/service';
|
static const String assetAlertsService = '/assets/alerts/service';
|
||||||
|
static const String assetMaintenanceMy = '/assets/maintenance/my';
|
||||||
|
static String assetMaintenanceLogs(String id) =>
|
||||||
|
'/assets/$id/maintenance-logs';
|
||||||
|
static String assetMaintenanceLogById(String id, String logId) =>
|
||||||
|
'/assets/$id/maintenance-logs/$logId';
|
||||||
static String assetAmc(String assetId) => '/assets/$assetId/amc';
|
static String assetAmc(String assetId) => '/assets/$assetId/amc';
|
||||||
static String assetAmcById(String assetId, String contractId) =>
|
static String assetAmcById(String assetId, String contractId) =>
|
||||||
'/assets/$assetId/amc/$contractId';
|
'/assets/$assetId/amc/$contractId';
|
||||||
|
|||||||
@ -63,6 +63,7 @@ class RouteConstants {
|
|||||||
static const String assetEdit = '/assets/:id/edit';
|
static const String assetEdit = '/assets/:id/edit';
|
||||||
static const String assetDetail = '/assets/:id';
|
static const String assetDetail = '/assets/:id';
|
||||||
static const String assetAlerts = '/assets/alerts';
|
static const String assetAlerts = '/assets/alerts';
|
||||||
|
static const String assetMaintenance = '/assets/maintenance';
|
||||||
|
|
||||||
// Master Data
|
// Master Data
|
||||||
static const String masterData = '/master-data';
|
static const String masterData = '/master-data';
|
||||||
|
|||||||
@ -357,6 +357,55 @@ class AssetRemoteDataSource {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<PaginatedResponse<AssetModel>> getMyMaintenanceAssets({
|
||||||
|
bool dueOnly = false,
|
||||||
|
int page = 1,
|
||||||
|
int limit = 20,
|
||||||
|
}) async {
|
||||||
|
final response = await dio.get(
|
||||||
|
ApiEndpoints.assetMaintenanceMy,
|
||||||
|
queryParameters: {
|
||||||
|
'page': page,
|
||||||
|
'limit': limit,
|
||||||
|
if (dueOnly) 'due_only': true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return _parsePaginated(response.data, AssetModel.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<AssetMaintenanceLogModel>> getMaintenanceLogs(String assetId) async {
|
||||||
|
final response = await dio.get(ApiEndpoints.assetMaintenanceLogs(assetId));
|
||||||
|
return _parseList(response.data, AssetMaintenanceLogModel.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<AssetMaintenanceLogModel> createMaintenanceLog(
|
||||||
|
String assetId,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) async {
|
||||||
|
final response = await dio.post(
|
||||||
|
ApiEndpoints.assetMaintenanceLogs(assetId),
|
||||||
|
data: data,
|
||||||
|
);
|
||||||
|
return AssetMaintenanceLogModel.fromJson(
|
||||||
|
response.data['data'] as Map<String, dynamic>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<AssetMaintenanceLogModel> getMaintenanceLogById(
|
||||||
|
String assetId,
|
||||||
|
String logId,
|
||||||
|
) async {
|
||||||
|
final response =
|
||||||
|
await dio.get(ApiEndpoints.assetMaintenanceLogById(assetId, logId));
|
||||||
|
return AssetMaintenanceLogModel.fromJson(
|
||||||
|
response.data['data'] as Map<String, dynamic>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteMaintenanceLog(String assetId, String logId) async {
|
||||||
|
await dio.delete(ApiEndpoints.assetMaintenanceLogById(assetId, logId));
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _queryToMap(AssetListQuery query) {
|
Map<String, dynamic> _queryToMap(AssetListQuery query) {
|
||||||
return {
|
return {
|
||||||
'page': query.page,
|
'page': query.page,
|
||||||
@ -374,8 +423,11 @@ class AssetRemoteDataSource {
|
|||||||
if (query.itemCategoryId != null) 'item_category_id': query.itemCategoryId,
|
if (query.itemCategoryId != null) 'item_category_id': query.itemCategoryId,
|
||||||
if (query.itemSubcategoryId != null)
|
if (query.itemSubcategoryId != null)
|
||||||
'item_subcategory_id': query.itemSubcategoryId,
|
'item_subcategory_id': query.itemSubcategoryId,
|
||||||
if (query.plantId != null) 'plant_id': query.plantId,
|
if (query.locationId != null) 'location_id': query.locationId,
|
||||||
if (query.departmentId != null) 'department_id': query.departmentId,
|
if (query.departmentId != null) 'department_id': query.departmentId,
|
||||||
|
if (query.maintenanceInchargeUserId != null)
|
||||||
|
'maintenance_incharge_user_id': query.maintenanceInchargeUserId,
|
||||||
|
if (query.dueOnly == true) 'due_only': true,
|
||||||
if (query.isActive != null) 'is_active': query.isActive,
|
if (query.isActive != null) 'is_active': query.isActive,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -262,6 +262,51 @@ class AssetRepositoryImpl implements AssetRepository {
|
|||||||
return safeApiCall(() => dataSource.renewInsurancePolicy(assetId, policyId, data));
|
return safeApiCall(() => dataSource.renewInsurancePolicy(assetId, policyId, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<PaginatedResponse<AssetModel>>> getMyMaintenanceAssets({
|
||||||
|
bool dueOnly = false,
|
||||||
|
int page = 1,
|
||||||
|
int limit = 20,
|
||||||
|
}) {
|
||||||
|
return safeApiCall(
|
||||||
|
() => dataSource.getMyMaintenanceAssets(
|
||||||
|
dueOnly: dueOnly,
|
||||||
|
page: page,
|
||||||
|
limit: limit,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<List<AssetMaintenanceLogModel>>> getMaintenanceLogs(
|
||||||
|
String assetId,
|
||||||
|
) {
|
||||||
|
return safeApiCall(() => dataSource.getMaintenanceLogs(assetId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<AssetMaintenanceLogModel>> createMaintenanceLog(
|
||||||
|
String assetId,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) {
|
||||||
|
return safeApiCall(() => dataSource.createMaintenanceLog(assetId, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<AssetMaintenanceLogModel>> getMaintenanceLogById(
|
||||||
|
String assetId,
|
||||||
|
String logId,
|
||||||
|
) {
|
||||||
|
return safeApiCall(
|
||||||
|
() => dataSource.getMaintenanceLogById(assetId, logId),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<void>> deleteMaintenanceLog(String assetId, String logId) {
|
||||||
|
return safeApiCall(() => dataSource.deleteMaintenanceLog(assetId, logId));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Result<List<EntityAttachmentModel>>> listAttachments(String assetId) {
|
Future<Result<List<EntityAttachmentModel>>> listAttachments(String assetId) {
|
||||||
return safeApiCall(() => dataSource.listAttachments(assetId));
|
return safeApiCall(() => dataSource.listAttachments(assetId));
|
||||||
|
|||||||
@ -89,6 +89,23 @@ abstract class AssetRepository {
|
|||||||
String policyId,
|
String policyId,
|
||||||
Map<String, dynamic> data,
|
Map<String, dynamic> data,
|
||||||
);
|
);
|
||||||
|
Future<Result<PaginatedResponse<AssetModel>>> getMyMaintenanceAssets({
|
||||||
|
bool dueOnly = false,
|
||||||
|
int page = 1,
|
||||||
|
int limit = 20,
|
||||||
|
});
|
||||||
|
Future<Result<List<AssetMaintenanceLogModel>>> getMaintenanceLogs(
|
||||||
|
String assetId,
|
||||||
|
);
|
||||||
|
Future<Result<AssetMaintenanceLogModel>> createMaintenanceLog(
|
||||||
|
String assetId,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
);
|
||||||
|
Future<Result<AssetMaintenanceLogModel>> getMaintenanceLogById(
|
||||||
|
String assetId,
|
||||||
|
String logId,
|
||||||
|
);
|
||||||
|
Future<Result<void>> deleteMaintenanceLog(String assetId, String logId);
|
||||||
Future<Result<List<EntityAttachmentModel>>> listAttachments(String assetId);
|
Future<Result<List<EntityAttachmentModel>>> listAttachments(String assetId);
|
||||||
Future<Result<EntityAttachmentModel>> uploadAttachment(
|
Future<Result<EntityAttachmentModel>> uploadAttachment(
|
||||||
String assetId, {
|
String assetId, {
|
||||||
|
|||||||
@ -14,9 +14,8 @@ import '../../../vendors/data/repositories/vendor_repository_impl.dart';
|
|||||||
|
|
||||||
class AssetFormLookups {
|
class AssetFormLookups {
|
||||||
const AssetFormLookups({
|
const AssetFormLookups({
|
||||||
this.plants = const [],
|
this.locations = const [],
|
||||||
this.departments = const [],
|
this.departments = const [],
|
||||||
this.warehouses = const [],
|
|
||||||
this.vendors = const [],
|
this.vendors = const [],
|
||||||
this.users = const [],
|
this.users = const [],
|
||||||
this.purchaseOrders = const [],
|
this.purchaseOrders = const [],
|
||||||
@ -24,9 +23,8 @@ class AssetFormLookups {
|
|||||||
this.options = const AssetDropdownOptionsModel(),
|
this.options = const AssetDropdownOptionsModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<FilterOptionModel> plants;
|
final List<FilterOptionModel> locations;
|
||||||
final List<FilterOptionModel> departments;
|
final List<FilterOptionModel> departments;
|
||||||
final List<FilterOptionModel> warehouses;
|
|
||||||
final List<FilterOptionModel> vendors;
|
final List<FilterOptionModel> vendors;
|
||||||
final List<FilterOptionModel> users;
|
final List<FilterOptionModel> users;
|
||||||
final List<FilterOptionModel> purchaseOrders;
|
final List<FilterOptionModel> purchaseOrders;
|
||||||
@ -50,9 +48,8 @@ final assetFormLookupsProvider =
|
|||||||
FutureProvider.autoDispose<AssetFormLookups>((ref) async {
|
FutureProvider.autoDispose<AssetFormLookups>((ref) async {
|
||||||
final master = ref.watch(masterRemoteDataSourceProvider);
|
final master = ref.watch(masterRemoteDataSourceProvider);
|
||||||
|
|
||||||
final plants = await _safeOptions(master.listPlants);
|
final locations = await _safeOptions(master.listLocations);
|
||||||
final departments = await _safeOptions(master.listDepartments);
|
final departments = await _safeOptions(master.listDepartments);
|
||||||
final warehouses = await _safeOptions(master.listWarehouses);
|
|
||||||
final vendors = await _safeVendorOptions(ref);
|
final vendors = await _safeVendorOptions(ref);
|
||||||
final users = await _safeUserOptions(ref);
|
final users = await _safeUserOptions(ref);
|
||||||
final purchaseOrders = await _safePurchaseOrderOptions(ref);
|
final purchaseOrders = await _safePurchaseOrderOptions(ref);
|
||||||
@ -60,9 +57,8 @@ final assetFormLookupsProvider =
|
|||||||
final options = await _safeAssetOptions(ref);
|
final options = await _safeAssetOptions(ref);
|
||||||
|
|
||||||
return AssetFormLookups(
|
return AssetFormLookups(
|
||||||
plants: plants,
|
locations: locations,
|
||||||
departments: departments,
|
departments: departments,
|
||||||
warehouses: warehouses,
|
|
||||||
vendors: vendors,
|
vendors: vendors,
|
||||||
users: users,
|
users: users,
|
||||||
purchaseOrders: purchaseOrders,
|
purchaseOrders: purchaseOrders,
|
||||||
|
|||||||
@ -118,10 +118,10 @@ class AssetsListNotifier extends AutoDisposeAsyncNotifier<AssetsListState> {
|
|||||||
applyQuery(current.query.copyWith(itemCategoryId: itemCategoryId, page: 1));
|
applyQuery(current.query.copyWith(itemCategoryId: itemCategoryId, page: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlantFilter(int? plantId) {
|
void setLocationFilter(int? locationId) {
|
||||||
final current = state.valueOrNull;
|
final current = state.valueOrNull;
|
||||||
if (current == null) return;
|
if (current == null) return;
|
||||||
applyQuery(current.query.copyWith(plantId: plantId, page: 1));
|
applyQuery(current.query.copyWith(locationId: locationId, page: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPage(int page) {
|
void setPage(int page) {
|
||||||
@ -594,3 +594,106 @@ class AssetAlertsNotifier extends AsyncNotifier<AssetAlertsState> {
|
|||||||
state = AsyncData(await _load(current.copyWith(expiryPage: page)));
|
state = AsyncData(await _load(current.copyWith(expiryPage: page)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyMaintenanceState {
|
||||||
|
const MyMaintenanceState({
|
||||||
|
this.assets = const [],
|
||||||
|
this.dueOnly = true,
|
||||||
|
this.page = 1,
|
||||||
|
this.limit = 20,
|
||||||
|
this.total = 0,
|
||||||
|
this.totalPages = 1,
|
||||||
|
this.isRefreshing = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<AssetModel> assets;
|
||||||
|
final bool dueOnly;
|
||||||
|
final int page;
|
||||||
|
final int limit;
|
||||||
|
final int total;
|
||||||
|
final int totalPages;
|
||||||
|
final bool isRefreshing;
|
||||||
|
|
||||||
|
MyMaintenanceState copyWith({
|
||||||
|
List<AssetModel>? assets,
|
||||||
|
bool? dueOnly,
|
||||||
|
int? page,
|
||||||
|
int? limit,
|
||||||
|
int? total,
|
||||||
|
int? totalPages,
|
||||||
|
bool? isRefreshing,
|
||||||
|
}) {
|
||||||
|
return MyMaintenanceState(
|
||||||
|
assets: assets ?? this.assets,
|
||||||
|
dueOnly: dueOnly ?? this.dueOnly,
|
||||||
|
page: page ?? this.page,
|
||||||
|
limit: limit ?? this.limit,
|
||||||
|
total: total ?? this.total,
|
||||||
|
totalPages: totalPages ?? this.totalPages,
|
||||||
|
isRefreshing: isRefreshing ?? this.isRefreshing,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final myMaintenanceProvider =
|
||||||
|
AsyncNotifierProvider<MyMaintenanceNotifier, MyMaintenanceState>(
|
||||||
|
MyMaintenanceNotifier.new,
|
||||||
|
);
|
||||||
|
|
||||||
|
class MyMaintenanceNotifier extends AsyncNotifier<MyMaintenanceState> {
|
||||||
|
@override
|
||||||
|
Future<MyMaintenanceState> build() async {
|
||||||
|
return _load(const MyMaintenanceState());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<MyMaintenanceState> _load(MyMaintenanceState filters) async {
|
||||||
|
final repository = ref.read(assetRepositoryProvider);
|
||||||
|
final result = await repository.getMyMaintenanceAssets(
|
||||||
|
dueOnly: filters.dueOnly,
|
||||||
|
page: filters.page,
|
||||||
|
limit: filters.limit,
|
||||||
|
);
|
||||||
|
if (result.failure != null) throw result.failure!;
|
||||||
|
final page = result.data!;
|
||||||
|
return MyMaintenanceState(
|
||||||
|
assets: page.items,
|
||||||
|
dueOnly: filters.dueOnly,
|
||||||
|
page: page.page,
|
||||||
|
limit: filters.limit,
|
||||||
|
total: page.total,
|
||||||
|
totalPages: page.totalPages,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> refresh() async {
|
||||||
|
final current = state.valueOrNull ?? const MyMaintenanceState();
|
||||||
|
state = AsyncData(current.copyWith(isRefreshing: true));
|
||||||
|
try {
|
||||||
|
state = AsyncData(await _load(current));
|
||||||
|
} catch (e, st) {
|
||||||
|
state = AsyncError(e, st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setDueOnly(bool dueOnly) async {
|
||||||
|
final current = state.valueOrNull ?? const MyMaintenanceState();
|
||||||
|
state = const AsyncLoading();
|
||||||
|
state = AsyncData(
|
||||||
|
await _load(current.copyWith(dueOnly: dueOnly, page: 1)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setPage(int page) async {
|
||||||
|
final current = state.valueOrNull ?? const MyMaintenanceState();
|
||||||
|
state = const AsyncLoading();
|
||||||
|
state = AsyncData(await _load(current.copyWith(page: page)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setPageSize(int limit) async {
|
||||||
|
final current = state.valueOrNull ?? const MyMaintenanceState();
|
||||||
|
state = const AsyncLoading();
|
||||||
|
state = AsyncData(
|
||||||
|
await _load(current.copyWith(limit: limit, page: 1)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -285,7 +285,8 @@ class _AlertCard extends StatelessWidget {
|
|||||||
final visual = _alertVisualStyle(alert);
|
final visual = _alertVisualStyle(alert);
|
||||||
final subtitleParts = [
|
final subtitleParts = [
|
||||||
if (alert.assetCode?.trim().isNotEmpty == true) alert.assetCode!.trim(),
|
if (alert.assetCode?.trim().isNotEmpty == true) alert.assetCode!.trim(),
|
||||||
if (alert.plantName?.trim().isNotEmpty == true) alert.plantName!.trim(),
|
if (alert.locationName?.trim().isNotEmpty == true)
|
||||||
|
alert.locationName!.trim(),
|
||||||
if (dateLabel != null) 'Due: $dateLabel',
|
if (dateLabel != null) 'Due: $dateLabel',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import '../../../../shared/widgets/app_side_panel.dart';
|
|||||||
import '../providers/assets_provider.dart';
|
import '../providers/assets_provider.dart';
|
||||||
import '../providers/asset_form_lookups_provider.dart';
|
import '../providers/asset_form_lookups_provider.dart';
|
||||||
import '../widgets/asset_form_panel.dart';
|
import '../widgets/asset_form_panel.dart';
|
||||||
|
import '../widgets/asset_maintenance_panel.dart';
|
||||||
import '../widgets/asset_side_panels.dart';
|
import '../widgets/asset_side_panels.dart';
|
||||||
import '../../../../shared/widgets/app_toast.dart';
|
import '../../../../shared/widgets/app_toast.dart';
|
||||||
|
|
||||||
@ -198,6 +199,12 @@ class _OverviewTab extends ConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final dateFormat = DateFormat('dd MMM yyyy');
|
final dateFormat = DateFormat('dd MMM yyyy');
|
||||||
|
final users =
|
||||||
|
ref.watch(assetFormLookupsProvider).valueOrNull?.users ?? const [];
|
||||||
|
final maintenanceInchargeLabel = _userLabel(
|
||||||
|
asset.maintenanceInchargeUserId,
|
||||||
|
users,
|
||||||
|
);
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Center(
|
child: Center(
|
||||||
@ -239,7 +246,40 @@ class _OverviewTab extends ConsumerWidget {
|
|||||||
'Subcategory',
|
'Subcategory',
|
||||||
asset.assetSubcategoryName ?? '—',
|
asset.assetSubcategoryName ?? '—',
|
||||||
),
|
),
|
||||||
_AssetInfo('Plant', asset.plantName ?? '—'),
|
_AssetInfo('Location', asset.locationName ?? '—'),
|
||||||
|
_AssetInfo(
|
||||||
|
'Commencement Date',
|
||||||
|
asset.commencementDate != null
|
||||||
|
? dateFormat.format(asset.commencementDate!)
|
||||||
|
: '—',
|
||||||
|
),
|
||||||
|
_AssetInfo(
|
||||||
|
'Maintenance Incharge',
|
||||||
|
maintenanceInchargeLabel,
|
||||||
|
),
|
||||||
|
_AssetInfo(
|
||||||
|
'Maintenance Frequency',
|
||||||
|
asset.maintenanceFrequencyInDays != null
|
||||||
|
? '${asset.maintenanceFrequencyInDays} days'
|
||||||
|
: '—',
|
||||||
|
),
|
||||||
|
if (asset.maintenance != null) ...[
|
||||||
|
_AssetInfo(
|
||||||
|
'Maintenance Due',
|
||||||
|
asset.maintenance!.isDue ? 'Yes' : 'No',
|
||||||
|
),
|
||||||
|
_AssetInfo(
|
||||||
|
'Next Due Date',
|
||||||
|
asset.maintenance!.nextDueDate != null
|
||||||
|
? dateFormat
|
||||||
|
.format(asset.maintenance!.nextDueDate!)
|
||||||
|
: '—',
|
||||||
|
),
|
||||||
|
_AssetInfo(
|
||||||
|
'Days Until Due',
|
||||||
|
asset.maintenance!.daysUntilDue?.toString() ?? '—',
|
||||||
|
),
|
||||||
|
],
|
||||||
_AssetInfo('Serial Number', asset.serialNumber ?? '—'),
|
_AssetInfo('Serial Number', asset.serialNumber ?? '—'),
|
||||||
_AssetInfo('Brand / Model', asset.brandModel ?? '—'),
|
_AssetInfo('Brand / Model', asset.brandModel ?? '—'),
|
||||||
_AssetInfo('Manufacturer', asset.manufacturer ?? '—'),
|
_AssetInfo('Manufacturer', asset.manufacturer ?? '—'),
|
||||||
@ -285,6 +325,36 @@ class _OverviewTab extends ConsumerWidget {
|
|||||||
_AssetInfo('Active', asset.isActive ? 'Yes' : 'No'),
|
_AssetInfo('Active', asset.isActive ? 'Yes' : 'No'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (asset.maintenanceFrequencyInDays != null ||
|
||||||
|
asset.maintenanceChecklistJson?.isNotEmpty == true ||
|
||||||
|
asset.maintenance != null) ...[
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
child: Divider(height: 1),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: OutlinedButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
final saved = await openSubmitMaintenancePanel(
|
||||||
|
context,
|
||||||
|
ref,
|
||||||
|
asset: asset,
|
||||||
|
);
|
||||||
|
if (saved == true && context.mounted) {
|
||||||
|
showAppToastFromSnackBar(
|
||||||
|
context,
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Maintenance log submitted'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.checklist_outlined),
|
||||||
|
label: const Text('Log Maintenance'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
if (asset.remarks?.trim().isNotEmpty == true) ...[
|
if (asset.remarks?.trim().isNotEmpty == true) ...[
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical: 20),
|
padding: EdgeInsets.symmetric(vertical: 20),
|
||||||
@ -410,6 +480,17 @@ class _AssetInfo {
|
|||||||
final Widget? valueWidget;
|
final Widget? valueWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _userLabel(int? userId, List<FilterOptionModel> users) {
|
||||||
|
if (userId == null || userId <= 0) return '—';
|
||||||
|
final id = userId.toString();
|
||||||
|
for (final user in users) {
|
||||||
|
if (user.id == id && user.name.trim().isNotEmpty) {
|
||||||
|
return user.name.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
class _AmcTab extends ConsumerWidget {
|
class _AmcTab extends ConsumerWidget {
|
||||||
const _AmcTab({required this.assetId, required this.contracts});
|
const _AmcTab({required this.assetId, required this.contracts});
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ class _AssetListScreenState extends ConsumerState<AssetListScreen> {
|
|||||||
final allCategories =
|
final allCategories =
|
||||||
ref.watch(itemCategoriesProvider).valueOrNull ?? [];
|
ref.watch(itemCategoriesProvider).valueOrNull ?? [];
|
||||||
final lookups = ref.watch(assetFormLookupsProvider).valueOrNull;
|
final lookups = ref.watch(assetFormLookupsProvider).valueOrNull;
|
||||||
final allPlants = lookups?.plants ?? const [];
|
final allLocations = lookups?.locations ?? const [];
|
||||||
final notifier = ref.read(assetsListProvider.notifier);
|
final notifier = ref.read(assetsListProvider.notifier);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@ -139,11 +139,11 @@ class _AssetListScreenState extends ConsumerState<AssetListScreen> {
|
|||||||
child: _AssetsFilterBar(
|
child: _AssetsFilterBar(
|
||||||
query: state.query,
|
query: state.query,
|
||||||
categories: allCategories,
|
categories: allCategories,
|
||||||
plants: allPlants,
|
locations: allLocations,
|
||||||
statuses: lookups?.statuses ?? const [],
|
statuses: lookups?.statuses ?? const [],
|
||||||
onSearch: notifier.setSearch,
|
onSearch: notifier.setSearch,
|
||||||
onCategoryChanged: notifier.setCategoryFilter,
|
onCategoryChanged: notifier.setCategoryFilter,
|
||||||
onPlantChanged: notifier.setPlantFilter,
|
onLocationChanged: notifier.setLocationFilter,
|
||||||
onStatusChanged: notifier.setStatusFilter,
|
onStatusChanged: notifier.setStatusFilter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -272,21 +272,21 @@ class _AssetsFilterBar extends StatelessWidget {
|
|||||||
const _AssetsFilterBar({
|
const _AssetsFilterBar({
|
||||||
required this.query,
|
required this.query,
|
||||||
required this.categories,
|
required this.categories,
|
||||||
required this.plants,
|
required this.locations,
|
||||||
required this.statuses,
|
required this.statuses,
|
||||||
required this.onSearch,
|
required this.onSearch,
|
||||||
required this.onCategoryChanged,
|
required this.onCategoryChanged,
|
||||||
required this.onPlantChanged,
|
required this.onLocationChanged,
|
||||||
required this.onStatusChanged,
|
required this.onStatusChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
final AssetListQuery query;
|
final AssetListQuery query;
|
||||||
final List<AssetCategoryModel> categories;
|
final List<AssetCategoryModel> categories;
|
||||||
final List<FilterOptionModel> plants;
|
final List<FilterOptionModel> locations;
|
||||||
final List<AssetDropdownOption> statuses;
|
final List<AssetDropdownOption> statuses;
|
||||||
final ValueChanged<String> onSearch;
|
final ValueChanged<String> onSearch;
|
||||||
final ValueChanged<int?> onCategoryChanged;
|
final ValueChanged<int?> onCategoryChanged;
|
||||||
final ValueChanged<int?> onPlantChanged;
|
final ValueChanged<int?> onLocationChanged;
|
||||||
final ValueChanged<String?> onStatusChanged;
|
final ValueChanged<String?> onStatusChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -315,13 +315,13 @@ class _AssetsFilterBar extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
final plantOptions = <AppDropdownOption<int?>>[
|
final locationOptions = <AppDropdownOption<int?>>[
|
||||||
const AppDropdownOption(value: null, label: 'All Plants'),
|
const AppDropdownOption(value: null, label: 'All Locations'),
|
||||||
for (final plant in plants)
|
for (final location in locations)
|
||||||
if (int.tryParse(plant.id) != null)
|
if (int.tryParse(location.id) != null)
|
||||||
AppDropdownOption(
|
AppDropdownOption(
|
||||||
value: int.parse(plant.id),
|
value: int.parse(location.id),
|
||||||
label: plant.name,
|
label: location.name,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -347,12 +347,12 @@ class _AssetsFilterBar extends StatelessWidget {
|
|||||||
onChanged: onCategoryChanged,
|
onChanged: onCategoryChanged,
|
||||||
),
|
),
|
||||||
AppSearchableDropdown<int?>(
|
AppSearchableDropdown<int?>(
|
||||||
label: 'Plant',
|
label: 'Location',
|
||||||
value: query.plantId,
|
value: query.locationId,
|
||||||
searchHint: 'Search plant...',
|
searchHint: 'Search location...',
|
||||||
isDense: true,
|
isDense: true,
|
||||||
options: plantOptions,
|
options: locationOptions,
|
||||||
onChanged: onPlantChanged,
|
onChanged: onLocationChanged,
|
||||||
),
|
),
|
||||||
AppSearchableDropdown<String?>(
|
AppSearchableDropdown<String?>(
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
@ -416,10 +416,10 @@ class _AssetDataTable extends StatelessWidget {
|
|||||||
cellBuilder: (_, asset) => Text(asset.assetCategoryName ?? '—'),
|
cellBuilder: (_, asset) => Text(asset.assetCategoryName ?? '—'),
|
||||||
),
|
),
|
||||||
AppDataColumn(
|
AppDataColumn(
|
||||||
label: 'Plant',
|
label: 'Location',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
searchText: (asset) => asset.plantName ?? '',
|
searchText: (asset) => asset.locationName ?? '',
|
||||||
cellBuilder: (_, asset) => Text(asset.plantName ?? '—'),
|
cellBuilder: (_, asset) => Text(asset.locationName ?? '—'),
|
||||||
),
|
),
|
||||||
AppDataColumn(
|
AppDataColumn(
|
||||||
label: 'Warranty',
|
label: 'Warranty',
|
||||||
@ -533,7 +533,7 @@ class _AssetMobileList extends StatelessWidget {
|
|||||||
_AssetCodeBadge(code: asset.assetCode!)
|
_AssetCodeBadge(code: asset.assetCode!)
|
||||||
else
|
else
|
||||||
const Text('—'),
|
const Text('—'),
|
||||||
Text('${asset.assetCategoryName ?? '—'} · ${asset.plantName ?? '—'}'),
|
Text('${asset.assetCategoryName ?? '—'} · ${asset.locationName ?? '—'}'),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|||||||
@ -1,30 +1,355 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import '../../../../core/constants/route_constants.dart';
|
||||||
|
import '../../../../core/errors/failure.dart';
|
||||||
|
import '../../../../core/utils/formatters.dart';
|
||||||
|
import '../../../../core/utils/responsive_utils.dart';
|
||||||
|
import '../../../../shared/models/asset_model.dart';
|
||||||
|
import '../../../../shared/widgets/app_data_table.dart';
|
||||||
|
import '../../../../shared/widgets/app_empty_state.dart';
|
||||||
|
import '../../../../shared/widgets/app_form_toggle_field.dart';
|
||||||
|
import '../../../../shared/widgets/app_loading_view.dart';
|
||||||
|
import '../../../../shared/widgets/app_pagination.dart';
|
||||||
|
import '../../../../shared/widgets/app_table_action_icon.dart';
|
||||||
|
import '../../../../shared/widgets/app_toast.dart';
|
||||||
import '../../../../shared/widgets/error_view.dart';
|
import '../../../../shared/widgets/error_view.dart';
|
||||||
import '../../../../shared/widgets/page_header.dart';
|
import '../../../../shared/widgets/page_header.dart';
|
||||||
|
import '../providers/assets_provider.dart';
|
||||||
|
import '../widgets/asset_maintenance_panel.dart';
|
||||||
|
|
||||||
class AssetMaintenanceScreen extends StatelessWidget {
|
class AssetMaintenanceScreen extends ConsumerWidget {
|
||||||
const AssetMaintenanceScreen({super.key});
|
const AssetMaintenanceScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return const Padding(
|
final maintenanceAsync = ref.watch(myMaintenanceProvider);
|
||||||
padding: EdgeInsets.all(24),
|
|
||||||
child: Column(
|
return Padding(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
padding: const EdgeInsets.all(24),
|
||||||
children: [
|
child: maintenanceAsync.when(
|
||||||
PageHeader(
|
loading: () =>
|
||||||
title: 'Asset Maintenance',
|
const AppLoadingView(message: 'Loading maintenance assets...'),
|
||||||
subtitle: 'Track repairs, service vendors, and costs',
|
error: (e, _) => ErrorView.fromFailure(
|
||||||
|
e is Failure ? e : Failure.unknown(message: e.toString()),
|
||||||
|
onRetry: () => ref.invalidate(myMaintenanceProvider),
|
||||||
|
),
|
||||||
|
data: (state) => _MyMaintenanceBody(state: state),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyMaintenanceBody extends ConsumerWidget {
|
||||||
|
const _MyMaintenanceBody({required this.state});
|
||||||
|
|
||||||
|
final MyMaintenanceState state;
|
||||||
|
|
||||||
|
Future<void> _openSubmit(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
AssetModel asset,
|
||||||
|
) async {
|
||||||
|
final saved = await openSubmitMaintenancePanel(context, ref, asset: asset);
|
||||||
|
if (saved == true && context.mounted) {
|
||||||
|
showAppToastFromSnackBar(
|
||||||
|
context,
|
||||||
|
const SnackBar(content: Text('Maintenance log submitted')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final notifier = ref.read(myMaintenanceProvider.notifier);
|
||||||
|
final isWide = context.isDesktop;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
PageHeader(
|
||||||
|
title: 'My Maintenance',
|
||||||
|
subtitle: 'Assets assigned to you for checklist-based maintenance',
|
||||||
|
actions: [
|
||||||
|
OutlinedButton.icon(
|
||||||
|
onPressed: () => context.go(RouteConstants.assets),
|
||||||
|
icon: const Icon(Icons.inventory_2_outlined),
|
||||||
|
label: const Text('Asset Master'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
runSpacing: 8,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
AppFormToggleField(
|
||||||
|
label: 'Due only',
|
||||||
|
subtitle: 'Show assets with maintenance due',
|
||||||
|
value: state.dueOnly,
|
||||||
|
onChanged: notifier.setDueOnly,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: state.isRefreshing ? null : () => notifier.refresh(),
|
||||||
|
icon: state.isRefreshing
|
||||||
|
? const SizedBox(
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
)
|
||||||
|
: const Icon(Icons.refresh),
|
||||||
|
tooltip: 'Refresh',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${state.total} asset${state.total == 1 ? '' : 's'}',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Expanded(
|
||||||
|
child: state.assets.isEmpty
|
||||||
|
? AppEmptyState(
|
||||||
|
title: state.dueOnly
|
||||||
|
? 'No due maintenance'
|
||||||
|
: 'No maintenance assets',
|
||||||
|
description: state.dueOnly
|
||||||
|
? 'Nothing is due right now. Turn off “Due only” to see all assigned assets.'
|
||||||
|
: 'Assets where you are the maintenance in-charge will appear here.',
|
||||||
|
icon: Icons.build_circle_outlined,
|
||||||
|
)
|
||||||
|
: isWide
|
||||||
|
? _MaintenanceTable(
|
||||||
|
assets: state.assets,
|
||||||
|
onSubmit: (asset) => _openSubmit(context, ref, asset),
|
||||||
|
onView: (asset) =>
|
||||||
|
context.push('${RouteConstants.assets}/${asset.id}'),
|
||||||
|
)
|
||||||
|
: _MaintenanceMobileList(
|
||||||
|
assets: state.assets,
|
||||||
|
onSubmit: (asset) => _openSubmit(context, ref, asset),
|
||||||
|
onView: (asset) =>
|
||||||
|
context.push('${RouteConstants.assets}/${asset.id}'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AppPagination(
|
||||||
|
currentPage: state.page,
|
||||||
|
totalPages: state.totalPages,
|
||||||
|
totalItems: state.total,
|
||||||
|
pageSize: state.limit,
|
||||||
|
onPageChanged: notifier.setPage,
|
||||||
|
onPageSizeChanged: notifier.setPageSize,
|
||||||
|
itemLabel: 'assets',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MaintenanceTable extends StatelessWidget {
|
||||||
|
const _MaintenanceTable({
|
||||||
|
required this.assets,
|
||||||
|
required this.onSubmit,
|
||||||
|
required this.onView,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<AssetModel> assets;
|
||||||
|
final void Function(AssetModel asset) onSubmit;
|
||||||
|
final void Function(AssetModel asset) onView;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final dateFormat = DateFormat('dd MMM yyyy');
|
||||||
|
|
||||||
|
return AppDataTable<AssetModel>(
|
||||||
|
wrapInCard: false,
|
||||||
|
columns: [
|
||||||
|
AppDataColumn(
|
||||||
|
label: 'Asset Code',
|
||||||
|
flex: 1,
|
||||||
|
searchText: (asset) => asset.assetCode ?? '',
|
||||||
|
cellBuilder: (_, asset) => Text(asset.assetCode ?? '—'),
|
||||||
|
),
|
||||||
|
AppDataColumn(
|
||||||
|
label: 'Asset Name',
|
||||||
|
flex: 2,
|
||||||
|
searchText: (asset) => asset.assetName,
|
||||||
|
cellBuilder: (_, asset) => Text(asset.assetName),
|
||||||
|
),
|
||||||
|
AppDataColumn(
|
||||||
|
label: 'Next Due',
|
||||||
|
flex: 1,
|
||||||
|
searchText: (asset) => DateFormatter.displayDate(
|
||||||
|
asset.maintenance?.nextDueDate,
|
||||||
|
),
|
||||||
|
cellBuilder: (_, asset) {
|
||||||
|
final nextDue = asset.maintenance?.nextDueDate;
|
||||||
|
return Text(
|
||||||
|
nextDue != null ? dateFormat.format(nextDue) : '—',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
AppDataColumn(
|
||||||
|
label: 'Status',
|
||||||
|
flex: 1,
|
||||||
|
searchText: (asset) =>
|
||||||
|
asset.maintenance?.isDue == true ? 'due' : 'ok',
|
||||||
|
cellBuilder: (_, asset) => _DueBadge(
|
||||||
|
isDue: asset.maintenance?.isDue == true,
|
||||||
|
daysUntilDue: asset.maintenance?.daysUntilDue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AppDataColumn(
|
||||||
|
label: 'Actions',
|
||||||
|
flex: 1,
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
enableSearch: false,
|
||||||
|
cellBuilder: (_, asset) => AppTableActions(
|
||||||
|
children: [
|
||||||
|
AppTableActionIcon(
|
||||||
|
tooltip: 'Submit checklist',
|
||||||
|
icon: Icons.checklist_outlined,
|
||||||
|
onPressed: () => onSubmit(asset),
|
||||||
|
),
|
||||||
|
AppTableActionIcon(
|
||||||
|
tooltip: 'View asset',
|
||||||
|
icon: Icons.visibility_outlined,
|
||||||
|
onPressed: () => onView(asset),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
rows: assets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MaintenanceMobileList extends StatelessWidget {
|
||||||
|
const _MaintenanceMobileList({
|
||||||
|
required this.assets,
|
||||||
|
required this.onSubmit,
|
||||||
|
required this.onView,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<AssetModel> assets;
|
||||||
|
final void Function(AssetModel asset) onSubmit;
|
||||||
|
final void Function(AssetModel asset) onView;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final dateFormat = DateFormat('dd MMM yyyy');
|
||||||
|
|
||||||
|
return ListView.separated(
|
||||||
|
itemCount: assets.length,
|
||||||
|
separatorBuilder: (_, __) => const SizedBox(height: 8),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final asset = assets[index];
|
||||||
|
final nextDue = asset.maintenance?.nextDueDate;
|
||||||
|
final subtitleParts = [
|
||||||
|
if (asset.assetCode?.trim().isNotEmpty == true)
|
||||||
|
asset.assetCode!.trim(),
|
||||||
|
if (nextDue != null) 'Next due: ${dateFormat.format(nextDue)}',
|
||||||
|
];
|
||||||
|
|
||||||
|
return Material(
|
||||||
|
color: theme.colorScheme.surfaceContainerHighest.withValues(
|
||||||
|
alpha: 0.35,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
onTap: () => onSubmit(asset),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
asset.assetName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: theme.textTheme.titleSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (subtitleParts.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
subtitleParts.join(' · '),
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_DueBadge(
|
||||||
|
isDue: asset.maintenance?.isDue == true,
|
||||||
|
daysUntilDue: asset.maintenance?.daysUntilDue,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: 'View asset',
|
||||||
|
onPressed: () => onView(asset),
|
||||||
|
icon: const Icon(Icons.visibility_outlined),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DueBadge extends StatelessWidget {
|
||||||
|
const _DueBadge({
|
||||||
|
required this.isDue,
|
||||||
|
this.daysUntilDue,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool isDue;
|
||||||
|
final int? daysUntilDue;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final color = isDue
|
||||||
|
? const Color(0xFFDC2626)
|
||||||
|
: const Color(0xFF16A34A);
|
||||||
|
final label = isDue
|
||||||
|
? (daysUntilDue != null && daysUntilDue! < 0
|
||||||
|
? 'Overdue'
|
||||||
|
: 'Due')
|
||||||
|
: (daysUntilDue != null
|
||||||
|
? 'In $daysUntilDue day${daysUntilDue == 1 ? '' : 's'}'
|
||||||
|
: 'On track');
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color.withValues(alpha: 0.12),
|
||||||
|
borderRadius: BorderRadius.circular(999),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: theme.textTheme.labelSmall?.copyWith(
|
||||||
|
color: color,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 0.2,
|
||||||
),
|
),
|
||||||
Expanded(
|
|
||||||
child: EmptyStateView(
|
|
||||||
title: 'No maintenance requests',
|
|
||||||
description: 'Create maintenance requests and view service history.',
|
|
||||||
icon: Icons.build_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,12 +78,13 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
final _depreciationRateController = TextEditingController();
|
final _depreciationRateController = TextEditingController();
|
||||||
final _salvageValueController = TextEditingController();
|
final _salvageValueController = TextEditingController();
|
||||||
final _remarksController = TextEditingController();
|
final _remarksController = TextEditingController();
|
||||||
|
final _frequencyController = TextEditingController();
|
||||||
int? _categoryId;
|
int? _categoryId;
|
||||||
int? _subcategoryId;
|
int? _subcategoryId;
|
||||||
int? _plantId;
|
int? _locationId;
|
||||||
int? _departmentId;
|
int? _departmentId;
|
||||||
int? _warehouseId;
|
|
||||||
int? _assignedToUserId;
|
int? _assignedToUserId;
|
||||||
|
int? _maintenanceInchargeUserId;
|
||||||
int? _vendorId;
|
int? _vendorId;
|
||||||
int? _poId;
|
int? _poId;
|
||||||
int? _grnId;
|
int? _grnId;
|
||||||
@ -93,7 +94,9 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
String? _depreciationMethod;
|
String? _depreciationMethod;
|
||||||
DateTime? _warrantyExpiry;
|
DateTime? _warrantyExpiry;
|
||||||
DateTime? _purchaseDate;
|
DateTime? _purchaseDate;
|
||||||
|
DateTime? _commencementDate;
|
||||||
DateTime? _disposalDate;
|
DateTime? _disposalDate;
|
||||||
|
List<AssetMaintenanceChecklistItem> _checklistItems = [];
|
||||||
bool _isActive = true;
|
bool _isActive = true;
|
||||||
bool _isSubmitting = false;
|
bool _isSubmitting = false;
|
||||||
String? _populatedSignature;
|
String? _populatedSignature;
|
||||||
@ -130,6 +133,7 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
_depreciationRateController.dispose();
|
_depreciationRateController.dispose();
|
||||||
_salvageValueController.dispose();
|
_salvageValueController.dispose();
|
||||||
_remarksController.dispose();
|
_remarksController.dispose();
|
||||||
|
_frequencyController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +143,7 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
|
|
||||||
String _assetSignature(AssetModel asset) =>
|
String _assetSignature(AssetModel asset) =>
|
||||||
'${asset.id}:${asset.assetCategoryId}:${asset.assetSubcategoryId}:'
|
'${asset.id}:${asset.assetCategoryId}:${asset.assetSubcategoryId}:'
|
||||||
'${asset.plantId}:${asset.status}:${asset.assetName}';
|
'${asset.locationId}:${asset.status}:${asset.assetName}';
|
||||||
|
|
||||||
int? _nullablePositiveId(int? id) {
|
int? _nullablePositiveId(int? id) {
|
||||||
if (id == null || id <= 0) return null;
|
if (id == null || id <= 0) return null;
|
||||||
@ -188,10 +192,11 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
_nameController.text = asset.assetName;
|
_nameController.text = asset.assetName;
|
||||||
_categoryId = asset.assetCategoryId;
|
_categoryId = asset.assetCategoryId;
|
||||||
_subcategoryId = asset.assetSubcategoryId;
|
_subcategoryId = asset.assetSubcategoryId;
|
||||||
_plantId = asset.plantId;
|
_locationId = asset.locationId;
|
||||||
_departmentId = _nullablePositiveId(asset.departmentId);
|
_departmentId = _nullablePositiveId(asset.departmentId);
|
||||||
_warehouseId = _nullablePositiveId(asset.warehouseId);
|
|
||||||
_assignedToUserId = _nullablePositiveId(asset.assignedToUserId);
|
_assignedToUserId = _nullablePositiveId(asset.assignedToUserId);
|
||||||
|
_maintenanceInchargeUserId =
|
||||||
|
_nullablePositiveId(asset.maintenanceInchargeUserId);
|
||||||
_vendorId = _nullablePositiveId(asset.vendorId);
|
_vendorId = _nullablePositiveId(asset.vendorId);
|
||||||
_poId = _nullablePositiveId(asset.poId);
|
_poId = _nullablePositiveId(asset.poId);
|
||||||
_grnId = _nullablePositiveId(asset.grnId);
|
_grnId = _nullablePositiveId(asset.grnId);
|
||||||
@ -201,7 +206,11 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
_depreciationMethod = asset.depreciationMethod;
|
_depreciationMethod = asset.depreciationMethod;
|
||||||
_warrantyExpiry = asset.warrantyExpiryDate;
|
_warrantyExpiry = asset.warrantyExpiryDate;
|
||||||
_purchaseDate = asset.purchaseDate;
|
_purchaseDate = asset.purchaseDate;
|
||||||
|
_commencementDate = asset.commencementDate;
|
||||||
_disposalDate = asset.disposalDate;
|
_disposalDate = asset.disposalDate;
|
||||||
|
_checklistItems = [
|
||||||
|
...(asset.maintenanceChecklistJson ?? const []),
|
||||||
|
];
|
||||||
_isActive = asset.isActive;
|
_isActive = asset.isActive;
|
||||||
_serialController.text = asset.serialNumber ?? '';
|
_serialController.text = asset.serialNumber ?? '';
|
||||||
_partNumberController.text = asset.partNumber ?? '';
|
_partNumberController.text = asset.partNumber ?? '';
|
||||||
@ -215,6 +224,8 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
_depreciationRateController.text = asset.depreciationRate?.toString() ?? '';
|
_depreciationRateController.text = asset.depreciationRate?.toString() ?? '';
|
||||||
_salvageValueController.text = asset.salvageValue?.toString() ?? '';
|
_salvageValueController.text = asset.salvageValue?.toString() ?? '';
|
||||||
_remarksController.text = asset.remarks ?? '';
|
_remarksController.text = asset.remarks ?? '';
|
||||||
|
_frequencyController.text =
|
||||||
|
asset.maintenanceFrequencyInDays?.toString() ?? '';
|
||||||
if (asset.purchaseCost != null) {
|
if (asset.purchaseCost != null) {
|
||||||
_costController.text = asset.purchaseCost!.toStringAsFixed(
|
_costController.text = asset.purchaseCost!.toStringAsFixed(
|
||||||
asset.purchaseCost! % 1 == 0 ? 0 : 2,
|
asset.purchaseCost! % 1 == 0 ? 0 : 2,
|
||||||
@ -261,6 +272,10 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
final usefulLife = int.tryParse(_usefulLifeController.text.trim());
|
final usefulLife = int.tryParse(_usefulLifeController.text.trim());
|
||||||
if (usefulLife != null) payload['useful_life_years'] = usefulLife;
|
if (usefulLife != null) payload['useful_life_years'] = usefulLife;
|
||||||
|
|
||||||
|
if (_commencementDate != null) {
|
||||||
|
payload['commencement_date'] =
|
||||||
|
DateFormat('yyyy-MM-dd').format(_commencementDate!);
|
||||||
|
}
|
||||||
if (_purchaseDate != null) {
|
if (_purchaseDate != null) {
|
||||||
payload['purchase_date'] = DateFormat('yyyy-MM-dd').format(_purchaseDate!);
|
payload['purchase_date'] = DateFormat('yyyy-MM-dd').format(_purchaseDate!);
|
||||||
}
|
}
|
||||||
@ -312,15 +327,21 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
'asset_name': _nameController.text.trim(),
|
'asset_name': _nameController.text.trim(),
|
||||||
'item_category_id': _categoryId,
|
'item_category_id': _categoryId,
|
||||||
'item_subcategory_id': _subcategoryId,
|
'item_subcategory_id': _subcategoryId,
|
||||||
'plant_id': _plantId,
|
'location_id': _locationId,
|
||||||
'is_active': _isActive,
|
'is_active': _isActive,
|
||||||
};
|
};
|
||||||
|
|
||||||
_putOptionalId(payload, 'department_id', _departmentId);
|
_putOptionalId(payload, 'department_id', _departmentId);
|
||||||
_putOptionalId(payload, 'warehouse_id', _warehouseId);
|
|
||||||
if (_isAssignableUser(_assignedToUserId)) {
|
if (_isAssignableUser(_assignedToUserId)) {
|
||||||
_putOptionalId(payload, 'assigned_to_user_id', _assignedToUserId);
|
_putOptionalId(payload, 'assigned_to_user_id', _assignedToUserId);
|
||||||
}
|
}
|
||||||
|
if (_isAssignableUser(_maintenanceInchargeUserId)) {
|
||||||
|
_putOptionalId(
|
||||||
|
payload,
|
||||||
|
'maintenance_incharge_user_id',
|
||||||
|
_maintenanceInchargeUserId,
|
||||||
|
);
|
||||||
|
}
|
||||||
_putOptionalId(payload, 'vendor_id', _vendorId);
|
_putOptionalId(payload, 'vendor_id', _vendorId);
|
||||||
_putOptionalId(payload, 'po_id', _poId);
|
_putOptionalId(payload, 'po_id', _poId);
|
||||||
_putOptionalId(payload, 'grn_id', _grnId);
|
_putOptionalId(payload, 'grn_id', _grnId);
|
||||||
@ -338,6 +359,10 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
if (_purchaseDate != null) {
|
if (_purchaseDate != null) {
|
||||||
payload['purchase_date'] = DateFormat('yyyy-MM-dd').format(_purchaseDate!);
|
payload['purchase_date'] = DateFormat('yyyy-MM-dd').format(_purchaseDate!);
|
||||||
}
|
}
|
||||||
|
if (_commencementDate != null) {
|
||||||
|
payload['commencement_date'] =
|
||||||
|
DateFormat('yyyy-MM-dd').format(_commencementDate!);
|
||||||
|
}
|
||||||
if (_warrantyExpiry != null) {
|
if (_warrantyExpiry != null) {
|
||||||
payload['warranty_expiry_date'] =
|
payload['warranty_expiry_date'] =
|
||||||
DateFormat('yyyy-MM-dd').format(_warrantyExpiry!);
|
DateFormat('yyyy-MM-dd').format(_warrantyExpiry!);
|
||||||
@ -353,6 +378,31 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
final usefulLife = int.tryParse(_usefulLifeController.text.trim());
|
final usefulLife = int.tryParse(_usefulLifeController.text.trim());
|
||||||
if (usefulLife != null) payload['useful_life_years'] = usefulLife;
|
if (usefulLife != null) payload['useful_life_years'] = usefulLife;
|
||||||
|
|
||||||
|
final frequency = int.tryParse(_frequencyController.text.trim());
|
||||||
|
if (frequency != null) payload['maintenance_frequency_in_days'] = frequency;
|
||||||
|
|
||||||
|
final checklistPayload = _checklistItems
|
||||||
|
.map((item) => item.toJson())
|
||||||
|
.where((item) {
|
||||||
|
final key = (item['key'] as String?)?.trim() ?? '';
|
||||||
|
final label = (item['label'] as String?)?.trim() ?? '';
|
||||||
|
return key.isNotEmpty || label.isNotEmpty;
|
||||||
|
})
|
||||||
|
.map((item) {
|
||||||
|
final key = (item['key'] as String?)?.trim() ?? '';
|
||||||
|
final label = (item['label'] as String?)?.trim() ?? '';
|
||||||
|
return {
|
||||||
|
'key': key.isNotEmpty ? key : label,
|
||||||
|
'label': label.isNotEmpty ? label : key,
|
||||||
|
'required': item['required'] == true,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.where((item) => (item['key'] as String).isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
if (checklistPayload.isNotEmpty) {
|
||||||
|
payload['maintenance_checklist_json'] = checklistPayload;
|
||||||
|
}
|
||||||
|
|
||||||
if (_depreciationMethod != null) {
|
if (_depreciationMethod != null) {
|
||||||
payload['depreciation_method'] = _depreciationMethod;
|
payload['depreciation_method'] = _depreciationMethod;
|
||||||
}
|
}
|
||||||
@ -467,7 +517,6 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final categoriesAsync = ref.watch(itemCategoriesFormProvider);
|
final categoriesAsync = ref.watch(itemCategoriesFormProvider);
|
||||||
final plantsAsync = ref.watch(assetPlantsProvider);
|
|
||||||
|
|
||||||
if (widget.isEditing) {
|
if (widget.isEditing) {
|
||||||
ref.listen(assetFormProvider(widget.assetId), (prev, next) {
|
ref.listen(assetFormProvider(widget.assetId), (prev, next) {
|
||||||
@ -513,15 +562,14 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
e is Failure ? e : Failure.unknown(message: e.toString()),
|
e is Failure ? e : Failure.unknown(message: e.toString()),
|
||||||
onRetry: () => ref.invalidate(assetFormProvider(widget.assetId)),
|
onRetry: () => ref.invalidate(assetFormProvider(widget.assetId)),
|
||||||
),
|
),
|
||||||
data: (_) => _buildForm(categoriesAsync, plantsAsync),
|
data: (_) => _buildForm(categoriesAsync),
|
||||||
)
|
)
|
||||||
: _buildForm(categoriesAsync, plantsAsync),
|
: _buildForm(categoriesAsync),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildForm(
|
Widget _buildForm(
|
||||||
AsyncValue<List<AssetCategoryModel>> categoriesAsync,
|
AsyncValue<List<AssetCategoryModel>> categoriesAsync,
|
||||||
AsyncValue<List<FilterOptionModel>> plantsAsync,
|
|
||||||
) {
|
) {
|
||||||
final subcategoriesAsync = ref.watch(itemSubcategoriesProvider(_categoryId));
|
final subcategoriesAsync = ref.watch(itemSubcategoriesProvider(_categoryId));
|
||||||
final lookupsAsync = ref.watch(assetFormLookupsProvider);
|
final lookupsAsync = ref.watch(assetFormLookupsProvider);
|
||||||
@ -589,10 +637,10 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
plantsAsync.when(
|
lookupsAsync.when(
|
||||||
loading: () => const LinearProgressIndicator(),
|
loading: () => const LinearProgressIndicator(),
|
||||||
error: (_, __) => const Text('Failed to load plants'),
|
error: (_, __) => const Text('Failed to load locations'),
|
||||||
data: (plants) => _plantDropdown(plants),
|
data: (lookups) => _locationDropdown(lookups.locations),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -681,16 +729,7 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
masterId: 'departments',
|
masterId: 'departments',
|
||||||
onChanged: (v) => setState(() => _departmentId = v),
|
onChanged: (v) => setState(() => _departmentId = v),
|
||||||
),
|
),
|
||||||
right: _optionalLookupDropdown(
|
right: AppTextField(
|
||||||
label: 'Warehouse',
|
|
||||||
value: _warehouseId,
|
|
||||||
options: lookups.warehouses,
|
|
||||||
masterId: 'warehouses',
|
|
||||||
onChanged: (v) => setState(() => _warehouseId = v),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
AppTextField(
|
|
||||||
isDense: true,
|
isDense: true,
|
||||||
controller: _locationDetailController,
|
controller: _locationDetailController,
|
||||||
label: 'Location Detail',
|
label: 'Location Detail',
|
||||||
@ -703,6 +742,7 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_optionalLookupDropdown(
|
_optionalLookupDropdown(
|
||||||
label: 'Assigned To',
|
label: 'Assigned To',
|
||||||
@ -713,6 +753,33 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SidePanelSection(
|
||||||
|
title: 'MAINTENANCE',
|
||||||
|
children: [
|
||||||
|
SidePanelFormRow(
|
||||||
|
left: _optionalLookupDropdown(
|
||||||
|
label: 'Maintenance Incharge',
|
||||||
|
value: _maintenanceInchargeUserId,
|
||||||
|
options: lookups.users,
|
||||||
|
onChanged: (v) =>
|
||||||
|
setState(() => _maintenanceInchargeUserId = v),
|
||||||
|
emptyHint: 'Unassigned',
|
||||||
|
),
|
||||||
|
right: AppTextField(
|
||||||
|
isDense: true,
|
||||||
|
controller: _frequencyController,
|
||||||
|
label: 'Frequency (Days)',
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
validator: (v) => Validators.optionalPositiveInt(
|
||||||
|
v,
|
||||||
|
fieldName: 'Frequency',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildChecklistEditor(),
|
||||||
|
],
|
||||||
|
),
|
||||||
SidePanelSection(
|
SidePanelSection(
|
||||||
title: 'PROCUREMENT',
|
title: 'PROCUREMENT',
|
||||||
children: [
|
children: [
|
||||||
@ -779,11 +846,23 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
_pickDate((d) => _purchaseDate = d, _purchaseDate),
|
_pickDate((d) => _purchaseDate = d, _purchaseDate),
|
||||||
),
|
),
|
||||||
right: _AssetFormDateField(
|
right: _AssetFormDateField(
|
||||||
|
label: 'Commencement Date',
|
||||||
|
value: _commencementDate,
|
||||||
|
onPick: () => _pickDate(
|
||||||
|
(d) => _commencementDate = d,
|
||||||
|
_commencementDate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
SidePanelFormRow(
|
||||||
|
left: _AssetFormDateField(
|
||||||
label: 'Warranty Expiry Date',
|
label: 'Warranty Expiry Date',
|
||||||
value: _warrantyExpiry,
|
value: _warrantyExpiry,
|
||||||
onPick: () =>
|
onPick: () =>
|
||||||
_pickDate((d) => _warrantyExpiry = d, _warrantyExpiry),
|
_pickDate((d) => _warrantyExpiry = d, _warrantyExpiry),
|
||||||
),
|
),
|
||||||
|
right: const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
SidePanelFormRow(
|
SidePanelFormRow(
|
||||||
@ -979,6 +1058,76 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildChecklistEditor() {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'Checklist Template',
|
||||||
|
style: theme.textTheme.labelLarge?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_checklistItems = [
|
||||||
|
..._checklistItems,
|
||||||
|
const AssetMaintenanceChecklistItem(
|
||||||
|
key: '',
|
||||||
|
label: '',
|
||||||
|
),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add, size: 18),
|
||||||
|
label: const Text('Add Item'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (_checklistItems.isEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 4),
|
||||||
|
child: Text(
|
||||||
|
'No checklist items. Add items for maintenance checks.',
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
for (var i = 0; i < _checklistItems.length; i++) ...[
|
||||||
|
if (i > 0) const SizedBox(height: 8),
|
||||||
|
_ChecklistItemRow(
|
||||||
|
key: ValueKey('checklist-row-$i'),
|
||||||
|
item: _checklistItems[i],
|
||||||
|
onChanged: (updated) {
|
||||||
|
setState(() {
|
||||||
|
_checklistItems = [
|
||||||
|
for (var j = 0; j < _checklistItems.length; j++)
|
||||||
|
if (j == i) updated else _checklistItems[j],
|
||||||
|
];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onRemove: () {
|
||||||
|
setState(() {
|
||||||
|
_checklistItems = [
|
||||||
|
for (var j = 0; j < _checklistItems.length; j++)
|
||||||
|
if (j != i) _checklistItems[j],
|
||||||
|
];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _optionalLookupDropdown({
|
Widget _optionalLookupDropdown({
|
||||||
required String label,
|
required String label,
|
||||||
required int? value,
|
required int? value,
|
||||||
@ -1034,7 +1183,6 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
options: dropdownOptions,
|
options: dropdownOptions,
|
||||||
refreshLookups: () {
|
refreshLookups: () {
|
||||||
ref.invalidate(assetFormLookupsProvider);
|
ref.invalidate(assetFormLookupsProvider);
|
||||||
ref.invalidate(assetPlantsProvider);
|
|
||||||
},
|
},
|
||||||
parseCreatedId: int.tryParse,
|
parseCreatedId: int.tryParse,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
@ -1128,33 +1276,125 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _plantDropdown(List<FilterOptionModel> plants) {
|
Widget _locationDropdown(List<FilterOptionModel> locations) {
|
||||||
final plantIds = plants
|
final locationIds = locations
|
||||||
.map((p) => int.tryParse(p.id))
|
.map((location) => int.tryParse(location.id))
|
||||||
.whereType<int>()
|
.whereType<int>()
|
||||||
.toList();
|
.toList();
|
||||||
return MasterQuickAddDropdown<int>(
|
return AppSearchableDropdown<int>(
|
||||||
masterId: 'plants',
|
label: 'Location *',
|
||||||
label: 'Plant *',
|
value: _dropdownValue(_locationId, locationIds),
|
||||||
value: _dropdownValue(_plantId, plantIds),
|
searchHint: 'Search plant or warehouse...',
|
||||||
searchHint: 'Search plant...',
|
|
||||||
isDense: true,
|
isDense: true,
|
||||||
options: plants
|
options: locations
|
||||||
.map(
|
.map(
|
||||||
(p) => AppDropdownOption(
|
(location) => AppDropdownOption(
|
||||||
value: int.tryParse(p.id) ?? 0,
|
value: int.tryParse(location.id) ?? 0,
|
||||||
label: p.name,
|
label: location.name,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.where((option) => option.value != 0)
|
.where((option) => option.value != 0)
|
||||||
.toList(),
|
.toList(),
|
||||||
refreshLookups: () {
|
onChanged: (v) => setState(() => _locationId = v),
|
||||||
ref.invalidate(assetPlantsProvider);
|
validator: (v) => v == null ? 'Location is required' : null,
|
||||||
ref.invalidate(assetFormLookupsProvider);
|
);
|
||||||
},
|
}
|
||||||
parseCreatedId: int.tryParse,
|
}
|
||||||
onChanged: (v) => setState(() => _plantId = v),
|
|
||||||
validator: (v) => v == null ? 'Plant is required' : null,
|
class _ChecklistItemRow extends StatefulWidget {
|
||||||
|
const _ChecklistItemRow({
|
||||||
|
super.key,
|
||||||
|
required this.item,
|
||||||
|
required this.onChanged,
|
||||||
|
required this.onRemove,
|
||||||
|
});
|
||||||
|
|
||||||
|
final AssetMaintenanceChecklistItem item;
|
||||||
|
final ValueChanged<AssetMaintenanceChecklistItem> onChanged;
|
||||||
|
final VoidCallback onRemove;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_ChecklistItemRow> createState() => _ChecklistItemRowState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChecklistItemRowState extends State<_ChecklistItemRow> {
|
||||||
|
late final TextEditingController _keyController;
|
||||||
|
late final TextEditingController _labelController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_keyController = TextEditingController(text: widget.item.key);
|
||||||
|
_labelController = TextEditingController(text: widget.item.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant _ChecklistItemRow oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (oldWidget.item.key != widget.item.key &&
|
||||||
|
_keyController.text != widget.item.key) {
|
||||||
|
_keyController.text = widget.item.key;
|
||||||
|
}
|
||||||
|
if (oldWidget.item.label != widget.item.label &&
|
||||||
|
_labelController.text != widget.item.label) {
|
||||||
|
_labelController.text = widget.item.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_keyController.dispose();
|
||||||
|
_labelController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _emit({String? key, String? label, bool? required}) {
|
||||||
|
widget.onChanged(
|
||||||
|
AssetMaintenanceChecklistItem(
|
||||||
|
key: key ?? _keyController.text,
|
||||||
|
label: label ?? _labelController.text,
|
||||||
|
required: required ?? widget.item.required,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
SidePanelFormRow(
|
||||||
|
left: AppTextField(
|
||||||
|
isDense: true,
|
||||||
|
controller: _keyController,
|
||||||
|
label: 'Key',
|
||||||
|
onChanged: (value) => _emit(key: value),
|
||||||
|
),
|
||||||
|
right: AppTextField(
|
||||||
|
isDense: true,
|
||||||
|
controller: _labelController,
|
||||||
|
label: 'Label',
|
||||||
|
onChanged: (value) => _emit(label: value),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: AppFormToggleField(
|
||||||
|
label: 'Required',
|
||||||
|
value: widget.item.required,
|
||||||
|
onChanged: (value) => _emit(required: value),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: 'Remove item',
|
||||||
|
onPressed: widget.onRemove,
|
||||||
|
icon: const Icon(Icons.delete_outline, size: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1340,11 +1580,6 @@ class _AssetFormDateFieldState extends State<_AssetFormDateField> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final assetPlantsProvider = FutureProvider<List<FilterOptionModel>>((ref) async {
|
|
||||||
final dataSource = ref.watch(masterRemoteDataSourceProvider);
|
|
||||||
return dataSource.listPlants();
|
|
||||||
});
|
|
||||||
|
|
||||||
final itemSubcategoriesProvider =
|
final itemSubcategoriesProvider =
|
||||||
FutureProvider.family<List<FilterOptionModel>, int?>((ref, categoryId) async {
|
FutureProvider.family<List<FilterOptionModel>, int?>((ref, categoryId) async {
|
||||||
if (categoryId == null) return [];
|
if (categoryId == null) return [];
|
||||||
|
|||||||
@ -0,0 +1,475 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import '../../../../core/utils/formatters.dart';
|
||||||
|
import '../../../../shared/models/asset_model.dart';
|
||||||
|
import '../../../../shared/widgets/app_button.dart';
|
||||||
|
import '../../../../shared/widgets/app_date_popup.dart';
|
||||||
|
import '../../../../shared/widgets/app_dropdown.dart';
|
||||||
|
import '../../../../shared/widgets/app_empty_state.dart';
|
||||||
|
import '../../../../shared/widgets/app_side_panel.dart';
|
||||||
|
import '../../../../shared/widgets/app_text_field.dart';
|
||||||
|
import '../../data/repositories/asset_repository_impl.dart';
|
||||||
|
import '../providers/assets_provider.dart';
|
||||||
|
|
||||||
|
List<AssetMaintenanceChecklistItem> checklistForAsset(AssetModel asset) {
|
||||||
|
final fromSummary = asset.maintenance?.checklist;
|
||||||
|
if (fromSummary != null && fromSummary.isNotEmpty) {
|
||||||
|
return fromSummary;
|
||||||
|
}
|
||||||
|
return asset.maintenanceChecklistJson ?? const [];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool?> openSubmitMaintenancePanel(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref, {
|
||||||
|
required AssetModel asset,
|
||||||
|
}) {
|
||||||
|
return showSidePanel<bool>(
|
||||||
|
context,
|
||||||
|
SubmitMaintenanceLogPanel(asset: asset),
|
||||||
|
width: 600,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SubmitMaintenanceLogPanel extends ConsumerStatefulWidget {
|
||||||
|
const SubmitMaintenanceLogPanel({super.key, required this.asset});
|
||||||
|
|
||||||
|
final AssetModel asset;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<SubmitMaintenanceLogPanel> createState() =>
|
||||||
|
_SubmitMaintenanceLogPanelState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChecklistRowState {
|
||||||
|
_ChecklistRowState({
|
||||||
|
required this.keyName,
|
||||||
|
required this.label,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String keyName;
|
||||||
|
final String label;
|
||||||
|
String status = 'OK';
|
||||||
|
final TextEditingController remarksController = TextEditingController();
|
||||||
|
|
||||||
|
void dispose() => remarksController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SubmitMaintenanceLogPanelState
|
||||||
|
extends ConsumerState<SubmitMaintenanceLogPanel> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
final _remarksController = TextEditingController();
|
||||||
|
DateTime _performedDate = DateTime.now();
|
||||||
|
late final List<_ChecklistRowState> _rows;
|
||||||
|
bool _isSubmitting = false;
|
||||||
|
bool _showLogs = false;
|
||||||
|
List<AssetMaintenanceLogModel>? _logs;
|
||||||
|
bool _logsLoading = false;
|
||||||
|
String? _logsError;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
final checklist = checklistForAsset(widget.asset);
|
||||||
|
_rows = checklist
|
||||||
|
.map(
|
||||||
|
(item) => _ChecklistRowState(
|
||||||
|
keyName: item.key.isNotEmpty ? item.key : item.label,
|
||||||
|
label: item.label.isNotEmpty ? item.label : item.key,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_remarksController.dispose();
|
||||||
|
for (final row in _rows) {
|
||||||
|
row.dispose();
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _pickPerformedDate() async {
|
||||||
|
final picked = await showAppDatePopup(
|
||||||
|
context: context,
|
||||||
|
initialDate: _performedDate,
|
||||||
|
firstDate: DateTime(2000),
|
||||||
|
lastDate: DateTime(2100),
|
||||||
|
helpText: 'Performed date',
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() => _performedDate = picked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadLogs() async {
|
||||||
|
setState(() {
|
||||||
|
_showLogs = true;
|
||||||
|
_logsLoading = true;
|
||||||
|
_logsError = null;
|
||||||
|
});
|
||||||
|
final result = await ref
|
||||||
|
.read(assetRepositoryProvider)
|
||||||
|
.getMaintenanceLogs(widget.asset.id);
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
_logsLoading = false;
|
||||||
|
if (result.failure != null) {
|
||||||
|
_logsError = result.failure!.message;
|
||||||
|
_logs = null;
|
||||||
|
} else {
|
||||||
|
_logs = result.data ?? [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _save() async {
|
||||||
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
if (_rows.isEmpty) {
|
||||||
|
showSidePanelSnackBar(context, 'No checklist items configured for this asset');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() => _isSubmitting = true);
|
||||||
|
try {
|
||||||
|
final payload = <String, dynamic>{
|
||||||
|
'performed_date': DateFormatter.toApiDate(_performedDate),
|
||||||
|
'checklist_json': _rows
|
||||||
|
.map(
|
||||||
|
(row) => {
|
||||||
|
'key': row.keyName,
|
||||||
|
'status': row.status,
|
||||||
|
if (row.remarksController.text.trim().isNotEmpty)
|
||||||
|
'remarks': row.remarksController.text.trim(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
if (_remarksController.text.trim().isNotEmpty)
|
||||||
|
'remarks': _remarksController.text.trim(),
|
||||||
|
};
|
||||||
|
|
||||||
|
final result = await ref
|
||||||
|
.read(assetRepositoryProvider)
|
||||||
|
.createMaintenanceLog(widget.asset.id, payload);
|
||||||
|
if (result.failure != null) throw result.failure!;
|
||||||
|
|
||||||
|
ref.invalidate(myMaintenanceProvider);
|
||||||
|
ref.invalidate(assetDetailProvider(widget.asset.id));
|
||||||
|
|
||||||
|
if (mounted) Navigator.of(context, rootNavigator: true).pop(true);
|
||||||
|
} catch (e) {
|
||||||
|
if (mounted) {
|
||||||
|
showSidePanelSnackBar(context, e.toString());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (mounted) setState(() => _isSubmitting = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final assetLabel = widget.asset.assetCode?.trim().isNotEmpty == true
|
||||||
|
? '${widget.asset.assetName} (${widget.asset.assetCode})'
|
||||||
|
: widget.asset.assetName;
|
||||||
|
|
||||||
|
return SidePanelScaffold(
|
||||||
|
title: 'Submit Maintenance',
|
||||||
|
footer: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: _isSubmitting
|
||||||
|
? null
|
||||||
|
: () => Navigator.of(context, rootNavigator: true).pop(),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
AppButton(
|
||||||
|
label: 'Submit Log',
|
||||||
|
expand: false,
|
||||||
|
icon: Icons.check,
|
||||||
|
isLoading: _isSubmitting,
|
||||||
|
onPressed: _isSubmitting ? null : _save,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
assetLabel,
|
||||||
|
style: theme.textTheme.titleSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
'Record checklist results for this maintenance visit.',
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
SidePanelSection(
|
||||||
|
title: 'Visit',
|
||||||
|
children: [
|
||||||
|
_DateField(
|
||||||
|
label: 'Performed Date *',
|
||||||
|
value: _performedDate,
|
||||||
|
onPick: _pickPerformedDate,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
AppTextField(
|
||||||
|
controller: _remarksController,
|
||||||
|
label: 'Remarks',
|
||||||
|
maxLines: 3,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
SidePanelSection(
|
||||||
|
title: 'Checklist',
|
||||||
|
children: [
|
||||||
|
if (_rows.isEmpty)
|
||||||
|
const AppEmptyState(
|
||||||
|
title: 'No checklist items',
|
||||||
|
description:
|
||||||
|
'Configure a maintenance checklist on the asset first.',
|
||||||
|
icon: Icons.checklist_outlined,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
..._rows.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
final row = entry.value;
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: index == _rows.length - 1 ? 0 : 12,
|
||||||
|
),
|
||||||
|
child: _ChecklistItemCard(
|
||||||
|
row: row,
|
||||||
|
onStatusChanged: (status) {
|
||||||
|
if (status == null) return;
|
||||||
|
setState(() => row.status = status);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Recent Logs',
|
||||||
|
style: theme.textTheme.titleSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: _logsLoading
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
if (_showLogs && _logs != null) {
|
||||||
|
setState(() => _showLogs = !_showLogs);
|
||||||
|
} else {
|
||||||
|
_loadLogs();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
_showLogs ? Icons.expand_less : Icons.history,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
label: Text(_showLogs ? 'Hide' : 'View'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (_showLogs) ...[
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
if (_logsLoading)
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 24),
|
||||||
|
child: Center(child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
else if (_logsError != null)
|
||||||
|
Text(
|
||||||
|
_logsError!,
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.error,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else if (_logs == null || _logs!.isEmpty)
|
||||||
|
const AppEmptyState(
|
||||||
|
title: 'No logs yet',
|
||||||
|
description: 'Submitted maintenance visits will appear here.',
|
||||||
|
icon: Icons.history_toggle_off_outlined,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
..._logs!.take(5).map(
|
||||||
|
(log) => Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
|
child: _MaintenanceLogTile(log: log),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DateField extends StatelessWidget {
|
||||||
|
const _DateField({
|
||||||
|
required this.label,
|
||||||
|
required this.value,
|
||||||
|
required this.onPick,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final DateTime? value;
|
||||||
|
final VoidCallback onPick;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextFormField(
|
||||||
|
readOnly: true,
|
||||||
|
onTap: onPick,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: label,
|
||||||
|
hintText: 'Select date',
|
||||||
|
suffixIcon: const Icon(Icons.calendar_today_outlined, size: 20),
|
||||||
|
),
|
||||||
|
controller: TextEditingController(
|
||||||
|
text: value != null ? DateFormatter.displayDate(value) : '',
|
||||||
|
),
|
||||||
|
validator: (_) => value == null ? 'Required' : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChecklistItemCard extends StatelessWidget {
|
||||||
|
const _ChecklistItemCard({
|
||||||
|
required this.row,
|
||||||
|
required this.onStatusChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
final _ChecklistRowState row;
|
||||||
|
final ValueChanged<String?> onStatusChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: theme.dividerColor),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
row.label,
|
||||||
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
AppDropdown<String>(
|
||||||
|
label: 'Status',
|
||||||
|
isDense: true,
|
||||||
|
value: row.status,
|
||||||
|
options: const [
|
||||||
|
AppDropdownOption(value: 'OK', label: 'OK'),
|
||||||
|
AppDropdownOption(value: 'NOT_OK', label: 'Not OK'),
|
||||||
|
AppDropdownOption(value: 'NA', label: 'N/A'),
|
||||||
|
],
|
||||||
|
onChanged: onStatusChanged,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
AppTextField(
|
||||||
|
controller: row.remarksController,
|
||||||
|
label: 'Item remarks',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MaintenanceLogTile extends StatelessWidget {
|
||||||
|
const _MaintenanceLogTile({required this.log});
|
||||||
|
|
||||||
|
final AssetMaintenanceLogModel log;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final dateFormat = DateFormat('dd MMM yyyy');
|
||||||
|
final performed = log.performedDate != null
|
||||||
|
? dateFormat.format(log.performedDate!)
|
||||||
|
: '—';
|
||||||
|
final nextDue =
|
||||||
|
log.nextDueDate != null ? dateFormat.format(log.nextDueDate!) : null;
|
||||||
|
final subtitleParts = [
|
||||||
|
'Performed: $performed',
|
||||||
|
if (nextDue != null) 'Next due: $nextDue',
|
||||||
|
if (log.createdByName?.trim().isNotEmpty == true) log.createdByName!.trim(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: theme.colorScheme.surfaceContainerHighest.withValues(alpha: 0.35),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
subtitleParts.join(' · '),
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (log.remarks?.trim().isNotEmpty == true) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
log.remarks!,
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (log.checklistJson.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Wrap(
|
||||||
|
spacing: 6,
|
||||||
|
runSpacing: 4,
|
||||||
|
children: log.checklistJson.map((item) {
|
||||||
|
final key = item['key']?.toString() ?? 'Item';
|
||||||
|
final status = item['status']?.toString() ?? '—';
|
||||||
|
return Chip(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
label: Text(
|
||||||
|
'$key: $status',
|
||||||
|
style: theme.textTheme.labelSmall,
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1242,10 +1242,9 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _reasonController = TextEditingController();
|
final _reasonController = TextEditingController();
|
||||||
DateTime _transferDate = DateTime.now();
|
DateTime _transferDate = DateTime.now();
|
||||||
int? _toPlantId;
|
int? _toLocationId;
|
||||||
int? _toDepartmentId;
|
int? _toDepartmentId;
|
||||||
int? _toUserId;
|
int? _toUserId;
|
||||||
int? _toWarehouseId;
|
|
||||||
bool _isSubmitting = false;
|
bool _isSubmitting = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1271,10 +1270,9 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
if (!_formKey.currentState!.validate()) return;
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
|
||||||
final hasDestination =
|
final hasDestination =
|
||||||
_toPlantId != null ||
|
_toLocationId != null ||
|
||||||
_toDepartmentId != null ||
|
_toDepartmentId != null ||
|
||||||
_toUserId != null ||
|
_toUserId != null;
|
||||||
_toWarehouseId != null;
|
|
||||||
if (!hasDestination) {
|
if (!hasDestination) {
|
||||||
showSidePanelSnackBar(
|
showSidePanelSnackBar(
|
||||||
context,
|
context,
|
||||||
@ -1287,10 +1285,9 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
try {
|
try {
|
||||||
await ref.read(assetDetailProvider(widget.assetId).notifier).transferAsset({
|
await ref.read(assetDetailProvider(widget.assetId).notifier).transferAsset({
|
||||||
'transfer_date': DateFormatter.toApiDate(_transferDate),
|
'transfer_date': DateFormatter.toApiDate(_transferDate),
|
||||||
if (_toPlantId != null) 'to_plant_id': _toPlantId,
|
if (_toLocationId != null) 'to_location_id': _toLocationId,
|
||||||
if (_toDepartmentId != null) 'to_department_id': _toDepartmentId,
|
if (_toDepartmentId != null) 'to_department_id': _toDepartmentId,
|
||||||
if (_toUserId != null) 'to_user_id': _toUserId,
|
if (_toUserId != null) 'to_user_id': _toUserId,
|
||||||
if (_toWarehouseId != null) 'to_warehouse_id': _toWarehouseId,
|
|
||||||
'reason': _reasonController.text.trim(),
|
'reason': _reasonController.text.trim(),
|
||||||
});
|
});
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
@ -1331,12 +1328,11 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
onPick: _pickDate,
|
onPick: _pickDate,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
MasterQuickAddDropdown<int>(
|
AppSearchableDropdown<int>(
|
||||||
masterId: 'plants',
|
label: 'To Location',
|
||||||
label: 'To Plant',
|
value: _toLocationId,
|
||||||
value: _toPlantId,
|
searchHint: 'Search plant or warehouse...',
|
||||||
searchHint: 'Search plant...',
|
options: lookups.locations
|
||||||
options: lookups.plants
|
|
||||||
.map((option) {
|
.map((option) {
|
||||||
final id = int.tryParse(option.id);
|
final id = int.tryParse(option.id);
|
||||||
if (id == null) return null;
|
if (id == null) return null;
|
||||||
@ -1344,10 +1340,7 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
})
|
})
|
||||||
.whereType<AppDropdownOption<int>>()
|
.whereType<AppDropdownOption<int>>()
|
||||||
.toList(),
|
.toList(),
|
||||||
refreshLookups: () =>
|
onChanged: (v) => setState(() => _toLocationId = v),
|
||||||
ref.invalidate(assetFormLookupsProvider),
|
|
||||||
parseCreatedId: int.tryParse,
|
|
||||||
onChanged: (v) => setState(() => _toPlantId = v),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
MasterQuickAddDropdown<int>(
|
MasterQuickAddDropdown<int>(
|
||||||
@ -1384,25 +1377,6 @@ class _TransferAssetPanelState extends ConsumerState<TransferAssetPanel> {
|
|||||||
onChanged: (v) => setState(() => _toUserId = v),
|
onChanged: (v) => setState(() => _toUserId = v),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
MasterQuickAddDropdown<int>(
|
|
||||||
masterId: 'warehouses',
|
|
||||||
label: 'To Warehouse',
|
|
||||||
value: _toWarehouseId,
|
|
||||||
searchHint: 'Search warehouse...',
|
|
||||||
options: lookups.warehouses
|
|
||||||
.map((option) {
|
|
||||||
final id = int.tryParse(option.id);
|
|
||||||
if (id == null) return null;
|
|
||||||
return AppDropdownOption(value: id, label: option.name);
|
|
||||||
})
|
|
||||||
.whereType<AppDropdownOption<int>>()
|
|
||||||
.toList(),
|
|
||||||
refreshLookups: () =>
|
|
||||||
ref.invalidate(assetFormLookupsProvider),
|
|
||||||
parseCreatedId: int.tryParse,
|
|
||||||
onChanged: (v) => setState(() => _toWarehouseId = v),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
AppTextField(
|
AppTextField(
|
||||||
controller: _reasonController,
|
controller: _reasonController,
|
||||||
label: 'Reason *',
|
label: 'Reason *',
|
||||||
@ -1476,9 +1450,8 @@ class _TransferHistoryEntry extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: _TransferLocationBlock(
|
child: _TransferLocationBlock(
|
||||||
label: 'From',
|
label: 'From',
|
||||||
plant: item.fromPlantName,
|
location: item.fromLocationName,
|
||||||
department: item.fromDepartmentName,
|
department: item.fromDepartmentName,
|
||||||
warehouse: item.fromWarehouseName,
|
|
||||||
user: item.fromUserName,
|
user: item.fromUserName,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1493,9 +1466,8 @@ class _TransferHistoryEntry extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: _TransferLocationBlock(
|
child: _TransferLocationBlock(
|
||||||
label: 'To',
|
label: 'To',
|
||||||
plant: item.toPlantName,
|
location: item.toLocationName,
|
||||||
department: item.toDepartmentName,
|
department: item.toDepartmentName,
|
||||||
warehouse: item.toWarehouseName,
|
|
||||||
user: item.toUserName,
|
user: item.toUserName,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1535,16 +1507,14 @@ class _TransferHistoryEntry extends StatelessWidget {
|
|||||||
class _TransferLocationBlock extends StatelessWidget {
|
class _TransferLocationBlock extends StatelessWidget {
|
||||||
const _TransferLocationBlock({
|
const _TransferLocationBlock({
|
||||||
required this.label,
|
required this.label,
|
||||||
this.plant,
|
this.location,
|
||||||
this.department,
|
this.department,
|
||||||
this.warehouse,
|
|
||||||
this.user,
|
this.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
final String? plant;
|
final String? location;
|
||||||
final String? department;
|
final String? department;
|
||||||
final String? warehouse;
|
|
||||||
final String? user;
|
final String? user;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1564,17 +1534,13 @@ class _TransferLocationBlock extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_TransferLocationRow(
|
_TransferLocationRow(
|
||||||
icon: Icons.factory_outlined,
|
icon: Icons.place_outlined,
|
||||||
value: plant,
|
value: location,
|
||||||
),
|
),
|
||||||
_TransferLocationRow(
|
_TransferLocationRow(
|
||||||
icon: Icons.apartment_outlined,
|
icon: Icons.apartment_outlined,
|
||||||
value: department,
|
value: department,
|
||||||
),
|
),
|
||||||
_TransferLocationRow(
|
|
||||||
icon: Icons.warehouse_outlined,
|
|
||||||
value: warehouse,
|
|
||||||
),
|
|
||||||
_TransferLocationRow(
|
_TransferLocationRow(
|
||||||
icon: Icons.person_outline,
|
icon: Icons.person_outline,
|
||||||
value: user,
|
value: user,
|
||||||
|
|||||||
@ -23,7 +23,12 @@ final grnLookupsProvider = FutureProvider.autoDispose<GrnLookups>((ref) async {
|
|||||||
final master = ref.watch(masterRemoteDataSourceProvider);
|
final master = ref.watch(masterRemoteDataSourceProvider);
|
||||||
final poRepo = ref.watch(purchaseOrderRepositoryProvider);
|
final poRepo = ref.watch(purchaseOrderRepositoryProvider);
|
||||||
|
|
||||||
final warehouses = await _safeOptions(master.listWarehouses);
|
final warehouses = await _safeOptions(() async {
|
||||||
|
final locations = await master.listLocations();
|
||||||
|
return locations
|
||||||
|
.where((location) => location.slug?.toLowerCase() == 'warehouse')
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
final users = await _safeUserOptions(ref);
|
final users = await _safeUserOptions(ref);
|
||||||
|
|
||||||
final receivablePos = <PurchaseOrderModel>[];
|
final receivablePos = <PurchaseOrderModel>[];
|
||||||
|
|||||||
@ -112,8 +112,8 @@ class _GrnFormScreenState extends ConsumerState<GrnFormScreen> {
|
|||||||
_lines
|
_lines
|
||||||
..clear()
|
..clear()
|
||||||
..addAll(draftsFromPurchaseOrder(po));
|
..addAll(draftsFromPurchaseOrder(po));
|
||||||
if (_warehouseId == null && po.warehouseId != null) {
|
if (_warehouseId == null && po.shippingId != null) {
|
||||||
_warehouseId = po.warehouseId;
|
_warehouseId = po.shippingId;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -453,12 +453,13 @@ class _GrnFormScreenState extends ConsumerState<GrnFormScreen> {
|
|||||||
value: existing?.poNumber ?? '—',
|
value: existing?.poNumber ?? '—',
|
||||||
),
|
),
|
||||||
MasterQuickAddDropdown<int>(
|
MasterQuickAddDropdown<int>(
|
||||||
masterId: 'warehouses',
|
masterId: 'locations',
|
||||||
label: 'Warehouse *',
|
label: 'Warehouse *',
|
||||||
value: _dropdownValue(_warehouseId, warehouseIds),
|
value: _dropdownValue(_warehouseId, warehouseIds),
|
||||||
hint: 'Select warehouse',
|
hint: 'Select warehouse',
|
||||||
searchHint: 'Search warehouse...',
|
searchHint: 'Search warehouse...',
|
||||||
options: _intOptions(lookups.warehouses),
|
options: _intOptions(lookups.warehouses),
|
||||||
|
initialValues: const {'type': 'warehouse'},
|
||||||
refreshLookups: () =>
|
refreshLookups: () =>
|
||||||
ref.invalidate(grnLookupsProvider),
|
ref.invalidate(grnLookupsProvider),
|
||||||
parseCreatedId: int.tryParse,
|
parseCreatedId: int.tryParse,
|
||||||
|
|||||||
@ -278,6 +278,12 @@ const masterDefinitions = <MasterDefinition>[
|
|||||||
type: MasterFieldType.number,
|
type: MasterFieldType.number,
|
||||||
required: true,
|
required: true,
|
||||||
),
|
),
|
||||||
|
MasterFieldDef(
|
||||||
|
key: 'tags',
|
||||||
|
label: 'Tags',
|
||||||
|
multiline: true,
|
||||||
|
showInList: true,
|
||||||
|
),
|
||||||
MasterFieldDef(key: 'description', label: 'Description', multiline: true),
|
MasterFieldDef(key: 'description', label: 'Description', multiline: true),
|
||||||
MasterFieldDef(key: 'specification', label: 'Specification', multiline: true),
|
MasterFieldDef(key: 'specification', label: 'Specification', multiline: true),
|
||||||
_activeField,
|
_activeField,
|
||||||
@ -341,47 +347,54 @@ const masterDefinitions = <MasterDefinition>[
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
MasterDefinition(
|
MasterDefinition(
|
||||||
id: 'plants',
|
id: 'locations',
|
||||||
title: 'Plants',
|
title: 'Locations',
|
||||||
subtitle: 'Manufacturing plants and units',
|
subtitle: 'Plants and warehouses',
|
||||||
category: 'Organization',
|
category: 'Organization',
|
||||||
routeKey: 'plants',
|
routeKey: 'locations',
|
||||||
apiPath: '/masters/plants',
|
apiPath: '/masters/locations',
|
||||||
module: 'plants',
|
module: 'locations',
|
||||||
icon: Icons.factory_outlined,
|
icon: Icons.place_outlined,
|
||||||
fields: [
|
fields: [
|
||||||
MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true),
|
|
||||||
MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true),
|
|
||||||
MasterFieldDef(key: 'gstin', label: 'GSTIN', showInList: true),
|
|
||||||
MasterFieldDef(key: 'city', label: 'City', showInList: true),
|
|
||||||
MasterFieldDef(key: 'state', label: 'State'),
|
|
||||||
MasterFieldDef(key: 'address', label: 'Address', multiline: true),
|
|
||||||
MasterFieldDef(key: 'pincode', label: 'Pincode'),
|
|
||||||
MasterFieldDef(key: 'phone', label: 'Phone'),
|
|
||||||
_activeField,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
MasterDefinition(
|
|
||||||
id: 'warehouses',
|
|
||||||
title: 'Warehouse',
|
|
||||||
subtitle: 'Storage locations by plant',
|
|
||||||
category: 'Organization',
|
|
||||||
routeKey: 'warehouses',
|
|
||||||
apiPath: '/masters/warehouses',
|
|
||||||
module: 'warehouses',
|
|
||||||
icon: Icons.warehouse_outlined,
|
|
||||||
fields: [
|
|
||||||
MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true),
|
|
||||||
MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true),
|
|
||||||
MasterFieldDef(
|
MasterFieldDef(
|
||||||
key: 'plant_id',
|
key: 'type',
|
||||||
label: 'Plant',
|
label: 'Type',
|
||||||
type: MasterFieldType.dropdown,
|
type: MasterFieldType.dropdown,
|
||||||
required: true,
|
required: true,
|
||||||
showInList: true,
|
showInList: true,
|
||||||
optionsMasterKey: 'plants',
|
staticOptions: const ['plant', 'warehouse'],
|
||||||
|
),
|
||||||
|
MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true),
|
||||||
|
MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true),
|
||||||
|
MasterFieldDef(
|
||||||
|
key: 'parent_id',
|
||||||
|
label: 'Parent Plant',
|
||||||
|
type: MasterFieldType.dropdown,
|
||||||
|
showInList: true,
|
||||||
|
optionsMasterKey: 'locations',
|
||||||
|
optionsQueryParams: const {'type': 'plant'},
|
||||||
|
visibleWhenFieldKey: 'type',
|
||||||
|
visibleWhenValue: 'warehouse',
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
MasterFieldDef(key: 'gstin', label: 'GSTIN', showInList: true),
|
||||||
|
MasterFieldDef(key: 'city', label: 'City', showInList: true),
|
||||||
|
MasterFieldDef(
|
||||||
|
key: 'state',
|
||||||
|
label: 'State',
|
||||||
|
type: MasterFieldType.dropdown,
|
||||||
|
optionsMasterKey: 'location_states',
|
||||||
|
showInList: true,
|
||||||
|
),
|
||||||
|
MasterFieldDef(key: 'address', label: 'Address', multiline: true),
|
||||||
|
MasterFieldDef(key: 'pincode', label: 'Pincode'),
|
||||||
|
MasterFieldDef(key: 'phone', label: 'Phone'),
|
||||||
|
MasterFieldDef(
|
||||||
|
key: 'location',
|
||||||
|
label: 'Location Detail',
|
||||||
|
visibleWhenFieldKey: 'type',
|
||||||
|
visibleWhenValue: 'warehouse',
|
||||||
),
|
),
|
||||||
MasterFieldDef(key: 'location', label: 'Location'),
|
|
||||||
_activeField,
|
_activeField,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -521,6 +534,18 @@ String masterCellValue(Map<String, dynamic> row, MasterFieldDef field) {
|
|||||||
final value = row[field.key];
|
final value = row[field.key];
|
||||||
if (value == null || value == '') return '—';
|
if (value == null || value == '') return '—';
|
||||||
|
|
||||||
|
if (field.key == 'tags') {
|
||||||
|
if (value is List) {
|
||||||
|
final tags = value
|
||||||
|
.map((e) => e.toString().trim())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
return tags.isEmpty ? '—' : tags.join(', ');
|
||||||
|
}
|
||||||
|
final text = value.toString().trim();
|
||||||
|
return text.isEmpty ? '—' : text;
|
||||||
|
}
|
||||||
|
|
||||||
if (field.type == MasterFieldType.boolean) {
|
if (field.type == MasterFieldType.boolean) {
|
||||||
return value == true ? 'Yes' : 'No';
|
return value == true ? 'Yes' : 'No';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import '../../../../core/constants/app_constants.dart';
|
|||||||
import '../../../../core/utils/table_search.dart';
|
import '../../../../core/utils/table_search.dart';
|
||||||
import '../../../../shared/models/export_file_result.dart';
|
import '../../../../shared/models/export_file_result.dart';
|
||||||
import '../../../assets/data/repositories/asset_repository_impl.dart';
|
import '../../../assets/data/repositories/asset_repository_impl.dart';
|
||||||
|
import '../../../masters/data/datasources/master_remote_data_source.dart';
|
||||||
import '../../data/repositories/master_repository_impl.dart';
|
import '../../data/repositories/master_repository_impl.dart';
|
||||||
import '../../domain/entities/master_definition.dart';
|
import '../../domain/entities/master_definition.dart';
|
||||||
|
|
||||||
@ -259,6 +260,13 @@ class MasterFormNotifier extends FamilyAsyncNotifier<MasterFormState, MasterForm
|
|||||||
.getById(_definition, arg.recordId!);
|
.getById(_definition, arg.recordId!);
|
||||||
if (result.failure != null) throw result.failure!;
|
if (result.failure != null) throw result.failure!;
|
||||||
values = Map<String, dynamic>.from(result.data ?? const {});
|
values = Map<String, dynamic>.from(result.data ?? const {});
|
||||||
|
final tags = values['tags'];
|
||||||
|
if (tags is List) {
|
||||||
|
values['tags'] = tags
|
||||||
|
.map((e) => e.toString().trim())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.join(', ');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (final field in _definition.formFields) {
|
for (final field in _definition.formFields) {
|
||||||
if (field.type == MasterFieldType.boolean) {
|
if (field.type == MasterFieldType.boolean) {
|
||||||
@ -342,6 +350,23 @@ class MasterFormNotifier extends FamilyAsyncNotifier<MasterFormState, MasterForm
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == 'location_states') {
|
||||||
|
try {
|
||||||
|
final states = await ref
|
||||||
|
.read(masterRemoteDataSourceProvider)
|
||||||
|
.listLocationStates();
|
||||||
|
options[lookupKey] = states
|
||||||
|
.map(
|
||||||
|
(option) => <String, dynamic>{
|
||||||
|
'id': option.id,
|
||||||
|
'name': option.name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
} catch (_) {}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final def = masterDefinitionById(key);
|
final def = masterDefinitionById(key);
|
||||||
if (def == null) continue;
|
if (def == null) continue;
|
||||||
final queryParameters = masterFieldOptionsQuery(
|
final queryParameters = masterFieldOptionsQuery(
|
||||||
@ -481,10 +506,17 @@ class MasterFormNotifier extends FamilyAsyncNotifier<MasterFormState, MasterForm
|
|||||||
final value = current.values[field.key];
|
final value = current.values[field.key];
|
||||||
if (value == null || value == '') continue;
|
if (value == null || value == '') continue;
|
||||||
|
|
||||||
|
if (field.key == 'tags') {
|
||||||
|
final tags = _parseTags(value);
|
||||||
|
if (tags.isNotEmpty) payload['tags'] = tags;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
payload[field.key] = switch (field.type) {
|
payload[field.key] = switch (field.type) {
|
||||||
MasterFieldType.number => num.tryParse(value.toString()) ?? value,
|
MasterFieldType.number => num.tryParse(value.toString()) ?? value,
|
||||||
MasterFieldType.dropdown => field.staticOptions != null ||
|
MasterFieldType.dropdown => field.staticOptions != null ||
|
||||||
field.optionsMasterKey == 'asset_depreciation_methods'
|
field.optionsMasterKey == 'asset_depreciation_methods' ||
|
||||||
|
field.optionsMasterKey == 'location_states'
|
||||||
? value.toString()
|
? value.toString()
|
||||||
: int.tryParse(value.toString()) ?? value,
|
: int.tryParse(value.toString()) ?? value,
|
||||||
MasterFieldType.boolean => value == true,
|
MasterFieldType.boolean => value == true,
|
||||||
@ -494,6 +526,26 @@ class MasterFormNotifier extends FamilyAsyncNotifier<MasterFormState, MasterForm
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _parseTags(dynamic value) {
|
||||||
|
if (value is List) {
|
||||||
|
return value
|
||||||
|
.map((e) => e.toString().trim())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.take(50)
|
||||||
|
.map((e) => e.length > 50 ? e.substring(0, 50) : e)
|
||||||
|
.toSet()
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
final parts = value
|
||||||
|
.toString()
|
||||||
|
.split(RegExp(r'[,;\n]+'))
|
||||||
|
.map((e) => e.trim())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.take(50)
|
||||||
|
.map((e) => e.length > 50 ? e.substring(0, 50) : e);
|
||||||
|
return parts.toSet().toList();
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the created/updated record id on success, otherwise null.
|
/// Returns the created/updated record id on success, otherwise null.
|
||||||
Future<String?> submit() async {
|
Future<String?> submit() async {
|
||||||
final current = state.valueOrNull ?? const MasterFormState();
|
final current = state.valueOrNull ?? const MasterFormState();
|
||||||
|
|||||||
@ -99,6 +99,9 @@ class _MasterFormPanelState extends ConsumerState<MasterFormPanel> {
|
|||||||
labelText: _fieldLabel(field),
|
labelText: _fieldLabel(field),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
alignLabelWithHint: true,
|
alignLabelWithHint: true,
|
||||||
|
hintText: field.key == 'tags'
|
||||||
|
? 'Comma-separated, e.g. critical, imported, rm'
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -224,6 +224,7 @@ String masterQuickAddNoun(String masterId) {
|
|||||||
'item_subcategories' => 'subcategory',
|
'item_subcategories' => 'subcategory',
|
||||||
'items' => 'item',
|
'items' => 'item',
|
||||||
'hsn_codes' => 'HSN code',
|
'hsn_codes' => 'HSN code',
|
||||||
|
'locations' => 'location',
|
||||||
'plants' => 'plant',
|
'plants' => 'plant',
|
||||||
'warehouses' => 'warehouse',
|
'warehouses' => 'warehouse',
|
||||||
'designations' => 'designation',
|
'designations' => 'designation',
|
||||||
|
|||||||
@ -23,6 +23,77 @@ class MasterRemoteDataSource {
|
|||||||
Future<List<FilterOptionModel>> listPlants() =>
|
Future<List<FilterOptionModel>> listPlants() =>
|
||||||
_listOptions(ApiEndpoints.plants);
|
_listOptions(ApiEndpoints.plants);
|
||||||
|
|
||||||
|
/// Plants and warehouses from the unified locations master.
|
||||||
|
/// Labels include type, e.g. "Chennai Plant (Plant)".
|
||||||
|
Future<List<FilterOptionModel>> listLocations() async {
|
||||||
|
final result = await listLocationsWithState();
|
||||||
|
return result.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indian states/UTs for location.state (same values as vendor source_of_supply).
|
||||||
|
Future<List<FilterOptionModel>> listLocationStates() async {
|
||||||
|
final response = await dio.get(ApiEndpoints.locationStates);
|
||||||
|
final data = response.data;
|
||||||
|
final list = data is Map ? data['data'] : null;
|
||||||
|
if (list is! List) return const [];
|
||||||
|
|
||||||
|
return list
|
||||||
|
.map((item) {
|
||||||
|
if (item is String) {
|
||||||
|
final value = item.trim();
|
||||||
|
if (value.isEmpty) return null;
|
||||||
|
return FilterOptionModel(id: value, name: value);
|
||||||
|
}
|
||||||
|
if (item is Map) {
|
||||||
|
final map = Map<String, dynamic>.from(item);
|
||||||
|
final value =
|
||||||
|
(map['value'] ?? map['id'] ?? map['code'] ?? '').toString().trim();
|
||||||
|
final label =
|
||||||
|
(map['label'] ?? map['name'] ?? value).toString().trim();
|
||||||
|
if (value.isEmpty) return null;
|
||||||
|
return FilterOptionModel(
|
||||||
|
id: value,
|
||||||
|
name: label.isEmpty ? value : label,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.whereType<FilterOptionModel>()
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Locations plus each row's `state` (for PO GST intra/inter preview).
|
||||||
|
Future<({List<FilterOptionModel> options, Map<String, String?> stateById})>
|
||||||
|
listLocationsWithState() async {
|
||||||
|
final rows = await _listAllMaps(ApiEndpoints.locations);
|
||||||
|
final options = <FilterOptionModel>[];
|
||||||
|
final stateById = <String, String?>{};
|
||||||
|
|
||||||
|
for (final item in rows) {
|
||||||
|
if (!isActiveOptionRow(item)) continue;
|
||||||
|
final id = item['id']?.toString() ?? '';
|
||||||
|
final name = _optionLabel(item);
|
||||||
|
if (id.isEmpty || name.isEmpty) continue;
|
||||||
|
|
||||||
|
final type = item['type']?.toString().trim();
|
||||||
|
final typeLabel = (type == null || type.isEmpty)
|
||||||
|
? null
|
||||||
|
: '${type[0].toUpperCase()}${type.substring(1)}';
|
||||||
|
final state = item['state']?.toString().trim();
|
||||||
|
stateById[id] = (state == null || state.isEmpty) ? null : state;
|
||||||
|
|
||||||
|
options.add(
|
||||||
|
FilterOptionModel(
|
||||||
|
id: id,
|
||||||
|
name: typeLabel == null ? name : '$name ($typeLabel)',
|
||||||
|
slug: type,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (options: options, stateById: stateById);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<FilterOptionModel>> listDesignations() =>
|
Future<List<FilterOptionModel>> listDesignations() =>
|
||||||
_listOptions(ApiEndpoints.designations);
|
_listOptions(ApiEndpoints.designations);
|
||||||
|
|
||||||
|
|||||||
@ -232,7 +232,8 @@ class PurchaseOrderRemoteDataSource {
|
|||||||
if (query.search != null && query.search!.isNotEmpty) 'search': query.search,
|
if (query.search != null && query.search!.isNotEmpty) 'search': query.search,
|
||||||
if (query.status != null) 'status': query.status,
|
if (query.status != null) 'status': query.status,
|
||||||
if (query.vendorId != null) 'vendor_id': query.vendorId,
|
if (query.vendorId != null) 'vendor_id': query.vendorId,
|
||||||
if (query.plantId != null) 'plant_id': query.plantId,
|
if (query.billingId != null) 'billing_id': query.billingId,
|
||||||
|
if (query.shippingId != null) 'shipping_id': query.shippingId,
|
||||||
if (query.dateFrom != null) 'date_from': query.dateFrom,
|
if (query.dateFrom != null) 'date_from': query.dateFrom,
|
||||||
if (query.dateTo != null) 'date_to': query.dateTo,
|
if (query.dateTo != null) 'date_to': query.dateTo,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,8 +9,9 @@ import '../../../vendors/domain/repositories/vendor_repository.dart';
|
|||||||
class PurchaseOrderLookups {
|
class PurchaseOrderLookups {
|
||||||
const PurchaseOrderLookups({
|
const PurchaseOrderLookups({
|
||||||
this.vendors = const [],
|
this.vendors = const [],
|
||||||
this.plants = const [],
|
this.locations = const [],
|
||||||
this.warehouses = const [],
|
this.vendorSourceOfSupplyById = const {},
|
||||||
|
this.locationStateById = const {},
|
||||||
this.paymentTerms = const [],
|
this.paymentTerms = const [],
|
||||||
this.deliveryTerms = const [],
|
this.deliveryTerms = const [],
|
||||||
this.items = const [],
|
this.items = const [],
|
||||||
@ -25,8 +26,12 @@ class PurchaseOrderLookups {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final List<FilterOptionModel> vendors;
|
final List<FilterOptionModel> vendors;
|
||||||
final List<FilterOptionModel> plants;
|
/// Billing / shipping options (plants + warehouses from locations master).
|
||||||
final List<FilterOptionModel> warehouses;
|
final List<FilterOptionModel> locations;
|
||||||
|
/// Vendor id → `source_of_supply` (state code/name) for GST split preview.
|
||||||
|
final Map<String, String?> vendorSourceOfSupplyById;
|
||||||
|
/// Location id → `state` for GST split preview.
|
||||||
|
final Map<String, String?> locationStateById;
|
||||||
final List<FilterOptionModel> paymentTerms;
|
final List<FilterOptionModel> paymentTerms;
|
||||||
final List<FilterOptionModel> deliveryTerms;
|
final List<FilterOptionModel> deliveryTerms;
|
||||||
final List<FilterOptionModel> items;
|
final List<FilterOptionModel> items;
|
||||||
@ -50,31 +55,31 @@ final purchaseOrderLookupsProvider =
|
|||||||
final master = ref.watch(masterRemoteDataSourceProvider);
|
final master = ref.watch(masterRemoteDataSourceProvider);
|
||||||
final vendorRepo = ref.watch(vendorRepositoryProvider);
|
final vendorRepo = ref.watch(vendorRepositoryProvider);
|
||||||
|
|
||||||
final vendors = await _safeOptions(() => _fetchActiveVendors(vendorRepo));
|
final vendorsWithSos = await _safeVendorsWithSos(vendorRepo);
|
||||||
|
final locationsWithState = await _safeLocationsWithState(master);
|
||||||
|
|
||||||
final itemsWithDefaults = await _safeItemsWithDefaults(master.listItemsWithHsn);
|
final itemsWithDefaults = await _safeItemsWithDefaults(master.listItemsWithHsn);
|
||||||
final gstWithPct = await _safeGstRatesWithPct(master.listGstRatesWithPct);
|
final gstWithPct = await _safeGstRatesWithPct(master.listGstRatesWithPct);
|
||||||
final hsnWithGst = await _safeHsnWithGst(master.listHsnCodesWithGstRate);
|
final hsnWithGst = await _safeHsnWithGst(master.listHsnCodesWithGstRate);
|
||||||
|
|
||||||
final results = await Future.wait([
|
final results = await Future.wait([
|
||||||
_safeOptions(master.listPlants),
|
|
||||||
_safeOptions(master.listWarehouses),
|
|
||||||
_safeOptions(master.listPaymentTerms),
|
_safeOptions(master.listPaymentTerms),
|
||||||
_safeOptions(master.listDeliveryTerms),
|
_safeOptions(master.listDeliveryTerms),
|
||||||
_safeOptions(master.listUom),
|
_safeOptions(master.listUom),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return PurchaseOrderLookups(
|
return PurchaseOrderLookups(
|
||||||
vendors: vendors,
|
vendors: vendorsWithSos.options,
|
||||||
plants: results[0],
|
locations: locationsWithState.options,
|
||||||
warehouses: results[1],
|
vendorSourceOfSupplyById: vendorsWithSos.sourceOfSupplyById,
|
||||||
paymentTerms: results[2],
|
locationStateById: locationsWithState.stateById,
|
||||||
deliveryTerms: results[3],
|
paymentTerms: results[0],
|
||||||
|
deliveryTerms: results[1],
|
||||||
items: itemsWithDefaults.options,
|
items: itemsWithDefaults.options,
|
||||||
itemHsnById: itemsWithDefaults.hsnByItemId,
|
itemHsnById: itemsWithDefaults.hsnByItemId,
|
||||||
itemUomById: itemsWithDefaults.uomByItemId,
|
itemUomById: itemsWithDefaults.uomByItemId,
|
||||||
itemGstRateById: itemsWithDefaults.gstRateByItemId,
|
itemGstRateById: itemsWithDefaults.gstRateByItemId,
|
||||||
uom: results[4],
|
uom: results[2],
|
||||||
gstRates: gstWithPct.options,
|
gstRates: gstWithPct.options,
|
||||||
gstRatePctById: gstWithPct.pctById,
|
gstRatePctById: gstWithPct.pctById,
|
||||||
hsnCodes: hsnWithGst.options,
|
hsnCodes: hsnWithGst.options,
|
||||||
@ -92,6 +97,52 @@ Future<List<FilterOptionModel>> _safeOptions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<
|
||||||
|
({
|
||||||
|
List<FilterOptionModel> options,
|
||||||
|
Map<String, String?> sourceOfSupplyById,
|
||||||
|
})> _safeVendorsWithSos(VendorRepository vendorRepo) async {
|
||||||
|
try {
|
||||||
|
final result = await vendorRepo.listVendorOptions();
|
||||||
|
if (result.failure != null) {
|
||||||
|
throw result.failure!;
|
||||||
|
}
|
||||||
|
|
||||||
|
final options = <FilterOptionModel>[];
|
||||||
|
final sourceOfSupplyById = <String, String?>{};
|
||||||
|
for (final vendor in result.data ?? const []) {
|
||||||
|
if (!isActiveVendorOption(
|
||||||
|
isActive: vendor.isActive,
|
||||||
|
status: vendor.status,
|
||||||
|
)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
options.add(FilterOptionModel(id: vendor.id, name: vendor.vendorName));
|
||||||
|
final sos = vendor.sourceOfSupply?.trim();
|
||||||
|
sourceOfSupplyById[vendor.id] =
|
||||||
|
(sos == null || sos.isEmpty) ? null : sos;
|
||||||
|
}
|
||||||
|
return (options: options, sourceOfSupplyById: sourceOfSupplyById);
|
||||||
|
} catch (_) {
|
||||||
|
return (
|
||||||
|
options: <FilterOptionModel>[],
|
||||||
|
sourceOfSupplyById: <String, String?>{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<
|
||||||
|
({
|
||||||
|
List<FilterOptionModel> options,
|
||||||
|
Map<String, String?> stateById,
|
||||||
|
})> _safeLocationsWithState(MasterRemoteDataSource master) async {
|
||||||
|
try {
|
||||||
|
return await master.listLocationsWithState();
|
||||||
|
} catch (_) {
|
||||||
|
return (options: <FilterOptionModel>[], stateById: <String, String?>{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<
|
Future<
|
||||||
({
|
({
|
||||||
List<FilterOptionModel> options,
|
List<FilterOptionModel> options,
|
||||||
@ -146,24 +197,3 @@ Future<({List<FilterOptionModel> options, Map<String, int?> gstRateByHsnId})>
|
|||||||
return (options: <FilterOptionModel>[], gstRateByHsnId: <String, int?>{});
|
return (options: <FilterOptionModel>[], gstRateByHsnId: <String, int?>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<FilterOptionModel>> _fetchActiveVendors(
|
|
||||||
VendorRepository vendorRepo,
|
|
||||||
) async {
|
|
||||||
final result = await vendorRepo.listVendorOptions();
|
|
||||||
if (result.failure != null) {
|
|
||||||
throw result.failure!;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (result.data ?? const [])
|
|
||||||
.where(
|
|
||||||
(vendor) => isActiveVendorOption(
|
|
||||||
isActive: vendor.isActive,
|
|
||||||
status: vendor.status,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.map(
|
|
||||||
(vendor) => FilterOptionModel(id: vendor.id, name: vendor.vendorName),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -421,7 +421,8 @@ class _DetailHeader extends StatelessWidget {
|
|||||||
final subtitleParts = [
|
final subtitleParts = [
|
||||||
vendorTypeLabel(order.vendorType),
|
vendorTypeLabel(order.vendorType),
|
||||||
if (order.vendorName?.trim().isNotEmpty == true) order.vendorName!.trim(),
|
if (order.vendorName?.trim().isNotEmpty == true) order.vendorName!.trim(),
|
||||||
if (order.plantName?.trim().isNotEmpty == true) order.plantName!.trim(),
|
if (order.billingName?.trim().isNotEmpty == true)
|
||||||
|
order.billingName!.trim(),
|
||||||
];
|
];
|
||||||
|
|
||||||
final actions = Wrap(
|
final actions = Wrap(
|
||||||
@ -737,12 +738,12 @@ class _OrderDetailsCard extends StatelessWidget {
|
|||||||
value: vendorTypeLabel(order.vendorType),
|
value: vendorTypeLabel(order.vendorType),
|
||||||
),
|
),
|
||||||
_DetailField(
|
_DetailField(
|
||||||
label: 'Plant',
|
label: 'Billing',
|
||||||
value: _displayOrDash(order.plantName),
|
value: _displayOrDash(order.billingName),
|
||||||
),
|
),
|
||||||
_DetailField(
|
_DetailField(
|
||||||
label: 'Warehouse',
|
label: 'Shipping',
|
||||||
value: _displayOrDash(order.warehouseName),
|
value: _displayOrDash(order.shippingName),
|
||||||
),
|
),
|
||||||
_DetailField(label: 'Payment Term', value: paymentTerm),
|
_DetailField(label: 'Payment Term', value: paymentTerm),
|
||||||
_DetailField(label: 'Delivery Term', value: deliveryTerm),
|
_DetailField(label: 'Delivery Term', value: deliveryTerm),
|
||||||
@ -1150,10 +1151,47 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
|
|
||||||
final PurchaseOrderModel order;
|
final PurchaseOrderModel order;
|
||||||
|
|
||||||
|
List<Widget> _gstSummaryRows() {
|
||||||
|
final igst = order.igst ?? 0;
|
||||||
|
final cgst = order.cgst ?? 0;
|
||||||
|
final sgst = order.sgst ?? 0;
|
||||||
|
final hasSplit =
|
||||||
|
order.cgst != null || order.sgst != null || order.igst != null;
|
||||||
|
if (!hasSplit) return const [];
|
||||||
|
|
||||||
|
if (igst > 0) {
|
||||||
|
return [
|
||||||
|
_SummaryRow(
|
||||||
|
label: 'IGST',
|
||||||
|
value: CurrencyFormatter.format(igst),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
_SummaryRow(
|
||||||
|
label: 'CGST',
|
||||||
|
value: CurrencyFormatter.format(cgst),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_SummaryRow(
|
||||||
|
label: 'SGST',
|
||||||
|
value: CurrencyFormatter.format(sgst),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final discount = order.discountAmount ?? 0;
|
final discount = order.discountAmount ?? 0;
|
||||||
|
final freight = order.freightCharges ?? 0;
|
||||||
|
final other = order.otherCharges ?? 0;
|
||||||
|
final subTotal = order.taxableAmount ?? 0;
|
||||||
|
final taxableAmount = (subTotal + freight + other - discount)
|
||||||
|
.clamp(0.0, double.infinity);
|
||||||
final primaryTint = theme.colorScheme.primary.withValues(alpha: 0.1);
|
final primaryTint = theme.colorScheme.primary.withValues(alpha: 0.1);
|
||||||
|
|
||||||
return _SectionCard(
|
return _SectionCard(
|
||||||
@ -1162,32 +1200,38 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
_SummaryRow(
|
_SummaryRow(
|
||||||
label: 'Taxable Amount',
|
label: 'Sub Total',
|
||||||
value: CurrencyFormatter.format(order.taxableAmount),
|
value: CurrencyFormatter.format(subTotal),
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
_SummaryRow(
|
|
||||||
label: 'Tax (GST)',
|
|
||||||
value: CurrencyFormatter.format(order.taxAmount),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_SummaryRow(
|
_SummaryRow(
|
||||||
label: 'Freight Charges',
|
label: 'Freight Charges',
|
||||||
value: CurrencyFormatter.format(order.freightCharges ?? 0),
|
value: CurrencyFormatter.format(freight),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_SummaryRow(
|
_SummaryRow(
|
||||||
label: 'Other Charges',
|
label: 'Other Charges',
|
||||||
value: CurrencyFormatter.format(order.otherCharges ?? 0),
|
value: CurrencyFormatter.format(other),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_SummaryRow(
|
_SummaryRow(
|
||||||
label: 'Discount',
|
label: 'Discount Amount',
|
||||||
value: discount > 0
|
value: discount > 0
|
||||||
? '-${CurrencyFormatter.format(discount)}'
|
? '-${CurrencyFormatter.format(discount)}'
|
||||||
: CurrencyFormatter.format(0),
|
: CurrencyFormatter.format(0),
|
||||||
valueColor: discount > 0 ? AppColors.error : null,
|
valueColor: discount > 0 ? AppColors.error : null,
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_SummaryRow(
|
||||||
|
label: 'Taxable Amount',
|
||||||
|
value: CurrencyFormatter.format(taxableAmount),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
..._gstSummaryRows(),
|
||||||
|
_SummaryRow(
|
||||||
|
label: 'Tax Total',
|
||||||
|
value: CurrencyFormatter.format(order.taxAmount),
|
||||||
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
|
|||||||
@ -51,8 +51,8 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
DateTime? _poDate;
|
DateTime? _poDate;
|
||||||
DateTime? _expectedDeliveryDate;
|
DateTime? _expectedDeliveryDate;
|
||||||
int? _vendorId;
|
int? _vendorId;
|
||||||
int? _plantId;
|
int? _billingId;
|
||||||
int? _warehouseId;
|
int? _shippingId;
|
||||||
int? _paymentTermId;
|
int? _paymentTermId;
|
||||||
int? _deliveryTermId;
|
int? _deliveryTermId;
|
||||||
final List<PoLineItemDraft> _lines = [];
|
final List<PoLineItemDraft> _lines = [];
|
||||||
@ -98,8 +98,8 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
_poDate = order.poDate ?? DateTime.now();
|
_poDate = order.poDate ?? DateTime.now();
|
||||||
_expectedDeliveryDate = order.expectedDeliveryDate;
|
_expectedDeliveryDate = order.expectedDeliveryDate;
|
||||||
_vendorId = order.vendorId;
|
_vendorId = order.vendorId;
|
||||||
_plantId = order.plantId;
|
_billingId = order.billingId;
|
||||||
_warehouseId = order.warehouseId;
|
_shippingId = order.shippingId;
|
||||||
_paymentTermId = order.paymentTermId;
|
_paymentTermId = order.paymentTermId;
|
||||||
_deliveryTermId = order.deliveryTermId;
|
_deliveryTermId = order.deliveryTermId;
|
||||||
_discountController.text =
|
_discountController.text =
|
||||||
@ -183,12 +183,30 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mirrors BE: compare billing location state vs vendor source_of_supply.
|
||||||
|
/// Missing either side → intra-state (CGST/SGST).
|
||||||
|
bool _isInterStateGst(PurchaseOrderLookups lookups) {
|
||||||
|
final billingState = lookups.locationStateById[_billingId?.toString()]
|
||||||
|
?.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
final vendorSos = lookups.vendorSourceOfSupplyById[_vendorId?.toString()]
|
||||||
|
?.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
if (billingState == null ||
|
||||||
|
billingState.isEmpty ||
|
||||||
|
vendorSos == null ||
|
||||||
|
vendorSos.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return billingState != vendorSos;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _buildPayload() {
|
Map<String, dynamic> _buildPayload() {
|
||||||
return {
|
return {
|
||||||
'po_date': DateFormatter.toApiDate(_poDate ?? DateTime.now()),
|
'po_date': DateFormatter.toApiDate(_poDate ?? DateTime.now()),
|
||||||
'vendor_id': _vendorId,
|
'vendor_id': _vendorId,
|
||||||
'plant_id': _plantId,
|
'billing_id': _billingId,
|
||||||
if (_warehouseId != null) 'warehouse_id': _warehouseId,
|
'shipping_id': _shippingId,
|
||||||
if (_paymentTermId != null) 'payment_term_id': _paymentTermId,
|
if (_paymentTermId != null) 'payment_term_id': _paymentTermId,
|
||||||
if (_deliveryTermId != null) 'delivery_term_id': _deliveryTermId,
|
if (_deliveryTermId != null) 'delivery_term_id': _deliveryTermId,
|
||||||
if (_expectedDeliveryDate != null)
|
if (_expectedDeliveryDate != null)
|
||||||
@ -238,7 +256,7 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vendorId == null || _plantId == null) {
|
if (_vendorId == null || _billingId == null || _shippingId == null) {
|
||||||
showAppToastFromSnackBar(context,
|
showAppToastFromSnackBar(context,
|
||||||
const SnackBar(content: Text('Please complete all required fields')),
|
const SnackBar(content: Text('Please complete all required fields')),
|
||||||
);
|
);
|
||||||
@ -352,8 +370,8 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
|
|
||||||
final vendorIds =
|
final vendorIds =
|
||||||
lookups.vendors.map((e) => _parseId(e.id)).whereType<int>();
|
lookups.vendors.map((e) => _parseId(e.id)).whereType<int>();
|
||||||
final plantIds =
|
final locationIds =
|
||||||
lookups.plants.map((e) => _parseId(e.id)).whereType<int>();
|
lookups.locations.map((e) => _parseId(e.id)).whereType<int>();
|
||||||
final totals = _computeTotals(lookups.gstRatePctById);
|
final totals = _computeTotals(lookups.gstRatePctById);
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
@ -373,9 +391,13 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_SectionCard(
|
_SectionCard(
|
||||||
title: 'ORDER DETAILS',
|
title: 'ORDER DETAILS',
|
||||||
child: Column(
|
child: QuickAddInlineHost(
|
||||||
children: [
|
child: ResponsiveFormGrid(
|
||||||
FormRowFour(
|
smallColumns: 1,
|
||||||
|
mediumColumns: 2,
|
||||||
|
largeColumns: 4,
|
||||||
|
mediumBreakpoint: 640,
|
||||||
|
largeBreakpoint: 1100,
|
||||||
children: [
|
children: [
|
||||||
_DateField(
|
_DateField(
|
||||||
label: 'PO Date *',
|
label: 'PO Date *',
|
||||||
@ -395,37 +417,28 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
validator: (v) =>
|
validator: (v) =>
|
||||||
v == null ? 'Vendor is required' : null,
|
v == null ? 'Vendor is required' : null,
|
||||||
),
|
),
|
||||||
MasterQuickAddDropdown<int>(
|
AppSearchableDropdown<int>(
|
||||||
masterId: 'plants',
|
label: 'Billing *',
|
||||||
label: 'Plant *',
|
value: _dropdownValue(_billingId, locationIds),
|
||||||
value: _dropdownValue(_plantId, plantIds),
|
hint: 'Select billing location',
|
||||||
hint: 'Select plant',
|
searchHint: 'Search plant or warehouse...',
|
||||||
searchHint: 'Search plant...',
|
options: _intOptions(lookups.locations),
|
||||||
options: _intOptions(lookups.plants),
|
|
||||||
refreshLookups: () =>
|
|
||||||
ref.invalidate(purchaseOrderLookupsProvider),
|
|
||||||
parseCreatedId: int.tryParse,
|
|
||||||
onChanged: (v) => setState(() => _plantId = v),
|
|
||||||
validator: (v) =>
|
|
||||||
v == null ? 'Plant is required' : null,
|
|
||||||
),
|
|
||||||
MasterQuickAddDropdown<int?>(
|
|
||||||
masterId: 'warehouses',
|
|
||||||
label: 'Warehouse',
|
|
||||||
value: _warehouseId,
|
|
||||||
hint: 'Select warehouse',
|
|
||||||
searchHint: 'Search warehouse...',
|
|
||||||
options: _nullableIntOptions(lookups.warehouses),
|
|
||||||
refreshLookups: () =>
|
|
||||||
ref.invalidate(purchaseOrderLookupsProvider),
|
|
||||||
parseCreatedId: int.tryParse,
|
|
||||||
onChanged: (v) =>
|
onChanged: (v) =>
|
||||||
setState(() => _warehouseId = v),
|
setState(() => _billingId = v),
|
||||||
|
validator: (v) =>
|
||||||
|
v == null ? 'Billing is required' : null,
|
||||||
),
|
),
|
||||||
],
|
AppSearchableDropdown<int>(
|
||||||
|
label: 'Shipping *',
|
||||||
|
value: _dropdownValue(_shippingId, locationIds),
|
||||||
|
hint: 'Select shipping location',
|
||||||
|
searchHint: 'Search plant or warehouse...',
|
||||||
|
options: _intOptions(lookups.locations),
|
||||||
|
onChanged: (v) =>
|
||||||
|
setState(() => _shippingId = v),
|
||||||
|
validator: (v) =>
|
||||||
|
v == null ? 'Shipping is required' : null,
|
||||||
),
|
),
|
||||||
FormRowFour(
|
|
||||||
children: [
|
|
||||||
MasterQuickAddDropdown<int?>(
|
MasterQuickAddDropdown<int?>(
|
||||||
masterId: 'payment_terms',
|
masterId: 'payment_terms',
|
||||||
label: 'Payment Term',
|
label: 'Payment Term',
|
||||||
@ -454,11 +467,6 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
onChanged: (v) =>
|
onChanged: (v) =>
|
||||||
setState(() => _deliveryTermId = v),
|
setState(() => _deliveryTermId = v),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
FormRow(
|
|
||||||
columnCount: 4,
|
|
||||||
children: [
|
|
||||||
_DateField(
|
_DateField(
|
||||||
label: 'Expected Delivery',
|
label: 'Expected Delivery',
|
||||||
value: _expectedDeliveryDate,
|
value: _expectedDeliveryDate,
|
||||||
@ -471,7 +479,6 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
@ -518,6 +525,7 @@ class _PurchaseOrderFormScreenState extends ConsumerState<PurchaseOrderFormScree
|
|||||||
otherChargesController: _otherChargesController,
|
otherChargesController: _otherChargesController,
|
||||||
discountController: _discountController,
|
discountController: _discountController,
|
||||||
isEditing: widget.isEditing,
|
isEditing: widget.isEditing,
|
||||||
|
isInterState: _isInterStateGst(lookups),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (stack) {
|
if (stack) {
|
||||||
@ -764,6 +772,7 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
required this.otherChargesController,
|
required this.otherChargesController,
|
||||||
required this.discountController,
|
required this.discountController,
|
||||||
required this.isEditing,
|
required this.isEditing,
|
||||||
|
required this.isInterState,
|
||||||
});
|
});
|
||||||
|
|
||||||
final PoOrderTotals totals;
|
final PoOrderTotals totals;
|
||||||
@ -771,6 +780,7 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
final TextEditingController otherChargesController;
|
final TextEditingController otherChargesController;
|
||||||
final TextEditingController discountController;
|
final TextEditingController discountController;
|
||||||
final bool isEditing;
|
final bool isEditing;
|
||||||
|
final bool isInterState;
|
||||||
|
|
||||||
String? _validateDiscount(String? value) {
|
String? _validateDiscount(String? value) {
|
||||||
final text = value?.trim() ?? '';
|
final text = value?.trim() ?? '';
|
||||||
@ -784,6 +794,34 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Widget> _gstSplitRows() {
|
||||||
|
final tax = totals.taxAmount;
|
||||||
|
if (isInterState) {
|
||||||
|
return [
|
||||||
|
_SummaryReadOnlyRow(
|
||||||
|
label: 'IGST',
|
||||||
|
value: CurrencyFormatter.format(tax),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
final cgst = double.parse((tax / 2).toStringAsFixed(4));
|
||||||
|
final sgst = double.parse((tax - cgst).toStringAsFixed(4));
|
||||||
|
return [
|
||||||
|
_SummaryReadOnlyRow(
|
||||||
|
label: 'CGST',
|
||||||
|
value: CurrencyFormatter.format(cgst),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
_SummaryReadOnlyRow(
|
||||||
|
label: 'SGST',
|
||||||
|
value: CurrencyFormatter.format(sgst),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
@ -800,13 +838,8 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
_SummaryReadOnlyRow(
|
_SummaryReadOnlyRow(
|
||||||
label: 'Taxable Amount',
|
label: 'Sub Total',
|
||||||
value: CurrencyFormatter.format(totals.taxableAmount),
|
value: CurrencyFormatter.format(totals.subTotal),
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_SummaryReadOnlyRow(
|
|
||||||
label: 'Tax (GST)',
|
|
||||||
value: CurrencyFormatter.format(totals.taxAmount),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
_SummaryInputRow(
|
_SummaryInputRow(
|
||||||
@ -826,6 +859,17 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
validator: _validateDiscount,
|
validator: _validateDiscount,
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
_SummaryReadOnlyRow(
|
||||||
|
label: 'Taxable Amount',
|
||||||
|
value: CurrencyFormatter.format(totals.taxableAmount),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
..._gstSplitRows(),
|
||||||
|
_SummaryReadOnlyRow(
|
||||||
|
label: 'Tax Total',
|
||||||
|
value: CurrencyFormatter.format(totals.taxAmount),
|
||||||
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
@ -856,7 +900,9 @@ class _AmountSummaryCard extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
isEditing
|
isEditing
|
||||||
? 'Editing charges or discount recalculates the grand total immediately — matches what will print on the PDF.'
|
? 'Editing charges or discount recalculates the grand total immediately — matches what will print on the PDF.'
|
||||||
: 'Taxable amount and tax are calculated automatically from line items. Grand total updates as you edit freight, other charges or discount.',
|
: isInterState
|
||||||
|
? 'IGST is previewed (vendor state differs from billing location); final values are computed on save.'
|
||||||
|
: 'CGST/SGST are previewed (vendor state matches billing location); final values are computed on save.',
|
||||||
style: theme.textTheme.bodySmall?.copyWith(
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
color: theme.colorScheme.onSurfaceVariant,
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
height: 1.4,
|
height: 1.4,
|
||||||
|
|||||||
@ -57,49 +57,60 @@ class PoLineCalculation {
|
|||||||
/// Order-level totals derived from line calculations + header charges.
|
/// Order-level totals derived from line calculations + header charges.
|
||||||
class PoOrderTotals {
|
class PoOrderTotals {
|
||||||
const PoOrderTotals({
|
const PoOrderTotals({
|
||||||
|
required this.subTotal,
|
||||||
required this.taxableAmount,
|
required this.taxableAmount,
|
||||||
required this.taxAmount,
|
required this.taxAmount,
|
||||||
required this.grandTotal,
|
required this.grandTotal,
|
||||||
required this.maxDiscountAmount,
|
required this.maxDiscountAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Sum of line amounts (before freight / other / discount).
|
||||||
|
final double subTotal;
|
||||||
|
|
||||||
|
/// Sub Total + Freight + Other − Discount.
|
||||||
final double taxableAmount;
|
final double taxableAmount;
|
||||||
final double taxAmount;
|
final double taxAmount;
|
||||||
final double grandTotal;
|
final double grandTotal;
|
||||||
|
|
||||||
/// Taxable + Tax + Freight + Other (discount cannot exceed this).
|
/// Sub Total + Tax + Freight + Other (discount cannot exceed this).
|
||||||
final double maxDiscountAmount;
|
final double maxDiscountAmount;
|
||||||
|
|
||||||
static const zero = PoOrderTotals(
|
static const zero = PoOrderTotals(
|
||||||
|
subTotal: 0,
|
||||||
taxableAmount: 0,
|
taxableAmount: 0,
|
||||||
taxAmount: 0,
|
taxAmount: 0,
|
||||||
grandTotal: 0,
|
grandTotal: 0,
|
||||||
maxDiscountAmount: 0,
|
maxDiscountAmount: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// 3.5 Taxable = sum of Line Amounts
|
/// Sub Total = sum of line amounts
|
||||||
/// 3.6 Tax = sum of GST Amounts
|
/// Taxable = Sub Total + Freight + Other − Discount
|
||||||
/// 3.7 Grand Total = Taxable + Tax + Freight + Other − Discount
|
/// Tax = sum of line GST amounts
|
||||||
|
/// Grand Total = Taxable + Tax
|
||||||
factory PoOrderTotals.compute({
|
factory PoOrderTotals.compute({
|
||||||
required Iterable<PoLineCalculation> lines,
|
required Iterable<PoLineCalculation> lines,
|
||||||
required double freight,
|
required double freight,
|
||||||
required double otherCharges,
|
required double otherCharges,
|
||||||
required double discountAmount,
|
required double discountAmount,
|
||||||
}) {
|
}) {
|
||||||
var taxable = 0.0;
|
var subTotal = 0.0;
|
||||||
var tax = 0.0;
|
var tax = 0.0;
|
||||||
for (final line in lines) {
|
for (final line in lines) {
|
||||||
taxable += line.lineAmount;
|
subTotal += line.lineAmount;
|
||||||
tax += line.gstAmount;
|
tax += line.gstAmount;
|
||||||
}
|
}
|
||||||
final maxDiscount = taxable + tax + freight + otherCharges;
|
final freightSafe = freight < 0 ? 0.0 : freight;
|
||||||
final clampedDiscount =
|
final otherSafe = otherCharges < 0 ? 0.0 : otherCharges;
|
||||||
discountAmount < 0 ? 0.0 : discountAmount;
|
final clampedDiscount = discountAmount < 0 ? 0.0 : discountAmount;
|
||||||
final grandTotalRaw = maxDiscount - clampedDiscount;
|
final taxableRaw = subTotal + freightSafe + otherSafe - clampedDiscount;
|
||||||
|
final taxable = taxableRaw < 0 ? 0.0 : taxableRaw;
|
||||||
|
final maxDiscount = subTotal + tax + freightSafe + otherSafe;
|
||||||
|
final grandTotal = taxable + tax;
|
||||||
return PoOrderTotals(
|
return PoOrderTotals(
|
||||||
|
subTotal: subTotal,
|
||||||
taxableAmount: taxable,
|
taxableAmount: taxable,
|
||||||
taxAmount: tax,
|
taxAmount: tax,
|
||||||
grandTotal: grandTotalRaw < 0 ? 0 : grandTotalRaw,
|
grandTotal: grandTotal < 0 ? 0 : grandTotal,
|
||||||
maxDiscountAmount: maxDiscount < 0 ? 0 : maxDiscount,
|
maxDiscountAmount: maxDiscount < 0 ? 0 : maxDiscount,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -521,16 +532,8 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
].whereType<AppDropdownOption<int?>>().toList();
|
].whereType<AppDropdownOption<int?>>().toList();
|
||||||
|
|
||||||
const spacing = 8.0;
|
const spacing = 8.0;
|
||||||
const minRowWidth = 1040.0;
|
|
||||||
|
|
||||||
Widget flex({required int flex, required Widget child}) {
|
final itemField = MasterQuickAddDropdown<int>(
|
||||||
return Expanded(flex: flex, child: child);
|
|
||||||
}
|
|
||||||
|
|
||||||
final fields = <Widget>[
|
|
||||||
flex(
|
|
||||||
flex: 3,
|
|
||||||
child: MasterQuickAddDropdown<int>(
|
|
||||||
key: ValueKey('$lineKey-item'),
|
key: ValueKey('$lineKey-item'),
|
||||||
masterId: 'items',
|
masterId: 'items',
|
||||||
label: 'Item *',
|
label: 'Item *',
|
||||||
@ -545,11 +548,8 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
parseCreatedId: int.tryParse,
|
parseCreatedId: int.tryParse,
|
||||||
onChanged: _onItemChanged,
|
onChanged: _onItemChanged,
|
||||||
validator: (v) => v == null ? 'Item is required' : null,
|
validator: (v) => v == null ? 'Item is required' : null,
|
||||||
),
|
);
|
||||||
),
|
final qtyField = AppTextField(
|
||||||
flex(
|
|
||||||
flex: 1,
|
|
||||||
child: AppTextField(
|
|
||||||
key: ValueKey('$lineKey-qty'),
|
key: ValueKey('$lineKey-qty'),
|
||||||
controller: line.qtyController,
|
controller: line.qtyController,
|
||||||
label: 'Qty *',
|
label: 'Qty *',
|
||||||
@ -561,11 +561,8 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
if (qty == null || qty <= 0) return 'Invalid';
|
if (qty == null || qty <= 0) return 'Invalid';
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
),
|
final uomField = MasterQuickAddDropdown<int>(
|
||||||
flex(
|
|
||||||
flex: 2,
|
|
||||||
child: MasterQuickAddDropdown<int>(
|
|
||||||
key: ValueKey('$lineKey-uom'),
|
key: ValueKey('$lineKey-uom'),
|
||||||
masterId: 'uom',
|
masterId: 'uom',
|
||||||
label: 'UOM *',
|
label: 'UOM *',
|
||||||
@ -580,11 +577,8 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
parseCreatedId: int.tryParse,
|
parseCreatedId: int.tryParse,
|
||||||
onChanged: (v) => _updateLine(() => line.uomId = v),
|
onChanged: (v) => _updateLine(() => line.uomId = v),
|
||||||
validator: (v) => v == null ? 'Required' : null,
|
validator: (v) => v == null ? 'Required' : null,
|
||||||
),
|
);
|
||||||
),
|
final rateField = AppTextField(
|
||||||
flex(
|
|
||||||
flex: 1,
|
|
||||||
child: AppTextField(
|
|
||||||
key: ValueKey('$lineKey-rate'),
|
key: ValueKey('$lineKey-rate'),
|
||||||
controller: line.rateController,
|
controller: line.rateController,
|
||||||
label: 'Rate *',
|
label: 'Rate *',
|
||||||
@ -596,21 +590,15 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
if (rate == null || rate < 0) return 'Invalid';
|
if (rate == null || rate < 0) return 'Invalid';
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
),
|
final discField = AppTextField(
|
||||||
flex(
|
|
||||||
flex: 1,
|
|
||||||
child: AppTextField(
|
|
||||||
key: ValueKey('$lineKey-discount'),
|
key: ValueKey('$lineKey-discount'),
|
||||||
controller: line.discountController,
|
controller: line.discountController,
|
||||||
label: 'Disc %',
|
label: 'Disc %',
|
||||||
hint: '0',
|
hint: '0',
|
||||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||||
),
|
);
|
||||||
),
|
final gstField = MasterQuickAddDropdown<int?>(
|
||||||
flex(
|
|
||||||
flex: 2,
|
|
||||||
child: MasterQuickAddDropdown<int?>(
|
|
||||||
key: ValueKey('$lineKey-gst'),
|
key: ValueKey('$lineKey-gst'),
|
||||||
masterId: 'gst_rates',
|
masterId: 'gst_rates',
|
||||||
label: 'GST %',
|
label: 'GST %',
|
||||||
@ -624,17 +612,12 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
},
|
},
|
||||||
parseCreatedId: int.tryParse,
|
parseCreatedId: int.tryParse,
|
||||||
onChanged: (v) => _updateLine(() => line.gstRateId = v),
|
onChanged: (v) => _updateLine(() => line.gstRateId = v),
|
||||||
),
|
);
|
||||||
),
|
final amountField = _AmountWithRemove(
|
||||||
flex(
|
|
||||||
flex: 2,
|
|
||||||
child: _AmountWithRemove(
|
|
||||||
amount: CurrencyFormatter.format(calc.lineAmount),
|
amount: CurrencyFormatter.format(calc.lineAmount),
|
||||||
backgroundColor: amountBg,
|
backgroundColor: amountBg,
|
||||||
onRemove: widget.onRemove,
|
onRemove: widget.onRemove,
|
||||||
),
|
);
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
@ -645,29 +628,48 @@ class _LineItemCardState extends ConsumerState<_LineItemCard> {
|
|||||||
child: QuickAddInlineHost(
|
child: QuickAddInlineHost(
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final rowWidth = constraints.maxWidth < minRowWidth
|
final width = constraints.maxWidth;
|
||||||
? minRowWidth
|
|
||||||
: constraints.maxWidth;
|
// Wide: single flex row
|
||||||
final row = SizedBox(
|
if (width >= 1100) {
|
||||||
width: rowWidth,
|
return Row(
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < fields.length; i++) ...[
|
Expanded(flex: 3, child: itemField),
|
||||||
if (i > 0) const SizedBox(width: spacing),
|
const SizedBox(width: spacing),
|
||||||
fields[i],
|
Expanded(flex: 1, child: qtyField),
|
||||||
|
const SizedBox(width: spacing),
|
||||||
|
Expanded(flex: 2, child: uomField),
|
||||||
|
const SizedBox(width: spacing),
|
||||||
|
Expanded(flex: 1, child: rateField),
|
||||||
|
const SizedBox(width: spacing),
|
||||||
|
Expanded(flex: 1, child: discField),
|
||||||
|
const SizedBox(width: spacing),
|
||||||
|
Expanded(flex: 2, child: gstField),
|
||||||
|
const SizedBox(width: spacing),
|
||||||
|
Expanded(flex: 2, child: amountField),
|
||||||
],
|
],
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (constraints.maxWidth < minRowWidth) {
|
|
||||||
return SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: row,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return row;
|
|
||||||
|
// Medium / narrow: wrapping grid (2–3 columns)
|
||||||
|
return ResponsiveFormGrid(
|
||||||
|
spacing: spacing,
|
||||||
|
smallColumns: 1,
|
||||||
|
mediumColumns: 2,
|
||||||
|
largeColumns: 3,
|
||||||
|
mediumBreakpoint: 520,
|
||||||
|
largeBreakpoint: 800,
|
||||||
|
children: [
|
||||||
|
itemField,
|
||||||
|
qtyField,
|
||||||
|
uomField,
|
||||||
|
rateField,
|
||||||
|
discField,
|
||||||
|
gstField,
|
||||||
|
amountField,
|
||||||
|
],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -66,7 +66,11 @@ class AddUserFormNotifier extends FamilyAsyncNotifier<AddUserFormState, String?>
|
|||||||
if (rolesResult.failure != null) throw rolesResult.failure!;
|
if (rolesResult.failure != null) throw rolesResult.failure!;
|
||||||
|
|
||||||
final departments = await masterRemote.listDepartments();
|
final departments = await masterRemote.listDepartments();
|
||||||
final plants = await masterRemote.listPlants();
|
final plants = await masterRemote.listLocations().then(
|
||||||
|
(locations) => locations
|
||||||
|
.where((location) => location.slug?.toLowerCase() == 'plant')
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
final designations = await masterRemote.listDesignations();
|
final designations = await masterRemote.listDesignations();
|
||||||
|
|
||||||
final usersResult = await userRepository.listUserOptions();
|
final usersResult = await userRepository.listUserOptions();
|
||||||
|
|||||||
@ -187,6 +187,7 @@ class _AddUserPanelState extends ConsumerState<AddUserPanel> {
|
|||||||
String? hint,
|
String? hint,
|
||||||
bool required = false,
|
bool required = false,
|
||||||
String? masterId,
|
String? masterId,
|
||||||
|
Map<String, dynamic>? initialValues,
|
||||||
}) {
|
}) {
|
||||||
final fieldLabel = required ? '$label *' : label;
|
final fieldLabel = required ? '$label *' : label;
|
||||||
final fieldHint = hint ?? 'Select ${label.toLowerCase()}';
|
final fieldHint = hint ?? 'Select ${label.toLowerCase()}';
|
||||||
@ -215,6 +216,7 @@ class _AddUserPanelState extends ConsumerState<AddUserPanel> {
|
|||||||
searchHint: 'Search $label...',
|
searchHint: 'Search $label...',
|
||||||
enabled: fieldEnabled,
|
enabled: fieldEnabled,
|
||||||
options: _toOptions(options),
|
options: _toOptions(options),
|
||||||
|
initialValues: initialValues,
|
||||||
refreshLookups: () =>
|
refreshLookups: () =>
|
||||||
ref.invalidate(addUserFormProvider(widget.userId)),
|
ref.invalidate(addUserFormProvider(widget.userId)),
|
||||||
parseCreatedId: (id) => id,
|
parseCreatedId: (id) => id,
|
||||||
@ -357,7 +359,8 @@ class _AddUserPanelState extends ConsumerState<AddUserPanel> {
|
|||||||
label: 'Plant / Unit',
|
label: 'Plant / Unit',
|
||||||
value: _selectedPlantId,
|
value: _selectedPlantId,
|
||||||
options: formState.plants,
|
options: formState.plants,
|
||||||
masterId: 'plants',
|
masterId: 'locations',
|
||||||
|
initialValues: const {'type': 'plant'},
|
||||||
onChanged: (v) => setState(() => _selectedPlantId = v),
|
onChanged: (v) => setState(() => _selectedPlantId = v),
|
||||||
),
|
),
|
||||||
right: _buildDropdown(
|
right: _buildDropdown(
|
||||||
|
|||||||
@ -106,8 +106,8 @@ class ReportsRemoteDataSource {
|
|||||||
if (query.itemSubcategoryId != null &&
|
if (query.itemSubcategoryId != null &&
|
||||||
query.itemSubcategoryId!.isNotEmpty)
|
query.itemSubcategoryId!.isNotEmpty)
|
||||||
'item_subcategory_id': query.itemSubcategoryId,
|
'item_subcategory_id': query.itemSubcategoryId,
|
||||||
if (query.plantId != null && query.plantId!.isNotEmpty)
|
if (query.locationId != null && query.locationId!.isNotEmpty)
|
||||||
'plant_id': query.plantId,
|
'location_id': query.locationId,
|
||||||
if (query.departmentId != null && query.departmentId!.isNotEmpty)
|
if (query.departmentId != null && query.departmentId!.isNotEmpty)
|
||||||
'department_id': query.departmentId,
|
'department_id': query.departmentId,
|
||||||
if (query.isActive != null) 'is_active': query.isActive,
|
if (query.isActive != null) 'is_active': query.isActive,
|
||||||
|
|||||||
@ -22,12 +22,17 @@ class ReportFilterOption {
|
|||||||
.toString()
|
.toString()
|
||||||
.trim();
|
.trim();
|
||||||
final code = map['code']?.toString().trim();
|
final code = map['code']?.toString().trim();
|
||||||
final display = (code != null &&
|
final type = map['type']?.toString().trim();
|
||||||
|
var display = (code != null &&
|
||||||
code.isNotEmpty &&
|
code.isNotEmpty &&
|
||||||
label.isNotEmpty &&
|
label.isNotEmpty &&
|
||||||
code != label)
|
code != label)
|
||||||
? '$label ($code)'
|
? '$label ($code)'
|
||||||
: (label.isEmpty ? value : label);
|
: (label.isEmpty ? value : label);
|
||||||
|
if (type != null && type.isNotEmpty) {
|
||||||
|
final typeLabel = '${type[0].toUpperCase()}${type.substring(1)}';
|
||||||
|
display = '$display ($typeLabel)';
|
||||||
|
}
|
||||||
final parentId = (map['item_category_id'] ?? map['parent_id'])
|
final parentId = (map['item_category_id'] ?? map['parent_id'])
|
||||||
?.toString()
|
?.toString()
|
||||||
.trim();
|
.trim();
|
||||||
@ -45,7 +50,7 @@ class ReportFilterOption {
|
|||||||
|
|
||||||
class DepreciationReportFilters {
|
class DepreciationReportFilters {
|
||||||
const DepreciationReportFilters({
|
const DepreciationReportFilters({
|
||||||
this.plants = const [],
|
this.locations = const [],
|
||||||
this.categories = const [],
|
this.categories = const [],
|
||||||
this.subcategories = const [],
|
this.subcategories = const [],
|
||||||
this.departments = const [],
|
this.departments = const [],
|
||||||
@ -53,7 +58,7 @@ class DepreciationReportFilters {
|
|||||||
this.depreciationMethods = const [],
|
this.depreciationMethods = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<ReportFilterOption> plants;
|
final List<ReportFilterOption> locations;
|
||||||
final List<ReportFilterOption> categories;
|
final List<ReportFilterOption> categories;
|
||||||
final List<ReportFilterOption> subcategories;
|
final List<ReportFilterOption> subcategories;
|
||||||
final List<ReportFilterOption> departments;
|
final List<ReportFilterOption> departments;
|
||||||
@ -79,7 +84,7 @@ class DepreciationReportFilters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return DepreciationReportFilters(
|
return DepreciationReportFilters(
|
||||||
plants: parse(['plants', 'plant_options', 'plant']),
|
locations: parse(['locations', 'location_options', 'location']),
|
||||||
categories: parse([
|
categories: parse([
|
||||||
'item_categories',
|
'item_categories',
|
||||||
'categories',
|
'categories',
|
||||||
@ -155,7 +160,7 @@ class DepreciationReportRow {
|
|||||||
this.assetName,
|
this.assetName,
|
||||||
this.categoryName,
|
this.categoryName,
|
||||||
this.subcategoryName,
|
this.subcategoryName,
|
||||||
this.plantName,
|
this.locationName,
|
||||||
this.departmentName,
|
this.departmentName,
|
||||||
this.status,
|
this.status,
|
||||||
this.purchaseDate,
|
this.purchaseDate,
|
||||||
@ -175,7 +180,7 @@ class DepreciationReportRow {
|
|||||||
final String? assetName;
|
final String? assetName;
|
||||||
final String? categoryName;
|
final String? categoryName;
|
||||||
final String? subcategoryName;
|
final String? subcategoryName;
|
||||||
final String? plantName;
|
final String? locationName;
|
||||||
final String? departmentName;
|
final String? departmentName;
|
||||||
final String? status;
|
final String? status;
|
||||||
final DateTime? purchaseDate;
|
final DateTime? purchaseDate;
|
||||||
@ -262,8 +267,9 @@ class DepreciationReportRow {
|
|||||||
]) ??
|
]) ??
|
||||||
readNestedName('item_subcategory') ??
|
readNestedName('item_subcategory') ??
|
||||||
readNestedName('subcategory'),
|
readNestedName('subcategory'),
|
||||||
plantName:
|
locationName:
|
||||||
readString(['plant_name', 'plantName']) ?? readNestedName('plant'),
|
readString(['location_name', 'locationName']) ??
|
||||||
|
readNestedName('location'),
|
||||||
departmentName: readString(['department_name', 'departmentName']) ??
|
departmentName: readString(['department_name', 'departmentName']) ??
|
||||||
readNestedName('department'),
|
readNestedName('department'),
|
||||||
status: readString(['status']),
|
status: readString(['status']),
|
||||||
@ -315,7 +321,7 @@ class DepreciationReportQuery {
|
|||||||
this.page = 1,
|
this.page = 1,
|
||||||
this.limit = 20,
|
this.limit = 20,
|
||||||
this.search,
|
this.search,
|
||||||
this.plantId,
|
this.locationId,
|
||||||
this.itemCategoryId,
|
this.itemCategoryId,
|
||||||
this.itemSubcategoryId,
|
this.itemSubcategoryId,
|
||||||
this.departmentId,
|
this.departmentId,
|
||||||
@ -330,7 +336,7 @@ class DepreciationReportQuery {
|
|||||||
final int page;
|
final int page;
|
||||||
final int limit;
|
final int limit;
|
||||||
final String? search;
|
final String? search;
|
||||||
final String? plantId;
|
final String? locationId;
|
||||||
final String? itemCategoryId;
|
final String? itemCategoryId;
|
||||||
final String? itemSubcategoryId;
|
final String? itemSubcategoryId;
|
||||||
final String? departmentId;
|
final String? departmentId;
|
||||||
@ -343,7 +349,7 @@ class DepreciationReportQuery {
|
|||||||
|
|
||||||
bool get hasActiveFilter =>
|
bool get hasActiveFilter =>
|
||||||
(search?.isNotEmpty ?? false) ||
|
(search?.isNotEmpty ?? false) ||
|
||||||
(plantId?.isNotEmpty ?? false) ||
|
(locationId?.isNotEmpty ?? false) ||
|
||||||
(itemCategoryId?.isNotEmpty ?? false) ||
|
(itemCategoryId?.isNotEmpty ?? false) ||
|
||||||
(itemSubcategoryId?.isNotEmpty ?? false) ||
|
(itemSubcategoryId?.isNotEmpty ?? false) ||
|
||||||
(departmentId?.isNotEmpty ?? false) ||
|
(departmentId?.isNotEmpty ?? false) ||
|
||||||
@ -358,7 +364,7 @@ class DepreciationReportQuery {
|
|||||||
int? page,
|
int? page,
|
||||||
int? limit,
|
int? limit,
|
||||||
String? search,
|
String? search,
|
||||||
String? plantId,
|
String? locationId,
|
||||||
String? itemCategoryId,
|
String? itemCategoryId,
|
||||||
String? itemSubcategoryId,
|
String? itemSubcategoryId,
|
||||||
String? departmentId,
|
String? departmentId,
|
||||||
@ -369,7 +375,7 @@ class DepreciationReportQuery {
|
|||||||
DateTime? purchaseDateFrom,
|
DateTime? purchaseDateFrom,
|
||||||
DateTime? purchaseDateTo,
|
DateTime? purchaseDateTo,
|
||||||
bool clearSearch = false,
|
bool clearSearch = false,
|
||||||
bool clearPlantId = false,
|
bool clearLocationId = false,
|
||||||
bool clearItemCategoryId = false,
|
bool clearItemCategoryId = false,
|
||||||
bool clearItemSubcategoryId = false,
|
bool clearItemSubcategoryId = false,
|
||||||
bool clearDepartmentId = false,
|
bool clearDepartmentId = false,
|
||||||
@ -384,7 +390,7 @@ class DepreciationReportQuery {
|
|||||||
page: page ?? this.page,
|
page: page ?? this.page,
|
||||||
limit: limit ?? this.limit,
|
limit: limit ?? this.limit,
|
||||||
search: clearSearch ? null : search ?? this.search,
|
search: clearSearch ? null : search ?? this.search,
|
||||||
plantId: clearPlantId ? null : plantId ?? this.plantId,
|
locationId: clearLocationId ? null : locationId ?? this.locationId,
|
||||||
itemCategoryId: clearItemCategoryId
|
itemCategoryId: clearItemCategoryId
|
||||||
? null
|
? null
|
||||||
: itemCategoryId ?? this.itemCategoryId,
|
: itemCategoryId ?? this.itemCategoryId,
|
||||||
|
|||||||
@ -145,14 +145,14 @@ class DepreciationReportNotifier
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setPlantId(String? value) async {
|
Future<void> setLocationId(String? value) async {
|
||||||
final current = state.valueOrNull?.query ??
|
final current = state.valueOrNull?.query ??
|
||||||
const DepreciationReportQuery(limit: AppConstants.defaultPageSize);
|
const DepreciationReportQuery(limit: AppConstants.defaultPageSize);
|
||||||
await applyQuery(
|
await applyQuery(
|
||||||
current.copyWith(
|
current.copyWith(
|
||||||
page: 1,
|
page: 1,
|
||||||
plantId: value,
|
locationId: value,
|
||||||
clearPlantId: value == null || value.isEmpty,
|
clearLocationId: value == null || value.isEmpty,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,7 +174,7 @@ class _DepreciationReportScreenState
|
|||||||
filters: state.filters,
|
filters: state.filters,
|
||||||
query: state.query,
|
query: state.query,
|
||||||
onSearch: notifier.setSearch,
|
onSearch: notifier.setSearch,
|
||||||
onPlantChanged: notifier.setPlantId,
|
onLocationChanged: notifier.setLocationId,
|
||||||
onCategoryChanged: notifier.setItemCategoryId,
|
onCategoryChanged: notifier.setItemCategoryId,
|
||||||
onSubcategoryChanged: notifier.setItemSubcategoryId,
|
onSubcategoryChanged: notifier.setItemSubcategoryId,
|
||||||
onDepartmentChanged: notifier.setDepartmentId,
|
onDepartmentChanged: notifier.setDepartmentId,
|
||||||
@ -324,7 +324,7 @@ class _FiltersBar extends StatefulWidget {
|
|||||||
required this.filters,
|
required this.filters,
|
||||||
required this.query,
|
required this.query,
|
||||||
required this.onSearch,
|
required this.onSearch,
|
||||||
required this.onPlantChanged,
|
required this.onLocationChanged,
|
||||||
required this.onCategoryChanged,
|
required this.onCategoryChanged,
|
||||||
required this.onSubcategoryChanged,
|
required this.onSubcategoryChanged,
|
||||||
required this.onDepartmentChanged,
|
required this.onDepartmentChanged,
|
||||||
@ -342,7 +342,7 @@ class _FiltersBar extends StatefulWidget {
|
|||||||
final DepreciationReportFilters filters;
|
final DepreciationReportFilters filters;
|
||||||
final DepreciationReportQuery query;
|
final DepreciationReportQuery query;
|
||||||
final ValueChanged<String> onSearch;
|
final ValueChanged<String> onSearch;
|
||||||
final ValueChanged<String?> onPlantChanged;
|
final ValueChanged<String?> onLocationChanged;
|
||||||
final ValueChanged<String?> onCategoryChanged;
|
final ValueChanged<String?> onCategoryChanged;
|
||||||
final ValueChanged<String?> onSubcategoryChanged;
|
final ValueChanged<String?> onSubcategoryChanged;
|
||||||
final ValueChanged<String?> onDepartmentChanged;
|
final ValueChanged<String?> onDepartmentChanged;
|
||||||
@ -425,11 +425,11 @@ class _FiltersBarState extends State<_FiltersBar> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final plant = dropdown(
|
final location = dropdown(
|
||||||
label: 'Plant',
|
label: 'Location',
|
||||||
value: query.plantId,
|
value: query.locationId,
|
||||||
options: filters.plants,
|
options: filters.locations,
|
||||||
onChanged: widget.onPlantChanged,
|
onChanged: widget.onLocationChanged,
|
||||||
);
|
);
|
||||||
final category = dropdown(
|
final category = dropdown(
|
||||||
label: 'Category',
|
label: 'Category',
|
||||||
@ -549,7 +549,7 @@ class _FiltersBarState extends State<_FiltersBar> {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
return AppResponsiveFilterGrid(
|
return AppResponsiveFilterGrid(
|
||||||
fields: [searchField, plant, category, asOfField],
|
fields: [searchField, location, category, asOfField],
|
||||||
footer: Align(
|
footer: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: actions,
|
child: actions,
|
||||||
@ -589,10 +589,10 @@ class _ReportTable extends StatelessWidget {
|
|||||||
cellBuilder: (_, row) => AppTableCell.text(row.categoryName),
|
cellBuilder: (_, row) => AppTableCell.text(row.categoryName),
|
||||||
),
|
),
|
||||||
AppDataColumn(
|
AppDataColumn(
|
||||||
label: 'Plant',
|
label: 'Location',
|
||||||
flex: 2,
|
flex: 2,
|
||||||
searchText: (row) => row.plantName ?? '',
|
searchText: (row) => row.locationName ?? '',
|
||||||
cellBuilder: (_, row) => AppTableCell.text(row.plantName),
|
cellBuilder: (_, row) => AppTableCell.text(row.locationName),
|
||||||
),
|
),
|
||||||
AppDataColumn(
|
AppDataColumn(
|
||||||
label: 'Purchase Date',
|
label: 'Purchase Date',
|
||||||
|
|||||||
@ -45,10 +45,21 @@ Object? _readItemCategoryName(Map<dynamic, dynamic> json, String key) {
|
|||||||
_readNestedName(json, 'asset_category');
|
_readNestedName(json, 'asset_category');
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _readPlantName(Map<dynamic, dynamic> json, String key) {
|
Object? _readLocationName(Map<dynamic, dynamic> json, String key) {
|
||||||
final flat = json['plant_name'];
|
final flat = json['location_name'];
|
||||||
if (flat is String && flat.isNotEmpty) return flat;
|
if (flat is String && flat.isNotEmpty) return flat;
|
||||||
return _readNestedName(json, 'plant');
|
final nested = json['location'];
|
||||||
|
if (nested is Map) {
|
||||||
|
final name = nested['name']?.toString().trim();
|
||||||
|
if (name == null || name.isEmpty) return null;
|
||||||
|
final type = nested['type']?.toString().trim();
|
||||||
|
if (type != null && type.isNotEmpty) {
|
||||||
|
final typeLabel = type[0].toUpperCase() + type.substring(1);
|
||||||
|
return '$name ($typeLabel)';
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _readItemCategoryId(Map<dynamic, dynamic> json, String key) {
|
Object? _readItemCategoryId(Map<dynamic, dynamic> json, String key) {
|
||||||
@ -61,10 +72,10 @@ Object? _readItemCategoryId(Map<dynamic, dynamic> json, String key) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _readPlantId(Map<dynamic, dynamic> json, String key) {
|
Object? _readLocationId(Map<dynamic, dynamic> json, String key) {
|
||||||
final flat = json['plant_id'];
|
final flat = json['location_id'];
|
||||||
if (flat != null) return flat;
|
if (flat != null) return flat;
|
||||||
final nested = json['plant'];
|
final nested = json['location'];
|
||||||
if (nested is Map) return nested['id'];
|
if (nested is Map) return nested['id'];
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -94,12 +105,6 @@ Object? _readDepartmentName(Map<dynamic, dynamic> json, String key) {
|
|||||||
return _readNestedName(json, 'department');
|
return _readNestedName(json, 'department');
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _readWarehouseName(Map<dynamic, dynamic> json, String key) {
|
|
||||||
final flat = json['warehouse_name'];
|
|
||||||
if (flat is String && flat.isNotEmpty) return flat;
|
|
||||||
return _readNestedName(json, 'warehouse');
|
|
||||||
}
|
|
||||||
|
|
||||||
Object? _readVendorNameFromNested(Map<dynamic, dynamic> json, String key) {
|
Object? _readVendorNameFromNested(Map<dynamic, dynamic> json, String key) {
|
||||||
final flat = json['vendor_name'];
|
final flat = json['vendor_name'];
|
||||||
if (flat is String && flat.isNotEmpty) return flat;
|
if (flat is String && flat.isNotEmpty) return flat;
|
||||||
@ -153,9 +158,14 @@ class AssetModel with _$AssetModel {
|
|||||||
int? assetSubcategoryId,
|
int? assetSubcategoryId,
|
||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
String? assetSubcategoryName,
|
String? assetSubcategoryName,
|
||||||
@JsonKey(name: 'plant_id', readValue: _readPlantId, fromJson: _intFromJsonNullable)
|
@JsonKey(
|
||||||
int? plantId,
|
name: 'location_id',
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
readValue: _readLocationId,
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? locationId,
|
||||||
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
|
String? locationName,
|
||||||
@JsonKey(name: 'brand_model') String? brandModel,
|
@JsonKey(name: 'brand_model') String? brandModel,
|
||||||
String? manufacturer,
|
String? manufacturer,
|
||||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||||
@ -163,11 +173,21 @@ class AssetModel with _$AssetModel {
|
|||||||
@JsonKey(name: 'department_id', fromJson: _intFromJsonNullable) int? departmentId,
|
@JsonKey(name: 'department_id', fromJson: _intFromJsonNullable) int? departmentId,
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
String? departmentName,
|
String? departmentName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable) int? warehouseId,
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName) String? warehouseName,
|
|
||||||
@JsonKey(name: 'location_detail') String? locationDetail,
|
@JsonKey(name: 'location_detail') String? locationDetail,
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
int? assignedToUserId,
|
int? assignedToUserId,
|
||||||
|
@JsonKey(name: 'maintenance_incharge_user_id', fromJson: _intFromJsonNullable)
|
||||||
|
int? maintenanceInchargeUserId,
|
||||||
|
@JsonKey(name: 'maintenance_frequency_in_days', fromJson: _intFromJsonNullable)
|
||||||
|
int? maintenanceFrequencyInDays,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? maintenanceChecklistJson,
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
DateTime? commencementDate,
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested) String? vendorName,
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested) String? vendorName,
|
||||||
@JsonKey(name: 'po_id', fromJson: _intFromJsonNullable) int? poId,
|
@JsonKey(name: 'po_id', fromJson: _intFromJsonNullable) int? poId,
|
||||||
@ -192,11 +212,161 @@ class AssetModel with _$AssetModel {
|
|||||||
@JsonKey(name: 'is_active') @Default(true) bool isActive,
|
@JsonKey(name: 'is_active') @Default(true) bool isActive,
|
||||||
@JsonKey(name: 'created_at', fromJson: _dateFromJsonNullable) DateTime? createdAt,
|
@JsonKey(name: 'created_at', fromJson: _dateFromJsonNullable) DateTime? createdAt,
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable) DateTime? updatedAt,
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable) DateTime? updatedAt,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
AssetMaintenanceSummary? maintenance,
|
||||||
}) = _AssetModel;
|
}) = _AssetModel;
|
||||||
|
|
||||||
factory AssetModel.fromJson(Map<String, dynamic> json) => _$AssetModelFromJson(json);
|
factory AssetModel.fromJson(Map<String, dynamic> json) => _$AssetModelFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AssetMaintenanceChecklistItem {
|
||||||
|
const AssetMaintenanceChecklistItem({
|
||||||
|
required this.key,
|
||||||
|
required this.label,
|
||||||
|
this.required = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String key;
|
||||||
|
final String label;
|
||||||
|
final bool required;
|
||||||
|
|
||||||
|
factory AssetMaintenanceChecklistItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
return AssetMaintenanceChecklistItem(
|
||||||
|
key: json['key']?.toString() ?? '',
|
||||||
|
label: json['label']?.toString() ?? '',
|
||||||
|
required: json['required'] == true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'key': key,
|
||||||
|
'label': label,
|
||||||
|
'required': required,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssetMaintenanceSummary {
|
||||||
|
const AssetMaintenanceSummary({
|
||||||
|
this.isDue = false,
|
||||||
|
this.nextDueDate,
|
||||||
|
this.lastMaintenanceDate,
|
||||||
|
this.daysUntilDue,
|
||||||
|
this.checklist = const [],
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool isDue;
|
||||||
|
final DateTime? nextDueDate;
|
||||||
|
final DateTime? lastMaintenanceDate;
|
||||||
|
final int? daysUntilDue;
|
||||||
|
final List<AssetMaintenanceChecklistItem> checklist;
|
||||||
|
|
||||||
|
static AssetMaintenanceSummary? fromJsonNullable(Object? value) {
|
||||||
|
if (value is! Map) return null;
|
||||||
|
return AssetMaintenanceSummary.fromJson(Map<String, dynamic>.from(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object? toJsonNullable(AssetMaintenanceSummary? value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
return value.toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'is_due': isDue,
|
||||||
|
if (nextDueDate != null)
|
||||||
|
'next_due_date': nextDueDate!.toIso8601String(),
|
||||||
|
if (lastMaintenanceDate != null)
|
||||||
|
'last_maintenance_date': lastMaintenanceDate!.toIso8601String(),
|
||||||
|
if (daysUntilDue != null) 'days_until_due': daysUntilDue,
|
||||||
|
'checklist': checklist.map((item) => item.toJson()).toList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
factory AssetMaintenanceSummary.fromJson(Map<String, dynamic> json) {
|
||||||
|
DateTime? parseDate(dynamic value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value is DateTime) return value;
|
||||||
|
return DateTime.tryParse(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final rawChecklist = json['checklist'] ?? json['checklist_json'];
|
||||||
|
final checklist = <AssetMaintenanceChecklistItem>[];
|
||||||
|
if (rawChecklist is List) {
|
||||||
|
for (final item in rawChecklist) {
|
||||||
|
if (item is Map) {
|
||||||
|
checklist.add(
|
||||||
|
AssetMaintenanceChecklistItem.fromJson(
|
||||||
|
Map<String, dynamic>.from(item),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetMaintenanceSummary(
|
||||||
|
isDue: json['is_due'] == true,
|
||||||
|
nextDueDate: parseDate(json['next_due_date']),
|
||||||
|
lastMaintenanceDate: parseDate(json['last_maintenance_date']),
|
||||||
|
daysUntilDue: _intFromJsonNullable(json['days_until_due']),
|
||||||
|
checklist: checklist,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssetMaintenanceLogModel {
|
||||||
|
const AssetMaintenanceLogModel({
|
||||||
|
required this.id,
|
||||||
|
this.performedDate,
|
||||||
|
this.nextDueDate,
|
||||||
|
this.remarks,
|
||||||
|
this.checklistJson = const [],
|
||||||
|
this.createdAt,
|
||||||
|
this.createdByName,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
final DateTime? performedDate;
|
||||||
|
final DateTime? nextDueDate;
|
||||||
|
final String? remarks;
|
||||||
|
final List<Map<String, dynamic>> checklistJson;
|
||||||
|
final DateTime? createdAt;
|
||||||
|
final String? createdByName;
|
||||||
|
|
||||||
|
factory AssetMaintenanceLogModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
DateTime? parseDate(dynamic value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value is DateTime) return value;
|
||||||
|
return DateTime.tryParse(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final rawChecklist = json['checklist_json'] ?? json['checklist'];
|
||||||
|
final checklist = <Map<String, dynamic>>[];
|
||||||
|
if (rawChecklist is List) {
|
||||||
|
for (final item in rawChecklist) {
|
||||||
|
if (item is Map) {
|
||||||
|
checklist.add(Map<String, dynamic>.from(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetMaintenanceLogModel(
|
||||||
|
id: _idFromJson(json['id']),
|
||||||
|
performedDate: parseDate(json['performed_date']),
|
||||||
|
nextDueDate: parseDate(json['next_due_date']),
|
||||||
|
remarks: json['remarks']?.toString(),
|
||||||
|
checklistJson: checklist,
|
||||||
|
createdAt: parseDate(json['created_at']),
|
||||||
|
createdByName: json['created_by_name']?.toString() ??
|
||||||
|
(json['created_by'] is Map
|
||||||
|
? (json['created_by']['name'] ?? json['created_by']['full_name'])
|
||||||
|
?.toString()
|
||||||
|
: null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String assetConditionLabel(String? value) {
|
String assetConditionLabel(String? value) {
|
||||||
if (value == null || value.trim().isEmpty) return '—';
|
if (value == null || value.trim().isEmpty) return '—';
|
||||||
return value.replaceAll('_', ' ');
|
return value.replaceAll('_', ' ');
|
||||||
@ -402,6 +572,35 @@ class InsurancePolicyModel with _$InsurancePolicyModel {
|
|||||||
_$InsurancePolicyModelFromJson(json);
|
_$InsurancePolicyModelFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<AssetMaintenanceChecklistItem>? _checklistFromJson(Object? value) {
|
||||||
|
if (value is! List) return null;
|
||||||
|
return value
|
||||||
|
.whereType<Map>()
|
||||||
|
.map(
|
||||||
|
(item) => AssetMaintenanceChecklistItem.fromJson(
|
||||||
|
Map<String, dynamic>.from(item),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.where((item) => item.key.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object? _checklistToJson(List<AssetMaintenanceChecklistItem>? value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
return value.map((item) => item.toJson()).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object? _readAlertLocationName(Map<dynamic, dynamic> json, String key) {
|
||||||
|
final flat = json['location_name'];
|
||||||
|
if (flat is String && flat.isNotEmpty) return flat;
|
||||||
|
final nested = json['location'];
|
||||||
|
if (nested is Map) {
|
||||||
|
final name = nested['name'];
|
||||||
|
if (name is String && name.isNotEmpty) return name;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class AssetAlertModel with _$AssetAlertModel {
|
class AssetAlertModel with _$AssetAlertModel {
|
||||||
const factory AssetAlertModel({
|
const factory AssetAlertModel({
|
||||||
@ -416,7 +615,8 @@ class AssetAlertModel with _$AssetAlertModel {
|
|||||||
@JsonKey(name: 'due_date', fromJson: _dateFromJsonNullable) DateTime? dueDate,
|
@JsonKey(name: 'due_date', fromJson: _dateFromJsonNullable) DateTime? dueDate,
|
||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable) int? daysRemaining,
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable) int? daysRemaining,
|
||||||
String? status,
|
String? status,
|
||||||
@JsonKey(name: 'plant_name') String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
|
String? locationName,
|
||||||
}) = _AssetAlertModel;
|
}) = _AssetAlertModel;
|
||||||
|
|
||||||
factory AssetAlertModel.fromJson(Map<String, dynamic> json) =>
|
factory AssetAlertModel.fromJson(Map<String, dynamic> json) =>
|
||||||
@ -428,12 +628,10 @@ class AssetTransferHistoryModel {
|
|||||||
required this.id,
|
required this.id,
|
||||||
this.transferDate,
|
this.transferDate,
|
||||||
this.reason,
|
this.reason,
|
||||||
this.fromPlantName,
|
this.fromLocationName,
|
||||||
this.toPlantName,
|
this.toLocationName,
|
||||||
this.fromDepartmentName,
|
this.fromDepartmentName,
|
||||||
this.toDepartmentName,
|
this.toDepartmentName,
|
||||||
this.fromWarehouseName,
|
|
||||||
this.toWarehouseName,
|
|
||||||
this.fromUserName,
|
this.fromUserName,
|
||||||
this.toUserName,
|
this.toUserName,
|
||||||
this.createdAt,
|
this.createdAt,
|
||||||
@ -443,12 +641,10 @@ class AssetTransferHistoryModel {
|
|||||||
final String id;
|
final String id;
|
||||||
final DateTime? transferDate;
|
final DateTime? transferDate;
|
||||||
final String? reason;
|
final String? reason;
|
||||||
final String? fromPlantName;
|
final String? fromLocationName;
|
||||||
final String? toPlantName;
|
final String? toLocationName;
|
||||||
final String? fromDepartmentName;
|
final String? fromDepartmentName;
|
||||||
final String? toDepartmentName;
|
final String? toDepartmentName;
|
||||||
final String? fromWarehouseName;
|
|
||||||
final String? toWarehouseName;
|
|
||||||
final String? fromUserName;
|
final String? fromUserName;
|
||||||
final String? toUserName;
|
final String? toUserName;
|
||||||
final DateTime? createdAt;
|
final DateTime? createdAt;
|
||||||
@ -466,7 +662,15 @@ class AssetTransferHistoryModel {
|
|||||||
if (nested is Map) {
|
if (nested is Map) {
|
||||||
for (final field in ['name', 'full_name']) {
|
for (final field in ['name', 'full_name']) {
|
||||||
final value = nested[field];
|
final value = nested[field];
|
||||||
if (value is String && value.trim().isNotEmpty) return value.trim();
|
if (value is String && value.trim().isNotEmpty) {
|
||||||
|
final name = value.trim();
|
||||||
|
final type = nested['type']?.toString().trim();
|
||||||
|
if (type != null && type.isNotEmpty) {
|
||||||
|
final typeLabel = type[0].toUpperCase() + type.substring(1);
|
||||||
|
return '$name ($typeLabel)';
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -482,14 +686,13 @@ class AssetTransferHistoryModel {
|
|||||||
id: _idFromJson(json['id']),
|
id: _idFromJson(json['id']),
|
||||||
transferDate: parseDate(json['transfer_date']),
|
transferDate: parseDate(json['transfer_date']),
|
||||||
reason: readName('reason'),
|
reason: readName('reason'),
|
||||||
fromPlantName: readName('from_plant_name') ?? readNestedName('from_plant'),
|
fromLocationName:
|
||||||
toPlantName: readName('to_plant_name') ?? readNestedName('to_plant'),
|
readName('from_location_name') ?? readNestedName('from_location'),
|
||||||
|
toLocationName:
|
||||||
|
readName('to_location_name') ?? readNestedName('to_location'),
|
||||||
fromDepartmentName:
|
fromDepartmentName:
|
||||||
readName('from_department_name') ?? readNestedName('from_department'),
|
readName('from_department_name') ?? readNestedName('from_department'),
|
||||||
toDepartmentName: readName('to_department_name') ?? readNestedName('to_department'),
|
toDepartmentName: readName('to_department_name') ?? readNestedName('to_department'),
|
||||||
fromWarehouseName:
|
|
||||||
readName('from_warehouse_name') ?? readNestedName('from_warehouse'),
|
|
||||||
toWarehouseName: readName('to_warehouse_name') ?? readNestedName('to_warehouse'),
|
|
||||||
fromUserName: readName('from_user_name') ?? readNestedName('from_user'),
|
fromUserName: readName('from_user_name') ?? readNestedName('from_user'),
|
||||||
toUserName: readName('to_user_name') ?? readNestedName('to_user'),
|
toUserName: readName('to_user_name') ?? readNestedName('to_user'),
|
||||||
createdAt: parseDate(json['created_at']),
|
createdAt: parseDate(json['created_at']),
|
||||||
@ -557,8 +760,10 @@ class AssetListQuery {
|
|||||||
this.condition,
|
this.condition,
|
||||||
this.itemCategoryId,
|
this.itemCategoryId,
|
||||||
this.itemSubcategoryId,
|
this.itemSubcategoryId,
|
||||||
this.plantId,
|
this.locationId,
|
||||||
this.departmentId,
|
this.departmentId,
|
||||||
|
this.maintenanceInchargeUserId,
|
||||||
|
this.dueOnly,
|
||||||
this.isActive,
|
this.isActive,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -569,8 +774,10 @@ class AssetListQuery {
|
|||||||
final String? condition;
|
final String? condition;
|
||||||
final int? itemCategoryId;
|
final int? itemCategoryId;
|
||||||
final int? itemSubcategoryId;
|
final int? itemSubcategoryId;
|
||||||
final int? plantId;
|
final int? locationId;
|
||||||
final int? departmentId;
|
final int? departmentId;
|
||||||
|
final int? maintenanceInchargeUserId;
|
||||||
|
final bool? dueOnly;
|
||||||
final bool? isActive;
|
final bool? isActive;
|
||||||
|
|
||||||
AssetListQuery copyWith({
|
AssetListQuery copyWith({
|
||||||
@ -581,8 +788,10 @@ class AssetListQuery {
|
|||||||
Object? condition = _unset,
|
Object? condition = _unset,
|
||||||
Object? itemCategoryId = _unset,
|
Object? itemCategoryId = _unset,
|
||||||
Object? itemSubcategoryId = _unset,
|
Object? itemSubcategoryId = _unset,
|
||||||
Object? plantId = _unset,
|
Object? locationId = _unset,
|
||||||
Object? departmentId = _unset,
|
Object? departmentId = _unset,
|
||||||
|
Object? maintenanceInchargeUserId = _unset,
|
||||||
|
Object? dueOnly = _unset,
|
||||||
Object? isActive = _unset,
|
Object? isActive = _unset,
|
||||||
}) {
|
}) {
|
||||||
return AssetListQuery(
|
return AssetListQuery(
|
||||||
@ -598,10 +807,15 @@ class AssetListQuery {
|
|||||||
itemSubcategoryId: identical(itemSubcategoryId, _unset)
|
itemSubcategoryId: identical(itemSubcategoryId, _unset)
|
||||||
? this.itemSubcategoryId
|
? this.itemSubcategoryId
|
||||||
: itemSubcategoryId as int?,
|
: itemSubcategoryId as int?,
|
||||||
plantId: identical(plantId, _unset) ? this.plantId : plantId as int?,
|
locationId:
|
||||||
|
identical(locationId, _unset) ? this.locationId : locationId as int?,
|
||||||
departmentId: identical(departmentId, _unset)
|
departmentId: identical(departmentId, _unset)
|
||||||
? this.departmentId
|
? this.departmentId
|
||||||
: departmentId as int?,
|
: departmentId as int?,
|
||||||
|
maintenanceInchargeUserId: identical(maintenanceInchargeUserId, _unset)
|
||||||
|
? this.maintenanceInchargeUserId
|
||||||
|
: maintenanceInchargeUserId as int?,
|
||||||
|
dueOnly: identical(dueOnly, _unset) ? this.dueOnly : dueOnly as bool?,
|
||||||
isActive:
|
isActive:
|
||||||
identical(isActive, _unset) ? this.isActive : isActive as bool?,
|
identical(isActive, _unset) ? this.isActive : isActive as bool?,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -438,13 +438,13 @@ mixin _$AssetModel {
|
|||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
String? get assetSubcategoryName => throw _privateConstructorUsedError;
|
String? get assetSubcategoryName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
int? get plantId => throw _privateConstructorUsedError;
|
int? get locationId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
String? get plantName => throw _privateConstructorUsedError;
|
String? get locationName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'brand_model')
|
@JsonKey(name: 'brand_model')
|
||||||
String? get brandModel => throw _privateConstructorUsedError;
|
String? get brandModel => throw _privateConstructorUsedError;
|
||||||
String? get manufacturer => throw _privateConstructorUsedError;
|
String? get manufacturer => throw _privateConstructorUsedError;
|
||||||
@ -456,14 +456,26 @@ mixin _$AssetModel {
|
|||||||
int? get departmentId => throw _privateConstructorUsedError;
|
int? get departmentId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
String? get departmentName => throw _privateConstructorUsedError;
|
String? get departmentName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
int? get warehouseId => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
String? get warehouseName => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(name: 'location_detail')
|
@JsonKey(name: 'location_detail')
|
||||||
String? get locationDetail => throw _privateConstructorUsedError;
|
String? get locationDetail => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
int? get assignedToUserId => throw _privateConstructorUsedError;
|
int? get assignedToUserId => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'maintenance_incharge_user_id', fromJson: _intFromJsonNullable)
|
||||||
|
int? get maintenanceInchargeUserId => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? get maintenanceFrequencyInDays => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? get maintenanceChecklistJson =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
DateTime? get commencementDate => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
||||||
int? get vendorId => throw _privateConstructorUsedError;
|
int? get vendorId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
||||||
@ -505,6 +517,13 @@ mixin _$AssetModel {
|
|||||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
DateTime? get createdAt => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
AssetMaintenanceSummary? get maintenance =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this AssetModel to a JSON map.
|
/// Serializes this AssetModel to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@ -544,12 +563,13 @@ abstract class $AssetModelCopyWith<$Res> {
|
|||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
String? assetSubcategoryName,
|
String? assetSubcategoryName,
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
int? plantId,
|
int? locationId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
|
String? locationName,
|
||||||
@JsonKey(name: 'brand_model') String? brandModel,
|
@JsonKey(name: 'brand_model') String? brandModel,
|
||||||
String? manufacturer,
|
String? manufacturer,
|
||||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||||
@ -558,13 +578,27 @@ abstract class $AssetModelCopyWith<$Res> {
|
|||||||
int? departmentId,
|
int? departmentId,
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
String? departmentName,
|
String? departmentName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
int? warehouseId,
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
String? warehouseName,
|
|
||||||
@JsonKey(name: 'location_detail') String? locationDetail,
|
@JsonKey(name: 'location_detail') String? locationDetail,
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
int? assignedToUserId,
|
int? assignedToUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_incharge_user_id',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? maintenanceInchargeUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? maintenanceFrequencyInDays,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? maintenanceChecklistJson,
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
DateTime? commencementDate,
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
||||||
String? vendorName,
|
String? vendorName,
|
||||||
@ -599,6 +633,12 @@ abstract class $AssetModelCopyWith<$Res> {
|
|||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
AssetMaintenanceSummary? maintenance,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,18 +664,20 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
Object? assetCategoryName = freezed,
|
Object? assetCategoryName = freezed,
|
||||||
Object? assetSubcategoryId = freezed,
|
Object? assetSubcategoryId = freezed,
|
||||||
Object? assetSubcategoryName = freezed,
|
Object? assetSubcategoryName = freezed,
|
||||||
Object? plantId = freezed,
|
Object? locationId = freezed,
|
||||||
Object? plantName = freezed,
|
Object? locationName = freezed,
|
||||||
Object? brandModel = freezed,
|
Object? brandModel = freezed,
|
||||||
Object? manufacturer = freezed,
|
Object? manufacturer = freezed,
|
||||||
Object? serialNumber = freezed,
|
Object? serialNumber = freezed,
|
||||||
Object? partNumber = freezed,
|
Object? partNumber = freezed,
|
||||||
Object? departmentId = freezed,
|
Object? departmentId = freezed,
|
||||||
Object? departmentName = freezed,
|
Object? departmentName = freezed,
|
||||||
Object? warehouseId = freezed,
|
|
||||||
Object? warehouseName = freezed,
|
|
||||||
Object? locationDetail = freezed,
|
Object? locationDetail = freezed,
|
||||||
Object? assignedToUserId = freezed,
|
Object? assignedToUserId = freezed,
|
||||||
|
Object? maintenanceInchargeUserId = freezed,
|
||||||
|
Object? maintenanceFrequencyInDays = freezed,
|
||||||
|
Object? maintenanceChecklistJson = freezed,
|
||||||
|
Object? commencementDate = freezed,
|
||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? vendorName = freezed,
|
Object? vendorName = freezed,
|
||||||
Object? poId = freezed,
|
Object? poId = freezed,
|
||||||
@ -658,6 +700,7 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
Object? isActive = null,
|
Object? isActive = null,
|
||||||
Object? createdAt = freezed,
|
Object? createdAt = freezed,
|
||||||
Object? updatedAt = freezed,
|
Object? updatedAt = freezed,
|
||||||
|
Object? maintenance = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(
|
return _then(
|
||||||
_value.copyWith(
|
_value.copyWith(
|
||||||
@ -689,13 +732,13 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
? _value.assetSubcategoryName
|
? _value.assetSubcategoryName
|
||||||
: assetSubcategoryName // ignore: cast_nullable_to_non_nullable
|
: assetSubcategoryName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantId: freezed == plantId
|
locationId: freezed == locationId
|
||||||
? _value.plantId
|
? _value.locationId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: locationId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantName: freezed == plantName
|
locationName: freezed == locationName
|
||||||
? _value.plantName
|
? _value.locationName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: locationName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
brandModel: freezed == brandModel
|
brandModel: freezed == brandModel
|
||||||
? _value.brandModel
|
? _value.brandModel
|
||||||
@ -721,14 +764,6 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
? _value.departmentName
|
? _value.departmentName
|
||||||
: departmentName // ignore: cast_nullable_to_non_nullable
|
: departmentName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
warehouseId: freezed == warehouseId
|
|
||||||
? _value.warehouseId
|
|
||||||
: warehouseId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
warehouseName: freezed == warehouseName
|
|
||||||
? _value.warehouseName
|
|
||||||
: warehouseName // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
locationDetail: freezed == locationDetail
|
locationDetail: freezed == locationDetail
|
||||||
? _value.locationDetail
|
? _value.locationDetail
|
||||||
: locationDetail // ignore: cast_nullable_to_non_nullable
|
: locationDetail // ignore: cast_nullable_to_non_nullable
|
||||||
@ -737,6 +772,22 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
? _value.assignedToUserId
|
? _value.assignedToUserId
|
||||||
: assignedToUserId // ignore: cast_nullable_to_non_nullable
|
: assignedToUserId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
maintenanceInchargeUserId: freezed == maintenanceInchargeUserId
|
||||||
|
? _value.maintenanceInchargeUserId
|
||||||
|
: maintenanceInchargeUserId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
maintenanceFrequencyInDays: freezed == maintenanceFrequencyInDays
|
||||||
|
? _value.maintenanceFrequencyInDays
|
||||||
|
: maintenanceFrequencyInDays // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
maintenanceChecklistJson: freezed == maintenanceChecklistJson
|
||||||
|
? _value.maintenanceChecklistJson
|
||||||
|
: maintenanceChecklistJson // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<AssetMaintenanceChecklistItem>?,
|
||||||
|
commencementDate: freezed == commencementDate
|
||||||
|
? _value.commencementDate
|
||||||
|
: commencementDate // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
vendorId: freezed == vendorId
|
vendorId: freezed == vendorId
|
||||||
? _value.vendorId
|
? _value.vendorId
|
||||||
: vendorId // ignore: cast_nullable_to_non_nullable
|
: vendorId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -825,6 +876,10 @@ class _$AssetModelCopyWithImpl<$Res, $Val extends AssetModel>
|
|||||||
? _value.updatedAt
|
? _value.updatedAt
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
|
maintenance: freezed == maintenance
|
||||||
|
? _value.maintenance
|
||||||
|
: maintenance // ignore: cast_nullable_to_non_nullable
|
||||||
|
as AssetMaintenanceSummary?,
|
||||||
)
|
)
|
||||||
as $Val,
|
as $Val,
|
||||||
);
|
);
|
||||||
@ -861,12 +916,13 @@ abstract class _$$AssetModelImplCopyWith<$Res>
|
|||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
String? assetSubcategoryName,
|
String? assetSubcategoryName,
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
int? plantId,
|
int? locationId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
|
String? locationName,
|
||||||
@JsonKey(name: 'brand_model') String? brandModel,
|
@JsonKey(name: 'brand_model') String? brandModel,
|
||||||
String? manufacturer,
|
String? manufacturer,
|
||||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||||
@ -875,13 +931,27 @@ abstract class _$$AssetModelImplCopyWith<$Res>
|
|||||||
int? departmentId,
|
int? departmentId,
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
String? departmentName,
|
String? departmentName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
int? warehouseId,
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
String? warehouseName,
|
|
||||||
@JsonKey(name: 'location_detail') String? locationDetail,
|
@JsonKey(name: 'location_detail') String? locationDetail,
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
int? assignedToUserId,
|
int? assignedToUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_incharge_user_id',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? maintenanceInchargeUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? maintenanceFrequencyInDays,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? maintenanceChecklistJson,
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
DateTime? commencementDate,
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
||||||
String? vendorName,
|
String? vendorName,
|
||||||
@ -916,6 +986,12 @@ abstract class _$$AssetModelImplCopyWith<$Res>
|
|||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
AssetMaintenanceSummary? maintenance,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,18 +1016,20 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
Object? assetCategoryName = freezed,
|
Object? assetCategoryName = freezed,
|
||||||
Object? assetSubcategoryId = freezed,
|
Object? assetSubcategoryId = freezed,
|
||||||
Object? assetSubcategoryName = freezed,
|
Object? assetSubcategoryName = freezed,
|
||||||
Object? plantId = freezed,
|
Object? locationId = freezed,
|
||||||
Object? plantName = freezed,
|
Object? locationName = freezed,
|
||||||
Object? brandModel = freezed,
|
Object? brandModel = freezed,
|
||||||
Object? manufacturer = freezed,
|
Object? manufacturer = freezed,
|
||||||
Object? serialNumber = freezed,
|
Object? serialNumber = freezed,
|
||||||
Object? partNumber = freezed,
|
Object? partNumber = freezed,
|
||||||
Object? departmentId = freezed,
|
Object? departmentId = freezed,
|
||||||
Object? departmentName = freezed,
|
Object? departmentName = freezed,
|
||||||
Object? warehouseId = freezed,
|
|
||||||
Object? warehouseName = freezed,
|
|
||||||
Object? locationDetail = freezed,
|
Object? locationDetail = freezed,
|
||||||
Object? assignedToUserId = freezed,
|
Object? assignedToUserId = freezed,
|
||||||
|
Object? maintenanceInchargeUserId = freezed,
|
||||||
|
Object? maintenanceFrequencyInDays = freezed,
|
||||||
|
Object? maintenanceChecklistJson = freezed,
|
||||||
|
Object? commencementDate = freezed,
|
||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? vendorName = freezed,
|
Object? vendorName = freezed,
|
||||||
Object? poId = freezed,
|
Object? poId = freezed,
|
||||||
@ -974,6 +1052,7 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
Object? isActive = null,
|
Object? isActive = null,
|
||||||
Object? createdAt = freezed,
|
Object? createdAt = freezed,
|
||||||
Object? updatedAt = freezed,
|
Object? updatedAt = freezed,
|
||||||
|
Object? maintenance = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(
|
return _then(
|
||||||
_$AssetModelImpl(
|
_$AssetModelImpl(
|
||||||
@ -1005,13 +1084,13 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
? _value.assetSubcategoryName
|
? _value.assetSubcategoryName
|
||||||
: assetSubcategoryName // ignore: cast_nullable_to_non_nullable
|
: assetSubcategoryName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantId: freezed == plantId
|
locationId: freezed == locationId
|
||||||
? _value.plantId
|
? _value.locationId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: locationId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantName: freezed == plantName
|
locationName: freezed == locationName
|
||||||
? _value.plantName
|
? _value.locationName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: locationName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
brandModel: freezed == brandModel
|
brandModel: freezed == brandModel
|
||||||
? _value.brandModel
|
? _value.brandModel
|
||||||
@ -1037,14 +1116,6 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
? _value.departmentName
|
? _value.departmentName
|
||||||
: departmentName // ignore: cast_nullable_to_non_nullable
|
: departmentName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
warehouseId: freezed == warehouseId
|
|
||||||
? _value.warehouseId
|
|
||||||
: warehouseId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
warehouseName: freezed == warehouseName
|
|
||||||
? _value.warehouseName
|
|
||||||
: warehouseName // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,
|
|
||||||
locationDetail: freezed == locationDetail
|
locationDetail: freezed == locationDetail
|
||||||
? _value.locationDetail
|
? _value.locationDetail
|
||||||
: locationDetail // ignore: cast_nullable_to_non_nullable
|
: locationDetail // ignore: cast_nullable_to_non_nullable
|
||||||
@ -1053,6 +1124,22 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
? _value.assignedToUserId
|
? _value.assignedToUserId
|
||||||
: assignedToUserId // ignore: cast_nullable_to_non_nullable
|
: assignedToUserId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
|
maintenanceInchargeUserId: freezed == maintenanceInchargeUserId
|
||||||
|
? _value.maintenanceInchargeUserId
|
||||||
|
: maintenanceInchargeUserId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
maintenanceFrequencyInDays: freezed == maintenanceFrequencyInDays
|
||||||
|
? _value.maintenanceFrequencyInDays
|
||||||
|
: maintenanceFrequencyInDays // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
maintenanceChecklistJson: freezed == maintenanceChecklistJson
|
||||||
|
? _value._maintenanceChecklistJson
|
||||||
|
: maintenanceChecklistJson // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<AssetMaintenanceChecklistItem>?,
|
||||||
|
commencementDate: freezed == commencementDate
|
||||||
|
? _value.commencementDate
|
||||||
|
: commencementDate // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
vendorId: freezed == vendorId
|
vendorId: freezed == vendorId
|
||||||
? _value.vendorId
|
? _value.vendorId
|
||||||
: vendorId // ignore: cast_nullable_to_non_nullable
|
: vendorId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -1141,6 +1228,10 @@ class __$$AssetModelImplCopyWithImpl<$Res>
|
|||||||
? _value.updatedAt
|
? _value.updatedAt
|
||||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
|
maintenance: freezed == maintenance
|
||||||
|
? _value.maintenance
|
||||||
|
: maintenance // ignore: cast_nullable_to_non_nullable
|
||||||
|
as AssetMaintenanceSummary?,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1170,12 +1261,13 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
this.assetSubcategoryName,
|
this.assetSubcategoryName,
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
this.plantId,
|
this.locationId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) this.plantName,
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
|
this.locationName,
|
||||||
@JsonKey(name: 'brand_model') this.brandModel,
|
@JsonKey(name: 'brand_model') this.brandModel,
|
||||||
this.manufacturer,
|
this.manufacturer,
|
||||||
@JsonKey(name: 'serial_number') this.serialNumber,
|
@JsonKey(name: 'serial_number') this.serialNumber,
|
||||||
@ -1184,13 +1276,27 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
this.departmentId,
|
this.departmentId,
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
this.departmentName,
|
this.departmentName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
this.warehouseId,
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
this.warehouseName,
|
|
||||||
@JsonKey(name: 'location_detail') this.locationDetail,
|
@JsonKey(name: 'location_detail') this.locationDetail,
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
this.assignedToUserId,
|
this.assignedToUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_incharge_user_id',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
this.maintenanceInchargeUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
this.maintenanceFrequencyInDays,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
final List<AssetMaintenanceChecklistItem>? maintenanceChecklistJson,
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
this.commencementDate,
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) this.vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) this.vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
||||||
this.vendorName,
|
this.vendorName,
|
||||||
@ -1225,7 +1331,13 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
this.createdAt,
|
this.createdAt,
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
this.updatedAt,
|
this.updatedAt,
|
||||||
});
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
this.maintenance,
|
||||||
|
}) : _maintenanceChecklistJson = maintenanceChecklistJson;
|
||||||
|
|
||||||
factory _$AssetModelImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$AssetModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$AssetModelImplFromJson(json);
|
_$$AssetModelImplFromJson(json);
|
||||||
@ -1261,14 +1373,14 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
final String? assetSubcategoryName;
|
final String? assetSubcategoryName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
final int? plantId;
|
final int? locationId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
final String? plantName;
|
final String? locationName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'brand_model')
|
@JsonKey(name: 'brand_model')
|
||||||
final String? brandModel;
|
final String? brandModel;
|
||||||
@ -1287,18 +1399,40 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
final String? departmentName;
|
final String? departmentName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
final int? warehouseId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
final String? warehouseName;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'location_detail')
|
@JsonKey(name: 'location_detail')
|
||||||
final String? locationDetail;
|
final String? locationDetail;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
final int? assignedToUserId;
|
final int? assignedToUserId;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(name: 'maintenance_incharge_user_id', fromJson: _intFromJsonNullable)
|
||||||
|
final int? maintenanceInchargeUserId;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
final int? maintenanceFrequencyInDays;
|
||||||
|
final List<AssetMaintenanceChecklistItem>? _maintenanceChecklistJson;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? get maintenanceChecklistJson {
|
||||||
|
final value = _maintenanceChecklistJson;
|
||||||
|
if (value == null) return null;
|
||||||
|
if (_maintenanceChecklistJson is EqualUnmodifiableListView)
|
||||||
|
return _maintenanceChecklistJson;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
final DateTime? commencementDate;
|
||||||
|
@override
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
||||||
final int? vendorId;
|
final int? vendorId;
|
||||||
@override
|
@override
|
||||||
@ -1361,10 +1495,17 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
@override
|
@override
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
final DateTime? updatedAt;
|
final DateTime? updatedAt;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
final AssetMaintenanceSummary? maintenance;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AssetModel(id: $id, assetName: $assetName, assetCode: $assetCode, assetCategoryId: $assetCategoryId, assetCategoryName: $assetCategoryName, assetSubcategoryId: $assetSubcategoryId, assetSubcategoryName: $assetSubcategoryName, plantId: $plantId, plantName: $plantName, brandModel: $brandModel, manufacturer: $manufacturer, serialNumber: $serialNumber, partNumber: $partNumber, departmentId: $departmentId, departmentName: $departmentName, warehouseId: $warehouseId, warehouseName: $warehouseName, locationDetail: $locationDetail, assignedToUserId: $assignedToUserId, vendorId: $vendorId, vendorName: $vendorName, poId: $poId, grnId: $grnId, grnItemId: $grnItemId, purchaseDate: $purchaseDate, purchaseCost: $purchaseCost, usefulLifeYears: $usefulLifeYears, depreciationMethod: $depreciationMethod, depreciationRate: $depreciationRate, salvageValue: $salvageValue, warrantyExpiryDate: $warrantyExpiryDate, condition: $condition, status: $status, qrCodeValue: $qrCodeValue, disposalDate: $disposalDate, disposalReason: $disposalReason, disposalValue: $disposalValue, remarks: $remarks, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
|
return 'AssetModel(id: $id, assetName: $assetName, assetCode: $assetCode, assetCategoryId: $assetCategoryId, assetCategoryName: $assetCategoryName, assetSubcategoryId: $assetSubcategoryId, assetSubcategoryName: $assetSubcategoryName, locationId: $locationId, locationName: $locationName, brandModel: $brandModel, manufacturer: $manufacturer, serialNumber: $serialNumber, partNumber: $partNumber, departmentId: $departmentId, departmentName: $departmentName, locationDetail: $locationDetail, assignedToUserId: $assignedToUserId, maintenanceInchargeUserId: $maintenanceInchargeUserId, maintenanceFrequencyInDays: $maintenanceFrequencyInDays, maintenanceChecklistJson: $maintenanceChecklistJson, commencementDate: $commencementDate, vendorId: $vendorId, vendorName: $vendorName, poId: $poId, grnId: $grnId, grnItemId: $grnItemId, purchaseDate: $purchaseDate, purchaseCost: $purchaseCost, usefulLifeYears: $usefulLifeYears, depreciationMethod: $depreciationMethod, depreciationRate: $depreciationRate, salvageValue: $salvageValue, warrantyExpiryDate: $warrantyExpiryDate, condition: $condition, status: $status, qrCodeValue: $qrCodeValue, disposalDate: $disposalDate, disposalReason: $disposalReason, disposalValue: $disposalValue, remarks: $remarks, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt, maintenance: $maintenance)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1385,9 +1526,10 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
other.assetSubcategoryId == assetSubcategoryId) &&
|
other.assetSubcategoryId == assetSubcategoryId) &&
|
||||||
(identical(other.assetSubcategoryName, assetSubcategoryName) ||
|
(identical(other.assetSubcategoryName, assetSubcategoryName) ||
|
||||||
other.assetSubcategoryName == assetSubcategoryName) &&
|
other.assetSubcategoryName == assetSubcategoryName) &&
|
||||||
(identical(other.plantId, plantId) || other.plantId == plantId) &&
|
(identical(other.locationId, locationId) ||
|
||||||
(identical(other.plantName, plantName) ||
|
other.locationId == locationId) &&
|
||||||
other.plantName == plantName) &&
|
(identical(other.locationName, locationName) ||
|
||||||
|
other.locationName == locationName) &&
|
||||||
(identical(other.brandModel, brandModel) ||
|
(identical(other.brandModel, brandModel) ||
|
||||||
other.brandModel == brandModel) &&
|
other.brandModel == brandModel) &&
|
||||||
(identical(other.manufacturer, manufacturer) ||
|
(identical(other.manufacturer, manufacturer) ||
|
||||||
@ -1400,14 +1542,27 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
other.departmentId == departmentId) &&
|
other.departmentId == departmentId) &&
|
||||||
(identical(other.departmentName, departmentName) ||
|
(identical(other.departmentName, departmentName) ||
|
||||||
other.departmentName == departmentName) &&
|
other.departmentName == departmentName) &&
|
||||||
(identical(other.warehouseId, warehouseId) ||
|
|
||||||
other.warehouseId == warehouseId) &&
|
|
||||||
(identical(other.warehouseName, warehouseName) ||
|
|
||||||
other.warehouseName == warehouseName) &&
|
|
||||||
(identical(other.locationDetail, locationDetail) ||
|
(identical(other.locationDetail, locationDetail) ||
|
||||||
other.locationDetail == locationDetail) &&
|
other.locationDetail == locationDetail) &&
|
||||||
(identical(other.assignedToUserId, assignedToUserId) ||
|
(identical(other.assignedToUserId, assignedToUserId) ||
|
||||||
other.assignedToUserId == assignedToUserId) &&
|
other.assignedToUserId == assignedToUserId) &&
|
||||||
|
(identical(
|
||||||
|
other.maintenanceInchargeUserId,
|
||||||
|
maintenanceInchargeUserId,
|
||||||
|
) ||
|
||||||
|
other.maintenanceInchargeUserId == maintenanceInchargeUserId) &&
|
||||||
|
(identical(
|
||||||
|
other.maintenanceFrequencyInDays,
|
||||||
|
maintenanceFrequencyInDays,
|
||||||
|
) ||
|
||||||
|
other.maintenanceFrequencyInDays ==
|
||||||
|
maintenanceFrequencyInDays) &&
|
||||||
|
const DeepCollectionEquality().equals(
|
||||||
|
other._maintenanceChecklistJson,
|
||||||
|
_maintenanceChecklistJson,
|
||||||
|
) &&
|
||||||
|
(identical(other.commencementDate, commencementDate) ||
|
||||||
|
other.commencementDate == commencementDate) &&
|
||||||
(identical(other.vendorId, vendorId) ||
|
(identical(other.vendorId, vendorId) ||
|
||||||
other.vendorId == vendorId) &&
|
other.vendorId == vendorId) &&
|
||||||
(identical(other.vendorName, vendorName) ||
|
(identical(other.vendorName, vendorName) ||
|
||||||
@ -1447,7 +1602,9 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
(identical(other.createdAt, createdAt) ||
|
(identical(other.createdAt, createdAt) ||
|
||||||
other.createdAt == createdAt) &&
|
other.createdAt == createdAt) &&
|
||||||
(identical(other.updatedAt, updatedAt) ||
|
(identical(other.updatedAt, updatedAt) ||
|
||||||
other.updatedAt == updatedAt));
|
other.updatedAt == updatedAt) &&
|
||||||
|
(identical(other.maintenance, maintenance) ||
|
||||||
|
other.maintenance == maintenance));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -1461,18 +1618,20 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
assetCategoryName,
|
assetCategoryName,
|
||||||
assetSubcategoryId,
|
assetSubcategoryId,
|
||||||
assetSubcategoryName,
|
assetSubcategoryName,
|
||||||
plantId,
|
locationId,
|
||||||
plantName,
|
locationName,
|
||||||
brandModel,
|
brandModel,
|
||||||
manufacturer,
|
manufacturer,
|
||||||
serialNumber,
|
serialNumber,
|
||||||
partNumber,
|
partNumber,
|
||||||
departmentId,
|
departmentId,
|
||||||
departmentName,
|
departmentName,
|
||||||
warehouseId,
|
|
||||||
warehouseName,
|
|
||||||
locationDetail,
|
locationDetail,
|
||||||
assignedToUserId,
|
assignedToUserId,
|
||||||
|
maintenanceInchargeUserId,
|
||||||
|
maintenanceFrequencyInDays,
|
||||||
|
const DeepCollectionEquality().hash(_maintenanceChecklistJson),
|
||||||
|
commencementDate,
|
||||||
vendorId,
|
vendorId,
|
||||||
vendorName,
|
vendorName,
|
||||||
poId,
|
poId,
|
||||||
@ -1495,6 +1654,7 @@ class _$AssetModelImpl implements _AssetModel {
|
|||||||
isActive,
|
isActive,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
|
maintenance,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// Create a copy of AssetModel
|
/// Create a copy of AssetModel
|
||||||
@ -1533,13 +1693,13 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
@JsonKey(name: 'item_subcategory_name', readValue: _readItemSubcategoryName)
|
||||||
final String? assetSubcategoryName,
|
final String? assetSubcategoryName,
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
final int? plantId,
|
final int? locationId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
final String? plantName,
|
final String? locationName,
|
||||||
@JsonKey(name: 'brand_model') final String? brandModel,
|
@JsonKey(name: 'brand_model') final String? brandModel,
|
||||||
final String? manufacturer,
|
final String? manufacturer,
|
||||||
@JsonKey(name: 'serial_number') final String? serialNumber,
|
@JsonKey(name: 'serial_number') final String? serialNumber,
|
||||||
@ -1548,13 +1708,27 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
final int? departmentId,
|
final int? departmentId,
|
||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
final String? departmentName,
|
final String? departmentName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
final int? warehouseId,
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
final String? warehouseName,
|
|
||||||
@JsonKey(name: 'location_detail') final String? locationDetail,
|
@JsonKey(name: 'location_detail') final String? locationDetail,
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
final int? assignedToUserId,
|
final int? assignedToUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_incharge_user_id',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
final int? maintenanceInchargeUserId,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
final int? maintenanceFrequencyInDays,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
final List<AssetMaintenanceChecklistItem>? maintenanceChecklistJson,
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
final DateTime? commencementDate,
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
||||||
final int? vendorId,
|
final int? vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
@JsonKey(name: 'vendor_name', readValue: _readVendorNameFromNested)
|
||||||
@ -1590,6 +1764,12 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
final DateTime? createdAt,
|
final DateTime? createdAt,
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
final DateTime? updatedAt,
|
final DateTime? updatedAt,
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
final AssetMaintenanceSummary? maintenance,
|
||||||
}) = _$AssetModelImpl;
|
}) = _$AssetModelImpl;
|
||||||
|
|
||||||
factory _AssetModel.fromJson(Map<String, dynamic> json) =
|
factory _AssetModel.fromJson(Map<String, dynamic> json) =
|
||||||
@ -1626,14 +1806,14 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
String? get assetSubcategoryName;
|
String? get assetSubcategoryName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'plant_id',
|
name: 'location_id',
|
||||||
readValue: _readPlantId,
|
readValue: _readLocationId,
|
||||||
fromJson: _intFromJsonNullable,
|
fromJson: _intFromJsonNullable,
|
||||||
)
|
)
|
||||||
int? get plantId;
|
int? get locationId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'location_name', readValue: _readLocationName)
|
||||||
String? get plantName;
|
String? get locationName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'brand_model')
|
@JsonKey(name: 'brand_model')
|
||||||
String? get brandModel;
|
String? get brandModel;
|
||||||
@ -1652,18 +1832,31 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
@JsonKey(name: 'department_name', readValue: _readDepartmentName)
|
||||||
String? get departmentName;
|
String? get departmentName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
|
||||||
int? get warehouseId;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
|
||||||
String? get warehouseName;
|
|
||||||
@override
|
|
||||||
@JsonKey(name: 'location_detail')
|
@JsonKey(name: 'location_detail')
|
||||||
String? get locationDetail;
|
String? get locationDetail;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'assigned_to_user_id', fromJson: _intFromJsonNullable)
|
||||||
int? get assignedToUserId;
|
int? get assignedToUserId;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(name: 'maintenance_incharge_user_id', fromJson: _intFromJsonNullable)
|
||||||
|
int? get maintenanceInchargeUserId;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_frequency_in_days',
|
||||||
|
fromJson: _intFromJsonNullable,
|
||||||
|
)
|
||||||
|
int? get maintenanceFrequencyInDays;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance_checklist_json',
|
||||||
|
fromJson: _checklistFromJson,
|
||||||
|
toJson: _checklistToJson,
|
||||||
|
)
|
||||||
|
List<AssetMaintenanceChecklistItem>? get maintenanceChecklistJson;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'commencement_date', fromJson: _dateFromJsonNullable)
|
||||||
|
DateTime? get commencementDate;
|
||||||
|
@override
|
||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable)
|
||||||
int? get vendorId;
|
int? get vendorId;
|
||||||
@override
|
@override
|
||||||
@ -1726,6 +1919,13 @@ abstract class _AssetModel implements AssetModel {
|
|||||||
@override
|
@override
|
||||||
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable)
|
||||||
DateTime? get updatedAt;
|
DateTime? get updatedAt;
|
||||||
|
@override
|
||||||
|
@JsonKey(
|
||||||
|
name: 'maintenance',
|
||||||
|
fromJson: AssetMaintenanceSummary.fromJsonNullable,
|
||||||
|
toJson: AssetMaintenanceSummary.toJsonNullable,
|
||||||
|
)
|
||||||
|
AssetMaintenanceSummary? get maintenance;
|
||||||
|
|
||||||
/// Create a copy of AssetModel
|
/// Create a copy of AssetModel
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -3913,8 +4113,8 @@ mixin _$AssetAlertModel {
|
|||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
||||||
int? get daysRemaining => throw _privateConstructorUsedError;
|
int? get daysRemaining => throw _privateConstructorUsedError;
|
||||||
String? get status => throw _privateConstructorUsedError;
|
String? get status => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'plant_name')
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
String? get plantName => throw _privateConstructorUsedError;
|
String? get locationName => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this AssetAlertModel to a JSON map.
|
/// Serializes this AssetAlertModel to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@ -3948,7 +4148,8 @@ abstract class $AssetAlertModelCopyWith<$Res> {
|
|||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
||||||
int? daysRemaining,
|
int? daysRemaining,
|
||||||
String? status,
|
String? status,
|
||||||
@JsonKey(name: 'plant_name') String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
|
String? locationName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3978,7 +4179,7 @@ class _$AssetAlertModelCopyWithImpl<$Res, $Val extends AssetAlertModel>
|
|||||||
Object? dueDate = freezed,
|
Object? dueDate = freezed,
|
||||||
Object? daysRemaining = freezed,
|
Object? daysRemaining = freezed,
|
||||||
Object? status = freezed,
|
Object? status = freezed,
|
||||||
Object? plantName = freezed,
|
Object? locationName = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(
|
return _then(
|
||||||
_value.copyWith(
|
_value.copyWith(
|
||||||
@ -4026,9 +4227,9 @@ class _$AssetAlertModelCopyWithImpl<$Res, $Val extends AssetAlertModel>
|
|||||||
? _value.status
|
? _value.status
|
||||||
: status // ignore: cast_nullable_to_non_nullable
|
: status // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantName: freezed == plantName
|
locationName: freezed == locationName
|
||||||
? _value.plantName
|
? _value.locationName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: locationName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
)
|
)
|
||||||
as $Val,
|
as $Val,
|
||||||
@ -4060,7 +4261,8 @@ abstract class _$$AssetAlertModelImplCopyWith<$Res>
|
|||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
||||||
int? daysRemaining,
|
int? daysRemaining,
|
||||||
String? status,
|
String? status,
|
||||||
@JsonKey(name: 'plant_name') String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
|
String? locationName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4089,7 +4291,7 @@ class __$$AssetAlertModelImplCopyWithImpl<$Res>
|
|||||||
Object? dueDate = freezed,
|
Object? dueDate = freezed,
|
||||||
Object? daysRemaining = freezed,
|
Object? daysRemaining = freezed,
|
||||||
Object? status = freezed,
|
Object? status = freezed,
|
||||||
Object? plantName = freezed,
|
Object? locationName = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(
|
return _then(
|
||||||
_$AssetAlertModelImpl(
|
_$AssetAlertModelImpl(
|
||||||
@ -4137,9 +4339,9 @@ class __$$AssetAlertModelImplCopyWithImpl<$Res>
|
|||||||
? _value.status
|
? _value.status
|
||||||
: status // ignore: cast_nullable_to_non_nullable
|
: status // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantName: freezed == plantName
|
locationName: freezed == locationName
|
||||||
? _value.plantName
|
? _value.locationName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: locationName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -4163,7 +4365,8 @@ class _$AssetAlertModelImpl implements _AssetAlertModel {
|
|||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
||||||
this.daysRemaining,
|
this.daysRemaining,
|
||||||
this.status,
|
this.status,
|
||||||
@JsonKey(name: 'plant_name') this.plantName,
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
|
this.locationName,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory _$AssetAlertModelImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$AssetAlertModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
@ -4199,12 +4402,12 @@ class _$AssetAlertModelImpl implements _AssetAlertModel {
|
|||||||
@override
|
@override
|
||||||
final String? status;
|
final String? status;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name')
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
final String? plantName;
|
final String? locationName;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AssetAlertModel(id: $id, assetId: $assetId, assetName: $assetName, assetCode: $assetCode, type: $type, title: $title, message: $message, expiryDate: $expiryDate, dueDate: $dueDate, daysRemaining: $daysRemaining, status: $status, plantName: $plantName)';
|
return 'AssetAlertModel(id: $id, assetId: $assetId, assetName: $assetName, assetCode: $assetCode, type: $type, title: $title, message: $message, expiryDate: $expiryDate, dueDate: $dueDate, daysRemaining: $daysRemaining, status: $status, locationName: $locationName)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -4227,8 +4430,8 @@ class _$AssetAlertModelImpl implements _AssetAlertModel {
|
|||||||
(identical(other.daysRemaining, daysRemaining) ||
|
(identical(other.daysRemaining, daysRemaining) ||
|
||||||
other.daysRemaining == daysRemaining) &&
|
other.daysRemaining == daysRemaining) &&
|
||||||
(identical(other.status, status) || other.status == status) &&
|
(identical(other.status, status) || other.status == status) &&
|
||||||
(identical(other.plantName, plantName) ||
|
(identical(other.locationName, locationName) ||
|
||||||
other.plantName == plantName));
|
other.locationName == locationName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -4246,7 +4449,7 @@ class _$AssetAlertModelImpl implements _AssetAlertModel {
|
|||||||
dueDate,
|
dueDate,
|
||||||
daysRemaining,
|
daysRemaining,
|
||||||
status,
|
status,
|
||||||
plantName,
|
locationName,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Create a copy of AssetAlertModel
|
/// Create a copy of AssetAlertModel
|
||||||
@ -4282,7 +4485,8 @@ abstract class _AssetAlertModel implements AssetAlertModel {
|
|||||||
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'days_remaining', fromJson: _intFromJsonNullable)
|
||||||
final int? daysRemaining,
|
final int? daysRemaining,
|
||||||
final String? status,
|
final String? status,
|
||||||
@JsonKey(name: 'plant_name') final String? plantName,
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
|
final String? locationName,
|
||||||
}) = _$AssetAlertModelImpl;
|
}) = _$AssetAlertModelImpl;
|
||||||
|
|
||||||
factory _AssetAlertModel.fromJson(Map<String, dynamic> json) =
|
factory _AssetAlertModel.fromJson(Map<String, dynamic> json) =
|
||||||
@ -4318,8 +4522,8 @@ abstract class _AssetAlertModel implements AssetAlertModel {
|
|||||||
@override
|
@override
|
||||||
String? get status;
|
String? get status;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name')
|
@JsonKey(name: 'location_name', readValue: _readAlertLocationName)
|
||||||
String? get plantName;
|
String? get locationName;
|
||||||
|
|
||||||
/// Create a copy of AssetAlertModel
|
/// Create a copy of AssetAlertModel
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
|||||||
@ -57,18 +57,26 @@ _$AssetModelImpl _$$AssetModelImplFromJson(Map<String, dynamic> json) =>
|
|||||||
),
|
),
|
||||||
assetSubcategoryName:
|
assetSubcategoryName:
|
||||||
_readItemSubcategoryName(json, 'item_subcategory_name') as String?,
|
_readItemSubcategoryName(json, 'item_subcategory_name') as String?,
|
||||||
plantId: _intFromJsonNullable(_readPlantId(json, 'plant_id')),
|
locationId: _intFromJsonNullable(_readLocationId(json, 'location_id')),
|
||||||
plantName: _readPlantName(json, 'plant_name') as String?,
|
locationName: _readLocationName(json, 'location_name') as String?,
|
||||||
brandModel: json['brand_model'] as String?,
|
brandModel: json['brand_model'] as String?,
|
||||||
manufacturer: json['manufacturer'] as String?,
|
manufacturer: json['manufacturer'] as String?,
|
||||||
serialNumber: json['serial_number'] as String?,
|
serialNumber: json['serial_number'] as String?,
|
||||||
partNumber: json['part_number'] as String?,
|
partNumber: json['part_number'] as String?,
|
||||||
departmentId: _intFromJsonNullable(json['department_id']),
|
departmentId: _intFromJsonNullable(json['department_id']),
|
||||||
departmentName: _readDepartmentName(json, 'department_name') as String?,
|
departmentName: _readDepartmentName(json, 'department_name') as String?,
|
||||||
warehouseId: _intFromJsonNullable(json['warehouse_id']),
|
|
||||||
warehouseName: _readWarehouseName(json, 'warehouse_name') as String?,
|
|
||||||
locationDetail: json['location_detail'] as String?,
|
locationDetail: json['location_detail'] as String?,
|
||||||
assignedToUserId: _intFromJsonNullable(json['assigned_to_user_id']),
|
assignedToUserId: _intFromJsonNullable(json['assigned_to_user_id']),
|
||||||
|
maintenanceInchargeUserId: _intFromJsonNullable(
|
||||||
|
json['maintenance_incharge_user_id'],
|
||||||
|
),
|
||||||
|
maintenanceFrequencyInDays: _intFromJsonNullable(
|
||||||
|
json['maintenance_frequency_in_days'],
|
||||||
|
),
|
||||||
|
maintenanceChecklistJson: _checklistFromJson(
|
||||||
|
json['maintenance_checklist_json'],
|
||||||
|
),
|
||||||
|
commencementDate: _dateFromJsonNullable(json['commencement_date']),
|
||||||
vendorId: _intFromJsonNullable(json['vendor_id']),
|
vendorId: _intFromJsonNullable(json['vendor_id']),
|
||||||
vendorName: _readVendorNameFromNested(json, 'vendor_name') as String?,
|
vendorName: _readVendorNameFromNested(json, 'vendor_name') as String?,
|
||||||
poId: _intFromJsonNullable(json['po_id']),
|
poId: _intFromJsonNullable(json['po_id']),
|
||||||
@ -91,10 +99,14 @@ _$AssetModelImpl _$$AssetModelImplFromJson(Map<String, dynamic> json) =>
|
|||||||
isActive: json['is_active'] as bool? ?? true,
|
isActive: json['is_active'] as bool? ?? true,
|
||||||
createdAt: _dateFromJsonNullable(json['created_at']),
|
createdAt: _dateFromJsonNullable(json['created_at']),
|
||||||
updatedAt: _dateFromJsonNullable(json['updated_at']),
|
updatedAt: _dateFromJsonNullable(json['updated_at']),
|
||||||
|
maintenance: AssetMaintenanceSummary.fromJsonNullable(
|
||||||
|
json['maintenance'],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$AssetModelImplToJson(_$AssetModelImpl instance) =>
|
Map<String, dynamic> _$$AssetModelImplToJson(
|
||||||
<String, dynamic>{
|
_$AssetModelImpl instance,
|
||||||
|
) => <String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'asset_name': instance.assetName,
|
'asset_name': instance.assetName,
|
||||||
'asset_code': instance.assetCode,
|
'asset_code': instance.assetCode,
|
||||||
@ -102,18 +114,22 @@ Map<String, dynamic> _$$AssetModelImplToJson(_$AssetModelImpl instance) =>
|
|||||||
'item_category_name': instance.assetCategoryName,
|
'item_category_name': instance.assetCategoryName,
|
||||||
'item_subcategory_id': instance.assetSubcategoryId,
|
'item_subcategory_id': instance.assetSubcategoryId,
|
||||||
'item_subcategory_name': instance.assetSubcategoryName,
|
'item_subcategory_name': instance.assetSubcategoryName,
|
||||||
'plant_id': instance.plantId,
|
'location_id': instance.locationId,
|
||||||
'plant_name': instance.plantName,
|
'location_name': instance.locationName,
|
||||||
'brand_model': instance.brandModel,
|
'brand_model': instance.brandModel,
|
||||||
'manufacturer': instance.manufacturer,
|
'manufacturer': instance.manufacturer,
|
||||||
'serial_number': instance.serialNumber,
|
'serial_number': instance.serialNumber,
|
||||||
'part_number': instance.partNumber,
|
'part_number': instance.partNumber,
|
||||||
'department_id': instance.departmentId,
|
'department_id': instance.departmentId,
|
||||||
'department_name': instance.departmentName,
|
'department_name': instance.departmentName,
|
||||||
'warehouse_id': instance.warehouseId,
|
|
||||||
'warehouse_name': instance.warehouseName,
|
|
||||||
'location_detail': instance.locationDetail,
|
'location_detail': instance.locationDetail,
|
||||||
'assigned_to_user_id': instance.assignedToUserId,
|
'assigned_to_user_id': instance.assignedToUserId,
|
||||||
|
'maintenance_incharge_user_id': instance.maintenanceInchargeUserId,
|
||||||
|
'maintenance_frequency_in_days': instance.maintenanceFrequencyInDays,
|
||||||
|
'maintenance_checklist_json': _checklistToJson(
|
||||||
|
instance.maintenanceChecklistJson,
|
||||||
|
),
|
||||||
|
'commencement_date': instance.commencementDate?.toIso8601String(),
|
||||||
'vendor_id': instance.vendorId,
|
'vendor_id': instance.vendorId,
|
||||||
'vendor_name': instance.vendorName,
|
'vendor_name': instance.vendorName,
|
||||||
'po_id': instance.poId,
|
'po_id': instance.poId,
|
||||||
@ -136,7 +152,8 @@ Map<String, dynamic> _$$AssetModelImplToJson(_$AssetModelImpl instance) =>
|
|||||||
'is_active': instance.isActive,
|
'is_active': instance.isActive,
|
||||||
'created_at': instance.createdAt?.toIso8601String(),
|
'created_at': instance.createdAt?.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||||
};
|
'maintenance': AssetMaintenanceSummary.toJsonNullable(instance.maintenance),
|
||||||
|
};
|
||||||
|
|
||||||
_$AmcContractModelImpl _$$AmcContractModelImplFromJson(
|
_$AmcContractModelImpl _$$AmcContractModelImplFromJson(
|
||||||
Map<String, dynamic> json,
|
Map<String, dynamic> json,
|
||||||
@ -314,7 +331,7 @@ _$AssetAlertModelImpl _$$AssetAlertModelImplFromJson(
|
|||||||
dueDate: _dateFromJsonNullable(json['due_date']),
|
dueDate: _dateFromJsonNullable(json['due_date']),
|
||||||
daysRemaining: _intFromJsonNullable(json['days_remaining']),
|
daysRemaining: _intFromJsonNullable(json['days_remaining']),
|
||||||
status: json['status'] as String?,
|
status: json['status'] as String?,
|
||||||
plantName: json['plant_name'] as String?,
|
locationName: _readAlertLocationName(json, 'location_name') as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$AssetAlertModelImplToJson(
|
Map<String, dynamic> _$$AssetAlertModelImplToJson(
|
||||||
@ -331,5 +348,5 @@ Map<String, dynamic> _$$AssetAlertModelImplToJson(
|
|||||||
'due_date': instance.dueDate?.toIso8601String(),
|
'due_date': instance.dueDate?.toIso8601String(),
|
||||||
'days_remaining': instance.daysRemaining,
|
'days_remaining': instance.daysRemaining,
|
||||||
'status': instance.status,
|
'status': instance.status,
|
||||||
'plant_name': instance.plantName,
|
'location_name': instance.locationName,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,11 +49,32 @@ Object? _readVendorType(Map<dynamic, dynamic> json, String key) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _readPlantName(Map<dynamic, dynamic> json, String key) =>
|
Object? _readLocationDisplayName(
|
||||||
_readNestedName(json, 'plant_name', 'plant');
|
Map<dynamic, dynamic> json,
|
||||||
|
String flatKey,
|
||||||
|
String nestedKey,
|
||||||
|
) {
|
||||||
|
final flat = json[flatKey];
|
||||||
|
if (flat is String && flat.isNotEmpty) return flat;
|
||||||
|
final nested = json[nestedKey];
|
||||||
|
if (nested is Map) {
|
||||||
|
final name = nested['name']?.toString().trim();
|
||||||
|
if (name == null || name.isEmpty) return null;
|
||||||
|
final type = nested['type']?.toString().trim();
|
||||||
|
if (type != null && type.isNotEmpty) {
|
||||||
|
final typeLabel = type[0].toUpperCase() + type.substring(1);
|
||||||
|
return '$name ($typeLabel)';
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Object? _readWarehouseName(Map<dynamic, dynamic> json, String key) =>
|
Object? _readBillingName(Map<dynamic, dynamic> json, String key) =>
|
||||||
_readNestedName(json, 'warehouse_name', 'warehouse');
|
_readLocationDisplayName(json, 'billing_name', 'billing');
|
||||||
|
|
||||||
|
Object? _readShippingName(Map<dynamic, dynamic> json, String key) =>
|
||||||
|
_readLocationDisplayName(json, 'shipping_name', 'shipping');
|
||||||
|
|
||||||
Object? _readItemName(Map<dynamic, dynamic> json, String key) {
|
Object? _readItemName(Map<dynamic, dynamic> json, String key) {
|
||||||
final flat = json['item_name'];
|
final flat = json['item_name'];
|
||||||
@ -154,10 +175,11 @@ class PurchaseOrderModel with _$PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorName) String? vendorName,
|
@JsonKey(name: 'vendor_name', readValue: _readVendorName) String? vendorName,
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType) String? vendorType,
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType) String? vendorType,
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable) int? plantId,
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable) int? billingId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
@JsonKey(name: 'billing_name', readValue: _readBillingName) String? billingName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable) int? warehouseId,
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable) int? shippingId,
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName) String? warehouseName,
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
|
String? shippingName,
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable) int? paymentTermId,
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable) int? paymentTermId,
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable) int? deliveryTermId,
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable) int? deliveryTermId,
|
||||||
@JsonKey(name: 'expected_delivery_date', fromJson: _dateFromJsonNullable)
|
@JsonKey(name: 'expected_delivery_date', fromJson: _dateFromJsonNullable)
|
||||||
@ -172,6 +194,9 @@ class PurchaseOrderModel with _$PurchaseOrderModel {
|
|||||||
double? taxableAmount,
|
double? taxableAmount,
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
||||||
double? taxAmount,
|
double? taxAmount,
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable) double? cgst,
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable) double? sgst,
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable) double? igst,
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
double? totalAmount,
|
double? totalAmount,
|
||||||
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
||||||
@ -265,7 +290,8 @@ class PurchaseOrderListQuery with _$PurchaseOrderListQuery {
|
|||||||
String? search,
|
String? search,
|
||||||
String? status,
|
String? status,
|
||||||
int? vendorId,
|
int? vendorId,
|
||||||
int? plantId,
|
int? billingId,
|
||||||
|
int? shippingId,
|
||||||
String? dateFrom,
|
String? dateFrom,
|
||||||
String? dateTo,
|
String? dateTo,
|
||||||
}) = _PurchaseOrderListQuery;
|
}) = _PurchaseOrderListQuery;
|
||||||
|
|||||||
@ -34,14 +34,14 @@ mixin _$PurchaseOrderModel {
|
|||||||
String? get vendorName => throw _privateConstructorUsedError;
|
String? get vendorName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
String? get vendorType => throw _privateConstructorUsedError;
|
String? get vendorType => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable)
|
||||||
int? get plantId => throw _privateConstructorUsedError;
|
int? get billingId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
String? get plantName => throw _privateConstructorUsedError;
|
String? get billingName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
int? get warehouseId => throw _privateConstructorUsedError;
|
int? get shippingId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
String? get warehouseName => throw _privateConstructorUsedError;
|
String? get shippingName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
int? get paymentTermId => throw _privateConstructorUsedError;
|
int? get paymentTermId => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
||||||
@ -58,6 +58,12 @@ mixin _$PurchaseOrderModel {
|
|||||||
double? get taxableAmount => throw _privateConstructorUsedError;
|
double? get taxableAmount => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
||||||
double? get taxAmount => throw _privateConstructorUsedError;
|
double? get taxAmount => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get cgst => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get sgst => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get igst => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
double? get totalAmount => throw _privateConstructorUsedError;
|
double? get totalAmount => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: 'terms_and_conditions')
|
@JsonKey(name: 'terms_and_conditions')
|
||||||
@ -98,12 +104,13 @@ abstract class $PurchaseOrderModelCopyWith<$Res> {
|
|||||||
String? vendorName,
|
String? vendorName,
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
String? vendorType,
|
String? vendorType,
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable) int? plantId,
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable) int? billingId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
String? billingName,
|
||||||
int? warehouseId,
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
int? shippingId,
|
||||||
String? warehouseName,
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
|
String? shippingName,
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
int? paymentTermId,
|
int? paymentTermId,
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
||||||
@ -118,6 +125,9 @@ abstract class $PurchaseOrderModelCopyWith<$Res> {
|
|||||||
double? otherCharges,
|
double? otherCharges,
|
||||||
@JsonKey(name: 'sub_total', readValue: _readSubTotal) double? taxableAmount,
|
@JsonKey(name: 'sub_total', readValue: _readSubTotal) double? taxableAmount,
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) double? taxAmount,
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) double? taxAmount,
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable) double? cgst,
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable) double? sgst,
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable) double? igst,
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
double? totalAmount,
|
double? totalAmount,
|
||||||
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
||||||
@ -154,10 +164,10 @@ class _$PurchaseOrderModelCopyWithImpl<$Res, $Val extends PurchaseOrderModel>
|
|||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? vendorName = freezed,
|
Object? vendorName = freezed,
|
||||||
Object? vendorType = freezed,
|
Object? vendorType = freezed,
|
||||||
Object? plantId = freezed,
|
Object? billingId = freezed,
|
||||||
Object? plantName = freezed,
|
Object? billingName = freezed,
|
||||||
Object? warehouseId = freezed,
|
Object? shippingId = freezed,
|
||||||
Object? warehouseName = freezed,
|
Object? shippingName = freezed,
|
||||||
Object? paymentTermId = freezed,
|
Object? paymentTermId = freezed,
|
||||||
Object? deliveryTermId = freezed,
|
Object? deliveryTermId = freezed,
|
||||||
Object? expectedDeliveryDate = freezed,
|
Object? expectedDeliveryDate = freezed,
|
||||||
@ -166,6 +176,9 @@ class _$PurchaseOrderModelCopyWithImpl<$Res, $Val extends PurchaseOrderModel>
|
|||||||
Object? otherCharges = freezed,
|
Object? otherCharges = freezed,
|
||||||
Object? taxableAmount = freezed,
|
Object? taxableAmount = freezed,
|
||||||
Object? taxAmount = freezed,
|
Object? taxAmount = freezed,
|
||||||
|
Object? cgst = freezed,
|
||||||
|
Object? sgst = freezed,
|
||||||
|
Object? igst = freezed,
|
||||||
Object? totalAmount = freezed,
|
Object? totalAmount = freezed,
|
||||||
Object? termsAndConditions = freezed,
|
Object? termsAndConditions = freezed,
|
||||||
Object? remarks = freezed,
|
Object? remarks = freezed,
|
||||||
@ -204,21 +217,21 @@ class _$PurchaseOrderModelCopyWithImpl<$Res, $Val extends PurchaseOrderModel>
|
|||||||
? _value.vendorType
|
? _value.vendorType
|
||||||
: vendorType // ignore: cast_nullable_to_non_nullable
|
: vendorType // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantId: freezed == plantId
|
billingId: freezed == billingId
|
||||||
? _value.plantId
|
? _value.billingId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: billingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantName: freezed == plantName
|
billingName: freezed == billingName
|
||||||
? _value.plantName
|
? _value.billingName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: billingName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
warehouseId: freezed == warehouseId
|
shippingId: freezed == shippingId
|
||||||
? _value.warehouseId
|
? _value.shippingId
|
||||||
: warehouseId // ignore: cast_nullable_to_non_nullable
|
: shippingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
warehouseName: freezed == warehouseName
|
shippingName: freezed == shippingName
|
||||||
? _value.warehouseName
|
? _value.shippingName
|
||||||
: warehouseName // ignore: cast_nullable_to_non_nullable
|
: shippingName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
paymentTermId: freezed == paymentTermId
|
paymentTermId: freezed == paymentTermId
|
||||||
? _value.paymentTermId
|
? _value.paymentTermId
|
||||||
@ -252,6 +265,18 @@ class _$PurchaseOrderModelCopyWithImpl<$Res, $Val extends PurchaseOrderModel>
|
|||||||
? _value.taxAmount
|
? _value.taxAmount
|
||||||
: taxAmount // ignore: cast_nullable_to_non_nullable
|
: taxAmount // ignore: cast_nullable_to_non_nullable
|
||||||
as double?,
|
as double?,
|
||||||
|
cgst: freezed == cgst
|
||||||
|
? _value.cgst
|
||||||
|
: cgst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
|
sgst: freezed == sgst
|
||||||
|
? _value.sgst
|
||||||
|
: sgst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
|
igst: freezed == igst
|
||||||
|
? _value.igst
|
||||||
|
: igst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
totalAmount: freezed == totalAmount
|
totalAmount: freezed == totalAmount
|
||||||
? _value.totalAmount
|
? _value.totalAmount
|
||||||
: totalAmount // ignore: cast_nullable_to_non_nullable
|
: totalAmount // ignore: cast_nullable_to_non_nullable
|
||||||
@ -305,12 +330,13 @@ abstract class _$$PurchaseOrderModelImplCopyWith<$Res>
|
|||||||
String? vendorName,
|
String? vendorName,
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
String? vendorType,
|
String? vendorType,
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable) int? plantId,
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable) int? billingId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) String? plantName,
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
String? billingName,
|
||||||
int? warehouseId,
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
int? shippingId,
|
||||||
String? warehouseName,
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
|
String? shippingName,
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
int? paymentTermId,
|
int? paymentTermId,
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
||||||
@ -325,6 +351,9 @@ abstract class _$$PurchaseOrderModelImplCopyWith<$Res>
|
|||||||
double? otherCharges,
|
double? otherCharges,
|
||||||
@JsonKey(name: 'sub_total', readValue: _readSubTotal) double? taxableAmount,
|
@JsonKey(name: 'sub_total', readValue: _readSubTotal) double? taxableAmount,
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) double? taxAmount,
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) double? taxAmount,
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable) double? cgst,
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable) double? sgst,
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable) double? igst,
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
double? totalAmount,
|
double? totalAmount,
|
||||||
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
@JsonKey(name: 'terms_and_conditions') String? termsAndConditions,
|
||||||
@ -360,10 +389,10 @@ class __$$PurchaseOrderModelImplCopyWithImpl<$Res>
|
|||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? vendorName = freezed,
|
Object? vendorName = freezed,
|
||||||
Object? vendorType = freezed,
|
Object? vendorType = freezed,
|
||||||
Object? plantId = freezed,
|
Object? billingId = freezed,
|
||||||
Object? plantName = freezed,
|
Object? billingName = freezed,
|
||||||
Object? warehouseId = freezed,
|
Object? shippingId = freezed,
|
||||||
Object? warehouseName = freezed,
|
Object? shippingName = freezed,
|
||||||
Object? paymentTermId = freezed,
|
Object? paymentTermId = freezed,
|
||||||
Object? deliveryTermId = freezed,
|
Object? deliveryTermId = freezed,
|
||||||
Object? expectedDeliveryDate = freezed,
|
Object? expectedDeliveryDate = freezed,
|
||||||
@ -372,6 +401,9 @@ class __$$PurchaseOrderModelImplCopyWithImpl<$Res>
|
|||||||
Object? otherCharges = freezed,
|
Object? otherCharges = freezed,
|
||||||
Object? taxableAmount = freezed,
|
Object? taxableAmount = freezed,
|
||||||
Object? taxAmount = freezed,
|
Object? taxAmount = freezed,
|
||||||
|
Object? cgst = freezed,
|
||||||
|
Object? sgst = freezed,
|
||||||
|
Object? igst = freezed,
|
||||||
Object? totalAmount = freezed,
|
Object? totalAmount = freezed,
|
||||||
Object? termsAndConditions = freezed,
|
Object? termsAndConditions = freezed,
|
||||||
Object? remarks = freezed,
|
Object? remarks = freezed,
|
||||||
@ -410,21 +442,21 @@ class __$$PurchaseOrderModelImplCopyWithImpl<$Res>
|
|||||||
? _value.vendorType
|
? _value.vendorType
|
||||||
: vendorType // ignore: cast_nullable_to_non_nullable
|
: vendorType // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
plantId: freezed == plantId
|
billingId: freezed == billingId
|
||||||
? _value.plantId
|
? _value.billingId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: billingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantName: freezed == plantName
|
billingName: freezed == billingName
|
||||||
? _value.plantName
|
? _value.billingName
|
||||||
: plantName // ignore: cast_nullable_to_non_nullable
|
: billingName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
warehouseId: freezed == warehouseId
|
shippingId: freezed == shippingId
|
||||||
? _value.warehouseId
|
? _value.shippingId
|
||||||
: warehouseId // ignore: cast_nullable_to_non_nullable
|
: shippingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
warehouseName: freezed == warehouseName
|
shippingName: freezed == shippingName
|
||||||
? _value.warehouseName
|
? _value.shippingName
|
||||||
: warehouseName // ignore: cast_nullable_to_non_nullable
|
: shippingName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
paymentTermId: freezed == paymentTermId
|
paymentTermId: freezed == paymentTermId
|
||||||
? _value.paymentTermId
|
? _value.paymentTermId
|
||||||
@ -458,6 +490,18 @@ class __$$PurchaseOrderModelImplCopyWithImpl<$Res>
|
|||||||
? _value.taxAmount
|
? _value.taxAmount
|
||||||
: taxAmount // ignore: cast_nullable_to_non_nullable
|
: taxAmount // ignore: cast_nullable_to_non_nullable
|
||||||
as double?,
|
as double?,
|
||||||
|
cgst: freezed == cgst
|
||||||
|
? _value.cgst
|
||||||
|
: cgst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
|
sgst: freezed == sgst
|
||||||
|
? _value.sgst
|
||||||
|
: sgst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
|
igst: freezed == igst
|
||||||
|
? _value.igst
|
||||||
|
: igst // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,
|
||||||
totalAmount: freezed == totalAmount
|
totalAmount: freezed == totalAmount
|
||||||
? _value.totalAmount
|
? _value.totalAmount
|
||||||
: totalAmount // ignore: cast_nullable_to_non_nullable
|
: totalAmount // ignore: cast_nullable_to_non_nullable
|
||||||
@ -502,12 +546,13 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) this.vendorId,
|
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) this.vendorId,
|
||||||
@JsonKey(name: 'vendor_name', readValue: _readVendorName) this.vendorName,
|
@JsonKey(name: 'vendor_name', readValue: _readVendorName) this.vendorName,
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType) this.vendorType,
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType) this.vendorType,
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable) this.plantId,
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable) this.billingId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName) this.plantName,
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
this.billingName,
|
||||||
this.warehouseId,
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
this.shippingId,
|
||||||
this.warehouseName,
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
|
this.shippingName,
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
this.paymentTermId,
|
this.paymentTermId,
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
||||||
@ -522,6 +567,9 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
this.otherCharges,
|
this.otherCharges,
|
||||||
@JsonKey(name: 'sub_total', readValue: _readSubTotal) this.taxableAmount,
|
@JsonKey(name: 'sub_total', readValue: _readSubTotal) this.taxableAmount,
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) this.taxAmount,
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal) this.taxAmount,
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable) this.cgst,
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable) this.sgst,
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable) this.igst,
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal) this.totalAmount,
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal) this.totalAmount,
|
||||||
@JsonKey(name: 'terms_and_conditions') this.termsAndConditions,
|
@JsonKey(name: 'terms_and_conditions') this.termsAndConditions,
|
||||||
this.remarks,
|
this.remarks,
|
||||||
@ -560,17 +608,17 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
final String? vendorType;
|
final String? vendorType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable)
|
||||||
final int? plantId;
|
final int? billingId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
final String? plantName;
|
final String? billingName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
final int? warehouseId;
|
final int? shippingId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
final String? warehouseName;
|
final String? shippingName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
final int? paymentTermId;
|
final int? paymentTermId;
|
||||||
@ -596,6 +644,15 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
||||||
final double? taxAmount;
|
final double? taxAmount;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? cgst;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? sgst;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? igst;
|
||||||
|
@override
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
final double? totalAmount;
|
final double? totalAmount;
|
||||||
@override
|
@override
|
||||||
@ -623,7 +680,7 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'PurchaseOrderModel(id: $id, poNo: $poNo, poDate: $poDate, status: $status, vendorId: $vendorId, vendorName: $vendorName, vendorType: $vendorType, plantId: $plantId, plantName: $plantName, warehouseId: $warehouseId, warehouseName: $warehouseName, paymentTermId: $paymentTermId, deliveryTermId: $deliveryTermId, expectedDeliveryDate: $expectedDeliveryDate, discountAmount: $discountAmount, freightCharges: $freightCharges, otherCharges: $otherCharges, taxableAmount: $taxableAmount, taxAmount: $taxAmount, totalAmount: $totalAmount, termsAndConditions: $termsAndConditions, remarks: $remarks, revisionNo: $revisionNo, createdAt: $createdAt, updatedAt: $updatedAt, items: $items)';
|
return 'PurchaseOrderModel(id: $id, poNo: $poNo, poDate: $poDate, status: $status, vendorId: $vendorId, vendorName: $vendorName, vendorType: $vendorType, billingId: $billingId, billingName: $billingName, shippingId: $shippingId, shippingName: $shippingName, paymentTermId: $paymentTermId, deliveryTermId: $deliveryTermId, expectedDeliveryDate: $expectedDeliveryDate, discountAmount: $discountAmount, freightCharges: $freightCharges, otherCharges: $otherCharges, taxableAmount: $taxableAmount, taxAmount: $taxAmount, cgst: $cgst, sgst: $sgst, igst: $igst, totalAmount: $totalAmount, termsAndConditions: $termsAndConditions, remarks: $remarks, revisionNo: $revisionNo, createdAt: $createdAt, updatedAt: $updatedAt, items: $items)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -641,13 +698,14 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
other.vendorName == vendorName) &&
|
other.vendorName == vendorName) &&
|
||||||
(identical(other.vendorType, vendorType) ||
|
(identical(other.vendorType, vendorType) ||
|
||||||
other.vendorType == vendorType) &&
|
other.vendorType == vendorType) &&
|
||||||
(identical(other.plantId, plantId) || other.plantId == plantId) &&
|
(identical(other.billingId, billingId) ||
|
||||||
(identical(other.plantName, plantName) ||
|
other.billingId == billingId) &&
|
||||||
other.plantName == plantName) &&
|
(identical(other.billingName, billingName) ||
|
||||||
(identical(other.warehouseId, warehouseId) ||
|
other.billingName == billingName) &&
|
||||||
other.warehouseId == warehouseId) &&
|
(identical(other.shippingId, shippingId) ||
|
||||||
(identical(other.warehouseName, warehouseName) ||
|
other.shippingId == shippingId) &&
|
||||||
other.warehouseName == warehouseName) &&
|
(identical(other.shippingName, shippingName) ||
|
||||||
|
other.shippingName == shippingName) &&
|
||||||
(identical(other.paymentTermId, paymentTermId) ||
|
(identical(other.paymentTermId, paymentTermId) ||
|
||||||
other.paymentTermId == paymentTermId) &&
|
other.paymentTermId == paymentTermId) &&
|
||||||
(identical(other.deliveryTermId, deliveryTermId) ||
|
(identical(other.deliveryTermId, deliveryTermId) ||
|
||||||
@ -664,6 +722,9 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
other.taxableAmount == taxableAmount) &&
|
other.taxableAmount == taxableAmount) &&
|
||||||
(identical(other.taxAmount, taxAmount) ||
|
(identical(other.taxAmount, taxAmount) ||
|
||||||
other.taxAmount == taxAmount) &&
|
other.taxAmount == taxAmount) &&
|
||||||
|
(identical(other.cgst, cgst) || other.cgst == cgst) &&
|
||||||
|
(identical(other.sgst, sgst) || other.sgst == sgst) &&
|
||||||
|
(identical(other.igst, igst) || other.igst == igst) &&
|
||||||
(identical(other.totalAmount, totalAmount) ||
|
(identical(other.totalAmount, totalAmount) ||
|
||||||
other.totalAmount == totalAmount) &&
|
other.totalAmount == totalAmount) &&
|
||||||
(identical(other.termsAndConditions, termsAndConditions) ||
|
(identical(other.termsAndConditions, termsAndConditions) ||
|
||||||
@ -689,10 +750,10 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
vendorId,
|
vendorId,
|
||||||
vendorName,
|
vendorName,
|
||||||
vendorType,
|
vendorType,
|
||||||
plantId,
|
billingId,
|
||||||
plantName,
|
billingName,
|
||||||
warehouseId,
|
shippingId,
|
||||||
warehouseName,
|
shippingName,
|
||||||
paymentTermId,
|
paymentTermId,
|
||||||
deliveryTermId,
|
deliveryTermId,
|
||||||
expectedDeliveryDate,
|
expectedDeliveryDate,
|
||||||
@ -701,6 +762,9 @@ class _$PurchaseOrderModelImpl extends _PurchaseOrderModel {
|
|||||||
otherCharges,
|
otherCharges,
|
||||||
taxableAmount,
|
taxableAmount,
|
||||||
taxAmount,
|
taxAmount,
|
||||||
|
cgst,
|
||||||
|
sgst,
|
||||||
|
igst,
|
||||||
totalAmount,
|
totalAmount,
|
||||||
termsAndConditions,
|
termsAndConditions,
|
||||||
remarks,
|
remarks,
|
||||||
@ -740,14 +804,14 @@ abstract class _PurchaseOrderModel extends PurchaseOrderModel {
|
|||||||
final String? vendorName,
|
final String? vendorName,
|
||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
final String? vendorType,
|
final String? vendorType,
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable)
|
||||||
final int? plantId,
|
final int? billingId,
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
final String? plantName,
|
final String? billingName,
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
final int? warehouseId,
|
final int? shippingId,
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
final String? warehouseName,
|
final String? shippingName,
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
final int? paymentTermId,
|
final int? paymentTermId,
|
||||||
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'delivery_term_id', fromJson: _intFromJsonNullable)
|
||||||
@ -764,6 +828,12 @@ abstract class _PurchaseOrderModel extends PurchaseOrderModel {
|
|||||||
final double? taxableAmount,
|
final double? taxableAmount,
|
||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
||||||
final double? taxAmount,
|
final double? taxAmount,
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? cgst,
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? sgst,
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable)
|
||||||
|
final double? igst,
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
final double? totalAmount,
|
final double? totalAmount,
|
||||||
@JsonKey(name: 'terms_and_conditions') final String? termsAndConditions,
|
@JsonKey(name: 'terms_and_conditions') final String? termsAndConditions,
|
||||||
@ -802,17 +872,17 @@ abstract class _PurchaseOrderModel extends PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
@JsonKey(name: 'vendor_type', readValue: _readVendorType)
|
||||||
String? get vendorType;
|
String? get vendorType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'billing_id', fromJson: _intFromJsonNullable)
|
||||||
int? get plantId;
|
int? get billingId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'plant_name', readValue: _readPlantName)
|
@JsonKey(name: 'billing_name', readValue: _readBillingName)
|
||||||
String? get plantName;
|
String? get billingName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'shipping_id', fromJson: _intFromJsonNullable)
|
||||||
int? get warehouseId;
|
int? get shippingId;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName)
|
@JsonKey(name: 'shipping_name', readValue: _readShippingName)
|
||||||
String? get warehouseName;
|
String? get shippingName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
@JsonKey(name: 'payment_term_id', fromJson: _intFromJsonNullable)
|
||||||
int? get paymentTermId;
|
int? get paymentTermId;
|
||||||
@ -838,6 +908,15 @@ abstract class _PurchaseOrderModel extends PurchaseOrderModel {
|
|||||||
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
@JsonKey(name: 'tax_total', readValue: _readTaxTotal)
|
||||||
double? get taxAmount;
|
double? get taxAmount;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(name: 'cgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get cgst;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'sgst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get sgst;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'igst', fromJson: _doubleFromJsonNullable)
|
||||||
|
double? get igst;
|
||||||
|
@override
|
||||||
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
@JsonKey(name: 'grand_total', readValue: _readGrandTotal)
|
||||||
double? get totalAmount;
|
double? get totalAmount;
|
||||||
@override
|
@override
|
||||||
@ -1642,7 +1721,8 @@ mixin _$PurchaseOrderListQuery {
|
|||||||
String? get search => throw _privateConstructorUsedError;
|
String? get search => throw _privateConstructorUsedError;
|
||||||
String? get status => throw _privateConstructorUsedError;
|
String? get status => throw _privateConstructorUsedError;
|
||||||
int? get vendorId => throw _privateConstructorUsedError;
|
int? get vendorId => throw _privateConstructorUsedError;
|
||||||
int? get plantId => throw _privateConstructorUsedError;
|
int? get billingId => throw _privateConstructorUsedError;
|
||||||
|
int? get shippingId => throw _privateConstructorUsedError;
|
||||||
String? get dateFrom => throw _privateConstructorUsedError;
|
String? get dateFrom => throw _privateConstructorUsedError;
|
||||||
String? get dateTo => throw _privateConstructorUsedError;
|
String? get dateTo => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@ -1666,7 +1746,8 @@ abstract class $PurchaseOrderListQueryCopyWith<$Res> {
|
|||||||
String? search,
|
String? search,
|
||||||
String? status,
|
String? status,
|
||||||
int? vendorId,
|
int? vendorId,
|
||||||
int? plantId,
|
int? billingId,
|
||||||
|
int? shippingId,
|
||||||
String? dateFrom,
|
String? dateFrom,
|
||||||
String? dateTo,
|
String? dateTo,
|
||||||
});
|
});
|
||||||
@ -1695,7 +1776,8 @@ class _$PurchaseOrderListQueryCopyWithImpl<
|
|||||||
Object? search = freezed,
|
Object? search = freezed,
|
||||||
Object? status = freezed,
|
Object? status = freezed,
|
||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? plantId = freezed,
|
Object? billingId = freezed,
|
||||||
|
Object? shippingId = freezed,
|
||||||
Object? dateFrom = freezed,
|
Object? dateFrom = freezed,
|
||||||
Object? dateTo = freezed,
|
Object? dateTo = freezed,
|
||||||
}) {
|
}) {
|
||||||
@ -1721,9 +1803,13 @@ class _$PurchaseOrderListQueryCopyWithImpl<
|
|||||||
? _value.vendorId
|
? _value.vendorId
|
||||||
: vendorId // ignore: cast_nullable_to_non_nullable
|
: vendorId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantId: freezed == plantId
|
billingId: freezed == billingId
|
||||||
? _value.plantId
|
? _value.billingId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: billingId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
shippingId: freezed == shippingId
|
||||||
|
? _value.shippingId
|
||||||
|
: shippingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
dateFrom: freezed == dateFrom
|
dateFrom: freezed == dateFrom
|
||||||
? _value.dateFrom
|
? _value.dateFrom
|
||||||
@ -1754,7 +1840,8 @@ abstract class _$$PurchaseOrderListQueryImplCopyWith<$Res>
|
|||||||
String? search,
|
String? search,
|
||||||
String? status,
|
String? status,
|
||||||
int? vendorId,
|
int? vendorId,
|
||||||
int? plantId,
|
int? billingId,
|
||||||
|
int? shippingId,
|
||||||
String? dateFrom,
|
String? dateFrom,
|
||||||
String? dateTo,
|
String? dateTo,
|
||||||
});
|
});
|
||||||
@ -1780,7 +1867,8 @@ class __$$PurchaseOrderListQueryImplCopyWithImpl<$Res>
|
|||||||
Object? search = freezed,
|
Object? search = freezed,
|
||||||
Object? status = freezed,
|
Object? status = freezed,
|
||||||
Object? vendorId = freezed,
|
Object? vendorId = freezed,
|
||||||
Object? plantId = freezed,
|
Object? billingId = freezed,
|
||||||
|
Object? shippingId = freezed,
|
||||||
Object? dateFrom = freezed,
|
Object? dateFrom = freezed,
|
||||||
Object? dateTo = freezed,
|
Object? dateTo = freezed,
|
||||||
}) {
|
}) {
|
||||||
@ -1806,9 +1894,13 @@ class __$$PurchaseOrderListQueryImplCopyWithImpl<$Res>
|
|||||||
? _value.vendorId
|
? _value.vendorId
|
||||||
: vendorId // ignore: cast_nullable_to_non_nullable
|
: vendorId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
plantId: freezed == plantId
|
billingId: freezed == billingId
|
||||||
? _value.plantId
|
? _value.billingId
|
||||||
: plantId // ignore: cast_nullable_to_non_nullable
|
: billingId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
shippingId: freezed == shippingId
|
||||||
|
? _value.shippingId
|
||||||
|
: shippingId // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
dateFrom: freezed == dateFrom
|
dateFrom: freezed == dateFrom
|
||||||
? _value.dateFrom
|
? _value.dateFrom
|
||||||
@ -1832,7 +1924,8 @@ class _$PurchaseOrderListQueryImpl implements _PurchaseOrderListQuery {
|
|||||||
this.search,
|
this.search,
|
||||||
this.status,
|
this.status,
|
||||||
this.vendorId,
|
this.vendorId,
|
||||||
this.plantId,
|
this.billingId,
|
||||||
|
this.shippingId,
|
||||||
this.dateFrom,
|
this.dateFrom,
|
||||||
this.dateTo,
|
this.dateTo,
|
||||||
});
|
});
|
||||||
@ -1850,7 +1943,9 @@ class _$PurchaseOrderListQueryImpl implements _PurchaseOrderListQuery {
|
|||||||
@override
|
@override
|
||||||
final int? vendorId;
|
final int? vendorId;
|
||||||
@override
|
@override
|
||||||
final int? plantId;
|
final int? billingId;
|
||||||
|
@override
|
||||||
|
final int? shippingId;
|
||||||
@override
|
@override
|
||||||
final String? dateFrom;
|
final String? dateFrom;
|
||||||
@override
|
@override
|
||||||
@ -1858,7 +1953,7 @@ class _$PurchaseOrderListQueryImpl implements _PurchaseOrderListQuery {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'PurchaseOrderListQuery(page: $page, limit: $limit, search: $search, status: $status, vendorId: $vendorId, plantId: $plantId, dateFrom: $dateFrom, dateTo: $dateTo)';
|
return 'PurchaseOrderListQuery(page: $page, limit: $limit, search: $search, status: $status, vendorId: $vendorId, billingId: $billingId, shippingId: $shippingId, dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1872,7 +1967,10 @@ class _$PurchaseOrderListQueryImpl implements _PurchaseOrderListQuery {
|
|||||||
(identical(other.status, status) || other.status == status) &&
|
(identical(other.status, status) || other.status == status) &&
|
||||||
(identical(other.vendorId, vendorId) ||
|
(identical(other.vendorId, vendorId) ||
|
||||||
other.vendorId == vendorId) &&
|
other.vendorId == vendorId) &&
|
||||||
(identical(other.plantId, plantId) || other.plantId == plantId) &&
|
(identical(other.billingId, billingId) ||
|
||||||
|
other.billingId == billingId) &&
|
||||||
|
(identical(other.shippingId, shippingId) ||
|
||||||
|
other.shippingId == shippingId) &&
|
||||||
(identical(other.dateFrom, dateFrom) ||
|
(identical(other.dateFrom, dateFrom) ||
|
||||||
other.dateFrom == dateFrom) &&
|
other.dateFrom == dateFrom) &&
|
||||||
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||||
@ -1886,7 +1984,8 @@ class _$PurchaseOrderListQueryImpl implements _PurchaseOrderListQuery {
|
|||||||
search,
|
search,
|
||||||
status,
|
status,
|
||||||
vendorId,
|
vendorId,
|
||||||
plantId,
|
billingId,
|
||||||
|
shippingId,
|
||||||
dateFrom,
|
dateFrom,
|
||||||
dateTo,
|
dateTo,
|
||||||
);
|
);
|
||||||
@ -1911,7 +2010,8 @@ abstract class _PurchaseOrderListQuery implements PurchaseOrderListQuery {
|
|||||||
final String? search,
|
final String? search,
|
||||||
final String? status,
|
final String? status,
|
||||||
final int? vendorId,
|
final int? vendorId,
|
||||||
final int? plantId,
|
final int? billingId,
|
||||||
|
final int? shippingId,
|
||||||
final String? dateFrom,
|
final String? dateFrom,
|
||||||
final String? dateTo,
|
final String? dateTo,
|
||||||
}) = _$PurchaseOrderListQueryImpl;
|
}) = _$PurchaseOrderListQueryImpl;
|
||||||
@ -1927,7 +2027,9 @@ abstract class _PurchaseOrderListQuery implements PurchaseOrderListQuery {
|
|||||||
@override
|
@override
|
||||||
int? get vendorId;
|
int? get vendorId;
|
||||||
@override
|
@override
|
||||||
int? get plantId;
|
int? get billingId;
|
||||||
|
@override
|
||||||
|
int? get shippingId;
|
||||||
@override
|
@override
|
||||||
String? get dateFrom;
|
String? get dateFrom;
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -16,10 +16,10 @@ _$PurchaseOrderModelImpl _$$PurchaseOrderModelImplFromJson(
|
|||||||
vendorId: _intFromJsonNullable(json['vendor_id']),
|
vendorId: _intFromJsonNullable(json['vendor_id']),
|
||||||
vendorName: _readVendorName(json, 'vendor_name') as String?,
|
vendorName: _readVendorName(json, 'vendor_name') as String?,
|
||||||
vendorType: _readVendorType(json, 'vendor_type') as String?,
|
vendorType: _readVendorType(json, 'vendor_type') as String?,
|
||||||
plantId: _intFromJsonNullable(json['plant_id']),
|
billingId: _intFromJsonNullable(json['billing_id']),
|
||||||
plantName: _readPlantName(json, 'plant_name') as String?,
|
billingName: _readBillingName(json, 'billing_name') as String?,
|
||||||
warehouseId: _intFromJsonNullable(json['warehouse_id']),
|
shippingId: _intFromJsonNullable(json['shipping_id']),
|
||||||
warehouseName: _readWarehouseName(json, 'warehouse_name') as String?,
|
shippingName: _readShippingName(json, 'shipping_name') as String?,
|
||||||
paymentTermId: _intFromJsonNullable(json['payment_term_id']),
|
paymentTermId: _intFromJsonNullable(json['payment_term_id']),
|
||||||
deliveryTermId: _intFromJsonNullable(json['delivery_term_id']),
|
deliveryTermId: _intFromJsonNullable(json['delivery_term_id']),
|
||||||
expectedDeliveryDate: _dateFromJsonNullable(json['expected_delivery_date']),
|
expectedDeliveryDate: _dateFromJsonNullable(json['expected_delivery_date']),
|
||||||
@ -28,6 +28,9 @@ _$PurchaseOrderModelImpl _$$PurchaseOrderModelImplFromJson(
|
|||||||
otherCharges: _doubleFromJsonNullable(json['other_charges']),
|
otherCharges: _doubleFromJsonNullable(json['other_charges']),
|
||||||
taxableAmount: (_readSubTotal(json, 'sub_total') as num?)?.toDouble(),
|
taxableAmount: (_readSubTotal(json, 'sub_total') as num?)?.toDouble(),
|
||||||
taxAmount: (_readTaxTotal(json, 'tax_total') as num?)?.toDouble(),
|
taxAmount: (_readTaxTotal(json, 'tax_total') as num?)?.toDouble(),
|
||||||
|
cgst: _doubleFromJsonNullable(json['cgst']),
|
||||||
|
sgst: _doubleFromJsonNullable(json['sgst']),
|
||||||
|
igst: _doubleFromJsonNullable(json['igst']),
|
||||||
totalAmount: (_readGrandTotal(json, 'grand_total') as num?)?.toDouble(),
|
totalAmount: (_readGrandTotal(json, 'grand_total') as num?)?.toDouble(),
|
||||||
termsAndConditions: json['terms_and_conditions'] as String?,
|
termsAndConditions: json['terms_and_conditions'] as String?,
|
||||||
remarks: json['remarks'] as String?,
|
remarks: json['remarks'] as String?,
|
||||||
@ -53,10 +56,10 @@ Map<String, dynamic> _$$PurchaseOrderModelImplToJson(
|
|||||||
'vendor_id': instance.vendorId,
|
'vendor_id': instance.vendorId,
|
||||||
'vendor_name': instance.vendorName,
|
'vendor_name': instance.vendorName,
|
||||||
'vendor_type': instance.vendorType,
|
'vendor_type': instance.vendorType,
|
||||||
'plant_id': instance.plantId,
|
'billing_id': instance.billingId,
|
||||||
'plant_name': instance.plantName,
|
'billing_name': instance.billingName,
|
||||||
'warehouse_id': instance.warehouseId,
|
'shipping_id': instance.shippingId,
|
||||||
'warehouse_name': instance.warehouseName,
|
'shipping_name': instance.shippingName,
|
||||||
'payment_term_id': instance.paymentTermId,
|
'payment_term_id': instance.paymentTermId,
|
||||||
'delivery_term_id': instance.deliveryTermId,
|
'delivery_term_id': instance.deliveryTermId,
|
||||||
'expected_delivery_date': instance.expectedDeliveryDate?.toIso8601String(),
|
'expected_delivery_date': instance.expectedDeliveryDate?.toIso8601String(),
|
||||||
@ -65,6 +68,9 @@ Map<String, dynamic> _$$PurchaseOrderModelImplToJson(
|
|||||||
'other_charges': instance.otherCharges,
|
'other_charges': instance.otherCharges,
|
||||||
'sub_total': instance.taxableAmount,
|
'sub_total': instance.taxableAmount,
|
||||||
'tax_total': instance.taxAmount,
|
'tax_total': instance.taxAmount,
|
||||||
|
'cgst': instance.cgst,
|
||||||
|
'sgst': instance.sgst,
|
||||||
|
'igst': instance.igst,
|
||||||
'grand_total': instance.totalAmount,
|
'grand_total': instance.totalAmount,
|
||||||
'terms_and_conditions': instance.termsAndConditions,
|
'terms_and_conditions': instance.termsAndConditions,
|
||||||
'remarks': instance.remarks,
|
'remarks': instance.remarks,
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import '../../modules/dashboard/presentation/screens/dashboard_screen.dart';
|
|||||||
import '../../modules/assets/presentation/screens/asset_alerts_screen.dart';
|
import '../../modules/assets/presentation/screens/asset_alerts_screen.dart';
|
||||||
import '../../modules/assets/presentation/screens/asset_detail_screen.dart';
|
import '../../modules/assets/presentation/screens/asset_detail_screen.dart';
|
||||||
import '../../modules/assets/presentation/screens/asset_list_screen.dart';
|
import '../../modules/assets/presentation/screens/asset_list_screen.dart';
|
||||||
|
import '../../modules/assets/presentation/screens/asset_maintenance_screen.dart';
|
||||||
import '../../modules/auth/presentation/screens/change_password_screen.dart';
|
import '../../modules/auth/presentation/screens/change_password_screen.dart';
|
||||||
import '../../modules/auth/presentation/screens/forgot_password_screen.dart';
|
import '../../modules/auth/presentation/screens/forgot_password_screen.dart';
|
||||||
import '../../modules/auth/presentation/screens/login_screen.dart';
|
import '../../modules/auth/presentation/screens/login_screen.dart';
|
||||||
@ -298,6 +299,10 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
path: 'alerts',
|
path: 'alerts',
|
||||||
builder: (context, state) => const AssetAlertsScreen(),
|
builder: (context, state) => const AssetAlertsScreen(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: 'maintenance',
|
||||||
|
builder: (context, state) => const AssetMaintenanceScreen(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: ':id',
|
path: ':id',
|
||||||
builder: (context, state) =>
|
builder: (context, state) =>
|
||||||
|
|||||||
@ -60,6 +60,12 @@ const List<MenuItem> appMenuItems = [
|
|||||||
route: RouteConstants.assetAlerts,
|
route: RouteConstants.assetAlerts,
|
||||||
module: 'assets',
|
module: 'assets',
|
||||||
),
|
),
|
||||||
|
MenuItem(
|
||||||
|
label: 'My Maintenance',
|
||||||
|
icon: Icons.build_outlined,
|
||||||
|
route: RouteConstants.assetMaintenance,
|
||||||
|
module: 'assets',
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
MenuItem(
|
MenuItem(
|
||||||
|
|||||||
@ -41,8 +41,11 @@ class AppResponsiveFilterBar extends StatelessWidget {
|
|||||||
final hasTrailing = trailing != null;
|
final hasTrailing = trailing != null;
|
||||||
|
|
||||||
if (maxWidth >= _rowBreakpoint) {
|
if (maxWidth >= _rowBreakpoint) {
|
||||||
|
final alignWithLabeledFilters = filters.isNotEmpty;
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: crossAxisAlignment,
|
crossAxisAlignment: alignWithLabeledFilters
|
||||||
|
? crossAxisAlignment
|
||||||
|
: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(flex: searchFlex, child: search),
|
Expanded(flex: searchFlex, child: search),
|
||||||
for (final filter in filters) ...[
|
for (final filter in filters) ...[
|
||||||
@ -52,7 +55,7 @@ class AppResponsiveFilterBar extends StatelessWidget {
|
|||||||
if (hasTrailing) ...[
|
if (hasTrailing) ...[
|
||||||
SizedBox(width: spacing),
|
SizedBox(width: spacing),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8),
|
padding: EdgeInsets.only(top: alignWithLabeledFilters ? 8 : 0),
|
||||||
child: trailing!,
|
child: trailing!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -61,6 +64,7 @@ class AppResponsiveFilterBar extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (maxWidth >= _stackBreakpoint) {
|
if (maxWidth >= _stackBreakpoint) {
|
||||||
|
final alignWithLabeledFilters = filters.isNotEmpty;
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
@ -69,6 +73,7 @@ class AppResponsiveFilterBar extends StatelessWidget {
|
|||||||
Wrap(
|
Wrap(
|
||||||
spacing: spacing,
|
spacing: spacing,
|
||||||
runSpacing: runSpacing,
|
runSpacing: runSpacing,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
for (final filter in filters)
|
for (final filter in filters)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@ -87,7 +92,9 @@ class AppResponsiveFilterBar extends StatelessWidget {
|
|||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 8),
|
padding: EdgeInsets.only(
|
||||||
|
top: alignWithLabeledFilters ? 8 : 0,
|
||||||
|
),
|
||||||
child: trailing!,
|
child: trailing!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class AppSearchExportBar extends StatelessWidget {
|
|||||||
hintText: searchHint,
|
hintText: searchHint,
|
||||||
prefixIcon: const Icon(Icons.search, size: 20),
|
prefixIcon: const Icon(Icons.search, size: 20),
|
||||||
isDense: true,
|
isDense: true,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||||
),
|
),
|
||||||
onChanged: onSearch,
|
onChanged: onSearch,
|
||||||
);
|
);
|
||||||
@ -41,7 +42,9 @@ class AppSearchExportBar extends StatelessWidget {
|
|||||||
return AppResponsiveFilterBar(
|
return AppResponsiveFilterBar(
|
||||||
search: searchField,
|
search: searchField,
|
||||||
trailing: showExport
|
trailing: showExport
|
||||||
? OutlinedButton.icon(
|
? SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: OutlinedButton.icon(
|
||||||
onPressed: isExporting ? null : onExport,
|
onPressed: isExporting ? null : onExport,
|
||||||
icon: isExporting
|
icon: isExporting
|
||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
@ -51,6 +54,7 @@ class AppSearchExportBar extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
: const Icon(Icons.download_outlined, size: 18),
|
: const Icon(Icons.download_outlined, size: 18),
|
||||||
label: Text(isExporting ? 'Exporting...' : 'Export'),
|
label: Text(isExporting ? 'Exporting...' : 'Export'),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user