po item history chart and scrollable list view added.

master-Api2.0
Sikander Saleem 11 months ago
parent b06fb6345a
commit 5ecb4845a1

@ -528,7 +528,7 @@
"noWinner": "حزين! لم يفز أحد اليوم.", "noWinner": "حزين! لم يفز أحد اليوم.",
"myTeam": "فريقي", "myTeam": "فريقي",
"youCanPlayDemo": "لكن يمكنك لعب العرض", "youCanPlayDemo": "لكن يمكنك لعب العرض",
"group" : "مجموعة", "group": "مجموعة",
"searchGroup": "مجموعة البحث", "searchGroup": "مجموعة البحث",
"connectHmgWifi": "قم بتوصيل HMG WIFI", "connectHmgWifi": "قم بتوصيل HMG WIFI",
"connectedHmgWifi": "اتصال HMG WIFI", "connectedHmgWifi": "اتصال HMG WIFI",
@ -545,19 +545,26 @@
"pleaseClickButtonToJoinMarathon": "الرجاء الضغط على الزر أدناه للانضمام إلى الماراثون", "pleaseClickButtonToJoinMarathon": "الرجاء الضغط على الزر أدناه للانضمام إلى الماراثون",
"youCannotJoinTheMarathon": "لا يمكنك الانضمام إلى الماراثون لأنك تجاوزت الحد الزمني", "youCannotJoinTheMarathon": "لا يمكنك الانضمام إلى الماراثون لأنك تجاوزت الحد الزمني",
"open": "يفتح", "open": "يفتح",
"requesterOperatingUnit":"وحدة تشغيل مقدم الطلب", "requesterOperatingUnit": "وحدة تشغيل مقدم الطلب",
"prepareEmpNum":"إعداد رقم الموظف", "prepareEmpNum": "إعداد رقم الموظف",
"supplierInfo" : "معلومات المورد", "supplierInfo": "معلومات المورد",
"supplierAcNo": "رقم حساب المورد", "supplierAcNo": "رقم حساب المورد",
"supplierAcName": "اسم حساب المورد", "supplierAcName": "اسم حساب المورد",
"supplierIBAN" : "رقم IBAN للمورد", "supplierIBAN": "رقم IBAN للمورد",
"supplierCRNo" :"رقم السجل التجاري", "supplierCRNo": "رقم السجل التجاري",
"suppliedAcNo" : "رقم الحساب المقدم", "suppliedAcNo": "رقم الحساب المقدم",
"patientRefundInvoice" : "فاتورة استرداد الأموال للمريض", "patientRefundInvoice": "فاتورة استرداد الأموال للمريض",
"patientNumber" : "رقم المريض", "patientNumber": "رقم المريض",
"patientName" : "اسم المريض", "patientName": "اسم المريض",
"invoiceDate" : "تاريخ الفاتورة", "invoiceDate": "تاريخ الفاتورة",
"refundInvoice" :"فاتورة الاسترجاع", "refundInvoice": "فاتورة الاسترجاع",
"hospitalClinic" : "عيادة المستشفى" "hospitalClinic": "عيادة المستشفى",
"graphicalAnalysis": "التحليل الرسومي",
"itemHistoryAnalysis": "تحليل تاريخ العنصر",
"pOno": "امر شراء #",
"oprUnit": "وحدة التشغيل",
"qtyOrdered": "الكمية المطلوبة",
"qtyReceived": "الكمية المستلمة",
"bonusQty": "كمية المكافأة",
"balQty": "كمية التوازن"
} }

@ -564,19 +564,26 @@
"addAtLeastOneAttachment": "Please add at least one attachment.", "addAtLeastOneAttachment": "Please add at least one attachment.",
"pleaseClickButtonToJoinMarathon": "Press the button below to join the Marathon.", "pleaseClickButtonToJoinMarathon": "Press the button below to join the Marathon.",
"youCannotJoinTheMarathon": "You cannot join the Marathon because you have exceeded the time limit.", "youCannotJoinTheMarathon": "You cannot join the Marathon because you have exceeded the time limit.",
"requesterOperatingUnit":"Requester Operating Unit", "requesterOperatingUnit": "Requester Operating Unit",
"prepareEmpNum":"Prepare Employee Num", "prepareEmpNum": "Prepare Employee Num",
"supplierInfo" : "Supplier Information", "supplierInfo": "Supplier Information",
"supplierAcNo": "Supplier Account No", "supplierAcNo": "Supplier Account No",
"supplierAcName":"Supplier Account Name", "supplierAcName": "Supplier Account Name",
"supplierIBAN" : "Supplier IBAN", "supplierIBAN": "Supplier IBAN",
"supplierCRNo" : "CR Number", "supplierCRNo": "CR Number",
"suppliedAcNo" : "Supplied Account No.", "suppliedAcNo": "Supplied Account No.",
"patientRefundInvoice" : "Patient Refund Invoice", "patientRefundInvoice": "Patient Refund Invoice",
"patientNumber" : "Patient Number", "patientNumber": "Patient Number",
"patientName" : "Patient Name", "patientName": "Patient Name",
"invoiceDate" : "Invoice Date", "invoiceDate": "Invoice Date",
"refundInvoice" :"Refund Invoice", "refundInvoice": "Refund Invoice",
"hospitalClinic" : "Hospital Clinic" "hospitalClinic": "Hospital Clinic",
"graphicalAnalysis": "Graphical Analysis",
"itemHistoryAnalysis": "Item History Analysis",
"pOno": "P.O #",
"oprUnit": "Opr. Unit",
"qtyOrdered": "Qty. Ordered",
"qtyReceived": "Qty. Received",
"bonusQty": "Bonus Qty.",
"balQty": "Bal. Qty."
} }

@ -9,9 +9,9 @@ class ApiConsts {
// static String baseUrl = "https://webservices.hmg.com"; // PreProd // static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://hmgwebservices.com"; // Live server // static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrl = "https://mohemm.hmg.com"; // New Live server // static String baseUrl = "https://mohemm.hmg.com"; // New Live server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "http://10.20.200.111:1010/"; // static String baseUrl = "http://10.20.200.111:1010/";
// static String baseUrl = "https://webservices.hmg.com"; // PreProd // static String baseUrl = "https://webservices.hmg.com"; // PreProd

File diff suppressed because it is too large Load Diff

@ -98,6 +98,7 @@ abstract class LocaleKeys {
static const reject = 'reject'; static const reject = 'reject';
static const approve = 'approve'; static const approve = 'approve';
static const cancel = 'cancel'; static const cancel = 'cancel';
static const generate = 'generate';
static const requestedItems = 'requestedItems'; static const requestedItems = 'requestedItems';
static const request = 'request'; static const request = 'request';
static const myRequest = 'myRequest'; static const myRequest = 'myRequest';
@ -403,7 +404,6 @@ abstract class LocaleKeys {
static const purchaseOrder = 'purchaseOrder'; static const purchaseOrder = 'purchaseOrder';
static const ITGForms = 'ITGForms'; static const ITGForms = 'ITGForms';
static const itemCreation = 'itemCreation'; static const itemCreation = 'itemCreation';
static const paymentRequest = 'paymentRequest';
static const stamp = 'stamp'; static const stamp = 'stamp';
static const addFavoriteList = 'addFavoriteList'; static const addFavoriteList = 'addFavoriteList';
static const feedbackUserExperience = 'feedbackUserExperience'; static const feedbackUserExperience = 'feedbackUserExperience';
@ -527,67 +527,31 @@ abstract class LocaleKeys {
static const expiredDocuments = 'expiredDocuments'; static const expiredDocuments = 'expiredDocuments';
static const missingDocuments = 'missingDocuments'; static const missingDocuments = 'missingDocuments';
static const uploadedDocuments = 'uploadedDocuments'; static const uploadedDocuments = 'uploadedDocuments';
static const addAtLeastOneAttachment = 'addAtLeastOneAttachment';
static const manage = 'manage'; static const pleaseClickButtonToJoinMarathon = 'pleaseClickButtonToJoinMarathon';
static const members = 'members'; static const youCannotJoinTheMarathon = 'youCannotJoinTheMarathon';
static const areYouSureWantTodelete = 'areYouSureWantTodelete'; static const open = 'open';
static const groupMembers = "groupMembers"; static const requesterOperatingUnit = 'requesterOperatingUnit';
static const manageGroup = "manageGroup"; static const prepareEmpNum = 'prepareEmpNum';
static const admin = "admin";
static const addUsers ="addUsers";
static const editGroups ="editGroups";
static const groupNameshouldbe ="groupNameshouldbe";
static const enterGroupName ="enterGroupName";
static const groupName ="groupName";
static const enterGroupNamePlease ="enterGroupNamePlease";
static const audioCall = 'audioCall';
static const videoCall ='videoCall';
static const shareScreen ='shareScreen';
static const searchByUserName ='searchByUserName';
static const userSearch ='userSearch';
static const userName ='userName';
static const userId ='userId';
static const addAtLeastOneAttachment ='addAtLeastOneAttachment';
static const pleaseClickButtonToJoinMarathon ='pleaseClickButtonToJoinMarathon';
static const youCannotJoinTheMarathon ='youCannotJoinTheMarathon';
static const open ='open';
static const generate = 'generate';
static const paymentDetails ='paymentDetails';
static const requestNo ='requestNo';
static const requesterEmpNum ='requesterEmpNum';
static const requesterEmpName ='requesterEmpName';
static const prepareEmpName ='prepareEmpName';
static const requesterPositionName ='requesterPositionName';
static const preparePositionName ='preparePositionName';
static const requesterPayrollName ='requesterPayrollName';
static const payingORGName ='payingORGName';
static const requestAmount ='requestAmount';
static const typeofPayment ='typeofPayment';
static const beneficiaryDetails ='beneficiaryDetails';
static const beneficiaryName ='beneficiaryName';
static const idIqama ='idIqama';
static const beneficiaryBankName ='beneficiaryBankName';
static const sadadNumber ='sadadNumber';
static const beneficiaryIBAN ='beneficiaryIBAN';
static const purchaseOrders ='purchaseOrders';
static const pOAmount ='pOAmount';
static const approvalDate ='approvalDate';
static const versionStatus ='versionStatus';
static const supplierNo ='supplierNo';
static const general ="general";
static const supplierInfo = 'supplierInfo'; static const supplierInfo = 'supplierInfo';
static const supplierAcNo = 'supplierAcNo'; static const supplierAcNo = 'supplierAcNo';
static const supplierAcName = 'supplierAcName'; static const supplierAcName = 'supplierAcName';
static const supplierIBAN = 'Supplier IBAN'; static const supplierIBAN = 'supplierIBAN';
static const supplierCRNo = 'CR Number'; static const supplierCRNo = 'supplierCRNo';
static const suppliedAcNo = 'Supplied Account No.'; static const suppliedAcNo = 'suppliedAcNo';
static const patientRefundInvoice = "patientRefundInvoice"; static const patientRefundInvoice = 'patientRefundInvoice';
static const patientNumber = 'Patient Number'; static const patientNumber = 'patientNumber';
static const patientName = 'Patient Name'; static const patientName = 'patientName';
static const invoiceDate = 'Invoice Date'; static const invoiceDate = 'invoiceDate';
static const refundInvoice = 'Refund Invoice'; static const refundInvoice = 'refundInvoice';
static const hospitalClinic = 'Hospital Clinic'; static const hospitalClinic = 'hospitalClinic';
static const requesterOperatingUnit ='requesterOperatingUnit'; static const graphicalAnalysis = 'graphicalAnalysis';
static const prepareEmpNum ='prepareEmpNum'; static const itemHistoryAnalysis = 'itemHistoryAnalysis';
static const pOno = 'pOno';
static const oprUnit = 'oprUnit';
static const qtyOrdered = 'qtyOrdered';
static const qtyReceived = 'qtyReceived';
static const bonusQty = 'bonusQty';
static const balQty = 'balQty';
} }

@ -2,7 +2,8 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:easy_localization/src/public_ext.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
@ -60,13 +61,21 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
int tabIndex = 0; int tabIndex = 0;
PageController controller = PageController(); PageController controller = PageController();
final ScrollController _horizontalScrollController = ScrollController();
final ScrollController _horizontalHeaderScrollController = ScrollController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_horizontalScrollController.addListener(() {
_horizontalHeaderScrollController.jumpTo(_horizontalScrollController.offset);
});
} }
@override @override
void dispose() { void dispose() {
_horizontalScrollController.dispose();
_horizontalHeaderScrollController.dispose();
super.dispose(); super.dispose();
actionHistoryList.clear(); actionHistoryList.clear();
} }
@ -129,23 +138,231 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
} }
} }
TableRow rowChildren(GetPoItemHistoryList poData, int index) {
return TableRow(
decoration: BoxDecoration(color: index % 2 == 0 ? Colors.white : Colors.grey[100]),
children: [
rowCell(poData.cREATIONDATE!, index),
rowCell(poData.pURCHASEPRICE!.toString(), index),
rowCell(poData.sUPPLIER!, index),
rowCell(poData.pONUMBER!.toString(), index),
rowCell(poData.oUNAME!, index),
rowCell(poData.rEVISIONNUM!.toString(), index),
rowCell(poData.bUYER!, index),
rowCell(poData.uOM!, index),
rowCell(poData.qUANTITYORDERED!.toString(), index),
rowCell(poData.qUANTITYRECEIVED!.toString(), index),
rowCell(poData.bONUSQUANTITY!.toString(), index),
rowCell(poData.dISCOUNTPERCENTAGE!.toString(), index),
rowCell(poData.bALANCEQUANTITY!.toString(), index),
rowCell(poData.nETPRICE!.toString(), index),
rowCell(poData.cLOSEDCODE!, index),
],
);
}
Widget rowCell(String data, int index) {
return TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Center(
child: Text(
data,
style: TextStyle(fontSize: 12, color: MyColors.normalTextColor, fontWeight: FontWeight.w500),
),
// data.toText12(color: MyColors.normalTextColor),
).paddingAll(8));
}
Widget headerCell(String data) {
return Container(
padding: const EdgeInsets.only(top: 16, bottom: 16, left: 8, right: 8),
width: 120,
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.grey[300]),
child: data.toText14(color: MyColors.darkIconColor),
);
}
List<Color> gradientColors = [MyColors.gradiantEndColor, MyColors.gradiantEndColor];
LineChartData drawLineChart(List<FlSpot> spots, List<GetPoItemHistoryList> reversedList) {
return LineChartData(
lineTouchData: LineTouchData(enabled: true, touchTooltipData: LineTouchTooltipData(tooltipBgColor: Colors.grey[300])),
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
drawVerticalLine: true,
verticalInterval: 1,
horizontalInterval: 1,
getDrawingVerticalLine: (value) {
return FlLine(color: Color(0xff37434d), strokeWidth: .3);
},
getDrawingHorizontalLine: (value) {
return FlLine(color: Color(0xff37434d), strokeWidth: .3);
},
),
titlesData: FlTitlesData(
show: true,
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
child: Text(reversedList[int.parse(meta.formattedValue)].cREATIONDATE!, style: TextStyle(fontSize: 10)),
);
})),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
child: Text(meta.formattedValue, style: TextStyle(fontSize: 10)),
);
})),
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 15,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
child: Text("", style: TextStyle(fontSize: 10)),
);
})),
),
borderData: FlBorderData(show: true, border: Border.all(color: const Color(0xff37434d))),
minX: 0,
maxX: poItemHistoryList.length.toDouble() - 1,
minY: poItemHistoryList.map((e) => e.pURCHASEPRICE!.toDouble()).reduce((curr, next) => curr < next ? curr : next) - 1,
maxY: poItemHistoryList.map((e) => e.pURCHASEPRICE!.toDouble()).reduce((curr, next) => curr > next ? curr : next) + 1,
lineBarsData: [
LineChartBarData(
spots: spots,
isCurved: true,
gradient: LinearGradient(
colors: [
ColorTween(begin: gradientColors[0], end: gradientColors[1]).lerp(0.2)!,
ColorTween(begin: gradientColors[0], end: gradientColors[1]).lerp(0.2)!,
],
),
barWidth: 2,
isStrokeCapRound: true,
dotData: FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
ColorTween(begin: gradientColors[0], end: gradientColors[1]).lerp(0.2)!.withOpacity(0.1),
ColorTween(begin: gradientColors[0], end: gradientColors[1]).lerp(0.2)!.withOpacity(0.1),
],
),
),
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
loadData(); loadData();
Widget? chartWidget;
if (_screenParams!.isItemHistory && poItemHistoryList.isNotEmpty) {
try {
List<GetPoItemHistoryList> reversedList = poItemHistoryList.reversed.toList();
List<FlSpot> dataPoints = List.generate(
reversedList.length,
(index) => FlSpot(index.toDouble(), reversedList[index].pURCHASEPRICE!.toDouble()),
);
double chartWidth = dataPoints.length * 70.0;
chartWidget = Column(
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.graphicalAnalysis.tr().toText14(color: MyColors.darkIconColor),
SizedBox(
height: 400,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: chartWidth,
padding: const EdgeInsets.all(16.0),
child: LineChart(drawLineChart(dataPoints, reversedList)),
),
),
),
],
);
} catch (ex) {}
}
return Scaffold( return Scaffold(
appBar: AppBarWidget(context, title: _screenParams?.title ?? ""), appBar: AppBarWidget(context, title: _screenParams?.title ?? ""),
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: ListView( body: (_screenParams!.isItemHistory && poItemHistoryList.isNotEmpty)
padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21), ? Column(
physics: const NeverScrollableScrollPhysics(), children: [
children: [ if (chartWidget != null) chartWidget,
if (_screenParams!.isPRInfo) prLinesDataView(), if (poItemHistoryList.isNotEmpty) ...[
if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), LocaleKeys.itemHistoryAnalysis.tr().toText14(color: MyColors.darkIconColor),
if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData(), 16.height,
if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData(), SingleChildScrollView(
if (moItemHistoryList.isEmpty && poItemHistoryList.isEmpty && quotationAnalysisList.isEmpty && !_screenParams!.isPRInfo) Utils.getNoDataWidget(context), scrollDirection: Axis.horizontal,
], physics: const NeverScrollableScrollPhysics(),
), controller: _horizontalHeaderScrollController,
child: Row(
children: [
headerCell(LocaleKeys.creationDate.tr()),
headerCell(LocaleKeys.purchasePrice.tr()),
headerCell(LocaleKeys.supplier.tr()),
headerCell(LocaleKeys.pOno.tr()),
headerCell(LocaleKeys.oprUnit.tr()),
headerCell(LocaleKeys.revision.tr()),
headerCell(LocaleKeys.buyer.tr()),
headerCell(LocaleKeys.uom.tr()),
headerCell(LocaleKeys.qtyOrdered.tr()),
headerCell(LocaleKeys.qtyReceived.tr()),
headerCell(LocaleKeys.bonusQty.tr()),
headerCell(LocaleKeys.discountPer.tr()),
headerCell(LocaleKeys.balQty.tr()),
headerCell(LocaleKeys.netPrice.tr()),
headerCell(LocaleKeys.closureStatus.tr()),
],
),
),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _horizontalScrollController,
child: Table(
defaultColumnWidth: const FixedColumnWidth(120.0),
children: [for (int index = 0; index < poItemHistoryList.length; index++) rowChildren(poItemHistoryList[index], index)],
),
),
).expanded,
],
],
)
: ListView(
padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21),
// physics: const NeverScrollableScrollPhysics(),
children: [
if (_screenParams!.isPRInfo) prLinesDataView(),
if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(),
if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData(),
if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData(),
if (moItemHistoryList.isEmpty && poItemHistoryList.isEmpty && quotationAnalysisList.isEmpty && !_screenParams!.isPRInfo) Utils.getNoDataWidget(context),
],
),
); );
} }

@ -76,6 +76,7 @@ dependencies:
flutter_rating_bar: ^4.0.1 flutter_rating_bar: ^4.0.1
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
pull_to_refresh: ^2.0.0 pull_to_refresh: ^2.0.0
fl_chart: ^0.62.0
# lottie json animations # lottie json animations
lottie: any lottie: any
# Marathon Card Swipe # Marathon Card Swipe

Loading…
Cancel
Save