From 07e22546b52520760316f74c1b61b90654fe916f Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Thu, 25 Mar 2021 17:51:39 +0300 Subject: [PATCH] . . . --- android/app/build.gradle | 2 + android/settings_aar.gradle | 1 + assets/fonts/icomoon.ttf | Bin 0 -> 4148 bytes assets/images/car-accident-icon.png | Bin 0 -> 10873 bytes assets/images/car-have-fault.png | Bin 0 -> 25493 bytes assets/images/check.png | Bin 0 -> 919 bytes assets/images/delivered_logo.png | Bin 0 -> 55460 bytes lib/config/config.dart | 38 +- lib/config/localized_values.dart | 37 + lib/config/shared_pref_kay.dart | 1 + lib/core/model/StatusModel.dart | 11 + .../request_initiate_order_delivery.dart | 10 - .../request_initiate_order_delivery.dart | 12 + .../request_validate_delivery.dart | 12 + .../response_initiate_order_delivery.dart | 0 .../orders/pending_orders_res_model.dart | 5 + .../request_update_driver_location.dart | 10 +- lib/core/service/client/base_app_client.dart | 87 +- .../service/delivery_tracking_services.dart | 133 ++- lib/core/service/orders_service.dart | 26 +- lib/core/viewModels/orders_view_model.dart | 57 +- lib/main.dart | 31 +- .../delivery_verification_page.dart | 453 +++++++++ lib/pages/dashboard/dashboard_screen.dart | 889 +++++++++--------- lib/pages/delivery/delivery_cancel_page.dart | 242 +++++ .../delivery/delivery_confirmed_page.dart | 8 +- lib/pages/delivery/information_page.dart | 234 +++-- lib/uitl/translations_delegate_base.dart | 25 + lib/uitl/utils.dart | 17 + lib/widgets/order/order_info_card.dart | 233 ++--- pubspec.yaml | 12 +- 31 files changed, 1847 insertions(+), 739 deletions(-) create mode 100644 android/settings_aar.gradle create mode 100644 assets/fonts/icomoon.ttf create mode 100644 assets/images/car-accident-icon.png create mode 100644 assets/images/car-have-fault.png create mode 100644 assets/images/check.png create mode 100644 assets/images/delivered_logo.png create mode 100644 lib/core/model/StatusModel.dart delete mode 100644 lib/core/model/initiate_order_delivey/request_initiate_order_delivery.dart create mode 100644 lib/core/model/order_delivey/request_initiate_order_delivery.dart create mode 100644 lib/core/model/order_delivey/request_validate_delivery.dart rename lib/core/model/{initiate_order_delivey => order_delivey}/response_initiate_order_delivery.dart (100%) create mode 100644 lib/pages/authentication/delivery_verification_page.dart create mode 100644 lib/pages/delivery/delivery_cancel_page.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 204fc49..a8fc6a7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -43,6 +43,8 @@ android { targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName + + multiDexEnabled true } buildTypes { diff --git a/android/settings_aar.gradle b/android/settings_aar.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/assets/fonts/icomoon.ttf b/assets/fonts/icomoon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..831c36334f96556178e5cde1659a4b348ce8413d GIT binary patch literal 4148 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 S1sn|)fI0>*-krPhKKTC#sxLGE literal 0 HcmV?d00001 diff --git a/assets/images/car-accident-icon.png b/assets/images/car-accident-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d837377cd4ca296bf09ab7c73864f00128258d61 GIT binary patch literal 10873 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 literal 0 HcmV?d00001 diff --git a/assets/images/car-have-fault.png b/assets/images/car-have-fault.png new file mode 100644 index 0000000000000000000000000000000000000000..b6f6c0d5f316da347cccf035b0b9a1c57141b17e GIT binary patch literal 25493 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 z zz5H;$c#*KY0(+5)snl`>Vkn#CsPXK3L-ngVKQ~6K zR6A{ERE(z^sn5X%DWzg<0HA|Yu`n-@4}O?nJ>oCfPDF8T+!?mJoZpBo8Tg>N%$CR# za=30};-Hv>TAvuyQ_*fGti#5O>GB{yKkde(fb%lLpa}WDgx!c44L_eO*L$}%9%ZYn`EhqL1r+uTWtgL8K;Pni23e?(H z{dN{ha8M!h<@(g)27Zz~O%A{23{_r+Q2JF2r5wXzk*v^SHI&9SCB5x&?RL`REiQyG z8*wtWoYOCYG5db42dj*`P$=tyoUTn_D8HS{jwU)zF(?eqDb&;l!*F2s0u+9*Xc|J! zCzo{<8;?*UIV-92u`e+51h|E9BOlLFVTjbZ#PKA*vIcpMaJiwok00S76ce_l6D zdh+LaIcvn5qHa51FWT?P#mHSR*J{tN!$-r}BquBZ#MzOZL!nyK3=7ocQdBd%%s`tZ z@P=W%t;>7Wy15gvQIPDSe+U%x9xWjt#a53!or(0zb;@zW3RS{#rCMTf9@=q)$dDHF z7n?iP5Y)>(@vP*T(yFTBoUVojHv7*FudvgFs&@)j*7}Dzl~-BM+a!%HgqY}!*B)@> zM3RmGcPa8?-#2h_Pv%*lr|k&H?nzq}P*X8ky~M21^Kns8(QlHqyJM_of8JmXg~PQB zQTZG;);|9XfF2;EM;AFu^4hJJ#^vN@{+g(S@fh}0;!FoRII70-gCYcYoVI$j8rj*k zJ-n7_A~urRMDCZ<8~e&ctx2Mt_O7p9((ZfKf?_uQ*oV>1jVw17u-*^w)Q9~7xph0G~xPJa{q z(gq7v$E3Vyv(7O*B-)LSkJD-~hse3-da=fxi^Z*k^xVyA%6B_LnIq8dwaP)0s!Zk) zfCZ__4=9A)9*FM^n83ci!DFme{0Z5abcN00_FF~*na~|!oQ6&yFA8uK+v^DQ9!{G~ zz=d47w3RtCVjh%?qRF_QME4Zs*5?x*1_e?U8$HMAJ&wqM;5CqFu)&hmR~4WTL%$KfHks#H?D!(>e{n&8KTg6`_g6ndS7g9<7AwQlRzCM-Cq z)Wrq8vh&6PMNjPlxiQJ^qeXq6ePezaCcI|vBr{7*R~;9;l`q5DZJzt1(?GRhB3M#H z-b78!Rap|+lp-l5g%)9~wqS-=4i@&WlTR`Z~gv{A}jqkP3&sf8c4(f%?n{KMi`1B1u&L;-&+PdbGJR_dLmfY|YtGLMFE?&Sn)gllh~!_4f8(nqA*lIz2eQ zO!*0I)5_de*kGSXyEtJjD`VsKTCX%Ht#tfU$yr)jYIZqaQfqa(-oc0wxRKl*O!>}Y z@^rNwfqD@b+4jw~WK!_m3auC$(6UtzT0p)sLbV@=CcwhxT^OW&)V$)eJc#u{_y%04 zN;s5%GJisgZ}5j|DRs^u^Y)(;XSk>=R_RizU>o*qwQsskc3xs0U`Yb-XA$g>hbI|% zLlYn9;p1~RKLljBlp0r- zkh6%~$b?tNh+^0g4?|JZedUVbC)ei$P%W$m4S1l)P=upR_579s8^vx9^gL==E>s>z zGOk#Az`;%GU%g(U$z@E%1CFM1J41)$6buuCO-|qXvUmiSsT0*plJfHlia20l=egjU z>NRpU+9e{fua|v6!4HUR_@Pl@U#?o|Ib8<|V<31I;a-n z-2HJs|HWC|>oIla%R`@nE-@#w^t+-eExFxscz+4BiPc&g$`?BVBCWm64;-4I?cilv ze^E^>>*IvBdZQDtD_+`|LLM4#t6BeW=~we=)qvpMr|*4S#F_HmdKP`Y+KeMBo_W|X z{i}iHdZ&<%-k!t{aKxl@eR@auK}<;jbr-B8GkOeILl+>w3shv|!&Sz}o30FsZ`@2~ z)XNTs|0ZF*Ubo-d{rSP0SCgxlA1$vUZuD)=9DlL-cUI(838gTtA?kNn1r>2CT0A5| z0ngEk_2-iDoX69&PLD_KU{Z|DZ#gq&OJS=OWIO$WnkA>4pUs;aT6I69$gDZO$(R<* zg{d1E4QQ8Px6FMzS#Ni}_nn0n46FFm9G$<&DrzIyO zW(mZ+D3oS=QbQEhe3*@aB6tAQ(}kJtO5uIc_|x6zy{%Ehz+P7ZS2j#%IX&^7mIUVR zI-$52_me9ZHOO$A6%1pgf=KXl#6%_q5fU6eWKB60 z6>-!mLtV*?a@G!^n2YLy;nO!_8i_OuT_l8QXJ)!wz)RuJ>3YeeBTB#K8qo6)E}z9S z?{BEdYL^yki9EG%?c;dp&1Ev$obu5M@wnFtBW*%NL6^Zaao?-i0{^>OxUeTp)zs8&Iqe`(^X(ma+Tp zwn<>_I38bfYzYMCX_(Nb8tUC(!pM+m#Koo5boN>-DC_+dPqwdgl3v(gCotkvYwn zFU+8ZbL07bykJwIQ4rsy5+Ej$agynE-O(q`)}4SmjLoLH;?)RVbw};Z8~o(tu6PCK-S?sYe3~SW;7v~9 zn7fdE4u_=EXy7hBKIbix*;gJ7jv?Q+Gx+oaHD}C8Px0oXNk}&@jFUfR|?zN`Eo-<+9sm|M5Gq5 zjI;dHb;I!x>YE!jq5?!SX?TGs)~_ea=d%<&PozhFyTnEszAzEk7b;L5$AxMi zpW~J3#ZF*QWbqC9IJhCZ0vNeL%I4W$&8dyemTfPdzy@bVnn_0q_!Iy8cWHiQW@U4U z=i_<=*yI5p{q7K8BPOEVMZ)HyaMLG?P)RpRMx%_Pltol7JRBeo^(Ruq#ClUej_3A_ zmC)xtdvP;?w>grUGa(Y4fc}TL=0t2_L4g$8wiuH?CsTvqYf6q!E4S_9ggkkXNdVBJ z_}fHjm6T$8qLeq%yn0VOBA;xl&302js$>!Qbg6c?W~V?*`Qvln2iiVN(C78M+3PUt z=Ycy6%DI?ZDMlH71F!Am0QIIP>3NUyF^TRqS@FL4I3}x0I7^{ne~4{x;3G5)-pn{0 z_K|JJ^$=)~#{-*zdLZgHDU-hdH8l@M6A`h1q4DE|uFp)@(@x5a>n3;K;WaNTbNAyx z45zT!#{dScy2Xh_l)5RoG71Lch7M4XyzA)&SC*1GzOUz;_<+>1wH`bJr>H>JgrtND zaFF?VLs{*^Vqms0u`yJh?sKu)%t=i+Oml?7?i`v7M#7`Q*7ag-4^6NR4HIN->7FxV z`3cNts6b0Vn|wQoU|dzm5dc~o!AMl8Nvxt&{5(1?pQ+I0j2#98zt1MJ%t$?rs}ATK zV%zxdrbOOdF2~;qq~RUEmW&2M1CEY13M7uVWMet&wVSFo*SqQ@%y$zu)btWO(q7Hcyt~-{oz^j znLgX$E;l^f!xyJhNA1m5qF5fc!v}o0U57KWi5dHSal{COFsicwm~bxm=)}8zdDCuS z3|J-(HEt%JJOaa1Y+KZ=PQ|Ry^**7i@*Nr>*8Sn=88mg?=qZG)UU(Ui6S$X#cD_FB zgTU)$tEeBNRH9vA`?TI33HorV^F1KR>g^nN4;=39X{&_%jU#xV#n0POvZJ?OJhC= z>$@HI-S_umB*O3qpUm4Bz2S;cOrZ@1rFAYy4yV{opo&W?_-Zs`*V5>=YxsO4$m4Up z%(-c$+3ih)-=Tpy2U_|2Qq-942t{G0Iw>-1CvGv))A&w~lP`cgG?q7h{>uU7I?Na< z0vp5%$%cp^Qylwc=f_6IyZoug@x_}zC5P2gY@n_XqORySgkbOdZ7!Ct*9_Swo>WNh zrL0ux8iuZ>bM_1J2)_%iS ztu)&*>aw2T@@Sa(Rb5btQqsKKpK1iO z5R=D%Bi5Q-POLYggmg30+AgsTdW1yd7Xd?*OJ8$P^bs0)Zfh4BFfDnXu^S17pd?|j zJjb0H1o+~V>5Pn_a55JBAB-oAeD*lt9eF8(@=YiH%e z*XK%$zAiNFCM2Eskq&iCdyjI+>~k&!S}|C#RGPfm%#U+Gk%S-6fT|Y}t(_ z1=li2SU|7>06YZ460OikxMb^Y zw{qMm-yNi~hp+wlh*;?uX;2V(jW^a>CqG($06sf9boq&J^NMs*0i%+#gSJB(Ial)% z0!~jUE`;dl=;T)CDZ`XaY1+CRDa z8cA3HHcl$+`u*Yz+m|0_2?`slYi$1XdR|e`c>9#GdTdwYQFxpik3hQ>aZo8&sHIyz zKf@nZ)|t|RI!s!7A-mKGqR6p_f+y%G5!;%&AVQXI%D7O?00ub&+^^ah`{&mnGVkr* zs}dJOL8>O9gt4SdFkyO6y|0&_U|DatH0V)uV#^)9id!T*Q|<Mvu+Rym8RX?1otO z_&IP7927@K5|;yC;=H-#MW;+ETWZHXbt7(k-6ZBKx$AlRqtE|Laehd!2QrKHkEb(x zy%dZke>mUA3t}}7GZUS%6@>+#vwuB;RF#r8Q(44xh6(XB&r3}liF4OAuYkCf1|f}D z56iu!r73r5k^^|0y`di3wx5(&IK+`<`S5L98uT!oeY{@i1jB!QiNk~%X89R`IpGFh5SnL=bM7a zIwV-uf^QKrF4L>*hx?7fR7WhNSO8oWJ!CQuKD(p@=^DTzPD$4!*$!g-up(Di6apP_v(f3wfX2yP1WeYB^h$NMC~IOpl- zaP&Do0DsCR7sC(Rf9BN-qR?RDfv=+`v;|J?0XeK=EW}j{bL#{*_b2mW zTJ|I7Y(CGRSE92SGQY=5`(+pJN?f#}$D@)X47+9rBQmb(OTgo1_m6FVv12v0sTE7x zrHzvPOKdn&5U&AL^OC6IxVs_>sAA;V6cLTL+Bui=au!w=i#F%W2gjT)FS8t%6@bpP z;VJuZW31#BIe4|L2Aw`LT7hzGp0)&-?i>>a&-;=vB&mbWmmritFnT!jl%iKBidoy$ z$Ft>28k^>ZhJm)4t2E77o_;lK{Z^IrBC{W7F9)lH47Q65%!LwKl$~3p)wqcAJ9F5U zr#0t4tk>_@kyHy5#qYKSz4GiO3PrWqEQySRb$?@1EtW)QD2L2)AC z5VkyioK)$yza_T_ldETK_Q}rX`ojbuE^;-2r8x z@}+U8;X_=!7tu-UnOa;M?zCJX`Ymj_G>Vn8QE)knnUb7w*jIi7mXT>rJ5wm9lKDt~ zrPf$NAhQyJ7gj-j_2Ha$R7$}I+m}J)z;N#XHR}sX@Qu}I>6i#53ou2@tc%Zk4c)FA z@|g{yv@Fnnd=j5QfEp>f^GI1)nGFRr);)bxS5oZ5eo31+2uP&K?LDOW&Ebj2BBPqP7*0g0&hN0YeGFG-1V7JmnWXR>DLbeX zoXx&8u-$*TPKPUaxFzdQb~#!S*0gF#=kzV7yn%xU{Hm4`FPeaMX;pDwKwK)%gb1!= zqKEzzug;IFD9^LUHV`#Y#ETaj`~Ca7;KOFjy647EtayupST;nN^AM7qQ#?O~BYKdA zD7}aZg1&x}EOE-9(|b%Oka~663=3I`dijE~S#zf+Dd$pz0y=;_$9mzC)NQsEN5+)H zNsWP3VlL>iKl;yjF?h-XtrGURG&Tx&DV7k+MhaMwAA4pC=?$0xLdMe}VtEP2awvVw zLM>Aejl*R3R>Fq`uB;n>U=0l^WW&by&C7~QsT@O=G%Zr+yhZWQ6xgK$b0Ql9=H_WN zZw&$8d6+g4JN zGruo)D&!bzX=$}giNh_LTeR&;j?bcRd~R8_c_yaj7NFV$8k3S{S~>9`&QisDKo?D@ z%6>D1VTra%D_RatEe)yNDAxYrn3D}7q|&e5`GFYu(?)IfBsB+SbB(e{;>5*0YvwdT zLGbfUVCoXl*xIJ)7s2GEim<2F3eY!lPb%gWq0DCiFn4Ym%B$ikitAatmO@OO+l;rd zeBrJSIqomC6KPq`;XxZLpu|kZpzt>oO%gBo1yN8wWxglPq`Y*m_7uBdK%*LU#m@Ch z4PFU%X5MC?Pdck|8YisQFwt6g!xYimt@)^d2SLttEb^cJN z)1`A{%Fo=nlWJs2LpO_HgBl@>+NX`AzdR-dGC(2EYFD43Vb9CI&GFOLC0;@m5IIf>ZHZ?BD#(tKb zbkEUM>2$7%B~+5zo;Jb}E`BT|RTPMS+SQU;fC#49T!9yaU=spmJw+%+ye@uwFs>`t zHvdZ_SKAR)1$o*4caI*IkOq`~bYktdd{kU0X4H%g);1M_x2hjWq~xlerp_+Jt`gaB zSZ&y#*`R#Hl${D@!8O^j1FCp1Auy17Y{;ue!$1@KK{oDf^&I}@e_v)m$)w8PNsWA* zKq5kjkh!Z;cw>KDAu3#Dx%evu=;ky}(o!LZ_YlvhC|}vO zj3>>I^xpwQS|eb(aGGt;RtIo9>@VyS$C#<#WZ&r!ag=vg-x!rv2l3= zZSNek;8Q32rVm6_e#WwyC+nmwDLPwRzavc&-J)3{MnlnkP8et(4;VGg@Lg>ELUcHV zzHeK^qq87b+o5IwJc@>7eY2qp(^TFr4`j`!nd|%OsK!H)UZ3xe{Jg5>GAQM~lCKo+ za9?j?^Oi}#T(QNEPfqe>t%o7I35;kq_dPCAx8~*i>Cd&TcMwWUL7j zxhp``1%7K4O0;*jM4y!dgY2H+KT@8Fj(w&3E)n2Q1*XkM?}M5iU)(9pIFvvq-aOAK zcoKPZ&1@`u8rL&wPTYEp9zAq(<){eRBgp%V$~$czD)lE$5|bKq2TJ59b?8cV_%>3*l>uHZ?n5UNY0Hm0 zB&%$er9>ez74J}EuRc7+>i$w;W{xt_l=RUlDUm-9(#%#kIitQs9l8b=&4x%oSZt?N z^@#fN(0RMt)kYsJz1QSj%j?RWFJ#_Db}k>MO&&O%Ex|`D+5b&Z*))Uc5{EHEvi#Bc z!12Yd+IVFmHPskfVUw1YhWD5*87Vs$Ioa;RRFe%f5&@Gbb)rY4XQ-oZy4RTLr7yIX zWrD<#1Nbe3f9KDipZ>qUU1nxxeo?&GHtG*!Bu&LsEtih*7g{c{JW*1U!NCGmLd@e7 zQJq_^pp=K$MaJK?4Guc@q2_bi+KJDEf%xvU#dUVoX;mkAN>6cH2|V!XXX;+Q-Sv`& z-JmNWIcK*91+fx&vZ^G?@li*n|18^eGuE)7sjh50FL=Hcv5+dpz)lXvN#>-F>UR$U z36tLXGVm>G`KGb5@lEOH+mq(kM;=OaBM3e6xfefTFJk^stJ}dT#Xk+&(n!pmz@W** zP$-O*drZ+~C5o1*8naEY`+cKlLt#3%t9Gee}@4iOyRhE-)o6f5km1J94|*uTxs zHacHnFt>6r9n8A0wZd-DZfO~~gKvXyM*8T#WPg}x#(!0IJW?#ZQ=|rWmS(0wRhSX* z<5nYs5X$MfJj{$7=gwkbWkjB0$sq4E<&pGGl9zv)LAhmJz$FjR+r)8U4!t$Oq$H!? z%-^eo!K6NNamd67SoenqWkn(o-i$(`I~T4Wc{7wZJz!hi@%)A%y3Af#kp&Wkato;e zIF^jqp%skeA>N5);D5}NV0En!j3Ijy2Q#tp3Wj#8 z{C$u3_eU+nurT3;KYNvJJ!`!!JQD;RtdvxJ?uT(QV{z~UOF`_B4{;;eu4^#)*h(x; zG?XT(nL{Q~?nUJu{l+oCGL$-g`OZ^4q;f+(KZl9(D0o}6dr>ST06|;Vq72E z6OX38*MKWD(A)(ZZRm0w02a%DpnHI*HMA8d|Hj8HjW6%LQl=Kyk;HUbxf?1n>fCAg z)jdDYHSAjkL#e3zeom@%@mCy8qkHy%xpKqIEZbqBJ5v7MlhVr8sXvm$6{nwtI4 zk7_5{9AJuBn95wYncYD})m?~BOl`35@dYIwtdW-tYAu)i`z1lRuXF8sI%F+`WFK!v z{Br`-42@s^N<&SyUs!rYMZb1Oq<=<4VPIh3vc`9NNT5T3c5WGKV2q55i*(Bvq6dv> z6t1GQ)STYSnnhgwQAYeW<9BO8jLa+%H!lB9oer#pt9pOIbYi{G7Lms`s(P#%cEYMB zg!xiFL7M@+c8rXZPJkhxo|UC);Ox?5%`Z(jfY-#Aazs82)?5{sO#wDL*fcC1{$K!C z`SlT?P6CQO0^HG|2Y&`)_+m_wO~c46%+1fUca08*Y(*xLSAZ{thg_OC)W6#3s5m9WYvobi;{lgQfl@+XBi6FCE}>lHbT|ru1POLdT~s}5`_e% zy)Q%Wblgq(=XARXs%a081z zunKcXJeKK`d90Hb7~9R4@mU3W7`7w~!VyJ7&VGXPSDLXKX|~)Yk^Rcxmm~jE0RRA$ z<*e^r=3+Hcra4MCLAs{XU?HT%e4*oVK~vZl!znxYN3s`x}-&s~O5k0=|hHWmFY zITp{2{zB%`%}Q5VwvVb#%MLY-O3mB2uJ$mOj*-+?1r}J^-UGG13?t>(hPq-#!Ap87 zB1>~2;?K|u>4nmBg*yKIEY%)3VlGo>#npWm^&@OGoGS}rCb+m@jFL=;(GPJ@;hwx+ zyLrNWp~l|2OA;&BzVE=%H(k<$zD!{Q*xG&584q`%ax$Jw>l2W zBR(Ys;H~!Tk&VW1&4uBcWEayy9#j`kd-Ye}55QkUfn$8&^h!}O)uHs_(+uLRls5}3!OA7+>TjoI7GfZ6Vbfs+DFD8Dq(I zb8ED625|qPSIx|6q)AcFEu9Q7t3CdbgdEl{5x8b#Y;@Y@e6no5cR;P{M^MF%tsc>B zkD?$2B3u_U^snC)guQ6av1I?e6?=)Zx>EX~o5)jC7?> zrt)?vKRaBTSlOHY5NtxGu#!rJ4FNNJtWDQQAlI!tHX*uB{)`MXCp z^wvZ>U2b$v8+Fm*`u|zKM5t&hP6mEaq7!8P7Cn6|vr?jvlg?p{Cay0Cn5iW8{$4F9 zuTXM+y_(~BGtxzyOz*L$d0m@PdtVj17cL;-4t|3VmbH|9wDfhQj)g_9C-NL1QJgm< zV%>a594vQlRW}U-?_aE>`8Xc{&toE;m~7m&Cr%iXnu<*=K%58Dr%UV_96KsG)Ky^U zb^op}YwDI#lU7rX*J)n3w{SQokfhu0()u<#DfoH(U66&AeYv{hW^^U5KNx7=McD@8 z^(Dy{6f59!V4uNF)}-!s6tSy}vJqXZgXAiyDoI4~Ss^8suhQ~;z`>NzoDG1-I%F8Y0 zICEQm!?jFN-xz>)ZynLkjBcxvYMts#R4<1Z|FI%^{sn{G^?>Ve-SSCq*a z?XWX;yxm-G6z-1I0JDFp+}=ifHbDRsZkgL-Yj3HTs5Z>5JPub|&l`JSNRG@y zQidA?sD?>&$B-Cs2Th1g;+C4J(SdmzohK>zS%E>vMMuBQZ@IXg%-HonNqrv=!omS} z7}pdZBe?2p!ZdBeScXy-rHgMbh^{{1h2)lfr2=5P=- z)9CD(pu1AKQH6rroCjEi<7+dn?q&`uDc-!Sv7D`ER%;92AEEYQVq#KRJgzTKyBd1W zkQbnShpdx)_2p*Odb1=5!MV>wu(D#EpgPM|%+4btBT}d~Hrb_LA~a6*kbW-Y@|c-N zHIm-m-e#Tj?K`wt0wd!*+o%3bm3 zXwqPzY{wPV|4(~o!4=i_#(SkZRJv2TbLi$rH%LjRlrS_XjWkk%^w112G%|#QbPY9h zgEMqXiFf|@ZQT0;&f4qjwf9=*`Nrq;1Or4{t*jxI*_w3b--1<{|Fq99+)$iq%Rqrg zSZtw9rcy`Dx&kGD&?wno4rixykAI*hVCTkpX0R!ZaVZbbjIX}F{vxEv6OZN7<9)05 zv`l5%8QI-4pEsnOfr7#mF31u#)RALtPT|r50?iXqifq}_&HH0fdz>OjSzdkp^_BNy z6ZCw~3oPP4Fi@)!Y{!1Lo!0u4%mjGYq#hsAG^Ok%KVEju5`9N+8}u$@r&h}uoiIIp)f4*nHm6&wbRn|$dW`$*7Eo@AyB8;5 zq1fK?*F5=iwv+Pp7xf&M$JM4fhK3m5Omw47;PcXPk)!?H95IS zPTq_^ix8~dW$HHbB+P5NS)?&m z2byy^*Df#{+bW;KiRGTQICTdt^*#~gS7G(4j^bjMdq~`6SQu-!`gJ`?jK)(bFX@Fm zghiK&e(%mpjidfK$xBSv`z0ZX3;MS(L`+OPc`?CRgnC>^SQu7xu~4}iRR3u1p1$WJ zt1Rpn@gs|%lBTp(PvF3(|BYUDjVSerj@ORz2vDWCIverP(ej?E#27SXM3H(WI{~qb z_&r6p)v3B+wU@EP0F4>~=O4en*eAHdJi%rNJr7i)?XRGlWE9n|r_#@z$jUkqARdsE zYtTv_>r_d{!La8K^{wC;7n7$e^CAJS|Gq9-DX_?s97 z4V4CZ8SgRXb3#?q*8TnRx&LImAXK5clYn=o+bNz1T4W@o(Z+o2AsuxvQ~6tAB<|i^ zUi)0(*4EaNVgk~6r3Tb)6)N`VmUii#j^jgZ^|QqO0jRr{n8LRHeNNpkILxCm0=-@Q zt*862LZu+X+NWy)Bf*fhT#N6j!%tPd+y(1)l4g~S$H41=(1zx3*pcY17fzj@Q&Vu8 zEH>P9e#Wot_*2CoDvMTTLI{;<@bGSjs@9c8Pf-J9#sDD3a&WJJ~^skIlo$W?+=(u98mY0&#WHfEx#mdwoKu=uleECmo6c16@CmC3h_ zpDa9HNA!fmD=bk7FeN9gSzG6f#lVrO-lq-nUeW&7VR&<2%Y|_K#AY@3<}QtfLje;u?Bw}73LYFEW=<>T~2|RvumZm3P~=W`#CQM-iy4zhXPyM-y@IwDz7n$ z2(0IGXHKgBVkS#khgb?Jh6w@8XJ)jb(Olb)R60JOIpY)@{d6mZ04Wbet|YQtxo3gg zZZHln8!vDjh5Ni> z^+!3zonlV>!Dr~_k5*RH%7kxt39kh&X6BLC=62H7-_H?`Z1n!v+Vcd&CS#C6dTx)MJ>4$zQvFbasMxn_|yOllRE@^Fb0oqbh zgL`a;Wd9gw2YK@v6$@BdfHXki=x<3UHCpxk4N>8$fJ(WjXgiCXGp8c>Wn8iQqsJ1Y z&oE1J>MO39IO;fN=Bt@mo5%sV^6}>;3Z&q>QEk>v+gDo)3k$)P95rR!-y)}lFBBr( zoDzmU>G6MG*I5;qIzczdI>dyceToXr>D%(ZJ}6Z;v$-m?#eLx7=DtxQqV=g6T2={H z*ggKAx&d%9vlhcXJg2md;lJ}xVBiN8rfn6Q>S&{ixbLh!;c77o^B$ow5s{1=d}(xt zD+UzjI%=xL=LN2re$awNvS|J~o%P>uXdI#0`fa>f!X)`u!#j@k`j_y)M@-MTQ}zaV zFF;+!FvX6$KFwks9TfrF^Y)M5*EV`eS}h1q;luPKZ~XYTu}t&TS;zvFnkm#B|O zhuCJBv7PS{11`#>M|)ggiZ5oR8NEGrf}4LV9%0&ywS&Q0v&eqHZF5bo4|nuoygp+u z93ELzH7}y}VoJ9KL$hg~3K3_K4f=P}@Tq_r;im>X%nWToxR`c|Cw4ktb-Em7e#KCA zIU^f*W|`p@9=EFh`*1U7A19zOSv>Ebz`udy4EL5LU>$7w3jIKR4<7~I#~=TV!xKph z#KlO3?)0x7SY^ZF^M3lAqqM$xEDx5n@7`NRvBlBZnpNAoZTYw3IecM?9oUCgh{7=4 zoEeW9JzmhYUg$ph@(c%t_N883wSR;Zpz(1T%Q$_HFaNxMGm9Q_@a* zczkJufdPQLySTI!?kOPs_={NgN_iWYP2Q z778EN)U?OUAR{}t<6A@D3o`P8bs=$i&AaotEO_X;d5Kj=q0;~LRtu!L6`XnWWYYhV z3`L|Fy)z#*?5}v?zda0%=KFjx_@k}O#KNa*XRMb0#}ln?f4kGS-$kFE!TphuiJ8Cr z9l-R)qLrXltP>H(7?b%)DZHyS9qcdkz6D|mi*DU3`OLHqiBolB)Wliy*Jgxc*XDuN7cN{~wdYn0W|3t3v+go_h z6}yp<2|J$oFGD2cWgF28a>WjXjLMb`7qR!aP&EdF36eE>W)oqzkbMLjJb-uwUDN|M zX6x57{1_9G1UWCs=m(V+yS#7hUiR}>*ggt~b&Q?2(qkmGQLd4CnQTLZ8b1Ffxz3#y zU2V{|(~WGZ1fgPwyPKbWuQ#O7ORnG_eMoM4om88y#w~&4yc5VTT&ijN7^|!~_`RoFM8mhB%3pUYZo)q<^29ySSadZzN(H9{M z0V;8FYu(g`VsS4*OQavZeo62)xi8$)yiletj1HhsEhFQ&Hj)=yZM0|m7Zh*+9afk- zDn5%2#i`K#PA(R50RBxx5Af6HWnHDYW)CP9n|nVWQ;SeWkBDfFU|%ABS!9oBc3di| z?;F|=PAn@ZH2u~-Pd;HRG_{7*DTsDziQw|p(z4e%<%wfoD{iWsH7ghBQICkIY?Rqqc;#QbX_Lmc~~D0HJWG8m#$ldzd4{x zv6SEZQ%jLdsqfmT^{Ae$7Q|mU*HJ|e{X7H-IqN)H1RlZHQBui4xB>;4jvqIWh09t5 zt4oSk_^D38H0~HjOZ8>OFH#cIj z;_P(5Z{AY%3{D#^2NN$rJIhj+HkfIt*}~E2P~-Sa0>r60CWZdV(oYMPjY(9hofuH5D@6nT(>iR(bKCy# z0#a?I(sR@2(NkR!->YfWP*}c)8fs`DHb|n%L zVFRU-rM{1lNXG9X9n@1`nEXO#xyhpX0((XU-dbZPpQYiKCR0YCLDIcLtNVLCshyOk zP-2Y*zqC9^onF+c_Gj28A-0oMHLnZw2}`77kMWq!U+j-8tnhN6u!X3@3q{mV4nzo8c;8Sm&If&K0Q4SqbS;H{aT;&7B9O3W58AM06 zs(a(s#M?JrJ7^NYKg~9?AP_@u-hK|;t<|XWSF>dpNDEJqMb~O)7NP#M>+-S%7Y@1d z-!3q1@ICj}-17`JYQ6#OMVk!`b2eL)eT~g+#uH4lV}9PJs(uFok(6X&p%rsS7?hG* zrD{~D?5fg_=~Lr1444w#G5eGf@9DMemAo;xO|VhEGsR$!jxBdd#Nfq&%~Y+Aq%?@1 z771H@np#%cMG+agP3eOXC2WNDcefrpgJ0Iezdax;v59CUt^$9wo8PLfNcy2$ZHRWVB?vxF zX)vy@uis+NJjZX4km&|&wfUg>&Ut=Rl};u(Fp`{-1#1h|33!+I2OyyT5&iF$_?Agv z97f|MixdXlKEPW%bkqjBcQ#Kz?psc=Pdq+KM^N0e#cNIv z%hW8ffZP1`bK_IS>T9}JzHSMETcvoo;(QbiPGz6|-L!9}CcvAOpNQ&YI*S^XUCH$}s?>MbhnwkOC2H`o5@t?F-c3v|k>&&LxJ%zwn*MRk z`R!tN_#eT9MN7Eiwe-K^W(ootfZr3Wbf=Mnq+-^i4La_YE%3AS`8Dnkz z7Q+^k{^`8ChhHXOpLYMrm~Uy}Z}(XBcbO?x5Jg$yCB#_TO*CN@>4izZTu;XNduca% zL;fJTRfaw3{ZAnw2`RL$aiqo$1*CxfzGxSrRgNZfAF)mo`})6Ix9iZTym$IANZuCk zpPm5G)jD%KE!8_WF=`}>UsSEwwjSXvyylQ=Leur0-%o4zA{3Fyi_nO~T0VFtid6iTk#-9?4X>tPQ>Ror#5=K|im}b1 zyz+g5%3Ki=FHo1D4?TvAM#Q%B3MFr1dJyu8v#6!aKcf&^bn1bn-LleJCJf~4H-~dj zc&glU$MOKjONNOfe)XR@9PzlymHZpc&eK(D^r0@no*VUjj%;jrS3bt9u+JV7{bM%q zFh(@1sxR)-giEfS^l&dLU4kTPh;=H}+b35C6GID-C9UlcGThF9S!OJC_6?Ft3UjYY zj7W=M`ME+kZnMq)EG6vFM!_?ck)1W+u%3sqAEh+&C#0szo$`SzpZ!SP{ey$)DV?Jp zT)BFx#A^(}XR}}3MkpN>BpozfqhTUZ-Gv_Uji95k68Lkkhjy7G@}ALj0f5ru_*hl0JCWDWmcpLrKEP z?4_9|Dqw|u_T$e6w~&xP!csaVKcq+-8g3zQZ5prGc$0dOybuSrf7#H9~;q$Xr zgQ@wV?^Gs+1%AA_xdY;0Zg>&&)$E%Z=(SY%PYN{A5OvWc{_)RHnN;~~4{hJsvVzNl zLHv1%2?$z?6AFu>FYUVsc1M8+KZfX3>PU$I3c}tf6O3;BXLOCS#tbO?IymB2>Jv)M zzF)q!U9eRj!jri)9htCdt}V7n!allS&b0|P7jc>nu)t+_aMkKrWqMNQzpfDy9ctAre%)`=5J4uuFK1_crOf{4@MjY zp@B66VvYd>x@UJM%`Uv+sQV<7`s?YbVka(=p}_N^jCO1!K}XPxNBDB~>WR6`Rb)Iw zkXL%kj9(j;^X*&wIESCCm99Hi@8Y?A>;g5%BV+1+8SG^F;&y|E@D%#6sVyd@OBC_v zLJ-agVzjfYCjheRCfl1mLV0o`tYjQh(jWKt$wK2^SLT!1XW~C=@t--oJQ+gc@_z}8B8Jq+n~yfOnh@SdgWZap`)3xxIt`e zLXL$3!O)FeGm=v%|!xBr4NbVg!Ca~Bnb9QcXaEAf-^v-B(Hc%oyc*HNjY{p`8c zqn)R$l``wx<(v#6^p1#Bj$e9=dCzOPNkyAA#k-|9)~P|mJ8<}2YCmvK}A#CI1XIf*Ljg!N-F7@Jfv^68sMaJ%w&XRqLCu18~`S7hzjxN#hl;r7Z`BcM@BB4M(w0mgqxjftY=NX+fNRmXpo(# z*xxq@jus2A9?8l84Y7N`eIi2;^Z0u(R{Bi2^w?rK|yNnV*0yCHs%ldJ3E2H_5P~u>1Qr`RUDKKF*Rg zi|=q$Dizk!k(Byb754M&?qlQ)qXL=5N)Mg`_{^D~la-`8Nw5}+Z?u~?2n)H=Ml_O* zT&tLioMbt5)9F8~+HPX7hhs2A3*~>R$Cv{PY93G<)#-~_sN1U0ZB(?X~~f@hqlQ0gxHfU^Cyb^4z%m>7TuMy742FuOyCqof%{ch$S#+G@zIznJ%W|oX>G3$_!0LSE`5Ig|wdn_&W6c^U8+6S>&_JcvaJb|$ni*7fY zn?vzp{*8?|F*uI-7$!C>w8Sd23^D%0U=DyRw~su+-yo%8p0+SLvA<|78?NzACM=SV zCU4#=jms&5P&+Id>$IP0jL5QxWI&u7DVX-z zV#_Y`znYI%iY4H z|CPVlHM5e)59y6PULQ1HuiaL~K)W=f#YF+s3M7_^+9sxeg~nR6nt@i;?S&u-^e5$6 zP=)rAMHGERRA53E`Uz6Kr~%@m1$X=bOFM$PbZcwJt(*!KkX-z{bg#`E-25?OYujn0 ztNF@>j8^>`;}x$_kydJ=iS~PkCp4@glhWbH^2kMja0Xk2{UB_h!eOt9n`!O(ZiB^c zRk#l>YcSduaXjq|W^44|J8NM}}Tolxv04+1d`jFx8Y8Y0yJ{V7KW}d?}yW ztRbg=Cjp9KY?@<1t2&&;D%qrG*6elMVz*824Xinc8e5x5N&fCFc{UHe7JVs6uU)&-sSe1!3@BV|EQQ6e{r7uJe)tgxq5ya9lMR3+?NJ$4X zoxXpt>FNR!KY*>UScUGVQb?3E9SZlw)L*?m!iR8?cgIJ#ruCr9L}HB@dQ?iJoE`cp zZ@O_M0lFaKcxUpd_7d^!fn`!!gYKtu4Fveg?^*ySAC#h*2xhDZ+hbKo;nm1= zWnQY*qD#J8I32FBV#q@!Jq??-g-Ci?^8+boqQGL{WCJ(poW_4j!OGT)((_(7{t9YJ z<|;Ke+j-9J>ZzSX^ZpvE7ghyDE>e+P?lp%bQzyv-;$>=diI=JI3E*GISESk}lm7po kl>Yw$EFQ-OSTJu0!9UDQ zA^0bSVv`i2g`%QCEMzMi1Bw`wR2qw5V+ceLeKS^yv!Y87S;Qh(h{(fYS!78ek2x0e z=iN8&?c#-D&YOGh`M&Sm^W7&77=t1QcpCd!=7MdJKs#R zf9F?V&H}d(kx<7o$wCch8%rS8Fz*YnTuI7+Z`vKvR5@bR5P`v_dxuz_RMNw$`Bp>D z{u!K7o33WkpJd)Cqjtm^JY)NlNoC!+EFo19@^7}c z-MXS>G}sQ#*OT*x-+@=lB&{%uz)APk7`B05qcX`Vp&zBz4bVDNQYAcYFcL@_8{R0B zbQI@9j9-vAQ_lyFy;UY@6~#rqf;c}%qOt8aLC;%sjRSlp_@YimtCBWotsP1vJvqqp zl?b?uIa+@g#$X}*q0qZ!ntlpAi@k^W6L_sm(s7*U3*f7m!~Iri@KNyP1f&+hb_2YkSw`QQMi& z73956qEN0zf_bta?IEs6$_x)n+9eDcI3&VcLtN<3g}Kf;N7um@%OtD9)iVK_Ag679 z0!KnvRJg&dY;uKZzf}?smPxkN=i2X2|2A+*(gJW>_#dRJz`E)N*%EpQagWVup$eEG t-?xH!V~`JzNP5o@2`-gM`uG3Y_a9DBmRPp{Zjk^0002ovPDHLkV1m2ko^JpE literal 0 HcmV?d00001 diff --git a/assets/images/delivered_logo.png b/assets/images/delivered_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bca11936fe470de2d4bc0d1c508f3eb50b58e5ee GIT binary patch literal 55460 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 literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index 3e3a45b..7bb0cca 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -3,22 +3,26 @@ import 'package:flutter/material.dart'; /// End points const isUAT = true; -const BASE_URL = 'https://${isUAT ? "uat." : ""}hmgwebservices.com/Services'; +const BASE_URL = 'https://${isUAT ? "uat." : ""}hmgwebservices.com/'; + const PING_SERVICE = '/Services/Weather.svc/REST/CheckConnectivity'; -const GET_PROJECT = '/Lists.svc/REST/GetProject'; -const LOGIN = "/Authentication.svc/REST/CheckDriverAuthentication"; -const GET_OPT = "/Patients.svc/REST/PatientER_Delivery_SendSMSForForgetPassword"; -const CHECK_ACTIVATION_CODE = "/Patients.svc/REST/PatientER_Delivery_CheckActivationCodeForForgetPassword"; -const CHANGE_FORGOT_PASSWORD = "/Patients.svc/REST/PatientER_Delivery_ChangeForgetedPasswordForDriver"; +const GET_PROJECT = '/Services/Lists.svc/REST/GetProject'; +const LOGIN = "/Services/Authentication.svc/REST/CheckDriverAuthentication"; +const GET_OPT = "/Services/Patients.svc/REST/PatientER_Delivery_SendSMSForForgetPassword"; +const CHECK_ACTIVATION_CODE = "/Services/Patients.svc/REST/PatientER_Delivery_CheckActivationCodeForForgetPassword"; +const CHANGE_FORGOT_PASSWORD = "/Services/Patients.svc/REST/PatientER_Delivery_ChangeForgetedPasswordForDriver"; + +const GET_ALL_ORDERS = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllOrder'; +const SCAN_QR = '/Services/Patients.svc/REST/PatientER_Delivery_OrderInsert'; +const UPDATE_ORDER_STATUS = '/Services/Patients.svc/REST/PatientER_Delivery_UpdateOrderStatus'; +const NEXT_ORDER = "/Services/Patients.svc/REST/PatientER_Delivery_NextOrder"; +const UPDATE_DRIVER_LOCATION = "/Services/Patients.svc/REST/PatientER_DriverLocation_Insert"; +const INITIATE_DELIVERY = "/epharmacy/api/sendsmstocustomerfordriver"; +const VERIFY_DELIVERY = "/Services/Patients.svc/REST/PatientER_ValidateSentOutForDeliveryOTPCode"; -const GET_ALL_ORDERS = '/Patients.svc/REST/PatientER_Delivery_GetAllOrder'; -const SCAN_QR = '/Patients.svc/REST/PatientER_Delivery_OrderInsert'; -const UPDATE_ORDER_STATUS = '/Patients.svc/REST/PatientER_Delivery_UpdateOrderStatus'; -const NEXT_ORDER = "/Patients.svc/REST/PatientER_Delivery_NextOrder"; -const UPDATE_DRIVER_LOCATION = "/Patients.svc/REST/PatientER_DriverLocation_Insert"; +const GET_ALL_DELIVERD_ORDER = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllDeliverdOrder'; +const GET_ALL_ORDERS_STATUS = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllOrderstatus'; -const GET_ALL_DELIVERD_ORDER = '/Patients.svc/REST/PatientER_Delivery_GetAllDeliverdOrder'; -const GET_ALL_ORDERS_STATUS = '/Patients.svc/REST/PatientER_Delivery_GetAllOrderstatus'; /// Body Constant const CHANNEL = 9; @@ -38,3 +42,11 @@ const LINEAR_GRADIENT = LinearGradient( ], // stops: [0.0, 1.0], ); + +abstract class DeliveryStatus{ + static final int pending = 1; + static final int delivered = 2; + static final int rejected = 3; + static final int cancel = 4; +} + diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 0303269..75bc0c0 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -82,8 +82,45 @@ const Map> localizedValues = { 'en': 'Please Enter your OPT code sent to your phone', 'ar': 'الرجاء إدخال رمز OPT الخاص بك المرسل إلى هاتفك' }, + 'enterCustomerVerificationCodeMsg': { + 'en': 'Please enter OTP sent to customer phone', + 'ar': 'Please enter OTP sent to customer phone' + }, 'startDelivery': { 'en': 'Start Delivery', 'ar': 'Start Delivery' }, + 'deliveryOption': { + 'en': 'Delivery Option', + 'ar': 'Delivery Option' + }, + 'selectReason': { + 'en': 'Select Reason', + 'ar': 'Select Reason' + }, + + 'accident': { + 'en': 'Got accident', + 'ar': 'Got accident' + }, + + 'notReachableOnPhoneCall': { + 'en': 'Not reachable on phone call', + 'ar': 'Not reachable on phone call' + }, + + 'notAvailableAtlocation': { + 'en': 'Not available at location', + 'ar': 'Not available at location' + }, + + 'deliverLater': { + 'en': 'Deliver later', + 'ar': 'Deliver later' + }, + + 'other': { + 'en': 'Other...', + 'ar': 'Other...' + }, }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index b1bfbc9..857ce5b 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -1,5 +1,6 @@ const TOKEN = 'token'; const APP_LANGUAGE = 'language'; const USER_PROFILE = 'user-profile'; +const ACTIVE_DELIVERIES = 'active-order-deliveries'; diff --git a/lib/core/model/StatusModel.dart b/lib/core/model/StatusModel.dart new file mode 100644 index 0000000..7337954 --- /dev/null +++ b/lib/core/model/StatusModel.dart @@ -0,0 +1,11 @@ +class ResponseModel{ + bool isSuccessful = false; + String message; + T data; + + isSuccessfull(Function(bool) callback){ + callback(isSuccessful); + } + + ResponseModel({this.message, this.isSuccessful, this.data}); +} \ No newline at end of file diff --git a/lib/core/model/initiate_order_delivey/request_initiate_order_delivery.dart b/lib/core/model/initiate_order_delivey/request_initiate_order_delivery.dart deleted file mode 100644 index fcddad1..0000000 --- a/lib/core/model/initiate_order_delivey/request_initiate_order_delivery.dart +++ /dev/null @@ -1,10 +0,0 @@ -class RequestInitiateOrderDelivery{ - int orderID = 0; - RequestInitiateOrderDelivery({this.orderID}); - - Map toJson() { - final Map data = new Map(); - data['OrderID'] = this.orderID; - return data; - } -} \ No newline at end of file diff --git a/lib/core/model/order_delivey/request_initiate_order_delivery.dart b/lib/core/model/order_delivey/request_initiate_order_delivery.dart new file mode 100644 index 0000000..b15407a --- /dev/null +++ b/lib/core/model/order_delivey/request_initiate_order_delivery.dart @@ -0,0 +1,12 @@ +class RequestInitiateOrderDelivery{ + int orderNo = 0; + String mobileNumber = ""; + RequestInitiateOrderDelivery({this.orderNo, this.mobileNumber}); + + Map toJson() { + final Map data = new Map(); + data['OrderNo'] = this.orderNo; + data['MobileNumber'] = this.mobileNumber; + return data; + } +} \ No newline at end of file diff --git a/lib/core/model/order_delivey/request_validate_delivery.dart b/lib/core/model/order_delivey/request_validate_delivery.dart new file mode 100644 index 0000000..6c2827b --- /dev/null +++ b/lib/core/model/order_delivey/request_validate_delivery.dart @@ -0,0 +1,12 @@ +class RequestValidateDelivery{ + String pinCode; + int orderNo; + RequestValidateDelivery({this.orderNo,this.pinCode}); + + Map toJson() { + final Map data = new Map(); + data['Password'] = this.pinCode; + data['OrderNo'] = this.orderNo; + return data; + } +} \ No newline at end of file diff --git a/lib/core/model/initiate_order_delivey/response_initiate_order_delivery.dart b/lib/core/model/order_delivey/response_initiate_order_delivery.dart similarity index 100% rename from lib/core/model/initiate_order_delivey/response_initiate_order_delivery.dart rename to lib/core/model/order_delivey/response_initiate_order_delivery.dart diff --git a/lib/core/model/orders/pending_orders_res_model.dart b/lib/core/model/orders/pending_orders_res_model.dart index 5df7082..ccf6870 100644 --- a/lib/core/model/orders/pending_orders_res_model.dart +++ b/lib/core/model/orders/pending_orders_res_model.dart @@ -27,6 +27,11 @@ class PendingOrdersRes { dynamic distanceInKilometers; List itemsQuantitiesList; + String receiverFullName(){ + var fullName = "${firstName ?? ''} ${middleName ?? ''} ${lastName ?? ''}"; + return fullName; + } + PendingOrdersRes( {this.rowID, this.orderID, diff --git a/lib/core/model/update_driver_location/request_update_driver_location.dart b/lib/core/model/update_driver_location/request_update_driver_location.dart index 64fbbf1..4cbfcc7 100644 --- a/lib/core/model/update_driver_location/request_update_driver_location.dart +++ b/lib/core/model/update_driver_location/request_update_driver_location.dart @@ -1,3 +1,6 @@ +import 'package:driverapp/config/shared_pref_kay.dart'; +import 'package:driverapp/core/model/authentication/authenticated_user.dart'; +import 'package:driverapp/uitl/app_shared_preferences.dart'; import 'package:location/location.dart'; class RequestUpdateDriverLocation{ @@ -5,11 +8,16 @@ class RequestUpdateDriverLocation{ LocationData location; RequestUpdateDriverLocation({this.orderID,this.location}); - Map toJson() { + Future> toJson() async{ final Map data = new Map(); data['OrderID'] = this.orderID; data['Latitude'] = "${this.location.latitude}"; data['Longitude'] = "${this.location.longitude}"; + + Map profile = await AppSharedPreferences().getObject(USER_PROFILE); + AuthenticatedUser doctorProfile = AuthenticatedUser.fromJson(profile); + data['DriverID'] = doctorProfile?.iD; + data['UserID'] = '${doctorProfile?.iD}'; return data; } } \ No newline at end of file diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8c3602b..969118c 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -16,21 +16,23 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); /// body: null); class BaseAppClient { - post( - String endPoint, { - Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - }) async { + String _Statictoken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; + post( + String endPoint, { + Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure}) async { String url = BASE_URL + endPoint; try { Map profile = await sharedPref.getObject(USER_PROFILE); String token = await sharedPref.getString(TOKEN); if (profile != null) { AuthenticatedUser doctorProfile = AuthenticatedUser.fromJson(profile); - body['DriverID'] = doctorProfile?.userID; + if(!body.keys.contains('DriverID') || body['DriverID'] == null) + body['DriverID'] = doctorProfile?.userID; + if(!body.keys.contains('UserID') || body['UserID'] == null) + body['UserID'] = '${doctorProfile?.userID}'; body['CreatedBy'] = doctorProfile?.userID; - body['UserID'] = '${doctorProfile?.userID}'; body['TokenID'] = token; body['MobileNo'] = doctorProfile?.mobileNumber; } @@ -45,7 +47,8 @@ class BaseAppClient { body: json.encode(body), headers: { 'Content-Type': 'application/json', - 'Accept': 'application/json' + 'Accept': 'application/json', + 'Statictoken': _Statictoken }); final int statusCode = response.statusCode; if (statusCode < 200 || statusCode >= 400 || json == null) { @@ -56,11 +59,11 @@ class BaseAppClient { // await helpers.logout(); //helpers.showErrorToast('Your session expired Please login agian'); // TODO create logout fun + onFailure("Unauthorized", 401); } else if (parsed['MessageStatus'] == 1) { onSuccess(parsed, statusCode); } else { - onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } else { @@ -71,4 +74,66 @@ class BaseAppClient { onFailure(e.toString(), -1); } } + + get( + String endPoint, { + Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure}) async { + String url = BASE_URL + endPoint; + try { + if (await Utils.checkConnection()) { + final response = await http.get(url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Statictoken': _Statictoken + }); + final int statusCode = response.statusCode; + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + var parsed = json.decode(response.body.toString()); + if (parsed['MessageStatus'] == 1) { + onSuccess(parsed, statusCode); + } else { + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + } + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } catch (e) { + print(e); + onFailure(e.toString(), -1); + } + } + + + simpleGet( + String url, + { Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure}) async { + try { + if (await Utils.checkConnection()) { + final response = await http.get(url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Statictoken': _Statictoken + }); + final int statusCode = response.statusCode; + if (statusCode < 200 || statusCode >= 400) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body, statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } catch (e) { + print(e); + onFailure(e.toString(), -1); + } + } } diff --git a/lib/core/service/delivery_tracking_services.dart b/lib/core/service/delivery_tracking_services.dart index 4a7c389..65fbb5d 100644 --- a/lib/core/service/delivery_tracking_services.dart +++ b/lib/core/service/delivery_tracking_services.dart @@ -1,100 +1,141 @@ import 'dart:collection'; +import 'dart:math'; import 'package:driverapp/config/config.dart'; -import 'package:driverapp/core/model/initiate_order_delivey/request_initiate_order_delivery.dart'; -import 'package:driverapp/core/model/orders/deliverd_order_res_model.dart'; -import 'package:driverapp/core/model/orders/next_order_request_model.dart'; -import 'package:driverapp/core/model/orders/pending_orders_req_model.dart'; +import 'package:driverapp/config/shared_pref_kay.dart'; +import 'package:driverapp/core/model/StatusModel.dart'; +import 'package:driverapp/core/model/order_delivey/request_initiate_order_delivery.dart'; +import 'package:driverapp/core/model/order_delivey/request_validate_delivery.dart'; import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; -import 'package:driverapp/core/model/orders/update_order_status_request_model.dart'; -import 'package:driverapp/core/model/scan_qr/scan_qr_request_model.dart'; import 'package:driverapp/core/model/update_driver_location/request_update_driver_location.dart'; import 'package:driverapp/core/service/base_service.dart'; +import 'package:driverapp/uitl/app_shared_preferences.dart'; import 'package:driverapp/uitl/utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:latlong/latlong.dart'; import 'package:location/location.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class DeliveryTrackingServices extends BaseService { - var _distanceFilter = 5; // [Meters] (Call update API if distance covered from last location is greater then 'value' ) + var _distanceFilter = 20; // [Meters] (Call update API if distance covered from last location is greater then 'value' ) - var initiateOrderDeliveryResponse = null; - Future initiateOrderDelivery(int orderID) async { + Future initiateOrderDelivery(PendingOrdersRes order) async { hasError = false; - var order = RequestInitiateOrderDelivery(orderID: orderID); + var testNumber = ""; + ResponseModel result; + // var orderRequest = RequestInitiateOrderDelivery(orderNo: order.ePharmacyOrderNo, mobileNumber: testNumber == "" ? order.mobileNumber : testNumber); + var fullUrl = BASE_URL + INITIATE_DELIVERY + "/${order.ePharmacyOrderNo}/${user.iD}"; + await baseAppClient.simpleGet(fullUrl, + onSuccess: (dynamic response, int statusCode) { + result = ResponseModel(isSuccessful: true,message: null, data: response); + startLocationUpdate(order.ePharmacyOrderNo); - try { - await baseAppClient.post(PING_SERVICE, - onSuccess: (dynamic response, int statusCode) { - initiateOrderDeliveryResponse = response; + }, onFailure: (String error, int statusCode) { + result = ResponseModel(isSuccessful: false,message: error,data: null); + }); - }, onFailure: (String error, int statusCode) { - super.hasError = true; - super.error = error; - }, body: order.toJson()); + return result; + } - } catch (e) { - hasError = true; - super.error = error; - throw e; - } + Future validateDelivery(PendingOrdersRes order, String pinCode) async{ + hasError = false; + var request = RequestValidateDelivery(orderNo: order.ePharmacyOrderNo, pinCode: pinCode); - return initiateOrderDeliveryResponse; + ResponseModel result; + await baseAppClient.post(VERIFY_DELIVERY, + onSuccess: (dynamic response, int statusCode) { + result = ResponseModel(isSuccessful: true,message: null, data: response); + }, onFailure: (String error, int statusCode) { + result = ResponseModel(isSuccessful: false,message: error,data: null); + }, body: request.toJson()); + + return result; } _updateDriverLocation(int orderID, LocationData location) async { if(location != null){ debugPrint("Updating driver location"); - var order = RequestUpdateDriverLocation(orderID: orderID, location: location); + var jsonBody = await RequestUpdateDriverLocation(orderID: orderID, location: location).toJson(); await baseAppClient.post(UPDATE_DRIVER_LOCATION, onSuccess: (dynamic response, int statusCode) { }, onFailure: (String errorMessage, int statusCode) { - if(statusCode == 200){ + if(statusCode == 200){ // Server responded but check failed (stop updating location) // stopLocationUpdate(orderID); // Show error message that you received in response } - }, body: order.toJson()); + }, body: jsonBody); } } - List _currentRunnings = List(); + Map _currentRunnings = Map(); Future startLocationUpdate(int orderID, {int frequencyInSeconds = 3}) async { - _currentRunnings.remove(orderID); // remove existing if its already running - _currentRunnings.add(orderID); - - while(_currentRunnings.contains(orderID)){ - await Future.delayed(Duration(seconds: frequencyInSeconds)); - Utils.possibleToGetLocation((value) async{ - if(value){ - var location = await Utils.getLocation(); - if (_haveEnoughLocationUpdate(location)) - await _updateDriverLocation(orderID, location); + if (_currentRunnings[orderID.toString()] == null){ + _currentRunnings[orderID.toString()] = Future.doWhile(() async{ + + await Future.delayed(Duration(seconds: frequencyInSeconds)); + var valid = _currentRunnings.containsKey(orderID.toString()); + if(valid){ + Utils.possibleToGetLocation((value) async{ + if(value){ + var location = await Utils.getLocation(); + if (_haveEnoughLocationUpdate(location)) + await _updateDriverLocation(orderID, location); + } + }); } + return valid; }); } + + SharedPreferences.getInstance().then((pref){ + pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList()); + }); + } + + bool isActiveDeliveringOrder(int ePharmacyOrderNo){ + return _currentRunnings.containsKey(ePharmacyOrderNo.toString()); + } + + List getActiveDeliveringOrders(){ + return _currentRunnings.keys.toList(growable: false); + } + + setActiveDeliveringOrders(List orders){ + orders.forEach((element) { + if(!_currentRunnings.containsKey(element)){ + _currentRunnings[element] = null; + } + }); + } + + clearActiveDeliveringOrders(){ + _currentRunnings.clear(); + SharedPreferences.getInstance().then((pref){ + pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList()); + }); } stopLocationUpdate(int orderID){ - _currentRunnings.remove(orderID); + _currentRunnings.remove(orderID.toString()); + SharedPreferences.getInstance().then((pref){ + pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList()); + }); } LocationData _lastLocation; bool _haveEnoughLocationUpdate(LocationData location){ - if(_lastLocation == null) { - _lastLocation = location; - return true; - }else{ - var distanceCovered = Utils.distanceBetween(_lastLocation, location, LengthUnit.Meter); - return (distanceCovered > _distanceFilter); - } + _lastLocation = _lastLocation ?? location; + var distanceCovered = Utils.distanceBetween(_lastLocation, location, LengthUnit.Meter); + // debugPrint("distance: $distanceCovered"); + return (distanceCovered > _distanceFilter); } } diff --git a/lib/core/service/orders_service.dart b/lib/core/service/orders_service.dart index 9fb9c24..33e073d 100644 --- a/lib/core/service/orders_service.dart +++ b/lib/core/service/orders_service.dart @@ -79,11 +79,11 @@ class OrdersService extends BaseService { try { await baseAppClient.post(GET_ALL_ORDERS_STATUS, onSuccess: (dynamic response, int statusCode) { - listCountDelivered = + listCountDelivered = response["PatientER_CountOrderList"][0]["NumberOfDeliveredOrder"]; - listCountUnDelivered = + listCountUnDelivered = response["PatientER_CountOrderList"][0]["NumberOfUnDeliveredOrder"]; - }, onFailure: (String error, int statusCode) { + }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: {}); @@ -100,10 +100,9 @@ class OrdersService extends BaseService { try { await baseAppClient.post(UPDATE_ORDER_STATUS, onSuccess: (dynamic response, int statusCode) { - isOrderStatusUpdated = - response["PatientER_Delivery_IsOrderUpdated"]; - listCountUnDelivered --; - listCountDelivered ++; + isOrderStatusUpdated = response["PatientER_Delivery_IsOrderUpdated"]; + listCountUnDelivered--; + listCountDelivered++; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -137,13 +136,12 @@ class OrdersService extends BaseService { Future getDeliveredList() async { LocationData loc = await Utils.getLocation(); PendingOrders _requestGetPendingOrders = PendingOrders( - searchKey: "", - pageSize: 0, - pageIndex: 0, - latitude: loc.latitude.toString(), - longitude: loc.longitude.toString(), - driverAppPageID: 0 - ); + searchKey: "", + pageSize: 0, + pageIndex: 0, + latitude: loc.latitude.toString(), + longitude: loc.longitude.toString(), + driverAppPageID: 0); if (loc != null) { hasError = false; try { diff --git a/lib/core/viewModels/orders_view_model.dart b/lib/core/viewModels/orders_view_model.dart index e584374..c2ef2e3 100644 --- a/lib/core/viewModels/orders_view_model.dart +++ b/lib/core/viewModels/orders_view_model.dart @@ -1,16 +1,20 @@ import 'package:driverapp/core/enum/viewstate.dart'; +import 'package:driverapp/core/model/StatusModel.dart'; import 'package:driverapp/core/model/orders/deliverd_order_res_model.dart'; import 'package:driverapp/core/model/orders/next_order_request_model.dart'; import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; import 'package:driverapp/core/model/orders/update_order_status_request_model.dart'; import 'package:driverapp/core/model/scan_qr/scan_qr_request_model.dart'; +import 'package:driverapp/core/service/delivery_tracking_services.dart'; import 'package:driverapp/core/service/orders_service.dart'; +import 'package:flutter/cupertino.dart'; import '../../locator.dart'; import 'base_view_model.dart'; class OrdersViewModel extends BaseViewModel { OrdersService _ordersService = locator(); + DeliveryTrackingServices deliveryService = locator(); List get orders => _ordersService.orders; @@ -64,15 +68,37 @@ class OrdersViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future updateOrderStatus( - UpdateOrderStatusRequestModel updateOrderStatusRequestModel) async { + Future updateOrderStatus({@required int orderNo, @required int status, String rejectionReason}) async { + var updateOrderStatusRequestModel + = UpdateOrderStatusRequestModel( + deliveryOrderID: orderNo, + deliveryOrderStatus: status, + rejectionReason: rejectionReason, + cancleReason: rejectionReason); + setState(ViewState.BusyLocal); await _ordersService.updateOrderStatus(updateOrderStatusRequestModel); if (_ordersService.hasError) { error = _ordersService.error; setState(ViewState.ErrorLocal); - } else + return ResponseModel(isSuccessful: false, message: error); + } else { setState(ViewState.Idle); + if(status == 2) + moveOrderFromPendingToDelivered(orderNo); + return ResponseModel(isSuccessful: true, message: "Successful"); + } + } + + + moveOrderFromPendingToDelivered(int orderNo) async{ + var idx = orders.indexWhere((element) => element.ePharmacyOrderNo == orderNo); + var order = orders[idx]; + orders.removeAt(idx); + var order_delivered = DeliverdOrderResModel.fromJson(order.toJson()); + order_delivered.description = "Delivered"; + order_delivered.descriptionN = "Delivered"; + deliverdOrders.add(order_delivered); } Future nextOrder(NextOrderRequestModel nextOrderRequestModel) async { @@ -85,6 +111,31 @@ class OrdersViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future initDelivery(PendingOrdersRes order, {Function(@required ResponseModel response) completion}) async{ + var response = await deliveryService.initiateOrderDelivery(order); + completion(response ?? ResponseModel(isSuccessful: false,message: "Something went wrong, Please try again later.")); + + return response; + // (true, response['ErrorEndUserMessage'] ?? response['ErrorMessage'] ?? "Successfully, Please start navigation.") + } + + Future validateDelivery(PendingOrdersRes order, String pinCode) async{ + return await deliveryService.validateDelivery(order, pinCode); + } + + Future resendOtpToReceiver(PendingOrdersRes order) async{ + // return await _deliveryService.validateDelivery(order, pinCode); + } + + bool isActiveDeliveringOrder(int index){ + return deliveryService.isActiveDeliveringOrder(orders[index].ePharmacyOrderNo); + } + + Future> getActiveDeliveringOrders() async{ + return deliveryService.getActiveDeliveringOrders(); + } + + showBottomSheet() { isBottomSheetAppear = true; setState(ViewState.Idle); diff --git a/lib/main.dart b/lib/main.dart index 1a9a040..b6abcd1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,14 @@ +import 'package:driverapp/core/service/delivery_tracking_services.dart'; +import 'package:driverapp/core/viewModels/orders_view_model.dart'; import 'package:driverapp/pages/splash_screen_page.dart'; +import 'package:driverapp/uitl/app_shared_preferences.dart'; import 'package:driverapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'config/shared_pref_kay.dart'; import 'config/size_config.dart'; import 'core/viewModels/authentication_view_model.dart'; import 'core/viewModels/project_view_model.dart'; @@ -14,9 +19,30 @@ void main() { runApp(MyApp()); } -class MyApp extends StatelessWidget { +class MyApp extends StatelessWidget with WidgetsBindingObserver{ + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + super.didChangeAppLifecycleState(state); + + if(state == AppLifecycleState.paused){ + debugPrint("....App paused...."); + + }else if(state == AppLifecycleState.resumed){ + debugPrint("....App resumed...."); + } + } + @override Widget build(BuildContext context) { + + WidgetsBinding.instance.addObserver(this); + + SharedPreferences.getInstance().then((value){ + var activeOrders = value.getStringList(ACTIVE_DELIVERIES) ?? []; + locator().setActiveDeliveringOrders(activeOrders); + }); + return LayoutBuilder( builder: (context, constraints) { return OrientationBuilder( @@ -30,6 +56,9 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider( create: (context) => AuthenticationViewModel(), ), + ChangeNotifierProvider( + create: (context) => OrdersViewModel(), + ), ], child: Consumer( builder: (context, projectProvider, child) => MaterialApp( diff --git a/lib/pages/authentication/delivery_verification_page.dart b/lib/pages/authentication/delivery_verification_page.dart new file mode 100644 index 0000000..b6ededd --- /dev/null +++ b/lib/pages/authentication/delivery_verification_page.dart @@ -0,0 +1,453 @@ +import 'package:driverapp/app-icons/driver_app_icons.dart'; +import 'package:driverapp/config/config.dart'; +import 'package:driverapp/config/size_config.dart'; +import 'package:driverapp/core/model/authentication/login_request.dart'; +import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; +import 'package:driverapp/core/service/delivery_tracking_services.dart'; +import 'package:driverapp/core/viewModels/authentication_view_model.dart'; +import 'package:driverapp/core/viewModels/orders_view_model.dart'; +import 'package:driverapp/core/viewModels/project_view_model.dart'; +import 'package:driverapp/locator.dart'; +import 'package:driverapp/pages/authentication/reset_password_page.dart'; +import 'package:driverapp/pages/delivery/delivery_confirmed_page.dart'; +import 'package:driverapp/uitl/app_toast.dart'; +import 'package:driverapp/uitl/translations_delegate_base.dart'; +import 'package:driverapp/uitl/utils.dart'; +import 'package:driverapp/widgets/buttons/secondary_button.dart'; +import 'package:driverapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; +import 'package:provider/provider.dart'; +import 'package:sweetalert/sweetalert.dart'; + +import 'forget_password_page.dart'; + +// ignore: must_be_immutable +class DeliveryVerificationPage extends StatelessWidget { + + final PendingOrdersRes order; + DeliveryVerificationPage({this.order}); + + ProjectViewModel _projectViewModel; + OrdersViewModel _ordersViewModel; + final formKey = GlobalKey(); + Map formValues = { + 'digit1': null, + 'digit2': null, + 'digit3': null, + 'digit4': null, + }; + + FocusNode focusD1 = FocusNode(); + FocusNode focusD2 = FocusNode(); + FocusNode focusD3 = FocusNode(); + FocusNode focusD4 = FocusNode(); + var model; + TextEditingController digit1 = TextEditingController(text: ""); + TextEditingController digit2 = TextEditingController(text: ""); + TextEditingController digit3 = TextEditingController(text: ""); + TextEditingController digit4 = TextEditingController(text: ""); + + bool _isLoading = false; + + SizedBox buildSizedBox([double height = 20]) { + return SizedBox( + height: height, + ); + } + + BuildContext _context; + @override + Widget build(BuildContext context) { + _context = context; + _projectViewModel = Provider.of(context); + _ordersViewModel = Provider.of(context); + + String validateCodeDigit(value) { + if (value.isEmpty) { + return 'Please enter your Password'; + } + + return null; + } + + return AnimatedSwitcher( + duration: Duration(milliseconds: 2000), + child: AppScaffold( + isShowAppBar: false, + body: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FractionallySizedBox( + widthFactor: 0.80, + child: Column( + children: [ + SizedBox( + height: 30, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Icon( + DriverApp.deliverd_icon, + size: 150, + color: Theme.of(context).primaryColor, + ), + margin: EdgeInsets.only( + top: 20, + ), + ), + ], + ), + SizedBox( + height: 20, + ), + Column( + children: [ + Center( + child: Text( + "Verification", + style: TextStyle( + fontSize: 25, + letterSpacing: 1, + fontWeight: FontWeight.w600), + ), + ), + ], + ), + SizedBox( + height: 30, + ), + SizedBox( + height: 10, + ), + Form( + key: formKey, + child: Container( + width: SizeConfig.realScreenWidth * 0.90, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20), + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Expanded( + child: Text( + TranslationBase.of(context) + .enterCustomerVerificationCodeMsg, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 13, + color: Colors.grey), + ), + ), + SizedBox( + height: 10, + ) + ], + ), + ), + buildSizedBox(30), + Center( + child: FractionallySizedBox( + widthFactor: 0.80, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + Container( + width: 55, + height: 55, + color: Colors.transparent, + child: Center( + child: TextFormField( + textInputAction: + TextInputAction.next, + style: TextStyle( + fontSize: SizeConfig + .textMultiplier * + 3, + ), + focusNode: focusD1, + controller: digit1, + enableInteractiveSelection: false, + showCursor: false, + maxLength: 1, + textAlign: TextAlign.center, + keyboardType: + TextInputType.number, + decoration: + buildInputDecoration( + context), + onSaved: (val) { + formValues[ + 'digit1'] = val; + }, + validator: validateCodeDigit, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD2); + }, + onChanged: (val) => val.isNotEmpty + ? FocusScope.of(context).requestFocus(focusD2) + : FocusScope.of(context).requestFocus(focusD1) + ), + ), + ), + Container( + width: 55, + height: 55, + color: Colors.transparent, + child: Center( + child: TextFormField( + focusNode: focusD2, + controller: digit2, + enableInteractiveSelection: false, + showCursor: false, + maxLength: 1, + textInputAction: + TextInputAction.next, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeConfig + .textMultiplier * + 3, + ), + keyboardType: + TextInputType.number, + decoration: + buildInputDecoration( + context), + validator: validateCodeDigit, + onSaved: (val) { + formValues[ + 'digit2'] = val; + }, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD3); + }, + onChanged: (val) => val.isNotEmpty + ? FocusScope.of(context).requestFocus(focusD3) + : FocusScope.of(context).requestFocus(focusD1) + ), + ), + ), + Container( + width: 55, + height: 55, + color: Colors.transparent, + child: Center( + child: TextFormField( + focusNode: focusD3, + controller: digit3, + enableInteractiveSelection: false, + showCursor: false, + maxLength: 1, + textInputAction: TextInputAction.next, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeConfig + .textMultiplier * 3, + ), + keyboardType: + TextInputType.number, + decoration: + buildInputDecoration( + context), + validator: validateCodeDigit, + onSaved: (val) { + formValues[ + 'digit3'] = val; + }, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD4); + }, + onChanged: (val) => val.isNotEmpty + ? FocusScope.of(context).requestFocus(focusD4) + : FocusScope.of(context).requestFocus(focusD2), + ), + )), + Container( + width: 55, + height: 55, + color: Colors.transparent, + child: Center( + child: TextFormField( + focusNode: focusD4, + controller: digit4, + enableInteractiveSelection: false, + showCursor: false, + maxLength: 1, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeConfig + .textMultiplier * + 3, + ), + keyboardType: + TextInputType.number, + decoration: + buildInputDecoration( + context), + validator: validateCodeDigit, + onSaved: (val) { + formValues[ + 'digit4'] = val; + }, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD4); + }, + onChanged: (val) => val.isNotEmpty + ? FocusScope.of(context).requestFocus(focusD4) + : FocusScope.of(context).requestFocus(focusD3) + ), + ), + ) + ], + ), + ), + ), + buildSizedBox(20), + // ShowTimerText(model: model), + ]))) + ], + ), + ), + SizedBox( + height: 20, + ), + SizedBox( + height: 10, + ), + Container( + margin: EdgeInsets.all(10), + height: MediaQuery.of(context).size.height * 0.22, + child: Column( + children: [ + SecondaryButton( + label: "Verify Receiver", + onTap: () { + _verifyCustomer(); + }, + disabled: _isLoading, + loading: _isLoading, + ), + SizedBox( + height: 10, + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // InkWell( + // onTap: () { + // Navigator.pushReplacement( + // context, + // MaterialPageRoute( + // builder: (context) => + // ForgetPasswordPage()), + // ); + // }, + // child: InkWell( + // onTap: () async { + // await _ordersViewModel.resendOtpToReceiver(order); + // }, + // child: Text( + // "Resend OPT?", + // style: TextStyle( + // fontSize: 14, + // color: Theme.of(context).primaryColor), + // ), + // ), + // ), + // ], + // ), + ], + )) + ], + ), + ), + ), + ); + } + + TextStyle buildTextStyle() { + return TextStyle( + fontSize: SizeConfig.textMultiplier * 3, + ); + } + + InputDecoration buildInputDecoration(BuildContext context) { + return InputDecoration( + filled: true, + fillColor: Colors.white, + // ts/images/password_icon.png + contentPadding: EdgeInsets.only(top: 30, bottom: 30), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide(color: Colors.grey), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).primaryColor, width: 2), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor, width: 2), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor, width: 2), + ), + counterText: "", + errorStyle: TextStyle(height: 0.0) + ); + } + + + + _verifyCustomer() async { + if (formKey.currentState.validate()) { + final pinCode = digit1.text + digit2.text + digit3.text + digit4.text; + formKey.currentState.save(); + + SweetAlert.show(_context, subtitle: "Please wait...", style: SweetAlertStyle.loading); + var results = await _ordersViewModel.validateDelivery(order, pinCode); + if (results != null && results.isSuccessful) { + results = await _ordersViewModel.updateOrderStatus(orderNo: order.orderID, status: DeliveryStatus.delivered); + popWithDelay(context: _context, seconds: 0.2, callback: (){ + if(results.isSuccessful){ + _goToDeliveryDoneConfirmation(); + }else{ + Utils.showErrorToast(results.message); + } + }); + + }else{ + Navigator.of(_context).pop(); + Utils.showErrorToast(results.message); + } + } + } + + + _goToDeliveryDoneConfirmation(){ + locator().stopLocationUpdate(order.ePharmacyOrderNo); // Stop Driver Location update for Order + Navigator.pushReplacement( + _context, + MaterialPageRoute( + builder: (context) => DeliveryConfirmedPage(order), + ), + ); + } +} diff --git a/lib/pages/dashboard/dashboard_screen.dart b/lib/pages/dashboard/dashboard_screen.dart index 7ea3f09..1b57561 100644 --- a/lib/pages/dashboard/dashboard_screen.dart +++ b/lib/pages/dashboard/dashboard_screen.dart @@ -2,8 +2,10 @@ import 'package:driverapp/config/config.dart'; import 'package:driverapp/config/size_config.dart'; import 'package:driverapp/core/enum/viewstate.dart'; import 'package:driverapp/core/model/scan_qr/scan_qr_request_model.dart'; +import 'package:driverapp/core/service/delivery_tracking_services.dart'; import 'package:driverapp/core/viewModels/authentication_view_model.dart'; import 'package:driverapp/core/viewModels/orders_view_model.dart'; +import 'package:driverapp/locator.dart'; import 'package:driverapp/pages/delivery/information_page.dart'; import 'package:driverapp/pages/orders/deliverd_orders_page.dart'; import 'package:driverapp/pages/orders/pending_orders_page.dart'; @@ -20,6 +22,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; +import 'package:sweetalert/sweetalert.dart'; import '../base/base_view.dart'; @@ -31,6 +34,7 @@ class DashboardScreen extends StatefulWidget { class _DashboardScreenState extends State { bool _isInit = false; AuthenticationViewModel _authenticationViewModel; + OrdersViewModel _ordersViewModel; @override void didChangeDependencies() { @@ -49,513 +53,548 @@ class _DashboardScreenState extends State { Utils.getLocation(); } + checkActiveDelivery() async{ + if(_ordersViewModel.orders.isNotEmpty){ + await Future.delayed(Duration(milliseconds: 200)); + var orderNos = await _ordersViewModel.getActiveDeliveringOrders(); + if(orderNos.isEmpty) return; + + int orderNo = int.parse(orderNos.first); + var order = _ordersViewModel.orders.firstWhere((element) => element.ePharmacyOrderNo == orderNo, orElse: (){ }); + if(order == null){ + // clear active deliveries if accidentally mismatched during some activity + _ordersViewModel.deliveryService.clearActiveDeliveringOrders(); + return; + } + delay(300, (){ + SweetAlert.show(context, subtitle: "You already have active delivery", confirmButtonText: "Continue Delivery", onPress: (isConfirm){ + pop(context, (){ + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InformationPage( + item: order, + ))); + }); + return false; + }); + }); + } + } + @override Widget build(BuildContext context) { - int orderId; + return BaseView( onModelReady: (model) async { - await model.getPendingOrders(1); + _ordersViewModel = model; + await model.getPendingOrders(1); + checkActiveDelivery(); }, builder: (BuildContext context, OrdersViewModel model, Widget child) => AppScaffold( - body: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).orientation == Orientation.landscape - ? MediaQuery.of(context).size.height * 1.6 - : MediaQuery.of(context).size.height * 1.0, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + body: SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).orientation == Orientation.landscape + ? MediaQuery.of(context).size.height * 1.6 + : MediaQuery.of(context).size.height * 1.0, + child: Column( children: [ - Padding( - padding: EdgeInsets.all(16.0), - child: Column( - children: [ - SafeArea( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(16.0), + child: Column( + children: [ + SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).haveGreatDay, + style: TextStyle( + fontSize: 14.5, + color: Color(0xff636363), + fontWeight: FontWeight.w300), + ), + Padding( + padding: EdgeInsets.only(top: 4.5), + child: Text( + _authenticationViewModel.user.userName, + style: TextStyle( + fontSize: 22.0, + color: HexColor("#343333"), + fontWeight: FontWeight.bold), + ), + ), + ], + ), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(16.0), + child: SafeArea( child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - TranslationBase.of(context).haveGreatDay, - style: TextStyle( - fontSize: 14.5, - color: Color(0xff636363), - fontWeight: FontWeight.w300), - ), - Padding( - padding: EdgeInsets.only(top: 4.5), - child: Text( - _authenticationViewModel.user.userName, - style: TextStyle( - fontSize: 22.0, - color: HexColor("#343333"), - fontWeight: FontWeight.bold), + InkWell( + child: CircleAvatar( + radius: 25.5, + backgroundColor: Color(0xff30B7B9), + child: CircleAvatar( + backgroundColor: Color(0xff30B7B9), + maxRadius: 26.0, + child: Image.asset( + 'assets/images/driver.png', + fit: BoxFit.contain, + ), + ), ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingPage( + driverName: _authenticationViewModel + .user.userName, + driverID: _authenticationViewModel + .user.userID))); + }, ), ], ), ), - ], - ), - ), - Padding( - padding: EdgeInsets.all(16.0), - child: SafeArea( - child: Column( - children: [ - InkWell( - child: CircleAvatar( - radius: 25.5, - backgroundColor: Color(0xff30B7B9), - child: CircleAvatar( - backgroundColor: Color(0xff30B7B9), - maxRadius: 26.0, - child: Image.asset( - 'assets/images/driver.png', - fit: BoxFit.contain, - ), - ), - ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SettingPage( - driverName: _authenticationViewModel - .user.userName, - driverID: _authenticationViewModel - .user.userID))); - }, - ), - ], ), - ), + ], ), - ], - ), - Row( - children: [ - Expanded( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Container( - height: MediaQuery.of(context).orientation == + Row( + children: [ + Expanded( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Container( + height: MediaQuery.of(context).orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.16 - : MediaQuery.of(context).size.height * 0.30, - width: MediaQuery.of(context).size.width * 0.44, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - gradient: LINEAR_GRADIENT, - ), - child: InkWell( - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - OrdersListScreen())), - child: Row( - mainAxisAlignment: + ? MediaQuery.of(context).size.height * 0.16 + : MediaQuery.of(context).size.height * 0.30, + width: MediaQuery.of(context).size.width * 0.44, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + gradient: LINEAR_GRADIENT, + ), + child: InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + OrdersListScreen())), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.all(2.0), - child: Column( - mainAxisAlignment: + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(2.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Text( - TranslationBase.of(context) - .youHave, - style: TextStyle( - color: Colors.white, - fontSize: MediaQuery.of(context) - .orientation == + children: [ + Text( + TranslationBase.of(context) + .youHave, + style: TextStyle( + color: Colors.white, + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig - .textMultiplier * + ? SizeConfig + .textMultiplier * 2.2 - : SizeConfig - .textMultiplier * + : SizeConfig + .textMultiplier * 1.3, - ), - ), - Text( - model.listCountUnDelivered - .toString(), - style: TextStyle( - color: Colors.white, - fontSize: SizeConfig + ), + ), + Text( + model.listCountUnDelivered + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: SizeConfig .textMultiplier * - 3.0), - ), - Text( - TranslationBase.of(context) - .undeliveredPackages, - style: TextStyle( - color: Colors.white, - fontSize: MediaQuery.of(context) - .orientation == + 3.0), + ), + Text( + TranslationBase.of(context) + .undeliveredPackages, + style: TextStyle( + color: Colors.white, + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig - .textMultiplier * + ? SizeConfig + .textMultiplier * 2.2 - : SizeConfig - .textMultiplier * + : SizeConfig + .textMultiplier * 1.3, - ), - ) - ], + ), + ) + ], + ), + ), ), - ), - ), - Padding( - padding: EdgeInsets.only(right: 9.5), - child: Container( - width: 100, - height: 100, - decoration: BoxDecoration( - color: Colors.white10, - shape: BoxShape.circle), - child: Column( - mainAxisAlignment: + Padding( + padding: EdgeInsets.only(right: 9.5), + child: Container( + width: 100, + height: 100, + decoration: BoxDecoration( + color: Colors.white10, + shape: BoxShape.circle), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/closed_box.png', - height: MediaQuery.of(context) - .orientation == + children: [ + Image.asset( + 'assets/images/closed_box.png', + height: MediaQuery.of(context) + .orientation == Orientation.portrait - ? MediaQuery.of(context) - .size - .height * + ? MediaQuery.of(context) + .size + .height * 0.09 - : MediaQuery.of(context) - .size - .height * + : MediaQuery.of(context) + .size + .height * 0.20, - width: MediaQuery.of(context) + width: MediaQuery.of(context) .size .width * - 0.20, - scale: 0.9, - fit: BoxFit.contain, + 0.20, + scale: 0.9, + fit: BoxFit.contain, + ), + ], ), - ], + ), ), - ), + ], ), - ], + ), ), - ), - ), - ) - ], - ), - ), - Expanded( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Container( - height: MediaQuery.of(context).orientation == + ) + ], + ), + ), + Expanded( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Container( + height: MediaQuery.of(context).orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.16 - : MediaQuery.of(context).size.height * 0.30, - width: MediaQuery.of(context).size.width * 0.45, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - gradient: LINEAR_GRADIENT, - ), - child: InkWell( - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - DeliverdOrdersPage())), - child: Row( - mainAxisAlignment: + ? MediaQuery.of(context).size.height * 0.16 + : MediaQuery.of(context).size.height * 0.30, + width: MediaQuery.of(context).size.width * 0.45, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + gradient: LINEAR_GRADIENT, + ), + child: InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + DeliverdOrdersPage())), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.all(2.0), - child: Column( - mainAxisAlignment: + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(2.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Text( - TranslationBase.of(context) - .youHave, - style: TextStyle( - color: Colors.white, - fontSize: MediaQuery.of(context) - .orientation == + children: [ + Text( + TranslationBase.of(context) + .youHave, + style: TextStyle( + color: Colors.white, + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig - .textMultiplier * + ? SizeConfig + .textMultiplier * 2.2 - : SizeConfig - .textMultiplier * + : SizeConfig + .textMultiplier * 1.3, - ), - ), - Text( - - model.listCountDelivered - .toString(), - style: TextStyle( - color: Colors.white, - fontSize: SizeConfig - .textMultiplier * - 3.0), - ), - Text( - TranslationBase.of(context) - .deliveredPackages, - style: TextStyle( - color: Colors.white, - fontSize: MediaQuery.of(context) - .orientation == + ), + ), + Text( + model.listCountDelivered + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: SizeConfig + .textMultiplier * + 3.0), + ), + Text( + TranslationBase.of(context) + .deliveredPackages, + style: TextStyle( + color: Colors.white, + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig - .textMultiplier * + ? SizeConfig + .textMultiplier * 2.2 - : SizeConfig - .textMultiplier * + : SizeConfig + .textMultiplier * 1.3, - ), - ) - ], - ), - ), - ), - Padding( - padding: EdgeInsets.only(right: 9.5), - child: Container( - width: 100, - height: 100, - decoration: BoxDecoration( - color: Colors.white10, - shape: BoxShape.circle, + ), + ) + ], + ), + ), ), - child: Column( - mainAxisAlignment: + Padding( + padding: EdgeInsets.only(right: 9.5), + child: Container( + width: 100, + height: 100, + decoration: BoxDecoration( + color: Colors.white10, + shape: BoxShape.circle, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/opend_box.png', - height: MediaQuery.of(context) - .orientation == + children: [ + Image.asset( + 'assets/images/opend_box.png', + height: MediaQuery.of(context) + .orientation == Orientation.portrait - ? MediaQuery.of(context) - .size - .height * + ? MediaQuery.of(context) + .size + .height * 0.09 - : MediaQuery.of(context) - .size - .height * + : MediaQuery.of(context) + .size + .height * 0.20, - width: MediaQuery.of(context) + width: MediaQuery.of(context) .size .width * - 0.20, - scale: 0.9, - fit: BoxFit.contain, + 0.20, + scale: 0.9, + fit: BoxFit.contain, + ), + ], ), - ], + ), ), - ), + ], ), - ], + ), ), - ), - ), - ) - ], - ), + ) + ], + ), + ), + ], ), - ], - ), - Padding( - padding: + Padding( + padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 15.0), - child: Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - _scanQrAndGetPatient(context, model); - }, - child: Container( - height: MediaQuery.of(context).orientation == + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + _scanQrAndGetPatient(context, model); + }, + child: Container( + height: MediaQuery.of(context).orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.18 - : MediaQuery.of(context).size.height * 0.30, - width: MediaQuery.of(context).size.width * 0.50, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - gradient: LINEAR_GRADIENT, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, + ? MediaQuery.of(context).size.height * 0.18 + : MediaQuery.of(context).size.height * 0.30, + width: MediaQuery.of(context).size.width * 0.50, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + gradient: LINEAR_GRADIENT, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Image.asset( - 'assets/images/qr_code.png', - width: MediaQuery.of(context).size.width * - 0.26, - height: MediaQuery.of(context) - .orientation == + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/qr_code.png', + width: MediaQuery.of(context).size.width * + 0.26, + height: MediaQuery.of(context) + .orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * + ? MediaQuery.of(context).size.height * 0.14 - : MediaQuery.of(context).size.height * + : MediaQuery.of(context).size.height * 0.28, - fit: BoxFit.contain, - ) - ], - ), - Column( - mainAxisAlignment: + fit: BoxFit.contain, + ) + ], + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(top: 8.0), - child: Text( - TranslationBase.of(context).scan, - style: TextStyle( - fontSize: MediaQuery.of(context) - .orientation == + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 8.0), + child: Text( + TranslationBase.of(context).scan, + style: TextStyle( + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig.textMultiplier * 6.0 - : SizeConfig.textMultiplier * 4.0, - color: Colors.white, - fontWeight: FontWeight.w400, + ? SizeConfig.textMultiplier * 6.0 + : SizeConfig.textMultiplier * 4.0, + color: Colors.white, + fontWeight: FontWeight.w400, + ), + ), ), - ), - ), - Padding( - padding: EdgeInsets.only(top: 0.0), - child: Text( - TranslationBase.of(context) - .toAddPackageToQue, - style: TextStyle( - fontSize: MediaQuery.of(context) - .orientation == + Padding( + padding: EdgeInsets.only(top: 0.0), + child: Text( + TranslationBase.of(context) + .toAddPackageToQue, + style: TextStyle( + fontSize: MediaQuery.of(context) + .orientation == Orientation.landscape - ? SizeConfig.textMultiplier * 3.0 - : SizeConfig.textMultiplier * 2.0, - color: Colors.white, - letterSpacing: 0.2, - wordSpacing: 0.5, + ? SizeConfig.textMultiplier * 3.0 + : SizeConfig.textMultiplier * 2.0, + color: Colors.white, + letterSpacing: 0.2, + wordSpacing: 0.5, + ), + ), ), - ), - ), + ], + ) ], - ) - ], + ), + ), ), - ), - ), - ) - ], - ), - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: 20.0, vertical: 1.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Text(TranslationBase.of(context).nearestDropOffs, - style: TextStyle( - fontSize: 18.0, - color: HexColor("#343333"), - fontWeight: FontWeight.bold)), + ) ], ), - if (model.state == ViewState.Idle) - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InkWell( - child: Row( - children: [ - Text( - TranslationBase.of(context).seeAll, - style: TextStyle( - fontSize: 14.5, - color: Color(0xff42B6AD)), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 20.0, vertical: 1.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + Text(TranslationBase.of(context).nearestDropOffs, + style: TextStyle( + fontSize: 18.0, + color: HexColor("#343333"), + fontWeight: FontWeight.bold)), + ], + ), + if (model.state == ViewState.Idle) + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: Row( + children: [ + Text( + TranslationBase.of(context).seeAll, + style: TextStyle( + fontSize: 14.5, + color: Color(0xff42B6AD)), + ), + Icon( + Icons.arrow_forward_ios, + size: 15.0, + color: Color(0xff42B6AD), + ), + ], ), - Icon( - Icons.arrow_forward_ios, - size: 15.0, - color: Color(0xff42B6AD), + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => OrdersListScreen()), ), - ], - ), - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => OrdersListScreen()), - ), + ), + ], ), - ], - ), - ], - ), - ), - if (model.state == ViewState.Idle) - model.orders.length == 0 - ? Text("There's No Orders To deliver") - : SizedBox(), - NetworkBaseView( - baseViewModel: model, - child: Expanded( - child: ListView.builder( - shrinkWrap: true, - scrollDirection: Axis.vertical, - itemCount: model.orders == null - ? 0 - : model.orders.length < 3 - ? model.orders.length - : 3, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 0.2), - child: OrderInfoCard( - order: model.orders[index], - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => InformationPage( - item: model.orders[index], - ))); + ], + ), + ), + if (model.state == ViewState.Idle && model.orders.length == 0) + Padding(padding: EdgeInsets.only(top:20), child: Text("There's No Orders To deliver"),), + + NetworkBaseView( + baseViewModel: model, + child: Expanded( + child: RefreshIndicator( + onRefresh: () async { + return await _ordersViewModel.getPendingOrders(1); + }, + child: ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.vertical, + itemCount: model.orders == null + ? 0 + : model.orders.length < 3 + ? model.orders.length + : 3, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 0.2), + child: OrderInfoCard( + order: model.orders[index], + isActiveToDeliver: _ordersViewModel.isActiveDeliveringOrder(index), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InformationPage( + item: model.orders[index], + ))); + }, + ), + ); }, ), - ); - }, + ), + ), ), - ), + ], ), - ], + ), ), ), - ), - ), ); } @@ -582,5 +621,5 @@ class _DashboardScreenState extends State { Utils.showErrorToast("Failed to get platform version."); // barcodeScanRes = 'Failed to get platform version.'; } - } + } } diff --git a/lib/pages/delivery/delivery_cancel_page.dart b/lib/pages/delivery/delivery_cancel_page.dart new file mode 100644 index 0000000..340ee15 --- /dev/null +++ b/lib/pages/delivery/delivery_cancel_page.dart @@ -0,0 +1,242 @@ +import 'package:driverapp/config/config.dart'; +import 'package:driverapp/core/enum/viewstate.dart'; +import 'package:driverapp/core/model/orders/next_order_request_model.dart'; +import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; +import 'package:driverapp/core/service/orders_service.dart'; +import 'package:driverapp/core/viewModels/orders_view_model.dart'; +import 'package:driverapp/locator.dart'; +import 'package:driverapp/pages/base/base_view.dart'; +import 'package:driverapp/root_page.dart'; +import 'package:driverapp/uitl/utils.dart'; +import 'package:driverapp/widgets/buttons/secondary_button.dart'; +import 'package:driverapp/widgets/delivery/customer_brief_card.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:location/location.dart'; + +import '../../uitl/translations_delegate_base.dart'; +import '../../widgets/others/app_scaffold_widget.dart'; +import 'information_page.dart'; + +class DeliveryCancelRejectedPage extends StatelessWidget { + final PendingOrdersRes item; + + DeliveryCancelRejectedPage(this.item); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (_, model, w) => AppScaffold( + isAppBarGradient: true, + isShowAppBar: true, + appBarColor: Theme.of(context).primaryColor, + arrowColor: Colors.white, + titleColor: Colors.white, + body: SafeArea( + child: Container( + // + child: ListView( + children: [ + Stack( + children: [ + Container( + decoration: BoxDecoration(gradient: LINEAR_GRADIENT), + height: MediaQuery.of(context).orientation == + Orientation.portrait + ? MediaQuery.of(context).size.width * 1 + : MediaQuery.of(context).size.width * 1, + child: Stack( + children: [ + Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).orientation == + Orientation.portrait + ? MediaQuery.of(context).size.width * 0.7 + : MediaQuery.of(context).size.width * 0.5, + padding: EdgeInsets.only( + top: MediaQuery.of(context).size.width * 0.14, + ), + decoration: BoxDecoration( + color: Colors.white10, shape: BoxShape.circle), + child: Column( + children: [ + Icon( + Icons.check_circle, + color: Colors.white, + size: 75, + ), + SizedBox( + height: + MediaQuery.of(context).size.width * 0.03, + ), + Text( + 'Delivery Confirmed', + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: + MediaQuery.of(context).size.width * 0.01, + ), + Text( + TranslationBase.of(context).confirmationSent, + style: TextStyle( + color: Colors.white, + fontSize: 13, + ), + ), + ], + ), + ), + ], + ), + ), +// Container( +// width: MediaQuery.of(context).size.width, +// height: MediaQuery.of(context).size.width, +// ), + Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).orientation == + Orientation.landscape + ? MediaQuery.of(context).size.width * 0.6 + : MediaQuery.of(context).size.width * 1.0, + margin: EdgeInsets.only( + top: MediaQuery.of(context).orientation == + Orientation.portrait + ? MediaQuery.of(context).size.width * 0.70 + : MediaQuery.of(context).size.width * 0.60, + ), + decoration: BoxDecoration( + color: Theme + .of(context) + .scaffoldBackgroundColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(80), + topRight: Radius.circular(80)), + ), + child: Column( + mainAxisAlignment: MediaQuery.of(context).orientation == + Orientation.landscape + ? MainAxisAlignment.center + : MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.only( + bottom: MediaQuery.of(context).size.width * 0.00, + ), + child: Padding( + padding: MediaQuery.of(context).orientation == + Orientation.landscape + ? EdgeInsets.only(top: 60.0) + : EdgeInsets.only(top: 30.0), + child: Column( + children: [ + // TODO return add note when its needed + // FlatButton.icon( + // padding: EdgeInsets.all(14.0), + // color: Colors.orangeAccent, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // label: Text( + // TranslationBase.of(context).addNoteBtn, + // style: TextStyle( + // color: Colors.white, fontSize: 20.0), + // ), + // icon: Icon( + // Icons.mode_edit, + // color: Colors.white, + // ), + // onPressed: () {}, + // ), + // SizedBox( + // height: MediaQuery.of(context).size.width * + // 0.00, //20, + // ), + Padding( + padding: const EdgeInsets.only(top: 30.0), + child: Container( + margin: EdgeInsets.all(10), + child: SecondaryButton( + label: TranslationBase.of(context) + .nextDelivery, + loading: + model.state == ViewState.BusyLocal, + onTap: () { + getNextOrder(context, model); + }, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only( + top: MediaQuery.of(context).orientation == + Orientation.portrait + ? MediaQuery.of(context).size.width * 0.6 + : MediaQuery.of(context).size.width * 0.4, + ), + child: CustomerBriefCard( + customerOrderId: item.orderID, + pharmacyOrderId: item.ePharmacyOrderNo, + customerFirstName: item.firstName, + customerLastName: item.lastName, + mobileNo: item.mobileNumber, + totalPayment: item.amount, + distanceInKilometers: item.distanceInKilometers, + showDistance: false, + deliveryTime: item.orderCreatedOn), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } + + getNextOrder(BuildContext context, OrdersViewModel model) async { + model.setState(ViewState.BusyLocal); + LocationData loc = await Utils.getLocation(); + NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel( + pageIndex: 0, + pageSize: 0, + latitude: loc.latitude.toString(), // "46.621730", + longitude: loc.longitude.toString(), // "24.797682", + searchKey: ""); + await model.nextOrder(nextOrderRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + if (model.nextOrdersList != null && model.nextOrdersList.length == 0) { + Utils.showErrorToast("No Items in the list"); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => RootPage(), + ), + ); + } else { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => + InformationPage(item: model.nextOrdersList[0]), + ), + ); + } + } + } +} diff --git a/lib/pages/delivery/delivery_confirmed_page.dart b/lib/pages/delivery/delivery_confirmed_page.dart index f8f48ee..f377e41 100644 --- a/lib/pages/delivery/delivery_confirmed_page.dart +++ b/lib/pages/delivery/delivery_confirmed_page.dart @@ -2,7 +2,9 @@ import 'package:driverapp/config/config.dart'; import 'package:driverapp/core/enum/viewstate.dart'; import 'package:driverapp/core/model/orders/next_order_request_model.dart'; import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; +import 'package:driverapp/core/service/orders_service.dart'; import 'package:driverapp/core/viewModels/orders_view_model.dart'; +import 'package:driverapp/locator.dart'; import 'package:driverapp/pages/base/base_view.dart'; import 'package:driverapp/root_page.dart'; import 'package:driverapp/uitl/utils.dart'; @@ -211,10 +213,8 @@ class DeliveryConfirmedPage extends StatelessWidget { NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel( pageIndex: 0, pageSize: 0, - latitude: loc.latitude.toString(), - //"46.621730", - longitude: loc.longitude.toString(), - //"24.797682", + latitude: loc.latitude.toString(), // "46.621730", + longitude: loc.longitude.toString(), // "24.797682", searchKey: ""); await model.nextOrder(nextOrderRequestModel); if (model.state == ViewState.ErrorLocal) { diff --git a/lib/pages/delivery/information_page.dart b/lib/pages/delivery/information_page.dart index 0b064d2..8b030e6 100644 --- a/lib/pages/delivery/information_page.dart +++ b/lib/pages/delivery/information_page.dart @@ -5,14 +5,18 @@ import 'package:android_intent/android_intent.dart'; import 'package:driverapp/app-icons/driver_app_icons.dart'; import 'package:driverapp/config/config.dart'; import 'package:driverapp/core/enum/viewstate.dart'; +import 'package:driverapp/core/model/StatusModel.dart'; import 'package:driverapp/core/model/orders/pending_orders_req_model.dart'; import 'package:driverapp/core/model/orders/pending_orders_res_model.dart'; import 'package:driverapp/core/model/orders/update_order_status_request_model.dart'; import 'package:driverapp/core/service/delivery_tracking_services.dart'; import 'package:driverapp/core/viewModels/orders_view_model.dart'; import 'package:driverapp/locator.dart'; +import 'package:driverapp/pages/authentication/delivery_verification_page.dart'; +import 'package:driverapp/pages/authentication/verification_page.dart'; import 'package:driverapp/pages/base/base_view.dart'; import 'package:driverapp/uitl/app_shared_preferences.dart'; +import 'package:driverapp/uitl/app_toast.dart'; import 'package:driverapp/uitl/translations_delegate_base.dart'; import 'package:driverapp/uitl/utils.dart'; import 'package:driverapp/widgets/bottom_sheet/action_sheet_button.dart'; @@ -25,11 +29,13 @@ import 'package:driverapp/widgets/delivery/package_content.dart'; import 'package:driverapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:hexcolor/hexcolor.dart'; -import 'package:maps_launcher/maps_launcher.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:map_launcher/map_launcher.dart'; +import 'package:sweetalert/sweetalert.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'delivery_cancel_page.dart'; import 'delivery_confirmed_page.dart'; @@ -44,16 +50,23 @@ class InformationPage extends StatefulWidget { // ignore: must_be_immutable class _InformationPageState extends State { - int _orderStatus; + var _deliveryService = locator(); PendingOrdersRes _item; - bool _isDeliveryStarted = false; + bool _isDeliveryStarted; + OrdersViewModel _viewModel; + @override + void initState() { + super.initState(); + _item = widget.item; + _isDeliveryStarted = _deliveryService.getActiveDeliveringOrders().contains(_item.ePharmacyOrderNo.toString()); + } @override Widget build(BuildContext context) { - _item = widget.item; return BaseView( + onModelReady: (model) => _viewModel = model, builder: (_, model, w) => AppScaffold( isShowAppBar: true, isShowHomeIcon: true, @@ -117,7 +130,7 @@ class _InformationPageState extends State { btnName: TranslationBase.of(context).location, btnFunction: () { - openMapIntent(_item); + _openMapDirection(_item); // MapsLauncher.launchCoordinates( // _item.latitude, _item.longitude); }, @@ -196,15 +209,11 @@ class _InformationPageState extends State { ? EdgeInsets.all(8.0) : EdgeInsets.symmetric(horizontal: 12.0), child: SecondaryButton( - label: - TranslationBase.of(context).clientReached, + label: _isDeliveryStarted + ? TranslationBase.of(context).deliveryOption + : TranslationBase.of(context).startDelivery, onTap: () { - locator() - .initiateOrderDelivery(_item.orderID) - .then((results){ - setState(() => _isDeliveryStarted = true); - // showDeliveryOptions(model); - }); + takeAction(); }, ), ), @@ -234,8 +243,69 @@ class _InformationPageState extends State { ); } + void takeAction(){ + if(_isDeliveryStarted) { + showDeliveryOptions(_viewModel); + }else{ + if(_deliveryService.getActiveDeliveringOrders().isEmpty){ + SweetAlert.show(context,subtitle: "Initializing delivery...", style: SweetAlertStyle.loading); + _viewModel.initDelivery(_item, completion: (response) { + if (response.isSuccessful) { + setState(() => _isDeliveryStarted = true); + Navigator.pop(context); + AppToast.showSuccessToast(message: "Start navigation by clicking icon [${response.data}]"); + + }else{ + SweetAlert.show(context,subtitle: response.message, style: SweetAlertStyle.error); + } + }); + }else{ + SweetAlert.show(context,subtitle: "Complete the last delivery first.",style: SweetAlertStyle.error); + } + } + } + + cancelDelivery() { + List speedOptions = [ + TranslationBase.of(context).notReachableOnPhoneCall, + TranslationBase.of(context).notAvailableAtlocation, + TranslationBase.of(context).accident, + TranslationBase.of(context).deliverLater, + // TranslationBase.of(context).other, + ]; + + List speedIcons = [ + Icon(IconData(0xe901, fontFamily: 'HMGIcon1')), + Icon(IconData(0xe900, fontFamily: 'HMGIcon1')), + Icon(IconData(0xe902, fontFamily: 'HMGIcon1')), + Icon(IconData(0xe903, fontFamily: 'HMGIcon1')), + ]; + showMaterialSelectionPicker( + context: context, + title: TranslationBase.of(context).selectReason, + items: speedOptions, + selectedItem: speedOptions.first, + icons: speedIcons, + onChanged: (value) async { + SweetAlert.show(context,subtitle: "Canceling delivery...", style: SweetAlertStyle.loading); + var result = await _viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.cancel); + Navigator.pop(context); + if(result.isSuccessful){ + _viewModel.deliveryService.stopLocationUpdate(_item.ePharmacyOrderNo); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => DeliveryCancelRejectedPage(_item), // Replace with Delivery Cancel Screen + ), + ); + }else{ + SweetAlert.show(context,subtitle: result.message,style: SweetAlertStyle.error); + } + }, + ); + } showDeliveryOptions(OrdersViewModel model) { showModalBottomSheet( @@ -250,7 +320,7 @@ class _InformationPageState extends State { context: context, builder: (BuildContext bc) { return FractionallySizedBox( - heightFactor: 0.35, + heightFactor: 0.40, child: ListView( children: [ Container( @@ -278,8 +348,7 @@ class _InformationPageState extends State { height: 10, ), FractionallySizedBox( - widthFactor: MediaQuery.of(context).orientation == - Orientation.portrait + widthFactor: MediaQuery.of(context).orientation == Orientation.portrait ? 0.9 : 0.98, child: Container( @@ -310,7 +379,11 @@ class _InformationPageState extends State { TranslationBase.of(context).delivered, icon: DriverApp.deliverd_icon, onTap: () { - selectAction(context, 2, model); + Navigator.of(context).pop(); // Pop Bottom Action Sheet + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => DeliveryVerificationPage(order: _item)), + ); }, ), SizedBox(height: 15), @@ -328,18 +401,19 @@ class _InformationPageState extends State { .deliveredRejected, icon: DriverApp.rejected_icon, onTap: () { - selectAction(context, 3, model); + Navigator.of(context).pop(); // Pop Bottom Action Sheet + rejectDelivery(); + } + ), + SizedBox(height: 15), + ActionSheetButton( + label: TranslationBase.of(context).cancel, + icon: DriverApp.not_reachable_icon, + onTap: () { + cancelDelivery(); }, ), SizedBox(height: 15), - // ActionSheetButton( - // label: TranslationBase.of(context).canceled, - // icon: DriverApp.not_reachable_icon, - // onTap: () { - // selectAction(context, 6, model); - // }, - // ), - // SizedBox(height: 15), ], ), ], @@ -355,88 +429,50 @@ class _InformationPageState extends State { }); } + rejectDelivery(){ + SweetAlert.show(context,title: "Are you sure?",style: SweetAlertStyle.confirm, showCancelButton: true,onPress: (bool isConfirm) { + if (isConfirm) { + _viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.rejected).then((results){ - selectAction(BuildContext context, orderStatus, OrdersViewModel model) { - String orderStatusText; - this._orderStatus = orderStatus; - switch (orderStatus) { - case 2: - orderStatusText = TranslationBase - .of(context) - .delivered; - break; - // case 4: - // orderStatusText = TranslationBase.of(context).deliveredAccepted; - // break; - case 3: - orderStatusText = TranslationBase - .of(context) - .deliveredRejected; - break; - // case 6: - // orderStatusText = TranslationBase.of(context).canceled; - // break; - } - showDialog( - context: context, - builder: (BuildContext context) { - return CustomDialog( - orderStatusText: orderStatusText, - callService: () { - updateOrderStatus(context, model); - }, - model: model, - ); }); + } + return true; + }); } - updateOrderStatus(BuildContext context, OrdersViewModel model) async { - UpdateOrderStatusRequestModel updateOrderStatusRequestModel = - UpdateOrderStatusRequestModel( - deliveryOrderID: _item.orderID, - deliveryOrderStatus: _orderStatus, - rejectionReason: "NO Reason", - cancleReason: ""); - await model.updateOrderStatus(updateOrderStatusRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - Navigator.of(context).pop(); - model.hideBottomSheet(); - } else { - /// to hide the dialog - Navigator.of(context).pop(); - model.hideBottomSheet(); - - /// to remove this page from the stack please no one remove this line. - Navigator.of(context).pop(); - - - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => - DeliveryConfirmedPage(_item), - ), - ); - } - } - - openMapIntent(PendingOrdersRes order) async{ + _openMapDirection(PendingOrdersRes order) async{ Utils.getLocation().then((locationData){ if(locationData != null){ - var url = "https://www.google.com/maps/dir/?api=1&destination=24.701833,46.697642&travelmode=driving&dir_action=navigate"; - if (Platform.isAndroid) { - var intent = AndroidIntent(action: 'action_view',data: url,package: 'com.google.android.apps.maps'); - intent.launch(); - }else { - print(url); - } + // MapLauncher.isMapAvailable(MapType.google).then((value){ + // if (value) { + // MapLauncher.showDirections( + // mapType: MapType.google, + // destination: Coords(order.latitude, order.longitude), + // directionsMode: DirectionsMode.driving, + // destinationTitle: order.receiverFullName()) + // .then((value) { + // + // }); + // }else{ + // // Google Map Not installed show error + // } + // }); + + /* Directly start navigation */ + MapLauncher.isMapAvailable(MapType.google).then((value){ + var url = "https://www.google.com/maps/dir/?api=1&destination=${order.latitude},${order.longitude}&travelmode=driving&dir_action=navigate"; + if (Platform.isAndroid) { + var intent = AndroidIntent(action: 'action_view',data: url,package: 'com.google.android.apps.maps'); + intent.launch(); + }else if (Platform.isIOS) { + launch(url); + } + }); // Start updating server wit your current location - locator().startLocationUpdate(order.orderID); + _deliveryService.startLocationUpdate(order.ePharmacyOrderNo); } }); - } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 07c8737..54020af 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -62,6 +62,9 @@ class TranslationBase { String get enterVerificationMsg => localizedValues['enterVerificationMsg'][locale.languageCode]; + String get enterCustomerVerificationCodeMsg => + localizedValues['enterCustomerVerificationCodeMsg'][locale.languageCode]; + String get forgotPassword => localizedValues['forgotPassword'][locale.languageCode]; @@ -111,6 +114,10 @@ class TranslationBase { String get startDelivery => localizedValues['startDelivery'][locale.languageCode]; + String get deliveryOption => + localizedValues['deliveryOption'][locale.languageCode]; + + String get addNoteBtn => localizedValues['addNoteBtn'][locale.languageCode]; String get nextDelivery => @@ -136,6 +143,24 @@ class TranslationBase { String get selectAction => localizedValues['selectAction'][locale.languageCode]; + String get selectReason => + localizedValues['selectReason'][locale.languageCode]; + + String get other => + localizedValues['other'][locale.languageCode]; + + String get notReachableOnPhoneCall => + localizedValues['notReachableOnPhoneCall'][locale.languageCode]; + + String get deliverLater => + localizedValues['deliverLater'][locale.languageCode]; + + String get notAvailableAtlocation => + localizedValues['notAvailableAtlocation'][locale.languageCode]; + + String get accident => + localizedValues['accident'][locale.languageCode]; + String get youHaveSelected => localizedValues['youHaveSelected'][locale.languageCode]; diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 074b97f..07a5532 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -13,6 +13,22 @@ import 'app_toast.dart'; AppSharedPreferences sharedPref = new AppSharedPreferences(); +popWithDelay({@required BuildContext context, @required num seconds, @required VoidCallback callback}){ + Navigator.of(context).pop(); + Future.delayed(Duration(milliseconds: (seconds*1000).toInt())).then((value){ + callback(); + }); +} + +pop(BuildContext context, VoidCallback callBack){ + Navigator.of(context).pop(); + callBack(); +} + +delay(int milliseconds, VoidCallback callback){ + Future.delayed(Duration(milliseconds: milliseconds)).then((value) => callback()); +} + class Utils { ///show custom Error Toast /// [message] to show for user @@ -138,3 +154,4 @@ class Utils { return formattedNamesList.join(' '); } } + diff --git a/lib/widgets/order/order_info_card.dart b/lib/widgets/order/order_info_card.dart index 7b9147d..f51a25b 100644 --- a/lib/widgets/order/order_info_card.dart +++ b/lib/widgets/order/order_info_card.dart @@ -6,140 +6,157 @@ import 'package:hexcolor/hexcolor.dart'; class OrderInfoCard extends StatelessWidget { const OrderInfoCard( - {Key key, this.order, this.onTap, this.showStatus = false}) + {Key key, this.order, this.onTap, this.showStatus = false, this.isActiveToDeliver = false}) : super(key: key); final dynamic order; final Function onTap; final bool showStatus; + final bool isActiveToDeliver; @override Widget build(BuildContext context) { return InkWell( - child: Container( + child: + Container( child: RoundedContainer( showShadow: true, raduis: 25.0, height: MediaQuery.of(context).orientation == Orientation.portrait ? MediaQuery.of(context).size.height * (showStatus ? 0.22 : 0.160) : MediaQuery.of(context).size.height * - (showStatus ? 0.359 : 0.269), + (showStatus ? 0.359 : 0.269), child: FractionallySizedBox( widthFactor: 0.98, - child: Column( - // mainAxisAlignment: MainAxisAlignment.start, + child: Stack( + children:[ + if(isActiveToDeliver) + Padding( + padding: const EdgeInsets.all(10.0), + child: Align( + alignment: Alignment.bottomRight, + child:Image.asset( + 'assets/images/check.png', + height: 20, + width: 20, + ), + ), + ), + Column( + // mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: - EdgeInsets.only(left: 15.0, top: 14.0), - child: Image.asset( - 'assets/images/location.png', - height: MediaQuery.of(context) - .orientation == - Orientation.portrait - ? MediaQuery.of(context).size.height * - 0.06 - : MediaQuery.of(context).size.height * - 0.11, - width: MediaQuery.of(context).orientation == - Orientation.portrait - ? MediaQuery.of(context).size.width * - 0.05 - : MediaQuery.of(context).size.width * - 0.09, - ), - ), - SizedBox( - width: 13, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(top: 20.0), - child: Text( - Utils.formatStringToPascalCase( - order.firstName + - ' ' + - order.lastName), - style: TextStyle( - fontSize: 18.0, - color: HexColor("#343333"), - fontWeight: FontWeight.bold), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: + EdgeInsets.only(left: 15.0, top: 14.0), + child: Image.asset( + 'assets/images/location.png', + height: MediaQuery.of(context) + .orientation == + Orientation.portrait + ? MediaQuery.of(context).size.height * + 0.06 + : MediaQuery.of(context).size.height * + 0.11, + width: MediaQuery.of(context).orientation == + Orientation.portrait + ? MediaQuery.of(context).size.width * + 0.05 + : MediaQuery.of(context).size.width * + 0.09, + ), ), - ), - Text( - order.mobileNumber, - style: TextStyle( - color: Color(0xff30B7B9), - fontWeight: FontWeight.w600, - fontSize: 15.0, + SizedBox( + width: 13, ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 20.0), + child: Text( + Utils.formatStringToPascalCase( + order.firstName + + ' ' + + order.lastName), + style: TextStyle( + fontSize: 18.0, + color: HexColor("#343333"), + fontWeight: FontWeight.bold), + ), + ), + Text( + order.mobileNumber, + style: TextStyle( + color: Color(0xff30B7B9), + fontWeight: FontWeight.w600, + fontSize: 15.0, + ), + ), + Text( + order.orderID.toString(), + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.w400, + letterSpacing: 8.0), + ), + ], + ), + ], + ), + ], + ) + ], + ), + Padding( + padding: EdgeInsets.all(8.0), + child: DistanceInKilometers( + distanceInKilometers: order.distanceInKilometers, + ), + ), + ], + ), + if (showStatus) + Row( + children: [ + Container( + margin: EdgeInsets.only(bottom: 12, left: 10), + child: RoundedContainer( + margin: 4, + showShadow: false, + backgroundColor: + order.statusID == 2 ? Colors.green : Colors.red, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 5, horizontal: 15), + child: Text( + order.description, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 15.0, ), - Text( - order.orderID.toString(), - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.w400, - letterSpacing: 8.0), - ), - ], + ), ), - ], + ), ), ], ) - ], - ), - Padding( - padding: EdgeInsets.all(8.0), - child: DistanceInKilometers( - distanceInKilometers: order.distanceInKilometers, - ), - ), - ], - ), - if (showStatus) - Row( - children: [ - Container( - margin: EdgeInsets.only(bottom: 12, left: 10), - child: RoundedContainer( - margin: 4, - showShadow: false, - backgroundColor: - order.statusID == 2 ? Colors.green : Colors.red, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 5, horizontal: 15), - child: Text( - order.description, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.w600, - fontSize: 15.0, - ), - ), - ), - ), - ), ], - ) - ], - ), + ), + ]), ), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 5cf6f1a..571f86f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,11 +86,11 @@ dependencies: #android_intent android_intent: any + # Alerts Dailogs + sweetalert: any - - - - + # flutter_material_pickers + flutter_material_pickers: 1.7.4 @@ -126,3 +126,7 @@ flutter: - asset: assets/fonts/Metropolis/Metropolis-Regular.otf - asset: assets/fonts/Metropolis/Metropolis-Bold.otf - asset: assets/fonts/Metropolis/Metropolis-Light.otf + + - family: HMGIcon1 + fonts: + - asset: assets/fonts/icomoon.ttf