From 91e1404bcb9b5ec81ba802de9ec6e59fb08f00bc Mon Sep 17 00:00:00 2001 From: mikael-zakaria Date: Thu, 18 Sep 2025 10:07:28 +0700 Subject: [PATCH 1/4] Update Show ValueSet menjadi left join --- app/Controllers/ValueSet.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Controllers/ValueSet.php b/app/Controllers/ValueSet.php index 88d4dcd..529f5ad 100644 --- a/app/Controllers/ValueSet.php +++ b/app/Controllers/ValueSet.php @@ -38,8 +38,9 @@ class ValueSet extends Controller { public function show($VID = null) { $rows = $this->db->table('valueset') - ->select("*") - ->where('VID', (int) $VID) + ->select("valueset.*, valuesetdef.VSName") + ->join('valuesetdef', 'valuesetdef.VSetID = valueset.VSetID', 'LEFT') + ->where('valueset.VID', (int) $VID) ->get()->getResultArray(); if (empty($rows)) { From 8f30704a2b0d2c2401787593f0d256ce8383b698 Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 18 Sep 2025 13:04:36 +0700 Subject: [PATCH 2/4] add param to valueset and valuesetdef --- app/Controllers/ValueSet.php | 10 +++++++--- app/Controllers/ValueSetDef.php | 12 ++++++++---- public/clqms01.sql.gz | Bin 0 -> 6668 bytes public/upload/meow.jpg | Bin 0 -> 13753 bytes public/upload/panda.jpg | Bin 0 -> 24331 bytes 5 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 public/clqms01.sql.gz create mode 100644 public/upload/meow.jpg create mode 100644 public/upload/panda.jpg diff --git a/app/Controllers/ValueSet.php b/app/Controllers/ValueSet.php index 529f5ad..145e7fa 100644 --- a/app/Controllers/ValueSet.php +++ b/app/Controllers/ValueSet.php @@ -17,9 +17,13 @@ class ValueSet extends Controller { } public function index() { - $rows = $this->db->table('valueset') - ->select("*") - ->get()->getResultArray(); + $builder = $this->db->table('valueset')->select("*"); + $param = $this->request->getVar('param'); + if ($param !== null) { + $builder->like('VValue', $param, 'both'); + $builder->orlike('VDesc', $param, 'both'); + } + $rows = $builder->get()->getResultArray(); if (empty($rows)) { return $this->respond([ diff --git a/app/Controllers/ValueSetDef.php b/app/Controllers/ValueSetDef.php index f3b7ec3..1bf8b93 100644 --- a/app/Controllers/ValueSetDef.php +++ b/app/Controllers/ValueSetDef.php @@ -17,10 +17,14 @@ class ValueSetDef extends Controller { } public function index() { - $rows = $this->db->table('valuesetdef') - ->select("*") - ->get()->getResultArray(); - + $builder = $this->db->table('valuesetdef')->select("*"); + $param = $this->request->getVar('param'); + if ($param !== null) { + $builder->like('VSName', $param, 'both'); + $builder->orlike('VSDesc', $param, 'both'); + } + $rows = $builder->get()->getResultArray(); + if (empty($rows)) { return $this->respond([ 'status' => 'success', diff --git a/public/clqms01.sql.gz b/public/clqms01.sql.gz new file mode 100644 index 0000000000000000000000000000000000000000..8e6591154454a856592f17230f9505d7be9b18cd GIT binary patch literal 6668 zcmV+n8uR5JiwFP!000000|Nj6000000000ViwFP!000001MOW~bK*#rexCXj+9zDI zR5cP{z!M#@+>9|uP)Ojmdp2ANq#?_?(7M=dzwd9^nD>3$xBg?Bc~XG5>8Ps9J-rdr zUB)2JIZB;dp8WFS4WQjEIZHkBxRsQwK;hs>e(ubxYlAC=s{7YY}JLQa13;Q5p--1|rRaz9(r z*<-*-3i7+)7yI7v=D=hO?(1V~a6hT{$L;%paevny4Y-WG+d0z`zt$YJ>sDK7)vbD? zZnl-rGy4}OD5#&6AO8AprGi>0D6RHoecZQ{=2d-EZ(8k$jEerPBVXYg#5J@FF+#UpPVBBuTNkuAIG7 zl+Pv$X}9%RVQzS)s_!>#GsgXXUJx|BIdd20OOQ&{b;G8Vnr z+zt5?@n=iopQ(i{OOj?wp_R+Wn&?v!(iZ>utjzhVu=pWW+npmM!%yIWKD>YTUTGVhuF?Ln>$)EI+N80$nSb0f^ZN7sf^v^1Hn%ai zXxA{?BTMNT)*xxHwYBoQX36jAKc8&g_5-}#sw%%#$$JG{+kAHhs`!h1Rr7zz)h|0a z@#|r+BrXd=;^x+0i&w6e9TrW{_UnS>xBs$Esnb*BMCig=eQzR|Q$O9#com zM(AsT(2D6p9t$CVic}7@04$xDg)JhY2y--uKaJ)HFBpC#d42AeA#)K9u=_~r*mo#q zK@}|CxRLbH6rmOdua8Zjj)IU!2__$GKDIU-7(H0~t_}3B)SnXe1@UxMSiErsjcSl3 zaY(w4t5u*M#q>U5h1nQMqjpx+Qg3# zdST{9yC2gpSmdPB7eW4AOwV3vI(Z4i83oH}tWj_8rWtHDTk1C8aMTG?RgS z2l81xn>{g-SB7@v^H>O(=Mq~nL!LVo?;%|d*u5?NgtIZ9<`t87kV>07CKnY25SS*J zlAq`QnJx=_qI)G}1w6`t^@{qhbm2W=QCbB5xT#C_FnA^y1Ng_pk_^!k4dZm4&IMjF zlDF~6E3?zdg_Cp#@+LkDS+G>P?p)M#gBj(o7WMgM&woi51I{y&=Jg|&GNmOPIv_Sl z_tGLbQb$HXWG@JoEsEetm+}E4|B>rmxg>#?&IJC{>c&hFf5LQn;Wy3UM9??M)KezZ zpQp!9QMgC%N|!9olvfByM=BhmsgGg?>U&;#P?Us2H0y?Ba0wD}CE*Fp+qgk54mW0& za-dX%yIcYr?|pc_SLzS4;~vpfG_~0*U4ZZfs|mTYxg_cCS`y}OUiBq0v(t54ItOYa zrgq8Cv-FrP3A;Cck~&`cyoBOCMV2rsfde#q!064qKsoDCoi3mgjgr(tDJ_83r9m&x@XPYVd_YYeSvqBR9vJ`8);AHfH77R0)^qCMbh@ z3}VH2kD0Vl7B0~obtMx|yvhhGp~~PGT^WJD{SQy|^S|f1Pae3qUPu11p2_xST6 z_W=(XL$}?;YN0ZC#rQ@N`{cL(CWzj_4Q_|P@Ur3=5%bt{@B>*4HDBp$iM0P*_(976 zd$g$Q5dSfqUU)+58cfmp!lqsnrl-PlVepm?`L^Xb%*8Bs4kHBV$!ms;spDK2z1@VW zqCJav3FW8L3uCuCw?MymS%vA;!qjFTT%*kk2x33scMulu7@vUWmx%D5knx1riI__f zH3-wUrO&r{7wRMQ6=C?c2|aN;2tBNduL#4NH+Pc$nLE0hZpezTeA|Nhr5!Grx5Dlq zEPvSt*SaM3V{$~PoatPBJOc;sF^{eYf4CeCq!{0$nNmhYxWc9M(@XXRc{Je%mt8{= zyJ&W=RG>-V)0aMRXX!bm0!}c#l;qT%ErkPM^;<vXkS$oj?rm@MLX2<7Z^Qcg!Wj{`@9lK zuO_R)_MIy*PiKkgxhjm`>B`2lDX&-f7(Jasn7=b>0*6m2V*VZZsrx zK(os;cODGl>=vfj6CO zwdc=K`NHbGI@CHn@=6|;C>E{)MA(yfR*$+b*b@so_qx!e9`o6hAn8H{jBq%D@~G$W z@@{8LHKg9krhm@`*&P!Q#GcejEHFE-aERUwq?}&#%#$5LFFc~xks5vR7cZ~4MgdUl z*P+|*6EE?IN5+zfDB&>uNnMHxpRlk8xUt^=WA^EkxJW^x0^Zm+Wm{?Bh0FATnhJ=^6kv)ay_Y>12kCYE?iD^;Soc&&h%WGo} zYx)hxDO zLtG00!Am(|sI!?bi-NpzN#~Sj7&@20e}HDhlJo{hF}i2Zy{E6qrvM!4&4J{03EFJ% z4Wkp&FFbUT3=l%yXvZ8p9ngi3+yy{FU6u)gC*Y$&f@FFC3iW!-<9jpgQ2;B{2X~U; zRSXAF?*mj&msqyW>v9Ln27m|}vLZ2f{e}%WRloy{(O5D>e)>Q`1sKp6Lhu=MMUZ+5 zP(Y*KlH_8j4PlyBddywSJtqq?sscJ_G~;_dD@|h4If~<`fDsyZ8@4-2@G28vLZb@_ z+u-G#PZkk2%PJhfXpbbzf+7|IpwQ^lH{|FnZV{R!EyOU70hG|VgzCxg{0Gl|%!13S z01@iFR?HVJd2v0 z;jj)08InhQwTB9b;jn)rIc#L?tO8&-G}|#b4S2sIW<%q7R1C&b0Y4nd>8BxAnu91D z;KQLzi9@oAh$6f@12&)nVmKV#N=|TXMAd*64yA7oDV7`nE*#39dAMXYTdjDb5bFbG zIBd$tXW@)6AG43J|4_~W4L#hoC15DK@FDlmXo00IKnjNvV;)A-4?Qulg5-CA20ux3 z;uFEJG8M4Fkp%BXzx^X}8CH7(JUALi4$r~s5WojVvJM$VK_F(IiN1VJ(0AhfN*C$pAJqLCyCgqTB(eZt>>2f~;2sM@xiZ0^PYhez0z->tg1sNjFr5SBsLN?y$s{XHGG38TiI|D1!N$x7$mFDHZADC&%as{|44$MFiJ#)}35ey588-%7 zV5S0IY08SlB(f)Pk;nni(zJ$>$5SlNkK#qd8ORK0yl~05MI8 zW0;~y#F7Hwn5JBaWKti$fp8!5wkhdfW=m?@h_W@nE6qOiC8n@BQTmjZ>IfJ3OGoOD z7gl8DA+xy}V3y`jddwocl=~&+ZrX~%OkS!1ifK-uV>N9)40uE|q5+I)PK-4Nx}r`4 zB-50OC`~cl?`2zTp#h$0%E?lb=SpnYpaFV$7ssub6^a*UAY9-R9dpYS&)aOmOkU-Y zFn?xTuh|+8o@2JQQq2g%@-$V>b4n*zVGHpzKsx(9ncRG)^oje3JS?D{ri7KVGzk1- zEHeSDFmn*61h~_@mPUIb_Ebz32t{5)B6*?i&kx92GC)Ah8yP^)ysyI=DObM4^elXp zBNT)QQpc@)vKLY5LdMC4(P@B)S~s9Zi?C+_whw)=&}{~wcBTb58la@sbx%t9!ZH-L z8UUe|Tw`nz_f=F7d1dS}G5pUugx3HPwd5?KwImGJ7l5KxAELx!j^}^q^C}r}20%qE zx%k-fkaaj30H0Q`FR33XR<&z@d|Cr(1&`-Ugk1QEWy#iXUuJV6UDNWW1Z|w~7fVhM zS-jB05H}4lP)ml6_1pjYkL(507Pv!Cm$&dA#cE~TApixnWQ8NRWNFkSOf1aGl&Sy} zwZ;=EfyXSOb^t`ja`Zc1pk<{7i0HTnnixNd^~H!H01mB>AfRK|KSx-pcfNn~>iXV|6JZY?V4<+cl%JP*# z6xuJm!E59Fygz(kyugaMy`kxIQ6nL_)+%0Cb(m z+HAsWvsYg6@=OIQmH}DFo~;0jofr@p6GlVDK<4x{fMO?|hUDO#xw~DQ6EEdODkH#V zCvwhfU&8pK`4M9mPI%LYQsjo%Hj`m_8HEutF|PqQ+cse>(v8TmzStGAMl z*3Dk+xCQ@=eO#NCzQx|GjcQMC&Dz|5^Zr{lVoCf;7rB$ZdJM^*c>&}ue2fkTtaLud z=wJqg-})s|YJAn_bDstQ7Bb_2`svY}DW+P~{;HVTJn?sm zsng1zdCoEAi_073H$CV3DxVAFX`P!lq`!uLRG!*A$eZhwhsffXQsMeWt1bTNtJONe zb_r+DzPK^Zp%m>d{unELuJcB)CyLU2LlDI}eshbn`Oy?6E^qAJoqy*P)}4#3qYsSw z*2@aD=9U_xY(G5ES;#Gd+VZVk&R^wCD1TH0?aN9wzMK=;s4TZeGYmkCU0GgcVEW0 zRy9pMcJCcAl?%0Wu`wEmDaD&Ix9U7_?yU$-sIySowTM8{inU!4r&|FcwDXISmK1Rw zZ`(|WD5i-hT@(s?t*FEsITIpITT_ZCUKA@y5!HBe=df;?YZ>Kq8LE1r?KGnn@AQm~ zD@5!E;*N-OA)=5B5)sFMAeg4H7O@|hdm>6)8A%Tpfn6%^D&u6RYUS7@I}aivy>z}S z;$)}_5j-@s-Dnq)UaIVfP)~+xETVc*Oa_>U^wO?-swdr3is0%jCp}!mXKB|xPX~z< zp;h;EaUSm@O^7(@o>D|nyC|(2nmP<)qSiZB#6S&rcCs!>D`bX}J$VQX)Eqmf(9~^^ z8q(nb-9d>k^yvfp6{9kULob;hgjoo6HlN#Q`2>`N@!mZPWuM^pHlv4(k5ac8K}V_` z>dr-Ncd}d@+GIut4-MvrOH3FL&5?4=41G$&dlh|9NvCC`E285P7NSQMt*5aty1VWW zEu4=Yy>wU%JA~OWs(`8_NsQ`cxb$4~L3D4*Y?_I*83my@yTDC@M`my;k`X!6RHqto zpGsAWSalH+Tg(ka2_HTxi`s0#E90-kMUVLhd!=r$WGhS+Ena&s1*SC<`+h$wQx+a= z8qkTt+~Sdt788BuK3d-Q0b;*)IF!uJ@AuEsN@U`*#D@dA-DG^W`}u$x{FrQ<{%kJ_ z-fCPXd!+rr*!HRNd(V;IbR79)=aAp&0P;IYKA%YB`AxFUClhjhlXUZY*)^Zcp!r0m z%qOy8K9TYAaaPMGGFM(^rz3}t?J7CHpHA}Yl#$;}3;AT|=l5egzX|62e$?i7Vsj62 zPexn*Afod7v6J7#NQSX53@dnzQx?TqZvDIWLfAL_))JRCBRf765eF7t6jCLBA&z{y7|$!iqDgfP$n!9zN5c5C(+nk>K{t_TjaihlgJzfISzvhlgLquc`MU zo0an^EN9!^vaq9wAXMcqP5#;+_QjS4&w*R-YUaqLbHD?Hzr>#^TD4fIYWqb$ECdqE zw9e%`%`?o;ZuO_`>Tl1Id`O?bf{-C{X>Hfy;Q;yQc=_;EJA_!Yq$1O~x84GG+fi67 zR;W#aRqFY9?#P8KcaX1N?}LYs0Kfrj9ANwA;KSaJ`n$rebQpGA3$=py|7840{%;Py zLns4aj5U0*hhrRtHIBr~p|_~t>Mi9H-cqgcAFWmeEuD)LE&i2+D~s{=TRF-;Xaj)F z8mZa7*(R$41ZV1P_cZ1jM5ZcO9!VYI6F4#8cj!&-;DTfuTuuGVOy zS9uE0si6E~pGM?2N?mtJl@mG@37-FKt_inDu(q~U0ynWj{A{^i)poU6&GWvIXLHEz zCvd!-%QXS4m1{Xr^4c$|xx|~by%{Lhq;o=6+sn;pwWpgS9l=+-Xd;(XkL$C-L%VXU z*ZjJ$KB?Cl==J<)A9@_qEUhbmS}yS>W*yRSubsI|&ztXE!?I#rjAYhb?Nog82rm|o zxZ>|tTS-y3rAMx`<8H@sT)=SG;O!oYD-J0o2a4kt1GfB1ulq{Xsf816S1s1GYAva} z(pz*T#{uh7T=c8!qF+rE{X^a{aCN!+>N40Wa_Pd`+ot^8y-ih*tE^NhmWpw|8>_7R zb}HKk=u2^4R@XxXRr~X)O#SETY=1_g99LHAdNd&4{7H1C{YkWzc@oB_3)?%ocqsm6 zvz%l^7kw}D0wQZ_3*ZU^CPy?KTD`RAS;TO%39%zO^y$;@USWqWsBLvySr)*w@YyAu z%$CfhIH5^{AV#Xw3G1s>mPsvd#s%VpH*`8Aiwx~+KOLKOJA(3u?1_ahIOT|vz(c3L zxI=#J0-lWU&}VJ32oszsR`w{rE!0 z)G6c%?w#2z&|a}1!?MSTc%G(B@WsImX4~}{y6j$%t>?eq+&$iGHRX=w{upl~$5&Nu zzKer(Qg2z`c_D3<<*|Kl200^rnRyttyjj`=Dt&lJr>M`Jbb_WEAOwGQ-&&jSk8!IL z1=i-fO&`EB!M{qZf0bDO-%G5G8^3LM`D8{9;tDQ)*Nt)eD^AivazyYIKyOo*#jSjc z1rV`HPj86ZPUFM#f5T?DYx0b2q7>+EgzcGzKTkwLlK%G!V1a4$7%3zWfAlA^$ukX@ zViV?KXS%}9HzLkbP9=i_foO;wNLc~o+9mGdkxY?Y`|wwXq6Knr4;%o9@4$ltGm+aThc!E_F7hr@^hqFB^jEW})b#heH`<`b;ye!-5Fg6;1!n*KMn z;FOF8dN3y}Qs>Q0_ar$9PF^rFIMX1@jz^en*{TZmh^EH{oVi3E`QQOjkER~Cc^0?V zb}gv$I^YpI?O=za#})2yPa$r$`@tV~VLrwF$^aZ?vAxZ;*o~deaK2{f6K546=bOXn z6{kG6!C%5`j{~Rud%njNU?T@+)Z(15<2#j%UK zEGOYXKVE}%*vYQH_`V(Ok>!}Fo$aO-|CA1Q+uAqjbhj!_>3DY*$!+xU4IMBXd5`wM zJ#h>jlI>xS6A3+=;l1z`bLaS0^F}nEFYyjn{I!B*G)tE!0=j=JWV!x7d{88aUK5i5 WssNf}$scmD_TvhG>KcmM!Krp(g- literal 0 HcmV?d00001 diff --git a/public/upload/meow.jpg b/public/upload/meow.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f28151aefd57bcb1759b16f24632432acdc9f223 GIT binary patch literal 13753 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 literal 0 HcmV?d00001 diff --git a/public/upload/panda.jpg b/public/upload/panda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..000b33ccf11726ec51a730c934afdabbc4770558 GIT binary patch literal 24331 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 literal 0 HcmV?d00001 From 7e86462b4f1fd6e0de322dbd470d7aa5557181ed Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 18 Sep 2025 15:52:37 +0700 Subject: [PATCH 3/4] add contact endpoint --- app/Config/Routes.php | 8 +- app/Controllers/Contact.php | 133 +++++++++--------- .../Migrations/2025-09-12-011643_Contact.php | 3 +- 3 files changed, 74 insertions(+), 70 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 388e9c9..26bc1ed 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -53,7 +53,13 @@ $routes->get('/api/location', 'Location::index'); $routes->get('/api/location/(:num)', 'Location::show/$1'); $routes->post('/api/location', 'Location::create'); $routes->patch('/api/location', 'Location::update'); -$routes->delete('/api/location', 'Patient::delete'); +$routes->delete('/api/location', 'Location::delete'); + +$routes->get('/api/contact', 'Contact::index'); +$routes->get('/api/contact/(:num)', 'Contact::show/$1'); +$routes->post('/api/contact', 'Contact::create'); +$routes->patch('/api/contact', 'Contact::update'); +$routes->delete('/api/contact', 'Contact::delete'); $routes->get('/api/valueset', 'ValueSet::index'); $routes->get('/api/valueset/(:num)', 'ValueSet::show/$1'); diff --git a/app/Controllers/Contact.php b/app/Controllers/Contact.php index bdb9413..e940851 100644 --- a/app/Controllers/Contact.php +++ b/app/Controllers/Contact.php @@ -16,17 +16,17 @@ class Contact extends Controller { } public function index() { - $rows = $this->db->table('contact') - ->select("contact.*, contactdetail.ContactEmail, contactdetail.JobTitle, contactdetail.Department, occupation.AbbTex, occupation.FullText, occupation.Description") - ->join("contactdetail", "contact.ContactID=contactdetail.ContactID") - ->join("occupation","occupation.OccupationID=contactdetail.OccupationID") - ->get()->getRowArray(); + $sql = $this->db->table('contact'); + $sql->select("*") + ->join("contactdetail", "contact.ContactID=contactdetail.ContactID", "left") + ->join("occupation","contactdetail.OccupationID=occupation.OccupationID", "left"); + $rows = $sql->get()->getRowArray(); if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "no Data.", - 'data' => [], + 'data' => $rows, ], 200); } @@ -38,10 +38,10 @@ class Contact extends Controller { } public function show($ContactID = null) { - $row=$this->db->table('contact') - ->select("contact.*, contactdetail.ContactEmail, contactdetail.JobTitle, contactdetail.Department, occupation.AbbTex, occupation.FullText, occupation.Description") - ->join("contactdetail", "contact.ContactID=contactdetail.ContactID") - ->join("occupation","occupation.OccupationID=contactdetail.OccupationID") + $rows=$this->db->table('contact') + ->select("*") + ->join("contactdetail", "contact.ContactID=contactdetail.ContactID", "left") + ->join("occupation","occupation.OccupationID=contactdetail.OccupationID", "left") ->where('contact.ContactID', (int) $ContactID) ->get()->getRowArray(); @@ -65,40 +65,38 @@ class Contact extends Controller { $input = $this->request->getJSON(true); // Prepare data - $dataLocation = $this->prepareLocationData($input); - $dataLocationAddress = $this->prepareLocationAddressData($input); + $dataContact = $this->prepareContactData($input); + $dataContactDetail = $this->prepareContactDetailData($input); - if (!$this->validateData($dataLocation, $this->rules)) { + if (!$this->validateData($dataContact, $this->rulesContact)) { return $this->failValidationErrors($this->validator->getErrors()); } // Start transaction $this->db->transStart(); + $this->db->table('contact')->insert($dataContact); + $newContactID = $this->db->insertID(); - // Insert location - $this->db->table('location')->insert($dataLocation); - $newLocationID = $this->db->insertID(); - - // Insert address if available - if (!empty($dataLocationAddress)) { - $dataLocationAddress['LocationID'] = $newLocationID; - $this->db->table('locationaddress')->insert($dataLocationAddress); + + if (!empty($dataContactDetail)) { + $dataContactDetail['ContactID'] = $newContactID; + $this->db->table('contactdetail')->insert($dataContactDetail); } - // Complete transaction - $this->db->transComplete(); - if ($this->db->transStatus() === false) { $dbError = $this->db->error(); return $this->failServerError( - 'Failed to create location data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error') + 'Failed to create data (transaction rolled back): ' . ( $dbError['message'] ?? 'Unknown database error') ); } + + // Complete transaction + $this->db->transComplete(); return $this->respondCreated([ 'status' => 'success', - 'message' => 'Location created successfully', - 'data' => $dataLocation, + 'message' => 'Contact created successfully', + 'data' => $dataContact, ], 201); } catch (\Throwable $e) { @@ -115,23 +113,22 @@ class Contact extends Controller { $input = $this->request->getJSON(true); // Prepare data - $dataLocation = $this->prepareLocationData($input); - $dataLocationAddress = $this->prepareLocationAddressData($input); + $dataContact = $this->prepareContactData($input); + $dataContactDetail = $this->prepareContactDetailData($input); - if (!$this->validateData($dataLocation, $this->rules)) { + if (!$this->validateData($dataContact, $this->rulesContact)) { return $this->failValidationErrors( $this->validator->getErrors()); } // Start transaction $this->db->transStart(); - // Insert location - $this->db->table('location')->where('LocationID', $dataLocation["LocationID"])->update($dataLocation); + $this->db->table('contact')->where('ContactID', $dataContact["ContactID"])->update($dataContact); // Insert address if available - if (!empty($dataLocationAddress)) { - $dataLocationAddress['LocationID'] = $input["LocationID"]; - $this->db->table('locationaddress')->upsert($dataLocationAddress); + if (!empty($dataContactDetail)) { + $dataContactDetail['ContactID'] = $input["ContactID"]; + $this->db->table('contactdetail')->upsert($dataContactDetail); } // Complete transaction @@ -140,14 +137,14 @@ class Contact extends Controller { if ($this->db->transStatus() === false) { $dbError = $this->db->error(); return $this->failServerError( - 'Failed to update location data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error') + 'Failed to update contact data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error') ); } return $this->respondCreated([ 'status' => 'success', - 'message' => 'Location updated successfully', - 'data' => $dataLocation, + 'message' => 'Contact updated successfully', + 'data' => $dataContact, ], 201); } catch (\Throwable $e) { @@ -162,22 +159,21 @@ class Contact extends Controller { public function delete() { try { $input = $this->request->getJSON(true); - $LocationID = $input["LocationID"]; - if (!$LocationID) { - return $this->failValidationError('LocationID is required.'); + $ContactID = $input["ContactID"]; + if (!$ContactID) { + return $this->failValidationError('ContactID is required.'); } - - $location = $this->db->table('location')->where('LocationID', $LocationID)->get()->getRow(); - if (!$location) { - return $this->failNotFound("LocationID with {$LocationID} not found."); + $contact = $this->db->table('contact')->where('ContactID', $ContactID)->get()->getRow(); + if (!$contact) { + return $this->failNotFound("data with {$ContactID} not found."); } - $this->db->table('location')->where('LocationID', $LocationID)->update(['DelDate' => NOW()]); + $this->db->table('contact')->where('ContactID', $ContactID)->update(['EndDate' => NOW()]); return $this->respondDeleted([ 'status' => 'success', - 'message' => "Location with {$LocationID} deleted successfully." + 'message' => "Contact with {$ContactID} deleted successfully." ]); } catch (\Throwable $e) { @@ -189,35 +185,36 @@ class Contact extends Controller { } } - private function prepareLocationData(array $input): array { - $LinkTo = null; - if (!empty($input['LinkTo'])) { - $ids = array_column($input['LinkTo'], 'InternalPID'); - $LinkTo = implode(',', $ids); - } - + private function prepareContactData(array $input): array { $data = [ - "LocCode" => $input['LocCode'] ?? null, - "Parent" => $input['Parent'] ?? null, - "LocFull" => $input['LocFull'] ?? null, - "Description" => $input['Description'] ?? null, + "NameFirst" => $input['NameFirst'] ?? null, + "NameLast" => $input['NameLast'] ?? null, + "Title" => $input['Title'] ?? null, + "Initial" => $input['Initial'] ?? null, + "Birthdate" => $input['Birthdate'] ?? null, + "EmailAddress1" => $input['EmailAddress1'] ?? null, + "EmailAddress2" => $input['EmailAddress2'] ?? null, + "Phone" => $input["Phone"] ?? null, + "MobilePhone1" => $input["MobilePhone1"] ?? null, + "MobilePhone2" => $input["MobilePhone2"] ?? null, + "Specialty" => $input["Specialty"] ?? null, + "SubSpecialty" => $input["SubSpecialty"] ?? null, ]; - if(!empty($input["LocationID"])) { $data["LocationID"] = $input["LocationID"]; } + if(!empty($input["ContactID"])) { $data["ContactID"] = $input["ContactID"]; } return $data; } - private function prepareLocationAddressData(array $input): array { + private function prepareContactDetailData(array $input): array { $data = [ - "LocationID" => $input['LocationID'] ?? null, - "Street1" => $input['Street1'] ?? null, - "Street2" => $input['Street2'] ?? null, - "City" => $input['City'] ?? null, - "Province" => $input['Province'] ?? null, - "PostCode" => $input['PostCode'] ?? null, - "GeoLocationSystem" => $input['GeoLocationSystem'] ?? null, - "GeoLocationData" => $input['GeoLocationData'] ?? null, + "Code" => $input['Code'] ?? null, + "ContactEmail" => $input['ContactEmail'] ?? null, + "OccupationID" => $input['OccupationID'] ?? null, + "JobTitle" => $input['JobTitle'] ?? null, + "Department" => $input['Department'] ?? null, + "ContactStartDate" => $input['ContactStartDate'] ?? null, + "ContactEndDate" => $input['ContactEndDate'] ?? null, ]; return $data; diff --git a/app/Database/Migrations/2025-09-12-011643_Contact.php b/app/Database/Migrations/2025-09-12-011643_Contact.php index d85d5a6..3b6eb45 100644 --- a/app/Database/Migrations/2025-09-12-011643_Contact.php +++ b/app/Database/Migrations/2025-09-12-011643_Contact.php @@ -8,7 +8,7 @@ class CreateContactTable extends Migration { public function up() { // Contact $this->forge->addField([ - 'ContactID' => [ 'type' => 'INT', 'constraint' => 11 ], + 'ContactID' => [ 'type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true ], 'NameFirst' => [ 'type' => 'VARCHAR', 'constraint' => 100, 'null' => true ], 'NameLast' => [ 'type' => 'VARCHAR', 'constraint' => 100, 'null' => true ], 'Title' => [ 'type' => 'VARCHAR', 'constraint' => 50, 'null' => true ], @@ -32,6 +32,7 @@ class CreateContactTable extends Migration { 'ContactDetID' => [ 'type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true ], 'ContactID' => [ 'type' => 'INT', 'constraint' => 11 ], 'SiteID' => [ 'type' => 'INT', 'constraint' => 11, 'null' => true ], + 'Code' => [ 'type' => 'varchar', 'constraint' => 11, 'null' => false ], 'ContactEmail' => [ 'type' => 'VARCHAR', 'constraint' => 150, 'null' => true ], 'OccupationID' => [ 'type' => 'VARCHAR', 'constraint' => 50, 'null' => true ], 'JobTitle' => [ 'type' => 'VARCHAR', 'constraint' => 100, 'null' => true ], From 5c67b06431ed1bb9e0f07828586bd04a2c668948 Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 18 Sep 2025 16:31:56 +0700 Subject: [PATCH 4/4] create occupation endpoint --- app/Config/Routes.php | 6 ++ app/Controllers/Occupation.php | 169 +++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 app/Controllers/Occupation.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 26bc1ed..cd0a95a 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -61,6 +61,12 @@ $routes->post('/api/contact', 'Contact::create'); $routes->patch('/api/contact', 'Contact::update'); $routes->delete('/api/contact', 'Contact::delete'); +$routes->get('/api/occupation', 'Occupation::index'); +$routes->get('/api/occupation/(:num)', 'Occupation::show/$1'); +$routes->post('/api/occupation', 'Occupation::create'); +$routes->patch('/api/occupation', 'Occupation::update'); +//$routes->delete('/api/occupation', 'Occupation::delete'); + $routes->get('/api/valueset', 'ValueSet::index'); $routes->get('/api/valueset/(:num)', 'ValueSet::show/$1'); $routes->post('/api/valueset', 'ValueSet::create'); diff --git a/app/Controllers/Occupation.php b/app/Controllers/Occupation.php new file mode 100644 index 0000000..bd1ed53 --- /dev/null +++ b/app/Controllers/Occupation.php @@ -0,0 +1,169 @@ +db = \Config\Database::connect(); + $this->rulesOccupation = [ + 'AbbTex' => 'required', + 'FullText' => 'required' + ]; + } + + public function index() { + $rows = $this->db->table('occupation')->select("*")->get()->getRowArray(); + + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => "no Data.", + 'data' => $rows, + ], 200); + } + + return $this->respond([ + 'status' => 'success', + 'message'=> "fetch success", + 'data' => $rows, + ], 200); + } + + public function show($OccupationID = null) { + $rows=$this->db->table('occupation')->select("*")->where('occupationID', (int) $OccupationID)->get()->getRowArray(); + + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => "Data not found.", + 'data' => [], + ], 200); + } + + return $this->respond([ + 'status' => 'success', + 'message'=> "Data fetched successfully", + 'data' => $rows, + ], 200); + } + + public function create() { + try { + $input = $this->request->getJSON(true); + $dataOccupation = $this->prepareOccupationData($input); + + if (!$this->validateData($dataOccupation, $this->rulesOccupation)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + + $this->db->transStart(); + $this->db->table('contact')->insert($dataOccupation); + + if ($this->db->transStatus() === false) { + $dbError = $this->db->error(); + return $this->failServerError( + 'Failed to create data (transaction rolled back): ' . ( $dbError['message'] ?? 'Unknown database error') + ); + } + + // Complete transaction + $this->db->transComplete(); + + return $this->respondCreated([ + 'status' => 'success', + 'message' => 'data created successfully', + 'data' => $dataOccupation, + ], 201); + + } catch (\Throwable $e) { + // Ensure rollback if something goes wrong + if ($this->db->transStatus() !== false) { + $this->db->transRollback(); + } + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function update() { + try { + $input = $this->request->getJSON(true); + $dataOccupation = $this->prepareOccupationData($input); + + if (!$this->validateData($dataOccupation, $this->rulesOccupation)) { + return $this->failValidationErrors( $this->validator->getErrors()); + } + + $this->db->transStart(); + $this->db->table('occupation')->where('OccupationID', $dataOccupation["OccupationID"])->update($dataOccupation); + + if ($this->db->transStatus() === false) { + $dbError = $this->db->error(); + return $this->failServerError( + 'Failed to update data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error') + ); + } + + $this->db->transComplete(); + + return $this->respondCreated([ + 'status' => 'success', + 'message' => 'Occupation updated successfully', + 'data' => $dataContact, + ], 201); + + } catch (\Throwable $e) { + // Ensure rollback if something goes wrong + if ($this->db->transStatus() !== false) { + $this->db->transRollback(); + } + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + /* + public function delete() { + try { + $input = $this->request->getJSON(true); + $OccupationID = $input["OccupationID"]; + if (!$OccupationID) { + return $this->failValidationError('ContactID is required.'); + } + + $occupation = $this->db->table('occupation')->where('OccupationID', $OccupationID)->get()->getRow(); + if (!$occupation) { + return $this->failNotFound("data with {$OccupationID} not found."); + } + + $this->db->table('occupation')->where('OccupationID', $OccupationID)->update(['EndDate' => NOW()]); + + return $this->respondDeleted([ + 'status' => 'success', + 'message' => "{$ContactID} deleted successfully." + ]); + + } catch (\Throwable $e) { + // Ensure rollback if something goes wrong + if ($this->db->transStatus() !== false) { + $this->db->transRollback(); + } + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + */ + + private function prepareOccupationData(array $input): array { + $data = [ + "AbbTex" => $input['AbbTex'] ?? null, + "FullText" => $input['FullText'] ?? null, + "Description" => $input['Description'] ?? null, + ]; + + if(!empty($input["OccupationID"])) { $data["OccupationID"] = $input["OccupationID"]; } + + return $data; + } +} \ No newline at end of file