|
|
|
@ -1,16 +1,29 @@
|
|
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
import 'dart:typed_data';
|
|
|
|
|
|
|
|
|
|
import 'package:easy_localization/src/public_ext.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/colors.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/date_uitl.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/utils.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_attachement_list_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_pr_action_history_list_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_pr_information_list.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart';
|
|
|
|
|
import 'package:open_file/open_file.dart';
|
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
|
|
|
|
|
|
class ItemHistoryScreenParams {
|
|
|
|
|
String? title;
|
|
|
|
@ -21,8 +34,10 @@ class ItemHistoryScreenParams {
|
|
|
|
|
int? pOrgId;
|
|
|
|
|
bool isPRInfo;
|
|
|
|
|
GetPRInformationList? getPRInformationList;
|
|
|
|
|
String pOLineID;
|
|
|
|
|
|
|
|
|
|
ItemHistoryScreenParams({@required this.title, this.isItemHistory = true, this.isMO = true, this.isPRInfo = false, this.getPRInformationList, this.pItemId, this.pPoHeaderId, this.pOrgId});
|
|
|
|
|
ItemHistoryScreenParams(
|
|
|
|
|
{@required this.title, this.isItemHistory = true, this.isMO = true, this.isPRInfo = false, this.getPRInformationList, this.pItemId, this.pPoHeaderId, this.pOrgId, this.pOLineID = ""});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ItemHistoryScreen extends StatefulWidget {
|
|
|
|
@ -40,6 +55,9 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
List<GetMoItemHistoryList> moItemHistoryList = [];
|
|
|
|
|
List<GetPoItemHistoryList> poItemHistoryList = [];
|
|
|
|
|
List<GetQuotationAnalysisList> quotationAnalysisList = [];
|
|
|
|
|
List<GetPRActionHistoryList> actionHistoryList = [];
|
|
|
|
|
List<GetAttachementList> getAttachmentList = [];
|
|
|
|
|
int tabIndex = 0;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
@ -49,6 +67,7 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
super.dispose();
|
|
|
|
|
actionHistoryList.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loadData() {
|
|
|
|
@ -60,6 +79,34 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void getActionsDataFromApi() async {
|
|
|
|
|
if (actionHistoryList.isEmpty) {
|
|
|
|
|
try {
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
actionHistoryList = await WorkListApiClient().getActionHistoryForPR(_screenParams!.pOLineID);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
setState(() {});
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
Utils.handleException(ex, context, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void getAttachmentsDataFromApi() async {
|
|
|
|
|
if (getAttachmentList.isEmpty) {
|
|
|
|
|
try {
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
getAttachmentList = await WorkListApiClient().getPRAttachments(_screenParams!.pOLineID!);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
setState(() {});
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
Utils.handleException(ex, context, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void getDataFromApi() async {
|
|
|
|
|
try {
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
@ -88,7 +135,7 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
appBar: AppBarWidget(context, title: _screenParams?.title ?? ""),
|
|
|
|
|
backgroundColor: Colors.white,
|
|
|
|
|
body: ListView(
|
|
|
|
|
padding: const EdgeInsets.all(21),
|
|
|
|
|
padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21),
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
children: [
|
|
|
|
|
if (_screenParams!.isPRInfo) prLinesDataView(),
|
|
|
|
@ -102,7 +149,37 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget prLinesDataView() {
|
|
|
|
|
return ListView.separated(
|
|
|
|
|
return Column(
|
|
|
|
|
children: [
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
|
|
|
|
|
decoration: const BoxDecoration(
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
bottomLeft: Radius.circular(25),
|
|
|
|
|
bottomRight: Radius.circular(25),
|
|
|
|
|
),
|
|
|
|
|
gradient: LinearGradient(
|
|
|
|
|
transform: GradientRotation(.83),
|
|
|
|
|
begin: Alignment.topRight,
|
|
|
|
|
end: Alignment.bottomLeft,
|
|
|
|
|
colors: [
|
|
|
|
|
MyColors.gradiantEndColor,
|
|
|
|
|
MyColors.gradiantStartColor,
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
myTab(LocaleKeys.info.tr(), 0),
|
|
|
|
|
myTab(LocaleKeys.actions.tr(), 1),
|
|
|
|
|
myTab(LocaleKeys.attachments.tr(), 2),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21),
|
|
|
|
|
if (tabIndex == 0)
|
|
|
|
|
ListView.separated(
|
|
|
|
|
padding: const EdgeInsets.all(21),
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
itemBuilder: (cxt, index) => Column(
|
|
|
|
@ -121,13 +198,183 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
),
|
|
|
|
|
ItemDetailGrid(
|
|
|
|
|
ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""),
|
|
|
|
|
Container(),
|
|
|
|
|
ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""),
|
|
|
|
|
isItLast: true,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
).objectContainerView(),
|
|
|
|
|
separatorBuilder: (cxt, index) => 12.height,
|
|
|
|
|
itemCount: _screenParams!.getPRInformationList!.pRLines!.length);
|
|
|
|
|
itemCount: _screenParams!.getPRInformationList!.pRLines!.length),
|
|
|
|
|
if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21),
|
|
|
|
|
if (tabIndex == 2) getPRAttachments(),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String determineFileIcon(String fileContentType) {
|
|
|
|
|
String icon = "";
|
|
|
|
|
switch (fileContentType) {
|
|
|
|
|
case "pdf":
|
|
|
|
|
icon = "assets/images/pdf.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "xls":
|
|
|
|
|
icon = "assets/images/xls.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "xlsx":
|
|
|
|
|
icon = "assets/images/xls.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "png":
|
|
|
|
|
icon = "assets/images/png.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "jpg":
|
|
|
|
|
icon = "assets/images/jpg.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "jpeg":
|
|
|
|
|
icon = "assets/images/jpg.svg";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return icon;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<String> _createFileFromString(String encodedStr, String ext) async {
|
|
|
|
|
Uint8List bytes = base64.decode(encodedStr);
|
|
|
|
|
String dir = (await getApplicationDocumentsDirectory()).path;
|
|
|
|
|
File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext);
|
|
|
|
|
await file.writeAsBytes(bytes);
|
|
|
|
|
return file.path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget getPRAttachments() {
|
|
|
|
|
return ListView.separated(
|
|
|
|
|
itemCount: getAttachmentList.length,
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
return Row(
|
|
|
|
|
children: [
|
|
|
|
|
SvgPicture.asset(determineFileIcon(getAttachmentList[index].fILECONTENTTYPE ?? "")),
|
|
|
|
|
12.width,
|
|
|
|
|
(getAttachmentList[index].fILENAME ?? "").toText16().expanded,
|
|
|
|
|
],
|
|
|
|
|
).objectContainerView().onPress(() async {
|
|
|
|
|
try {
|
|
|
|
|
String path = await _createFileFromString(getAttachmentList[index].fILEDATA ?? "", getAttachmentList[index].fILECONTENTTYPE ?? "");
|
|
|
|
|
OpenFile.open(path);
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
Utils.showToast("Cannot open file.");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (BuildContext context, int index) => 12.height,
|
|
|
|
|
).paddingAll(21);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget getPRActionsHistory() {
|
|
|
|
|
return SingleChildScrollView(
|
|
|
|
|
child: ListView.separated(
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
itemCount: actionHistoryList.length,
|
|
|
|
|
padding: EdgeInsets.all(21),
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
return showItem(context, actionHistoryList[index], index);
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (BuildContext context, int index) {
|
|
|
|
|
return 12.height;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget showItem(BuildContext context, GetPRActionHistoryList actionHistory, int index) {
|
|
|
|
|
return Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
borderRadius: BorderRadius.circular(10),
|
|
|
|
|
boxShadow: [
|
|
|
|
|
BoxShadow(
|
|
|
|
|
color: const Color(0xff000000).withOpacity(.05),
|
|
|
|
|
blurRadius: 26,
|
|
|
|
|
offset: const Offset(0, -3),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
clipBehavior: Clip.antiAlias,
|
|
|
|
|
child: Stack(
|
|
|
|
|
clipBehavior: Clip.antiAlias,
|
|
|
|
|
children: [
|
|
|
|
|
Positioned(
|
|
|
|
|
left: -20,
|
|
|
|
|
top: -10,
|
|
|
|
|
child: Transform.rotate(
|
|
|
|
|
angle: 15,
|
|
|
|
|
child: Container(
|
|
|
|
|
width: 50,
|
|
|
|
|
height: 30,
|
|
|
|
|
color: getStatusColor(actionHistory.aCTIONCODE!),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Column(
|
|
|
|
|
children: [
|
|
|
|
|
Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
actionHistory.eMPLOYEEIMAGE != null
|
|
|
|
|
? CircularAvatar(url: actionHistory.eMPLOYEEIMAGE ?? "", isImageBase64: true, height: 34, width: 34)
|
|
|
|
|
: CircularAvatar(url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", isImageBase64: false, height: 34, width: 34),
|
|
|
|
|
9.width,
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
actionHistory.nAME!.toText16(),
|
|
|
|
|
if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color),
|
|
|
|
|
4.height,
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
actionHistory.aCTION!.toText10(color: getStatusColor(actionHistory.aCTIONCODE!)),
|
|
|
|
|
8.width,
|
|
|
|
|
if (actionHistory.aPPROVALDATE!.isNotEmpty)
|
|
|
|
|
DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDateddMMyyyy(actionHistory.aPPROVALDATE!), false).toText12(color: MyColors.lightTextColor),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
10.height,
|
|
|
|
|
// getActionDuration(index).toText11(maxLine: 1, color: const Color(0xff1FA269))
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
).paddingOnly(top: 19, left: 16, right: 16, bottom: 12),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Color getStatusColor(String code) {
|
|
|
|
|
if (code == "SUBMIT") {
|
|
|
|
|
return const Color(0xff2E303A);
|
|
|
|
|
} else if (code == "REJECTED") {
|
|
|
|
|
return MyColors.redColor;
|
|
|
|
|
} else if (code == "REJECT") {
|
|
|
|
|
return MyColors.redColor;
|
|
|
|
|
} else if (code == "PENDING") {
|
|
|
|
|
return MyColors.orange;
|
|
|
|
|
} else if (code == "APPROVED" || code == "APPROVE" || code == "ANSWER_INFO") {
|
|
|
|
|
return const Color(0xff1FA269);
|
|
|
|
|
} else if (code == "REQUEST_INFO" || code == "FORWARD") {
|
|
|
|
|
return const Color(0xff2E303A);
|
|
|
|
|
} else if (code != "SUBMIT" && code != "REJECT" && code != "PENDING") {
|
|
|
|
|
return MyColors.orange;
|
|
|
|
|
} else {
|
|
|
|
|
return const Color(0xff2E303A);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget getActionHistory() {
|
|
|
|
|
return Container();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget loadMoItemHistoryData() {
|
|
|
|
@ -266,4 +513,34 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
|
|
|
|
|
separatorBuilder: (cxt, index) => 12.height,
|
|
|
|
|
itemCount: quotationAnalysisList.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget myTab(String title, int index) {
|
|
|
|
|
bool isSelected = (index == tabIndex);
|
|
|
|
|
return Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true),
|
|
|
|
|
4.height,
|
|
|
|
|
Container(
|
|
|
|
|
height: 8,
|
|
|
|
|
width: 8,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
shape: BoxShape.circle,
|
|
|
|
|
color: isSelected ? Colors.white : Colors.transparent,
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
).onPress(() {
|
|
|
|
|
setState(() {
|
|
|
|
|
if (index == 1) {
|
|
|
|
|
getActionsDataFromApi();
|
|
|
|
|
}
|
|
|
|
|
if (index == 2) {
|
|
|
|
|
getAttachmentsDataFromApi();
|
|
|
|
|
}
|
|
|
|
|
tabIndex = index;
|
|
|
|
|
});
|
|
|
|
|
}).expanded;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|